Closed mohammadv184 closed 12 months ago
CC @jba
Is this just syntax sugar for slog.String("validation error", vErr.Error())
?
Is this just syntax sugar for
slog.String("validation error", vErr.Error())
?
No, it's not just syntax sugar. It introduces a new Value Kind slog.KindErr
which is distinguishable in handlers between errors and strings. This distinction can be valuable in log processing and analysis.
I think it's syntactic sugar for slog.Any(key, err)
.
You can write the Err
function easily yourself. I'm not sure it's worth adding to slog
. Usually people name their error variables err
or similar, so it's pretty clear to the reader that you're constructing an Attr that holds an error.
Handlers can distinguish errors with a type assertion. Adding a kind doesn't really do much; the Kinds are there to distinguish the various ways that Value
represents certain Go values, but a Value of KindError would look exactly like a value of KindAny.
While it's possible to manually distinguish value types through type assertions, this approach can lead to a degree of ambiguity and inconsistency in log entries. The slog.Err
function, on the other hand, is introduced to enhance the clarity and consistency of error logging.
It's worth noting that if we follow the logic that every value type can be distinguished by assertion, one could argue that we don't need slog.Kind
and slog.Value
types at all. However, the purpose of slog.Kind
is to provide a systematic way to categorize and work with different types of values in a structured log. Each slog.Kind
serves as a clear marker for a specific type of data, making it easier to understand and manipulate log entries consistently.
The introduction of slog.Err
aims to provide a convenient and intuitive mechanism for handling errors, much like other helper functions within the package streamline the process of working with different data types. It contributes to making the "log/slog" package more user-friendly and facilitates a standardized approach to structured error logging, which can be particularly beneficial in larger codebases and collaborative projects.
The slog.Err function, on the other hand, is introduced to enhance the clarity and consistency of error logging.
How does it make it more clear? I argued that seeing the err
in slog.Any(key, err)
is clear enough. Also, I pointed out that you can define Err
in your own code.
How does it make it more consistent? If you'd proposed a canonical key for errors, like we have for message, level and time, then I'd see how that would help consistency. How does adding KindError
help? I think your answer is
Each slog.Kind serves as a clear marker for a specific type of data, making it easier to understand and manipulate log entries consistently
but that's not actually the purpose of the different Kinds, and even if it were I don't quite see the argument for consistency.
It's worth noting that if we follow the logic that every value type can be distinguished by assertion, one could argue that we don't need slog.Kind and slog.Value types at all.
That is absolutely true. Value
and its kinds are there only for performance. Otherwise we would have used any
.
That is absolutely true. Value and its kinds are there only for performance. Otherwise we would have used any.
OK, I understood, Thank you for your feedback.
I would prefer to isolate err as well to have transformation in slog abstraction rather than in the application code. However, currently I end up with having helper to serve data in OTEL format for otlp exporters:
func Error(val error) slog.Attr {
stack := make([]byte, 4096)
n := runtime.Stack(stack, false)
return slog.Group("error",
slog.String("exception.message", val.Error()),
slog.String("exception.stacktrace", fmt.Sprintf("%s", stack[:n])),
)
}
ref: https://opentelemetry.io/docs/specs/semconv/exceptions/exceptions-logs/#attributes
That helper looks fine to me. Even if we implemented this proposal's suggestion, it wouldn't include a stack trace, so you'd need to write your function anyway.
Abstract
This proposal suggests adding a dedicated error type,
slog.KindErr
, and a helper function,slog.Err
, to the "log/slog" package. These additions aim to improve structured error logging by providing a clear and efficient mechanism to distinguish and include errors in log entries.Proposal
slog.KindErr
add a new type,slog.KindErr
, for representing errors in structured log entries. This type will enhance the distinction of errors from other attributes.slog.Err
Helper Function Add a helper function,slog.Err
, for simplifying the process of logging errors as structured attributes. This function will accept a message and an error, creating aslog.KindErr
attribute in the log entry.Usage
Developers can use slog.Err to conveniently log errors:
This approach ensures that error attributes are clearly distinguished from other key-value pairs.