Hacker News new | ask | show | jobs
by reggieband 1372 days ago
I see some asking for stack support in the logs, and that is something I would be looking for. Often when an error happens on a server it might be inside some generic utility. At least with a stack, you might realize that all of the calls to that utility function are coming from the same location a few steps up the stack. In my experience that can significantly speed up identifying the root cause of issues.

I'm not sure I like the way they are handling attributes either. One pattern I strongly discourage on projects I work on is formatting data into the log message. When I've had access to decent log aggregation tools (e.g. Splunk, Datadog) I like to generate reports on error messages. That is usually possible with regex magic but in my experience it is much much cleaner to have a static unchanging message for all messages. I then store all additional details in a separate part of the log line. I tend to prefer JSON for those details since it is well supported and even parsed by default by many tools. Another benefit of JSON for those additional details is that it is supports arrays and hash-tables. The attribute system proposed here doesn't seem to have that same hierarchical attribute support.

IMO, unified, clean and consistent logging is one of the most underrated techniques for maintaining long running services.

3 comments

This is what annoys me in my current job - every service uses unstructured logging. We use a couple popular loggers in Go and still, people put values in messages rather than just make the message static and put all variables into, well, variables.
These days I kind of wish we didn't do text logging at all. There's essentially two types of logs: fixed messages, and values.

A binary logging protocol can make this definition explicit and more efficient: you're either emitting a token for the fixed message in your applications format, or you're emitting values...and a fixed token for the format string, which can be parsed and reconstructed later.

Our applications don't need to be doing this sort of text formatting in them at all, and we need the developer interface to make explicit what's happening and what's important.

All I ever want to know is what line of code in MY code is in the stack trace. Maybe I’m doing it wrong but this is a regular pain point for me.

Sometimes I’ll even get Python or JS traces that don’t even list a single line of my own code.

I think a lot of people want what you mentioned. But I also think that even if stack support is implemented, they will "keep it simple" and pass the responsibility of extracting the location/details of your code from the stack trace to, you. That will give rise to everyone writing there own variety of utility/common stack parsing methods and then libraries will spring-up that provide such conveniences and it'll go on to become its own thing.

I feel like that is Go's underlying theme: "we don't provide last-mile-connectivity; how else will the ecosystem grow?!"

Isn't letting the log library do the formatting a common practice? That way you can get formatted logs and the library can cluster logs by the format string instead of the final output.
I don't care about the formatting, I care about the available data types. JSON is just easy to use since it includes arrays/hash-tables and it is already supported by a large number of tools.

If you look at the Attr type definition you can see they support many primitive types including Int, Float, Bool, String, Duration, and Time. So if I had a record type, like a customer I could do:

    slog.LogAttrs(slog.ErrorLevel, "oops",
        slog.Int("customer_id", 123456), 
        slog.Float("customer_balance", 12.42)
        slog.Time("customer_updated_at", ...))
But I would prefer a structured data type there. Something more like:

    { "customer": {
        "id": 123456,
        "balance": 12.42
        "updated_at": ...
        }
    }
In fact, I'm not sure how I'd go about supporting arrays as Attr except with keys like "item_0", "item_1", etc. Or maybe serialize it into a representation like comma separated values. But now I'm coupling my log to a custom serialization/deserialization - I'd rather just use JSON once again since most tools will know how to handle it.