I built LogLayer to address these pain points by introducing a fluid, expressive API. With methods like "withMetadata" and "withError", LogLayer separates object injection from the log message itself, making your logging code both cleaner and more maintainable.
Logs are processed through a LogLayer Transport, which acts as an adapter for your preferred logging library. This design offers several key advantages:
- Multi-Transport Support: Send logs to multiple destinations (e.g., DataDog and New Relic) simultaneously. I've personally used this feature to ship logs directly to DataDog without relying on their APM package or sidecars.
- Easy Logger Swapping: If you’ve ever used Pino with Next.js, you might have encountered issues where it doesn’t work out of the box after a production build without webpack hacks. With LogLayer, you can swap in a better-suited library without touching your logging code.
I spent a good few months on and off and used my winter break to launch version 5 of LogLayer, and also created the documentation using Vitepress.
LogLayer has been battle-tested in production at Airtop (https://airtop.ai), where it’s been an integral part of our systems for years (we were running as Switchboard for almost four years and pivoted late last year).
(Disclaimer: I work at Airtop, but LogLayer is not sponsored / affiliated with them.)
It makes me actively disinterested in these libraries. I just want some built in interface with levels, hierarchy, and structured logging
Though I myself prefer Log4J2, as I'm already using Log4J2 as the concrete logging implementation.
The API of Log4J2 and SLF4J v2 are similar enough that it does not matter for basic usage, I don't see the benefit of SLF4J in a project that's already using Log4J2.
It probably has the most complex and messy logging story of any language - but at least the solutions are very mature at this point.
(There are some of Microsoft.Extensions that exist outside of dotnet/runtime in dotnet/extensions: https://github.com/dotnet/extensions/tree/main/src/Libraries)
In Java it is common to use the MDC support of slf4j. You can add to metadata in thread local variables, so that you don't have to add it at every logging site.
Where does log layer fit into the broader ecosystem?
Although I lack experience, this version of LogLayer allows people to build their own transports / plugins that someone with experience and familiarity in this space can build a LogLayer integration.
That being said, I'll definitely start reading more into it with the link you provided and any other resources would be appreciated!
Thanks for your hard work!
The advantage for the in-app case is that it's fast to on-board with and doesn't require significant / any devops involvement compared to the above scenario.
One downside though is depending on how those logs get shipped, it might not scale well if you're writing an extreme frequency of logs (it's possible to reach HTTP limits with DataDog and New Relic log publish APIs in a high volume/frequency situation), and that's when you would want to move to and external collector that can process logs in a much more asynchronous fashion.
I'm not sure if the question is specific to LogLayer or just talking about logger transports in general that does in-app push, but I see the cloud collector features of LogLayer as something that you can easily add to your logging stack when you start out small and need it, but transition to an external collector later.
(One might argue that some OTEL tools can also do this, but as stated in another response, I'm not familiar enough to know if they'd do a better job or not in terms of the overall logging DX that LogLayer provides; their primary job is to ship logs from my understanding.)
You get a growing combination of N apps x M log servers to support and link into the application. Even if you only use one of them yourself. Ops should be able to change to a new logging backend without rebuilding every application.
Bugs in the log shipper has the possibility to take down your app, you never want this. Also think about the unnecessary security surface this adds, especially when multiplied by M above. (log4j anyone?)
When the log server is unavailable or saturated you still want those file or console logs available for last resort debugging.
Shutting down the app risks loosing last minute of unshipped logs, unless you require slow graceful shutdowns, which is never a good idea. Think about crashes, where you need logs the most.
Use sidecar and similar strategies instead. You are most likely also running some third party application elsewhere, where you don't have the option to rebuild with a new logger, so you need this type of knowledge anyway.