log

package
v0.0.0-...-9997ea8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 5, 2026 License: BSD-2-Clause Imports: 14 Imported by: 0

Documentation

Overview

Package log is tt's logging facade over log/slog.

Diagnostics - progress, warnings, errors, debug detail - go to stderr through slog. A command's result never goes through this package; it goes to stdout through github.com/tarantool/tt/sdk/output.

The tt core owns the process logger: it installs the handler that renders records as text or JSON, filters by level and redacts secrets, and makes it slog.Default. Nothing here configures handlers. A module logs through the *slog.Logger tt hands it; the printf functions below serve tt's own code.

The levels are slog's four: Debug, Info, Warn, Error. There is no Fatal: a failure is returned as an error and the core decides the exit code.

The package also holds the secret-redaction logic (Redactor, Secret, RedactURL) so that the core's handler and the tests of any module apply the same rules.

Index

Constants

View Source
const LibraryKey = "library"

LibraryKey is the attribute key that names the library a record came from.

View Source
const MinSecretLen = 4

MinSecretLen is the shortest value a Redactor accepts. Redaction replaces every occurrence of a value anywhere in a message, so a short value masks ordinary text: a one-letter "secret" would mask that letter everywhere, and a three-letter one matches common words and path parts. Four characters is the shortest a real password or token plausibly is while still rare in prose. URI userinfo is masked by shape regardless of its length.

View Source
const Redacted = "[REDACTED]"

Redacted is what a secret is replaced with.

Variables

This section is empty.

Functions

func Debug

func Debug(msg string, attrs ...any)

Debug logs msg at Debug level on the process logger. The optional attrs are key-value pairs or slog.Attr values, as for slog.Logger.Debug.

func Debugf

func Debugf(format string, args ...any)

Debugf logs a formatted message at Debug level on the process logger.

func Error

func Error(msg string, attrs ...any)

Error logs msg at Error level on the process logger. The optional attrs are key-value pairs or slog.Attr values, as for slog.Logger.Error.

func Errorf

func Errorf(format string, args ...any)

Errorf logs a formatted message at Error level on the process logger.

func Info

func Info(msg string, attrs ...any)

Info logs msg at Info level on the process logger. The optional attrs are key-value pairs or slog.Attr values, as for slog.Logger.Info.

func Infof

func Infof(format string, args ...any)

Infof logs a formatted message at Info level on the process logger.

func Library

func Library(name string) *slog.Logger

Library returns a logger for a third-party library, built on the process logger. See LibraryOf.

It binds the handler slog.Default has at the time of the call, so call it where the library is set up, not in a package-level variable initialised before tt has configured logging.

func LibraryOf

func LibraryOf(base *slog.Logger, name string) *slog.Logger

LibraryOf returns a logger for a third-party library, built on base.

A library's Info is chatter from tt's point of view - go-luarocks logs every line luarocks prints at Info - so records from Info up to, but not including, Warn are demoted by the distance between Info and Debug. Warn and Error pass unchanged: those are for the user.

Every record carries a top-level library=<name> attribute. It is a plain attribute rather than a group so that the library's own attributes keep their keys and the text format stays one flat line.

func Logger

func Logger() *slog.Logger

Logger returns the process logger, slog.Default.

func Redact

func Redact(text string) string

Redact masks secrets in text with the process-wide registry.

func RedactTarget

func RedactTarget(target string) string

RedactTarget returns target, a connection URI or whatever a user typed in the place of one, fit to be shown in an error or a log message: the credentials of a URI are hidden whether or not it parses (connect.RedactCredentials), and so is every secret registered with the process (Redact).

Unlike RedactURL it does not need the string to be a URL, nor the userinfo to be well formed: a message that quotes a piece of a target cut at a ":", such as the "instance" of user:password@host:3301, or a target with a "/" in its password, passes through here.

func RedactURL

func RedactURL(raw string) string

RedactURL returns raw with its userinfo removed entirely and the remainder redacted with the process-wide registry.

url.URL.Redacted is not enough: it masks only a password and keeps a bare username, and in https://<token>@host the username is the secret. A raw string that does not parse as a URL with userinfo - a Tarantool admin:secret@host:3301 parses as an opaque one - is redacted by Redact.

func RegisterSecret

func RegisterSecret(value string) bool

RegisterSecret adds value to the process-wide registry so that it is masked in every log record from then on. It reports whether the value was accepted: values shorter than MinSecretLen are ignored.

func Spinner

func Spinner(msg string) func()

Spinner shows msg with an animation on the status line of the process logger until the returned stop function is called. See SpinnerOf.

func SpinnerOf

func SpinnerOf(logger *slog.Logger, msg string) func()

SpinnerOf shows msg with an animation on the status line of logger's handler until the returned stop function is called.

The spinner is progress for a person watching a terminal: when the handler is not a StatusHandler - the output is not a terminal, the format is JSON, or the logger is not tt's - nothing is shown and stop does nothing. It never writes to stdout. Records logged while it spins stay whole.

func Warn

func Warn(msg string, attrs ...any)

Warn logs msg at Warn level on the process logger. The optional attrs are key-value pairs or slog.Attr values, as for slog.Logger.Warn.

func Warnf

func Warnf(format string, args ...any)

Warnf logs a formatted message at Warn level on the process logger.

Types

type Redactor

type Redactor struct {
	// contains filtered or unexported fields
}

Redactor masks secrets in log text: every value registered with it, and the userinfo of anything that looks like a URI. It is safe for concurrent use. The process has one, reached through Secrets; tests can make their own with NewRedactor.

func NewRedactor

func NewRedactor() *Redactor

NewRedactor returns a Redactor with no registered values. It still masks URI userinfo.

func Secrets

func Secrets() *Redactor

Secrets returns the process-wide Redactor that RegisterSecret adds to and the core's log handler applies.

func (*Redactor) Redact

func (r *Redactor) Redact(text string) string

Redact returns text with every registered value and every URI userinfo replaced by Redacted. A URI with a scheme loses its whole userinfo, since a bare "token@" is as much a secret as "user:password@"; without a scheme only the "user:password@" form is recognised.

func (*Redactor) RedactAttr

func (r *Redactor) RedactAttr(attr slog.Attr) slog.Attr

RedactAttr returns attr with its secrets masked. The value is resolved first, so a slog.LogValuer is redacted by what it logs as. Strings are redacted, groups member by member at any depth, and any other value - an error, a struct - by its fmt "%+v" rendering: when that rendering holds a secret the value is replaced by the redacted text, otherwise it is kept as it is. Numbers, booleans, times and durations pass through.

func (*Redactor) RedactRecord

func (r *Redactor) RedactRecord(record slog.Record) slog.Record

RedactRecord returns a copy of record with its message and attributes redacted. Attributes a handler holds from WithAttrs are not part of the record; the handler redacts those itself.

func (*Redactor) Register

func (r *Redactor) Register(value string) bool

Register adds value to the set this Redactor masks. It reports whether the value was accepted: values shorter than MinSecretLen are ignored.

type Secret

type Secret struct {
	// contains filtered or unexported fields
}

Secret holds a value that must never reach a log or an output: its fmt rendering under every verb, its slog value and its text and JSON encodings are all Redacted. Only Secret.Reveal returns the value.

A Secret does not register its value; call RegisterSecret as well when the value may also leak through a path that does not hold the Secret, such as a URL or an error message.

func NewSecret

func NewSecret(value string) Secret

NewSecret wraps value.

func (Secret) Format

func (Secret) Format(state fmt.State, _ rune)

Format writes Redacted for every fmt verb. Without it, verbs a Stringer does not cover, such as %d, would print the struct and its field.

func (Secret) GoString

func (Secret) GoString() string

GoString returns Redacted, so %#v does not print the struct.

func (Secret) LogValue

func (Secret) LogValue() slog.Value

LogValue makes slog log Redacted.

func (Secret) MarshalText

func (Secret) MarshalText() ([]byte, error)

MarshalText returns Redacted; encoding/json and YAML encoders use it.

func (Secret) Reveal

func (s Secret) Reveal() string

Reveal returns the wrapped value.

func (Secret) String

func (Secret) String() string

String returns Redacted.

type StatusHandler

type StatusHandler interface {
	slog.Handler
	// Status shows msg on the status line until the returned stop is
	// called. Stop clears the line, waits until nothing more is drawn and
	// may be called more than once. A handler that cannot show a status
	// line at the moment returns a stop that does nothing.
	Status(msg string) (stop func())
}

StatusHandler is implemented by a handler that can keep a transient status line - a spinner - on its output while a long operation runs. The core's text handler implements it when stderr is a terminal; it keeps the status line below the records it writes, clearing the line before a record and drawing it again after.

Directories

Path Synopsis
Package logtest captures slog records for tests.
Package logtest captures slog records for tests.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL