Live data from Hacker News

Structured logging with slog

go.dev

111–120 of 174 posts

Re: Structured logging with slog

#111
I guess it's nice to have a standard, but I wish the Golang developers stopped introducing stuff like "args ...any" all over the place in the standard library.

It's not the level of type-safety that I expect from a strongly typed language.

Re: Structured logging with slog

#112

Structured logging is such an easy to gain, massive improvement to observability. Assuming you can pay for the log processor to make sense of it all :) I’ve been working on a side project to bring something like the DataDog log explorer to the local development environment. The prototype I made has already been extremely helpful in debugging issues in a very complex async ball of Rails code. Does something like that…

The Grafana stack, including Loki for logs, can be started easily in a docker-compose project in your local environment. Not that Grafanas log viewer is the best in class but it’s at least something. For terminal fans there is a logcli.

If you are concerned with cost of the log processor, Loki again has your back by being very easy and lightweight to deploy. Giving you same tools in dev as in prod.

Re: Structured logging with slog

#113

Earlier quoted context omitted.

> providing a core library way of wrapping with stacktraces would be a very useful next step What eventually became the standard library error wrapping proposal evolved from the work done on the Upspin project. It did include stacktraces, and believed like you that it would be useful to have them. But analysis of the data showed that nobody ever really used them in practice and, for that reason, was removed from the…

In the last few months I've realized what I desperately need: a way to wrap an error with a call stack at the point where it enters our code base. This would probably save me on average 20-30 minutes a week. I see this all the time: main.go:141 error: could not transmogrify the thing: a144cd21c48 And then I literally grep the code base to find the error message. That works ~50% of the time, but the other 50%, I see t…

This is such an infuriating problem. I'm convinced I'm using Go wrong, because I simply can't understand how this doesn't make it a toy language. Why the $expletive am I wasting 20-30 and more minutes per week of my life looking for the source of an error!?

Have you seen https://github.com/tomarrell/wrapcheck? It's a linter than does a fairly good job of warning when an error originates from an external package but hasn't been wrapped in your codebase to make it unique or stacktraced. It comes with https://github.com/golangci/golangci-lint and can even be made part of your in-editor LSP diagnostics.

But still, it's not perfect. And so I remain convinced that I'm misunderstanding something fundamental about the language because not being able to consistently find the source of an error is such an egregious failing for a programming language.

Re: Structured logging with slog

#114
post #8

Admittedly I'm not a huge fan of having: slog.Info("hello, world", "user", os.Getenv("USER")) It's a little magical that "user" is a key. So what if you have multiple key-value pairs? Arguably it most likely going to be obvious which is the keys, but having every other value be a key and the rest values seems a little clumsy. I really like Pythons approach where you can have user="value" it makes things a bit more cl…

You use attrs [1] instead. I personally find this much more readable, and prefer this.

  slog.Info("hello, world", slog.String("user", os.Getenv("USER")))
[1]: https://pkg.go.dev/log/slog#hdr-Attrs_and_Values

Re: Structured logging with slog

#115
post #70
post #35

Earlier quoted context omitted.

Rust seems to do find with a de-facto logging library, and the Java ecosystem seems to have converged on a common API, but with a lot of effort I think.

PHP did so with PSR-3 as well https://www.php-fig.org/psr/psr-3/ .

A PSR is not de facto, nor is this structured.

Re: Structured logging with slog

#116
post #22
post #8

Admittedly I'm not a huge fan of having: slog.Info("hello, world", "user", os.Getenv("USER")) It's a little magical that "user" is a key. So what if you have multiple key-value pairs? Arguably it most likely going to be obvious which is the keys, but having every other value be a key and the rest values seems a little clumsy. I really like Pythons approach where you can have user="value" it makes things a bit more cl…

It’s not without precedence, for example: https://pkg.go.dev/strings#NewReplacer I don’t mind it. You can use LogAttrs if you want to be explicit. Although I do wonder if there’s anything tricky with the type system that is preventing something like this from being supported: https://go.dev/play/p/_YV7sYdnZ5V

You don’t need LogAttrs to pass in Attr entries, it should work fine with normal functions

The reason it doesn’t use maps is that maps are significantly slower, TFA has an entire section on performances.

However if you prefer that interface and don’t mind the performance hit, nothing precludes writing your own Logger (it’s just a façade over the Handler interface) and taking maps.

Re: Structured logging with slog

#117
post #8

Admittedly I'm not a huge fan of having: slog.Info("hello, world", "user", os.Getenv("USER")) It's a little magical that "user" is a key. So what if you have multiple key-value pairs? Arguably it most likely going to be obvious which is the keys, but having every other value be a key and the rest values seems a little clumsy. I really like Pythons approach where you can have user="value" it makes things a bit more cl…

Rust's slog ( https://docs.rs/slog/ ) does: use slog::info; ... info!("hello, world"; "user" => std::env::var("USER"));

It can do that because Rust’s macros can have their own mini language at the top level, and can transform that into whatever data structure they want under the cover.

For better or for worse, Go doesn’t have that.

Re: Structured logging with slog

#118

Earlier quoted context omitted.

The lack of Error Handling in Go is a feature, not a bug. See here: https://go.dev/doc/faq#exceptions . I think I'd be disappointed if Try/Catch ever made their way into the language.

Error handling != exceptions. Step one would bee sum types, so only valid value space can be represented (return value or error, but not both or neither).

What would be the big gain from this, over the existing approach using multiple return values?

Re: Structured logging with slog

#119
post #105

Earlier quoted context omitted.

In this use case using maps doesn't solve any problem, requires at least one allocation, and requires hashing each key. This is not even an interesting discussion.

I can see the case for flat logging, aka. key value logging, as an optimization for very, very performance critical code that needs to emit string logs. That however, isn’t mainstream in my experience. The far, far more common case is logging in code with complex data-driven behaviors where the data is structured (more than one level, not flat) and where forensic debugging via logs is a critical activity. If that’s n…

I think you seem to be arguing that the end result should be a "map"-like structure, whereas the other commenter is arguing about the interface to the logging library not being based on maps. These are not the same and taking maps in the interface is likely to incur allocations, yes. Having to specify your key-value pairs without maps is the only downside to not taking fully constructed maps in the interface.
Post reply on HN