sink

package
v0.11.669 Latest Latest
Warning

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

Go to latest
Published: Sep 7, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package sink provides a generic record-and-close interface for writing JSON-marshalable payloads to a destination, the concrete implementations (file, nop) the rest of the codebase consumes, and the OTel decorator that re-encodes any payload as OTLP/JSON log records on the way to a sink.

The interface is deliberately payload-agnostic: callers pass any value that json.Marshal can handle, and the sink takes responsibility for serialisation, transport, and durability semantics. This lets unrelated subsystems (audit, future activity/telemetry channels, etc) share the same plumbing -- file rotation, GC, alternate transports plug in once and benefit everyone.

Index

Constants

View Source
const (
	OTelSeverityInfo  = 9
	OTelSeverityError = 17

	// DefaultOTelSchemaURL pins the semantic conventions release the stable
	// attributes (service.*, error.*) are taken from.
	DefaultOTelSchemaURL = "https://opentelemetry.io/schemas/1.44.0"
)

OTel log severity numbers per the OpenTelemetry logs data model.

Variables

This section is empty.

Functions

func OTelRandomID added in v0.11.669

func OTelRandomID(n int) string

OTelRandomID returns n random bytes as lowercase hex (16 bytes for a trace id, 8 for a span or call id).

Types

type FileConfig

type FileConfig struct {
	// Path is the absolute or relative path to the log file.  When set,
	// Dir and DefaultFilename are ignored.
	Path string `json:"path,omitempty" yaml:"path,omitempty"`

	// Dir is the directory in which the sink writes the log when Path is
	// empty.  Must be set in that case.  Relative directories are resolved
	// against cwd at NewFileSink time.
	Dir string `json:"dir,omitempty" yaml:"dir,omitempty"`

	// MaxSizeMB triggers rotation when the file grows past this size.
	// Zero means lumberjack's default (100 MB).
	MaxSizeMB int `json:"max_size_mb,omitempty" yaml:"max_size_mb,omitempty"`

	// MaxBackups is the number of rotated files to keep.
	// Zero means keep all (lumberjack default).
	MaxBackups int `json:"max_backups,omitempty" yaml:"max_backups,omitempty"`

	// MaxAgeDays is the maximum age in days for rotated files.
	// Zero means no age-based deletion (lumberjack default).
	MaxAgeDays int `json:"max_age_days,omitempty" yaml:"max_age_days,omitempty"`

	// DefaultFilename is consulted when Path is empty.  It returns just the
	// basename; the sink joins it with Dir.  When nil, a generic
	// "sink_<RFC3339-utc-second>.log" filename is used.  Made a function so
	// callers can encode their own naming convention (eg
	// "stackql_mcp_server_<timestamp>.log") without bringing the format
	// string into the sink package.
	DefaultFilename func(time.Time) string `json:"-" yaml:"-"`
}

FileConfig is the on-disk file sink configuration.

Either Path (a complete file path) or Dir (a directory in which the sink will pick a filename via DefaultFilename) must be set. NewFileSink errors when both are empty; the sink never silently picks a directory of its own. The caller -- not the sink -- owns the "where do logs land" decision.

type OTelAnyValue added in v0.11.669

type OTelAnyValue struct {
	StringValue *string  `json:"stringValue,omitempty"`
	IntValue    *string  `json:"intValue,omitempty"`
	DoubleValue *float64 `json:"doubleValue,omitempty"`
	BoolValue   *bool    `json:"boolValue,omitempty"`
}

OTelAnyValue is the OTLP/JSON encoding of an attribute value; exactly one field is set.

type OTelAttribute added in v0.11.669

type OTelAttribute struct {
	Key   string       `json:"key"`
	Value OTelAnyValue `json:"value"`
}

OTelAttribute is one OTLP/JSON key/value pair.

func OTelAttributesFromJSON added in v0.11.669

func OTelAttributesFromJSON(raw []byte) ([]OTelAttribute, bool)

OTelAttributesFromJSON maps a JSON object's top-level fields to typed attributes in key order; nested values are carried as JSON strings and nulls as empty strings (dropped on encode). ok is false when raw is not an object.

func OTelBool added in v0.11.669

func OTelBool(key string, v bool) OTelAttribute

func OTelDouble added in v0.11.669

func OTelDouble(key string, v float64) OTelAttribute

func OTelInt added in v0.11.669

func OTelInt(key string, v int64) OTelAttribute

func OTelString added in v0.11.669

func OTelString(key, v string) OTelAttribute

OTelString / OTelInt / OTelDouble / OTelBool build typed attributes.

type OTelLogRecord added in v0.11.669

type OTelLogRecord struct {
	Time     time.Time
	Severity int
	Body     string
	// Attributes are emitted in order; empty string values are dropped.
	Attributes []OTelAttribute
	// TraceParent is a caller-supplied W3C traceparent, honoured when well
	// formed; otherwise one trace id is generated per CorrelationKey (e.g. a
	// session) so related records correlate.
	TraceParent    string
	CorrelationKey string
}

OTelLogRecord is one log record before envelope decoration; the sink adds the resource, scope, observed time, and trace/span ids.

type OTelLogsData added in v0.11.669

type OTelLogsData struct {
	ResourceLogs []OTelResourceLogs `json:"resourceLogs"`
}

OTelLogsData is one OTLP/JSON logs export payload; the file sink writes one per line, the shape the collector's otlp_json_file receiver ingests.

type OTelRecorder added in v0.11.669

type OTelRecorder interface {
	OTelLogRecords() []OTelLogRecord
}

OTelRecorder is implemented by payloads that map themselves onto log records. Payloads that do not implement it are decorated generically: the JSON object's top-level fields become attributes and the whole object the body.

type OTelResource added in v0.11.669

type OTelResource struct {
	ServiceName    string
	ServiceVersion string
	// Attributes are appended after service.name / service.version.
	Attributes []OTelAttribute
}

OTelResource identifies the emitting service.

type OTelResourceLogs added in v0.11.669

type OTelResourceLogs struct {
	Resource  otelResource    `json:"resource"`
	ScopeLogs []OTelScopeLogs `json:"scopeLogs"`
	SchemaURL string          `json:"schemaUrl"`
}

OTelResourceLogs is an OTLP/JSON ResourceLogs.

type OTelScope added in v0.11.669

type OTelScope struct {
	Name      string
	Version   string
	SchemaURL string
}

OTelScope identifies the instrumentation that produced the records; use Version for the emitted attribute schema so consumers can pin against it.

type OTelScopeLogs added in v0.11.669

type OTelScopeLogs struct {
	Scope      otelInstrumentationScope `json:"scope"`
	LogRecords []OTelWireLogRecord      `json:"logRecords"`
	SchemaURL  string                   `json:"schemaUrl"`
}

OTelScopeLogs is an OTLP/JSON ScopeLogs.

type OTelWireLogRecord added in v0.11.669

type OTelWireLogRecord struct {
	TimeUnixNano         string          `json:"timeUnixNano"`
	ObservedTimeUnixNano string          `json:"observedTimeUnixNano"`
	SeverityNumber       int             `json:"severityNumber"`
	SeverityText         string          `json:"severityText"`
	Body                 OTelAnyValue    `json:"body"`
	Attributes           []OTelAttribute `json:"attributes"`
	TraceID              string          `json:"traceId"`
	SpanID               string          `json:"spanId"`
}

OTelWireLogRecord is an OTLP/JSON LogRecord.

type Sink

type Sink interface {
	// Record serialises and writes one payload.  Errors include transport
	// failures (full disk, broken pipe, etc) and marshalling failures.
	Record(ctx context.Context, payload any) error
	// Close flushes any buffered state and releases the underlying resource.
	Close() error
}

Sink is the generic destination contract. Implementations must be safe for concurrent calls from multiple goroutines.

func NewFileSink

func NewFileSink(cfg FileConfig) (Sink, error)

NewFileSink constructs a file-backed sink. Exactly one of cfg.Path or cfg.Dir must be supplied:

  • cfg.Path set: used as-is. Relative paths are resolved against cwd.
  • cfg.Path empty + cfg.Dir set: the sink picks the basename via cfg.DefaultFilename (or the package-default fallback) and joins it with Dir.

The resolved absolute path is logged to stderr at startup so operators can find the file later.

func NewNopSink

func NewNopSink() Sink

NewNopSink returns a Sink that ignores every Record call.

func NewOTelSink added in v0.11.669

func NewOTelSink(inner Sink, resource OTelResource, scope OTelScope) Sink

NewOTelSink wraps inner so every recorded payload is written as OTLP/JSON.

Jump to

Keyboard shortcuts

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