2

We are currently running a command on a Linux box that we have little control over. The command tails a log file, piping the results to an outbound SSH connection to our server, redirecting the output to a file.

The command we use to do this is:

sh -c tail -f /var/log/x/a.log | ssh [email protected] -T 'cat - > /media/z/logs/a.log'

We are then able to perform additional processing of the captured log segment.

However, we now need the ability to forward the streaming output of an additional log file using the same ssh connection.

Doing

sh -c tail -f /var/log/x/a.log /var/log/x/b.log | ssh [email protected] -T 'cat - > /media/z/logs/a.log'

works, but it combines the two log files into one (with a header appearing before each line saying which file it came from).

We need the output to bee two different files but are limited to a single outbound SSH connection from the log server to our server. We do not have sudo or admin rights on the log server and are not able to get any software that would require it installed. If it matters, the remote log server is running CentOS and our server is running Ubuntu.

Is there a way to split the output into two files? Or some other method of running multiple commands in parallel over the reverse SSH connection?

1
  • @AdminBee - A single connection at a time, unfortunately. Commented Apr 28, 2020 at 13:53

2 Answers 2

1

If little.control.server has perl installed, you can use GNU Parallel by running parallel --embed on your development machine:

parallel --lb --tag tail -f ::: /var/log/x/a.log /var/log/x/b.log |
       ssh [email protected] -T perl -e \''
        $|=1; # if you need less buffering
        open(A, ">", "a.log");open(B, ">", "b.log");
        while(<>) {
           if(s:/var/log/x/a.log\t::) { print A } 
           if(s:/var/log/x/b.log\t::) { print B }
        }'\'

Also look into ssh -M for multiplexing multiple sshs over a single ssh channel.

1

Your own solution:

sh -c tail -f /var/log/x/a.log /var/log/x/b.log | ssh [email protected] -T 'cat - > /media/z/logs/a.log'

gets all the needed log information to the log server, the (Ubuntu) server that is under your control. (Writing it to a file a.log seems slightly confusing, because it is really writing a file more like a-and-b.log .

So, one possible solution seems to be: write a script that reads that resulting single a-and-b.log file with its header lines, and writes the two separate logs (without header lines, just using them to determine which file each log line belongs to). Run this script on the log server, and you should be all set.

Is this an acceptable answer? It doesn't do anything "clever" with SSH, because it seems that is not needed -- tail already looks at both logs and sends all the log entries via a single SSH connection to the log server, with headers to identify which log they come from. I think you just need to break them back out into two files, on the log server.

2
  • You're right, the combined log file is badly named in my example code. Thanks for the suggestion. Do you know of a way through Linux commands to split the output of the file on our server? We could probably get some regExes built, but that approach seems brittle. Part of the issue is that the header lines only appear when output is detected from a different file, so the number of lines after each header is variable. Commented Apr 28, 2020 at 13:56
  • An awk script would be one "obvious" way to proceed, to me at least. Perl or Python would also work fine. It could be done in bash if you prefer, but I think it would be uglier. Commented Apr 29, 2020 at 15:26

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.