update logging standards doc (#3497)

#### Type of change

- [x] 🗺️ Documentation
This commit is contained in:
Keepers 2023-05-25 00:28:40 -06:00 committed by GitHub
parent 7181e2ef90
commit e8325711b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -6,6 +6,7 @@ import (
"github.com/alcionai/clues" "github.com/alcionai/clues"
"github.com/alcionai/corso/src/internal/connector" "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/logger"
"github.com/alcionai/corso/src/pkg/path" "github.com/alcionai/corso/src/pkg/path"
) )
@ -62,7 +63,8 @@ func Example_seed() {
func Example_logger_standards() { func Example_logger_standards() {
log := logger.Ctx(context.Background()) 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. // This ensures logs are easy to scan, and simple to grok.
// //
// preferred // preferred
@ -70,7 +72,15 @@ func Example_logger_standards() {
// avoid // avoid
log.Info("Getting one item from the service so that we can send it through the item feed.") 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, // 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. // 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 // avoid
log.Errorf("getting item %s: %v", itemID, err) 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. // Overly generic keys can collide unexpectedly.
// //
// preferred // preferred
@ -98,14 +108,14 @@ func Example_logger_standards() {
// avoid // avoid
log.With("err", err).Warn("getting item") 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 // Panic and Fatal logging can crash the application without
// flushing buffered logs and finishing out other telemetry. // flushing buffered logs and finishing out other telemetry.
// //
// preferred // preferred
log.With("err", err).Error("unable to connect") log.With("err", err).Error("connecting to repo")
// avoid // 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. // 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) ctx = clues.Add(ctx, "item_id", itemID)
logger.Ctx(ctx).With(clues.In(ctx).Slice()...).Info("getting item") 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 // preferred
log.With("error", err).Errorw("getting item", clues.InErr(err).Slice()...) 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 // Ex: clues.Hide(userName). This will hash the value according to
// the user's hash algorithm configuration. // 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 // interface requires a struct to comply with Conceal() (for cases
// where the struct is handed to a clues aggregator directly), and // where the struct is handed to a clues aggregator directly), and
// fmt's Format(state, verb), where the assumption is the standard // fmt's Format(state, verb), where the assumption is the standard
@ -166,7 +191,8 @@ func Example_logger_clues_standards() {
"resource_type", connector.Users, "resource_type", connector.Users,
// string containing sensitive info, wrap with Hide() // string containing sensitive info, wrap with Hide()
"user_name", clues.Hide("your_user_name@microsoft.example"), "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 // a concealer-compliant struct, safe to add plainly
"storage_path", itemPath, "storage_path", itemPath)
)
} }