update logging standards doc (#3497)
#### Type of change
- [x] 🗺️ Documentation
This commit is contained in:
parent
7181e2ef90
commit
e8325711b3
@ -6,6 +6,7 @@ import (
|
||||
"github.com/alcionai/clues"
|
||||
|
||||
"github.com/alcionai/corso/src/internal/connector"
|
||||
"github.com/alcionai/corso/src/internal/connector/graph"
|
||||
"github.com/alcionai/corso/src/pkg/logger"
|
||||
"github.com/alcionai/corso/src/pkg/path"
|
||||
)
|
||||
@ -62,7 +63,8 @@ func Example_seed() {
|
||||
func Example_logger_standards() {
|
||||
log := logger.Ctx(context.Background())
|
||||
|
||||
// 1. Keep messages short. Lowercase text, no ending punctuation.
|
||||
// 1. Keep messages short. When possible, messages should state the current action.
|
||||
// Lowercase text, no ending punctuation.
|
||||
// This ensures logs are easy to scan, and simple to grok.
|
||||
//
|
||||
// preferred
|
||||
@ -70,7 +72,15 @@ func Example_logger_standards() {
|
||||
// avoid
|
||||
log.Info("Getting one item from the service so that we can send it through the item feed.")
|
||||
|
||||
// 2. Do not fmt values into the message. Use With() or -w() to add structured data.
|
||||
// 2. Avoid statements like "unable to...", "failed to..", or "error when...".
|
||||
// Error level logs automatically imply a failure to do the action.
|
||||
//
|
||||
// preferred
|
||||
log.With("err", err).Error("connecting to repo")
|
||||
// avoid
|
||||
log.With("err", err).Error("unable to connect to repo")
|
||||
|
||||
// 3. Do not fmt values into the message. Use With() or -w() to add structured data.
|
||||
// By keeping dynamic data in a structured format, we maximize log readability,
|
||||
// and make logs very easy to search or filter in bulk, and very easy to control pii.
|
||||
//
|
||||
@ -80,7 +90,7 @@ func Example_logger_standards() {
|
||||
// avoid
|
||||
log.Errorf("getting item %s: %v", itemID, err)
|
||||
|
||||
// 3. Give data keys reasonable namespaces. Use snake_case.
|
||||
// 4. Give data keys reasonable namespaces. Use snake_case.
|
||||
// Overly generic keys can collide unexpectedly.
|
||||
//
|
||||
// preferred
|
||||
@ -98,14 +108,14 @@ func Example_logger_standards() {
|
||||
// avoid
|
||||
log.With("err", err).Warn("getting item")
|
||||
|
||||
// 4. Avoid Panic/Fatal-level logging. Prefer Error.
|
||||
// 5. Avoid Panic/Fatal-level logging. Prefer Error.
|
||||
// Panic and Fatal logging can crash the application without
|
||||
// flushing buffered logs and finishing out other telemetry.
|
||||
//
|
||||
// preferred
|
||||
log.With("err", err).Error("unable to connect")
|
||||
log.With("err", err).Error("connecting to repo")
|
||||
// avoid
|
||||
log.With("err", err).Panic("unable to connecct")
|
||||
log.With("err", err).Panic("connecting to repo")
|
||||
}
|
||||
|
||||
// ExampleLoggerCluesStandards reviews code standards around using the Clues package while logging.
|
||||
@ -124,7 +134,14 @@ func Example_logger_clues_standards() {
|
||||
ctx = clues.Add(ctx, "item_id", itemID)
|
||||
logger.Ctx(ctx).With(clues.In(ctx).Slice()...).Info("getting item")
|
||||
|
||||
// 2. Always extract structured data from errors.
|
||||
// 2. The last func to handle a context must add the clues to the error.
|
||||
//
|
||||
// preferred
|
||||
err := clues.Wrap(err, "reason").WithClues(ctx)
|
||||
// this dereference added for linter happiness
|
||||
_ = err
|
||||
|
||||
// 3. Always extract structured data from errors.
|
||||
//
|
||||
// preferred
|
||||
log.With("error", err).Errorw("getting item", clues.InErr(err).Slice()...)
|
||||
@ -153,7 +170,15 @@ func Example_logger_clues_standards() {
|
||||
// Ex: clues.Hide(userName). This will hash the value according to
|
||||
// the user's hash algorithm configuration.
|
||||
//
|
||||
// Third: structs that comply with clues.Concealer. The Concealer
|
||||
// Third: managed string concealers. Certain values have common
|
||||
// format and content, but appear commonly in the code as strings.
|
||||
// Examples include URLs and kopia repository paths. These values
|
||||
// may have a concealer built specifically for them to maximize the
|
||||
// data we can view when debugging, instead of hashing the complete
|
||||
// string. See graph/middleware.go LoggableURL{} and path/elements.go
|
||||
// LoggableDir{}.
|
||||
//
|
||||
// Fourth: structs that comply with clues.Concealer. The Concealer
|
||||
// interface requires a struct to comply with Conceal() (for cases
|
||||
// where the struct is handed to a clues aggregator directly), and
|
||||
// fmt's Format(state, verb), where the assumption is the standard
|
||||
@ -166,7 +191,8 @@ func Example_logger_clues_standards() {
|
||||
"resource_type", connector.Users,
|
||||
// string containing sensitive info, wrap with Hide()
|
||||
"user_name", clues.Hide("your_user_name@microsoft.example"),
|
||||
// string partially concealed by a managed concealer.
|
||||
"request_url", graph.LoggableURL("https://corsobackup.io"),
|
||||
// a concealer-compliant struct, safe to add plainly
|
||||
"storage_path", itemPath,
|
||||
)
|
||||
"storage_path", itemPath)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user