docs: add structured logging docs in code formatting rules doc
This commit is contained in:
1 file changed
+89
@@ -178,6 +178,95 @@ be used for calls to formatting functions like `fmt.Errorf`,
|
|||||||
But not for statements that are important for the flow or logic of the code,
|
But not for statements that are important for the flow or logic of the code,
|
||||||
like `require.NoErrorf()`.
|
like `require.NoErrorf()`.
|
||||||
|
|
||||||
|
#### Exceptions and additional styling for structured logging
|
||||||
|
|
||||||
|
When making use of structured logging calls (there are any `btclog.Logger`
|
||||||
|
methods ending in `S`), a few different rules and exceptions apply.
|
||||||
|
|
||||||
|
1) **Static messages:** Structured log calls take a `context.Context` as a first
|
||||||
|
parameter and a _static_ string as the second parameter (the `msg` parameter).
|
||||||
|
Formatted strings should ideally not be used for the construction of the `msg`
|
||||||
|
parameter. Instead, key-value pairs (or `slog` attributes) should be used to
|
||||||
|
provide additional variables to the log line.
|
||||||
|
|
||||||
|
**WRONG**
|
||||||
|
```go
|
||||||
|
log.DebugS(ctx, fmt.Sprintf("User %d just spent %.8f to open a channel", userID, 0.0154))
|
||||||
|
```
|
||||||
|
|
||||||
|
**RIGHT**
|
||||||
|
```go
|
||||||
|
log.InfoS(ctx, "Channel open performed",
|
||||||
|
slog.Int("user_id", userID),
|
||||||
|
btclog.Fmt("amount", "%.8f", 0.00154))
|
||||||
|
```
|
||||||
|
|
||||||
|
2) **Key-value attributes**: The third parameter in any structured log method is
|
||||||
|
a variadic list of the `any` type but it is required that these are provided in
|
||||||
|
key-value pairs such that an associated `slog.Attr` variable can be created for
|
||||||
|
each key-value pair. The simplest way to specify this is to directly pass in the
|
||||||
|
key-value pairs as raw literals as follows:
|
||||||
|
|
||||||
|
```go
|
||||||
|
log.InfoS(ctx, "Channel open performed", "user_id", userID, "amount", 0.00154)
|
||||||
|
```
|
||||||
|
This does work, but it becomes easy to make a mistake and accidentally leave out
|
||||||
|
a value for each key provided leading to a nonsensical log line. To avoid this,
|
||||||
|
it is suggested to make use of the various `slog.Attr` helper functions as
|
||||||
|
follows:
|
||||||
|
|
||||||
|
```go
|
||||||
|
log.InfoS(ctx, "Channel open performed",
|
||||||
|
slog.Int("user_id", userID),
|
||||||
|
btclog.Fmt("amount", "%.8f", 0.00154))
|
||||||
|
```
|
||||||
|
|
||||||
|
3) **Line wrapping**: Structured log lines are an exception to the 80-character
|
||||||
|
line wrapping rule. This is so that the key-value pairs can be easily read and
|
||||||
|
reasoned about. If it is the case that there is only a single key-value pair
|
||||||
|
and the entire log line is still less than 80 characters, it is acceptable to
|
||||||
|
have the key-value pair on the same line as the log message. However, if there
|
||||||
|
are multiple key-value pairs, it is suggested to use the one line per key-value
|
||||||
|
pair format. Due to this suggestion, it is acceptable for any single key-value
|
||||||
|
pair line to exceed 80 characters for the sake of readability.
|
||||||
|
|
||||||
|
**WRONG**
|
||||||
|
```go
|
||||||
|
// Example 1.
|
||||||
|
log.InfoS(ctx, "User connected",
|
||||||
|
"user_id", userID)
|
||||||
|
|
||||||
|
// Example 2.
|
||||||
|
log.InfoS(ctx, "Channel open performed", "user_id", userID,
|
||||||
|
btclog.Fmt("amount", "%.8f", 0.00154), "channel_id", channelID)
|
||||||
|
|
||||||
|
// Example 3.
|
||||||
|
log.InfoS(ctx, "Bytes received",
|
||||||
|
"user_id", userID,
|
||||||
|
btclog.Hex("peer_id", peerID.SerializeCompressed()),
|
||||||
|
btclog.Hex("message", []bytes{
|
||||||
|
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
||||||
|
})))
|
||||||
|
```
|
||||||
|
|
||||||
|
**RIGHT**
|
||||||
|
```go
|
||||||
|
// Example 1.
|
||||||
|
log.InfoS(ctx, "User connected", "user_id", userID)
|
||||||
|
|
||||||
|
// Example 2.
|
||||||
|
log.InfoS(ctx, "Channel open performed",
|
||||||
|
slog.Int("user_id", userID),
|
||||||
|
btclog.Fmt("amount", "%.8f", 0.00154),
|
||||||
|
slog.String("channel_id", channelID))
|
||||||
|
|
||||||
|
// Example 3.
|
||||||
|
log.InfoS(ctx, "Bytes received",
|
||||||
|
"user_id", userID,
|
||||||
|
btclog.Hex("peer_id", peerID.SerializeCompressed()),
|
||||||
|
btclog.Hex("message", []bytes{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08})))
|
||||||
|
```
|
||||||
|
|
||||||
### Wrapping long function definitions
|
### Wrapping long function definitions
|
||||||
|
|
||||||
If one is forced to wrap lines of function arguments that exceed the
|
If one is forced to wrap lines of function arguments that exceed the
|
||||||
|
|||||||
Reference in new issue
Block a user