Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I redirect tail -f output to curl (HTTP stream)

I want to collect realtime logs from embedded devices. The device have limited command. It would be great if I can do it by a shell script.

So, can I do something like this tail -f /var/logs/some-log.log | curl -X POST --data-urlencode @- http://<log-collaction.website>?

I have tried many ways, but all failed. For example:

ping www.google.com | while read -r LINE; do curl -X POST --silent --data-binary $LINE "http://localhost:8080/"; done

The above command works, but it will post messages line by line. However, I think the performance is not good if I have a lot of content to send.

I know HTTP/1.1 support chunked encoding. How can I redirect a program's stdout to curl or a HTTP stream (maybe long connection?).

Thanks

like image 973
Charles Wei Avatar asked Sep 09 '17 15:09

Charles Wei


People also ask

How do you grep the output of a curl?

Using Curl Options to Allow Grep The --stderr option in curl allows you to redirect the standard error (STDERR) to a file. If you specify the filename as - (a single dash) the output will be written to standard output. This allows you to pipe it to grep without any shell redirection.

Where does curl output to?

If not told otherwise, curl writes the received data to stdout. It can be instructed to instead save that data into a local file, using the --output or --remote-name options. If curl is given multiple URLs to transfer on the command line, it similarly needs multiple options for where to save them.

Does curl write to stdout?

When asking curl to get a URL it'll send the output to stdout by default. You can of course easily change this behavior with options or just using your shell's redirect feature, but without any option it'll spew it out to stdout.


1 Answers

You can use a tool like buffer (or perhaps even better mbuffer) to combine both strategies.

tail -f  /var/logs/some-log.log | buffer | while read -r LINE; do curl -X POST --silent --data-binary $LINE "http://localhost:8080/"; done

This reduces the number of HTTP requests by curl to your webservice (but possibly makes you lose some logs when your connection dies).

However, I agree with Nick Russo that implementing websockets might be a better idea altogether.

Hope this helps!

like image 109
Bart Van Loon Avatar answered Oct 27 '22 18:10

Bart Van Loon