types/logger: add Context and related helpers

We often need both a log function and a context.
We can do this by adding the log function as a context value.
This commit adds helper glue to make that easy.
It is designed to allow incremental adoption.

Updates tailscale/corp#3138

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
This commit is contained in:
Josh Bleecher Snyder
2021-11-30 14:32:30 -08:00
committed by Josh Bleecher Snyder
parent f93cf6fa03
commit deb2f5e793
2 changed files with 51 additions and 0 deletions

View File

@@ -18,6 +18,8 @@ import (
"strings"
"sync"
"time"
"context"
)
// Logf is the basic Tailscale logger type: a printf-like func.
@@ -25,6 +27,27 @@ import (
// Logf functions must be safe for concurrent use.
type Logf func(format string, args ...interface{})
// A Context is a context.Context that should contain a custom log function, obtainable from FromContext.
// If no log function is present, FromContext will return log.Printf.
// To construct a Context, use Add
type Context context.Context
type logfKey struct{}
// FromContext extracts a log function from ctx.
func FromContext(ctx Context) Logf {
v := ctx.Value(logfKey{})
if v == nil {
return log.Printf
}
return v.(Logf)
}
// Ctx constructs a Context from ctx with fn as its custom log function.
func Ctx(ctx context.Context, fn Logf) Context {
return context.WithValue(ctx, logfKey{}, fn)
}
// WithPrefix wraps f, prefixing each format with the provided prefix.
func WithPrefix(f Logf, prefix string) Logf {
return func(format string, args ...interface{}) {