Making syslog() not block
github.com
github.com
I've always felt that using UDP is an uneasy tradeoff -- you're solving the problem of blocking, but at the cost of getting no batching whatsoever. When you're logging to disk, TCP, or memory, the fast path call to log just plops your data into a buffer and returns to you. More messages, the bigger your buffer gets. With UDP, each message instead goes straight to the NIC and out.
Kafka makes a different tradeoff -- buffer/batch to disk. Once you have enough data, compress it and ship it off reliably. If your consumer goes away, buffer as much as you can before losing messages; disk is cheap! The cost comes as small additional latency. In the fast path, it's quick (data stays RAM resident, and it's much cheaper to compress & batch send 1000 messages than 1000 UDPs).
As I understand the use case for this software, it would be talking UDP to a local syslog server, not over the network.
At Facebook, we use scribe, and generally use (in-memory, in-app) batched writes to local scribe, and then batched writes (memory+disk, scribe daemon) from that local scribe to an upstream scribe storage system.
If the standard syslogd is inadequate, how about using a different logger? Gerritt Pape's svlogd, an implementation of DJB's daemontools loggers, solves this problem very nicely, is very reliable, can log over UDP and write to disk if desired. Heck, it can even replace syslog and run more reliably.
Not to say that this software is not useful. It is a great solution if the client software insists on using syslog and cannot be modified or reconfigured and syslogd cannot be modified or replaced. However, these are quite specific and generally unusual cases. For more prosaic circumstances, there are simpler and better solutions.
Does it drop messages in this situation? Is that why you warn that "liblogfaf should not be used in an environment where reliable log message delivery is required."? That is probably the most elegant solution.
Thus you lose log messages.
It does not, however, affect the application that is sending the log messages because sending the UDP packet is always possible (minus other kernel issues).
Depending on your use-case you might want not start dropping log messages when the load is high enough for a log processor to not be able to process them. My reasoning: At that point, something is seriously wrong and according to Murphy, the message that's going to be dropped is the one that contains the actual reason for the issue amidst all the other log spam caused by the real issue.
Hi, I am a country bumpkin nerd. What does this mean, please? Thanks.
"Facebook won't sue you over patents in this code."
Is this to workaround programs that respond to logs and can deadlock when logging (e.g. logrotate)? Workaround other broken programs (noncritical logspam at emergency level)?
I suppose such an approach is less ideal when using a language that isn't truly concurrent or if the code doesn't run long enough for it to be efficient to spawn a logging thread.
Also: Why are they using LD_PRELOAD to do this?
I did not look too closely at the implementation, but are they actually using UDP and just throwing away log entries under load? That is bad engineering.
Imagine you are running an application, which is some sort of a network server - it accepts a connection, parses the query, logs it using syslog(), and then returns some sort of response. If it gets blocked while logging, response might be lost or delayed. If serving the request is more important than logging it (which might not be the case for all applications), you might want to ensure that your logging does not block the request processing flow.
If there is one application like this and it's open source, you can patch it directly. However, if you have several applications with similar logging behavior or if you cannot modify source code, overriding syslog() allows you to de-couple logging without changing the application. Of course, you should have monitoring in place to catch situations when your logging system cannot keep up (or malfunctions), but when that happens your application keeps running and you only lose your log data.
e.g. I wish there was less magic (or whole mini-industry) behind hooking functions this way.