<div dir="ltr">Hi.<div><br></div><div>We were using lager for about 7 years and have rewritten it to our own subsystem called "events" (not opensourced and possible will not be).</div><div><br></div><div>Why?</div><div><br></div><div>Because logging has changed. </div><div><br></div><div>In the ancient times of old sysadmins with beards that are boasting big uptime, logging was a synonym of appending lines to text file and extracting data from these lines with a perl script.</div><div><br></div><div>Things like webalyzer or radius were an ancient ancestors of modern ELK/Clickhouse stack.</div><div><br></div><div>Nowadays logging is changing and it seems that it has completely splitted into 2 different data streams.</div><div><br></div><div>One data stream is consumed by business analytics. It is collecting events from happy path. Request started, request finished, upstream request made, etc.  Here we need to log structured key-value objects that are collected from all servers of the project and linked together according to some metadata like "request-id" or "user-id"</div><div><br></div><div><br></div><div><br></div><div>Another data stream is about exceptions. They need to be collected and sent directly to developer tool like Sentry (on-premises and free. It is excellent) or Airbrake (good old service).</div><div><br></div><div><br></div><div><br></div><div>So we have changed from   lager:info("HTTP request handled") to</div><div><br></div><div>events:http_request([{ip,IP},{user_id,UserId},....]).</div><div><br></div><div>"events" is our own module with small preprocessor that takes all calls like  events:http_request on compile time and checks if they are defined in config file.</div><div><br></div><div>Thus we can simulate some kind of static typing and give our customers documentation on all methods without grep.</div><div><br></div><div>In config file it is possible to declare sinks like:</div><div><br></div><div>notify broken_video_stream {</div><div>  only media=mystream;</div><div>  sink <a href="http://logger-server/logs.php">http://logger-server/logs.php</a>;</div><div>}</div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div>Then appeared new logger and I see that it has:</div><div><br></div><div>1) metadata.  It is very, very important.  Metadata is more important than text of message.</div><div>In our events we have following approach:</div><div>events:http_request([{ip,IP},{user_id,UserId},{method,Method}]).<br></div><div><br></div><div>and</div><div><br></div><div>{http_request,  ["HTTP request from ip ",ip, {user_id, [" user_id ",user_id],""}, " to ",method]}.</div><div><br></div><div>Yes, it is lager conditional formatting and it is really good. Metadata for robots, text line for sysadmins debugging this software.</div><div><br></div><div>2) remote proxy. Very cool.  It happened to be designed exactly 1-1 as we have designed in Flussonic, so it seems that we have done it right =)</div><div><br></div><div>3) lack of central process.</div><div><br></div><div>error_logger and lager were a big problem for us because they had single bottleneck that was working even for debug messages. Very often lager_event became a reason of crash for flussonic, so we have removed it and now it is ok.</div><div><br></div><div>However, I see that we have a bit more complicated mechanism of log buffering and handler overload.</div><div><br></div><div><br></div><div><a href="https://gist.github.com/maxlapshin/ea632f04f79188aaba46d3a92406f8f6#file-events_router-erl-L94">https://gist.github.com/maxlapshin/ea632f04f79188aaba46d3a92406f8f6#file-events_router-erl-L94</a><br></div><div><br></div><div>Before sending message to log handler, we check if it is overloaded, then check its configuration and only after this we send message to log sink.</div><div><br></div><div>Overloading is checked by each sink itself: it sends message to itself:</div><div><a href="https://gist.github.com/maxlapshin/7873727e3f93519cf4bb14287264fd3d#file-events_sink-erl-L15">https://gist.github.com/maxlapshin/7873727e3f93519cf4bb14287264fd3d#file-events_sink-erl-L15</a><br></div><div><br></div><div><br></div><div>All this is very important, because logging must not kill system due to slow disk or network.</div><div><br></div><div><br></div><div><br></div><div><br></div><div>I want to thank again for new system, I will think how to combine our private logging subsystem with standard infrastructure.</div><div><br></div><div>If our system is of some interest, I can open it code and explain our design ideas.</div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div></div>