Skip to content

Commit 93327d5

Browse files
authored
docs: Add logging style guide (strangelove-ventures#69)
1 parent 00bca98 commit 93327d5

File tree

4 files changed

+82
-3
lines changed

4 files changed

+82
-3
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ See [`cmd/ibctest/README.md`](cmd/ibctest/README.md) for more details.
1414
Note that `ibc-test-framework` is under active development
1515
and we are not yet ready to commit to any stable APIs around the testing interfaces.
1616

17+
Please read the [logging style guide](./docs/logging.md).
18+
1719
## Trophies
1820

1921
Significant bugs that were more easily fixed with the `ibc-test-framework`:

chain/cosmos/chain_node.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ func (tn *ChainNode) maybeLogBlock(height int64) {
250250
ctx := context.Background()
251251
blockRes, err := tn.Client.Block(ctx, &height)
252252
if err != nil {
253-
tn.logger().Error("Get block", zap.Error(err))
253+
tn.logger().Info("Failed to get block", zap.Error(err))
254254
return
255255
}
256256
txs := blockRes.Block.Txs
@@ -259,7 +259,7 @@ func (tn *ChainNode) maybeLogBlock(height int64) {
259259
}
260260
pp, err := tendermint.PrettyPrintTxs(ctx, txs, tn.Client.Tx)
261261
if err != nil {
262-
tn.logger().Error("Pretty print block", zap.Error(err))
262+
tn.logger().Info("Failed to pretty print block", zap.Error(err))
263263
return
264264
}
265265
tn.logger().Debug(pp, zap.Int64("height", height), zap.String("block", pp))

chain/cosmos/cosmos_chain.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,11 @@ func (c *CosmosChain) initializeChainNodes(testName, home string,
254254
Tag: image.Version,
255255
}, docker.AuthConfiguration{})
256256
if err != nil {
257-
c.log.Error("Pull image", zap.Error(err))
257+
c.log.Error("Failed to pull image",
258+
zap.Error(err),
259+
zap.String("repository", image.Repository),
260+
zap.String("tag", image.Version),
261+
)
258262
}
259263
}
260264
for i := 0; i < count; i++ {

docs/logging.md

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Logging
2+
3+
This code uses the [zap](https://pkg.go.dev/go.uber.org/zap) logging framework.
4+
5+
Zap is a production quality logging library that is performant and highly configurable.
6+
Zap produces structured logging that can be easily machine-parsed,
7+
so that people can easily use tooling to filter through logs,
8+
or logs can easily be sent to log aggregation tooling.
9+
10+
## Conventions
11+
12+
### Instantiation
13+
14+
Structs should hold a reference to their own `*zap.Logger` instance, as an unexported field named `log`.
15+
Callers should provide the logger instance as the first argument to a `NewFoo` method, setting any extra fields with the `With` method externally.
16+
For example:
17+
18+
```go
19+
path := "/tmp/foo"
20+
foo := NewFoo(log.With(zap.String("path", path)), path)
21+
```
22+
23+
### Usage
24+
25+
Log messages should begin with an uppercase letter and should not end with any punctuation.
26+
Log messages should be constant string literals; dynamic content is to be set as log fields.
27+
Names of log fields should be all lowercase `snake_case` format.
28+
29+
```go
30+
// Do this:
31+
x.log.Debug("Updated height", zap.Int64("height", height))
32+
33+
// Don't do this:
34+
x.log.Debug(fmt.Sprintf("Updated height to %d.", height))
35+
```
36+
37+
Errors are intended to be logged with `zap.Error(err)`.
38+
Error values should only be logged when they are not returned.
39+
40+
```go
41+
// Do this:
42+
for _, x := range xs {
43+
if err := x.Validate(); err != nil {
44+
y.log.Info("Skipping x that failed validation", zap.String("id", x.ID), zap.Error(err))
45+
continue
46+
}
47+
}
48+
49+
// Don't do this:
50+
if err := x.Validate(); err != nil {
51+
y.log.Info("X failed validation", zap.String("id", x.ID), zap.Error(err))
52+
return err // Bad!
53+
// Returning an error that has already been logged may cause the same error
54+
// to be logged many times.
55+
}
56+
```
57+
58+
#### Log levels
59+
60+
Debug level messages are off by default.
61+
Debug messages should be used sparingly;
62+
they are typically only intended for consumption by developers when actively debugging an issue.
63+
64+
Info level messages and higher are on by default.
65+
They may contain any general information useful to an operator.
66+
It should be safe to discard all info level messages if an operator so desires.
67+
68+
Warn level messages should be used to indicate a problem that may worsen without operator intervention.
69+
70+
Error level messages should only be used to indicate a serious problem that cannot automatically recover.
71+
Error level messages should be reserved for events that are worthy of paging an engineer.
72+
73+
Do not use Fatal or Panic level messages.

0 commit comments

Comments
 (0)