martosaur

martosaur

Seriously, what do we do with logs in Elixir? There is seemingly no way to make them good both in dev and prod. This is especially noticeable in libraries, which often choose to simply not log.

In my new post I propose a solution and explain why telemetry isn’t quite it.

TL;DR: structured logging aka reports logging is a great way to make your logs programmatically accessible and thus customizable while still providing a preferred, terminal-friendly text representation

Showing Posts 1 to 10

krasenyp

krasenyp

Good article buy I was surprised Syslog 5424 wasn’t mentioned at all. No need to come up with a format while there’s already a standard which includes both structured data and human-readable portion.

dimitarvp

dimitarvp

Well, TIL about RFC / syslog 5424.

lud

lud

I use a telemetry based logger in my libs (gen_mcp : gen_mcp/lib/gen_mcp/telemetry_logger.ex at main · lud/gen_mcp · GitHub , crown : crown/lib/crown/telemetry_logger.ex at main · lud/crown · GitHub )

I believe you should expand that part of the post, or make a follow post, because it’s the best solution (to me at least): it lets people enable the logs they want, and does not get in the way.

martosaur

martosaur OP

Hmm, I admit I don’t have a lot of experience with Syslog 5424, but I think it’s a format, right? Just like GCP or Datadog json-based formats? In that case, it’s not really relevant here, since I’m not proposing a new export format, but rather a way to write logs that will better accommodate any format. In general case, a running app can have multiple logging handlers: a default handler with default terminal formatter, an additional handler with json format and another one that sends errors to Sentry over HTTP. Reports are equipped to work well with all of them.

martosaur

martosaur OP

I touched this topic at the end. Telemetry doesn’t really solve this particular problem. In your library, you still have a handler that calls Logger.log with dynamic message and metadata, which is ok, but not perfect. If users were to customize logs, they would have to basically throw away all your efforts and do the work themselves. Telemetry just makes it easier to do.

You could totally use reports in your handler and that would make your logs even better!

lud

lud

I touched this topic at the end

I know and mentioned it :slight_smile:

Telemetry loggers like mine have advantages too, it’s opt-in, filtering by prefixes is easy and straightforward, and it’s telemetry, you are dispatching an event that can be logged, but can also be used for other purposes such as converting to OTel metrics.

But I don’t disagree with your post at all, actually I think it’s very interesting.

You could totally use reports in your handler and that would make your logs even better!

Yes! A basic telemetry logger could in addition call the logger with the whole telemetry metadata and report_cb instead of converting to a string. So users can attach the default logger and filter / reformat, or they can filter at the producer level (and still reformat).

they would have to basically throw away all your efforts and do the work themselves

This is a good thing in my opinion. It’s basic code that is really easy to write. Writing a filter is more or less the same level of effort, but attaching your own telemetry handler lets you start with a blank slate.

hauleth

hauleth

RFC 5424 is just the output format, not the approach to firing logs, as @martosaur pointed out. This format is also quite painful to use in many places, because you need to apply for Private Enterprise Number if you want to conform to it. And SD-DATA from RFC 5424 is more for metadata rather than message itself (there is difference, substantial difference, between these two).

TBH the same applies to report/structured logs. Telemetry is log dispatching mechanism (very primitive one), just focused mostly on metrics.

LostKobrakai

LostKobrakai

This feels very much in line with me favoring using exception modules (Example) to build exception messages from data – even though I myself am not the best in following that advice.

But besides the technical question there’s also the “what is worth logging and how do I decide on a severity” portion, especially when working on a library. Because if that one’s not right then people need to start filtering out logs and I personally prefer to work additive rather than logging stuff only for it then needed to be filtered. That’s what I personally struggle more with. Maybe that’s why I tend to debug in production using traces. I know they’re not useful when you cannot reproduce an issue, but when you can they’re just so much more flexible.

Edit:

I just looked at logger — OTP 29.0.3 (kernel 11.0.3). It seems like there’s also a arity 2 version, which would allow replacing the :io formatting with a custom to string formatting. That could be used to make this a bit more approachable from elixirs end.

hauleth

hauleth

That is why I am not much of a fan of Elixir’s default of Logger level set to :debug. Erlang which sets it by default to :notice is IMHO better one, as it (by default) filter more messages that are irrelevant to the user. It has slight disadvantage in development, but IMHO we should make defaults safe for production, not for development.

Anyway, I digress a little.

Actually it is the exact opposite. The reason for that is that when you use report_cb/2 then it is your requirement to ensure, that for example line length is preserved. If you use report_cb/1 it is left to the formatter to keep all that requirements.

LostKobrakai

LostKobrakai

I understood that. But it means :io.format is no the only possible option. I do agree with the blog post that this is quite the arcane formatting syntax, which I’ve never really seen favored by people using elixir. There could be alternatives still handling all those constraints, but using a different syntax for formatting.

Where Next? Top

Trending in Blog Posts Top

mudasobwa
I am seeing a lot of aplications of Argumentum ad Vericundiam in software discussions. They do link some piece of writing and point us to...
New
bartblast
Hey folks, I just published a post about Hologram’s funding and where the project goes next - the short version: Curiosum as Main Spons...
New
pckrishnadas88
A while back, I had to process millions of database updates in a legacy system that was already hitting its 64 GB RAM limit, so scaling t...
New
rhcarvalho
At the heart of every Phoenix application is the often “invisible” HTTP server layer. For over a decade Cowboy has served the community ...
New
smaller_infinity
I recently figured out how to the the Rust hotpath profiling crate running in an elixir benchmark script (for profiling NIFs). I had some...
New
rhcarvalho
The Phoenix framework is notorious for its long term stability and dependability. Unlike most comparable projects, the Phoenix team activ...
New
pckrishnadas88
I’ve published Part 3 of my Elixir distributed systems learning series. This part explores process monitoring using the low-level primit...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
wintermeyer
There are three potential reasons for members of this forum to have a look at https://vutuv.de You are tired or annoyed of LinkedIn. Yo...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews