logging

package
v0.4.99 Latest Latest
Warning

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

Go to latest
Published: Mar 13, 2024 License: Apache-2.0 Imports: 28 Imported by: 0

Documentation

Overview

Package logging contains logging related utilities.

Index

Examples

Constants

View Source
const SystemAttributeKey = "serviceweaver/system"

SystemAttributeKey is present as the key of an attribute (with an empty value) in log entries generated by Service Weaver system components.

Variables

This section is empty.

Functions

func IsSystemGenerated

func IsSystemGenerated(entry *protos.LogEntry) bool

IsSystemGenerated returns true for log entries generated by system components.

func NewTestSlogger

func NewTestSlogger(t TB, verbose bool) *slog.Logger

NewTestSlogger returns a new logger for tests.

func Parse

func Parse(query Query) (*cel.Ast, error)

Parse parses and type-checks a query.

func Shorten

func Shorten(s string) string

Shorten returns a short prefix of the provided string.

func ShortenComponent

func ShortenComponent(component string) string

ShortenComponent shortens the given component name to be of the format <pkg>.<IfaceType>. (Recall that the full component name is of the format <path1>/<path2>/.../<pathN>/<IfaceType>.)

func StderrLogger

func StderrLogger(opts Options) *slog.Logger

StderrLogger returns a logger that pretty prints log entries to stderr.

Types

type FileStore

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

FileStore stores log entries in files.

func NewFileStore

func NewFileStore(dir string) (*FileStore, error)

NewFileStore returns a LogStore that writes files to the specified directory.

func (*FileStore) Add

func (fs *FileStore) Add(e *protos.LogEntry)

Add stores the specified log entry, assigning a timestamp to it if necessary.

func (*FileStore) Close

func (fs *FileStore) Close() error

Close closes the specified log-store, including any opened files.

type LogHandler

type LogHandler struct {
	Opts  Options                      // configures the log entries
	Write func(entry *protos.LogEntry) // called on every log entry
}

LogHandler implements a custom slog.Handler.

func (*LogHandler) Enabled

func (h *LogHandler) Enabled(context.Context, slog.Level) bool

Enabled implements the slog.Handler interface.

func (*LogHandler) Handle

func (h *LogHandler) Handle(ctx context.Context, rec slog.Record) error

Handle implements the slog.Handler interface.

func (*LogHandler) WithAttrs

func (h *LogHandler) WithAttrs(attrs []slog.Attr) slog.Handler

WithAttrs implements the slog.Handler interface.

func (*LogHandler) WithGroup

func (h *LogHandler) WithGroup(string) slog.Handler

WithGroup implements the slog.Handler interface.

TODO(rgrandl): Implement it, so the users have the same experience as slog if they decide to use WithGroup.

type Options

type Options struct {
	App        string // Service Weaver application (e.g., "todo")
	Deployment string // Service Weaver deployment (e.g., "36105c89-85b1...")
	Component  string // Service Weaver component (e.g., "Todo")
	Weavelet   string // Service Weaver weavelet id (e.g., "36105c89-85b1...")

	// Pre-assigned attributes. These will be attached to each log entry
	// generated by the logger. This slice will never be appended to in place.
	Attrs []string
}

Options configures the log entries produced by a logger.

type PrettyPrinter

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

PrettyPrinter pretty prints log entries. You can safely use a PrettyPrinter from multiple goroutines.

func NewPrettyPrinter

func NewPrettyPrinter(color bool) *PrettyPrinter

NewPrettyPrinter returns a new PrettyPrinter. If color is true, the pretty printer colorizes its output using ANSII escape codes.

func (*PrettyPrinter) Format

func (pp *PrettyPrinter) Format(e *protos.LogEntry) string

Format formats a log entry as a single line of human-readable text. Here are some examples of what pretty printed log entries look like:

I0921 10:07:31.733831 distributor 076cb5f1 distributor.go:164 │ Registering versions...
I0921 10:07:31.759352 distributor 076cb5f1 anneal.go:155      │ Deploying versions...
I0921 10:07:31.759696 manager     076cb5f1 manager.go:125     │ Starting versions...
I0921 10:07:31.836563 manager     076cb5f1 manager.go:137     │ Success starting...
I0921 10:07:31.849647 distributor 076cb5f1 anneal.go:184      │ Successfully deployed...
I0921 10:07:31.862637 distributor 076cb5f1 distributor.go:169 │ Successfully registered...
I0921 10:07:31.862754 controller  076cb5f1 anneal.go:331      │ Successfully distributed...

type Query

type Query = string

Query is a filter for log entries.

Syntax

Queries are written using a subset of the CEL language 1. Thus, every syntactically valid query is also a syntactically valid CEL program. Specifically, a query is a CEL program over the following fields:

  • app: string
  • version: string
  • full_version: string
  • component: string
  • full_component: string
  • node: string
  • full_node: string
  • time: timestamp
  • level: string
  • source: string
  • msg: string
  • attrs: map[string]string

A query is restricted to:

  • boolean algebra (!, &&, ||),
  • equalities and inequalities (==, !=, <, <=, >, >=),
  • the string operations "contains" and "matches",
  • map indexing (attrs["foo"]) and membership ("foo" in attrs), and
  • constant strings, timestamps, and ints.

All equalities and inequalities must look like `app == "todo"` or `attrs["foo"] == "bar"`; i.e. a field or attribute on the left and a constant on the right.

Semantics

Queries have the same semantics as CEL programs except for one small exception. An attribute expression like `attrs["foo"]` has an implicit membership test `"foo" in attrs`. For example, the query

attrs["foo"] == "bar"

is evaluated like the CEL program

"foo" in attrs && attrs["foo"] == "bar"

TODO(mwhittaker): Expand the set of valid queries. For example, we can allow more constant expressions on the right hand side of a comparison. We can also allow fields on the right and constants on the left.

type Reader

type Reader interface {
	// Read returns the next log entry, or io.EOF when there are no more log
	// entries. Calling Read on a closed reader will return an error. If a
	// non-nil error is returned, the returned entry is guaranteed to be nil.
	Read(context.Context) (*protos.LogEntry, error)

	// Close closes the Reader. Close can safely be called multiple times.
	Close()
}

Reader is a log entry iterator. A Reader is not thread-safe; its methods cannot be called concurrently.

Example
ctx := context.Background()
reader := getLogReader()
defer reader.Close()
for {
	entry, err := reader.Read(ctx)
	if errors.Is(err, io.EOF) {
		// No more log entries.
		return
	} else if err != nil {
		fmt.Fprintln(os.Stderr, err)
		return
	}
	fmt.Println(entry)
}
Output:

type Source

type Source interface {
	// Query returns a log entry reader.
	//
	// Log entries produced by a single component replica are guaranteed to be
	// returned in increasing timestamp order, but log entries across component
	// replicas are interleaved in timestamp order only on a best-effort basis.
	//
	// If follow is true, then the returned reader follows logs like `tail -f`.
	// Otherwise, log entries that are created during an executing query may or
	// may not be returned. Similarly, the returned reader does not return old
	// log entries that have been garbage collected.
	Query(ctx context.Context, q Query, follow bool) (Reader, error)
}

Source is a log source. You can use a source to cat and follow logs, filtering log entries using a query. A Source can safely be used concurrently from multiple goroutines.

func FileSource

func FileSource(dir string) Source

FileSource returns a new Source that reads logs from files saved by a FileStore.

type TB

type TB interface {
	Log(args ...any)
	Cleanup(func())
}

TB is the subset of the testing.TB interface needed by a TestLogger.

type TestLogger

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

TestLogger implements a logger for tests.

func NewTestLogger

func NewTestLogger(t TB, verbose bool) *TestLogger

NewTestLogger returns a new TestLogger.

func (*TestLogger) Log

func (t *TestLogger) Log(entry *protos.LogEntry)

Log logs the provided log entry using t.t.Log while the test is running and logs to stderr afterwards.

Jump to

Keyboard shortcuts

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