Reference / Records API for Go
Records API for Go
Every public type, function and constant of the Records engine in tinyshed.org/tinystore/records and tinyshed.org/tinystore/console, generated from its source. The Records guide explains how to use them, and the Bun and Node, Python and Rust pages list the same API.
Buffer
func Buffer(lines int) console.OptionBuffer is the lines a store's handler holds for the store, 1024 unless given: past it a line is dropped and counted, never waited for.
Keep
func Keep(d time.Duration) keepKeep is how long the stream keeps its events, kept in its file with it: an events handle and a store's handler of one name share it. An open that gives none changes nothing; a stream nobody gave one keeps 14 days.
WithTrace
func WithTrace(ctx context.Context, traceID, spanID string) context.ContextWithTrace is ctx carrying a trace and the span inside it, as a traceparent header's 32 and 16 hex digits: a line logged and an event appended with it, however deep, take them. Ids that are not hex of that length are no trace, as W3C's traceparent ignores them; a span may be "".
AllEvents
type AllEvents struct {
// contains filtered or unexported fields
}AllEvents is every stream's events, to read, and what a store holds of them.
OpenAllEvents
func OpenAllEvents(store *tinystore.Store) (*AllEvents, error)OpenAllEvents is every stream's events of the store, to read.
AllEvents.Aggregate
func (a *AllEvents) Aggregate(ctx context.Context, q Query) ([]Row, error)Aggregate is a row for each span of Every and each value of the keys of By, with its count, the Stats of its fields and their Distinct values.
AllEvents.All
func (a *AllEvents) All(ctx context.Context, q Query) iter.Seq2[Event, error]All is every event the query finds, a page after another, holding nothing between pages.
AllEvents.Count
func (a *AllEvents) Count(ctx context.Context, q Query) (int, error)Count is how many events the query finds.
AllEvents.Damaged
func (a *AllEvents) Damaged(ctx context.Context) ([]Damage, error)Damaged is what reads met that no longer reads, which Drop removes: each head row and segment with its times.
AllEvents.Drop
func (a *AllEvents) Drop(ctx context.Context, damage Damage) errorDrop removes a head row or a segment that Damaged listed, so that the reads over it work again; one that still reads is never dropped.
AllEvents.FieldNames
func (a *AllEvents) FieldNames(ctx context.Context, q Query) ([]string, error)FieldNames is the keys the events hold, in fields and in context, sorted; Prefix narrows them.
AllEvents.List
func (a *AllEvents) List(ctx context.Context, q Query) (Page, error)List is one page of every stream's events, from one moment of the file; Streams narrows them.
AllEvents.Poll
func (a *AllEvents) Poll(ctx context.Context, cursor string) (Batch, error)Poll is every event once, a batch a call, from a cursor the program keeps, the oldest event kept from "". With no event past the cursor, the batch is empty and its cursor the one given. It reads what the store has packed, which a stream's waiting events are once a segment's worth or an hour old.
AllEvents.Streams
func (a *AllEvents) Streams(ctx context.Context) ([]Stream, error)Streams is every stream with events, by name, with what it keeps, where that begins and its newest event's time.
AllEvents.Tail
func (a *AllEvents) Tail(ctx context.Context, q Query) iter.Seq2[TailBatch, error]Tail is the events written from now on that the query finds, a batch as they are written. A reader slower than the writers skips what left the store's hold, and the batch after says how many. It ends when the loop is left, ctx is done or the store closes.
AllEvents.Top
func (a *AllEvents) Top(ctx context.Context, key string, q Query) ([]Top, error)Top is a key's most frequent values and how many events hold each: ten unless Limit asks for more, 1000 at most. The key is a field's or a context's, or stream, name or level.
AppendOption
type AppendOption interface {
// contains filtered or unexported methods
}AppendOption is what an append gives besides a name and fields.
At
func At(t time.Time) AppendOptionAt is the event's time: from what its stream keeps to ten minutes ahead.
Context
func Context(value any) AppendOptionContext is what the event happened in: who asked, which request.
Batch
type Batch struct {
Events []Event
// Cursor is where the next poll begins, kept once these events are safe.
Cursor string
// Expired is the events keep removed before the cursor reached them.
Expired int
}Batch is every event once, a batch a poll: its events, where the next poll begins, and what expired before it.
Damage
type Damage struct {
// Part is "head row" or "segment".
Part string
ID int64
Stream string
First, Last time.Time
Error string
}Damage is a head row or a segment that no longer reads, as Damaged lists it and Drop takes it.
Event
type Event struct {
// At is the zero time for now on a write.
At time.Time
// Stream is the stream a read found it in.
Stream string
// Name is what happened; "log" for a logger's line.
Name string
// Level is nil for an event without one, and slog's number on a read.
Level slog.Leveler
Message string
// Fields is what happened: on a write any value JSON writes as an object,
// a Fields or a struct; on a read the object's JSON as the file keeps it, a
// json.RawMessage, its spelling, its keys' order and a key written twice
// as they were. Nil when it has none.
Fields any
// Context is what it happened in, as Fields is: a logger's With, an Append's Context.
Context any
// TraceID is 32 hex digits, as a traceparent header writes it: the
// context's trace on a write unless given.
TraceID string
// SpanID is 16 hex digits.
SpanID string
}Event is an event: what AppendMany writes and what a read gives back. A read fills every field it has; a write gives a name and what it knows, its time now unless given, from what the stream keeps to ten minutes ahead.
Events
type Events struct {
// contains filtered or unexported fields
}Events is a stream of events: written with Append, which returns once the file holds them, and read back.
OpenEvents
func OpenEvents(store *tinystore.Store, stream string, opts ...Option) (*Events, error)OpenEvents opens a stream of events. It opens at its first call; its error is a name or an option it refuses.
Events.Aggregate
func (e *Events) Aggregate(ctx context.Context, q Query) ([]Row, error)Aggregate is a row for each span of Every and each value of the keys of By, with its count, the Stats of its fields and their Distinct values.
Events.All
func (e *Events) All(ctx context.Context, q Query) iter.Seq2[Event, error]All is every event the query finds, a page after another, holding nothing between pages.
Events.Append
func (e *Events) Append(ctx context.Context, name string, fields any, opts ...AppendOption) errorAppend writes an event: fields any value JSON writes as an object, a Fields or a struct. It returns once the event is written, and a read finds it at once.
Events.AppendMany
func (e *Events) AppendMany(ctx context.Context, events []Event) errorAppendMany writes a list of events whole or not at all; a refused event names its place in the list and its name.
Events.Count
func (e *Events) Count(ctx context.Context, q Query) (int, error)Count is how many events the query finds.
Events.FieldNames
func (e *Events) FieldNames(ctx context.Context, q Query) ([]string, error)FieldNames is the keys the events hold, in fields and in context, sorted; Prefix narrows them.
Events.Lines
func (e *Events) Lines(ctx context.Context) (*Lines, error)Lines is a writer of another program's output into this stream, each line an event at the time it arrived; a stack trace's or a JSON value's lines make one, and a write never waits. Close hands over what it holds.
out, err := worker.Lines(ctx)
cmd.Stdout = out
err = cmd.Run()
err = out.Close()Events.List
func (e *Events) List(ctx context.Context, q Query) (Page, error)List is one page of the stream's events, from one moment of its file.
Events.Name
func (e *Events) Name() stringName is the stream's name.
Events.Tail
func (e *Events) Tail(ctx context.Context, q Query) iter.Seq2[TailBatch, error]Tail is the events written from now on that the query finds, a batch as they are written. A reader slower than the writers skips what left the store's hold, and the batch after says how many. It ends when the loop is left, ctx is done or the store closes.
Events.Top
func (e *Events) Top(ctx context.Context, key string, q Query) ([]Top, error)Top is a key's most frequent values and how many events hold each: ten unless Limit asks for more, 1000 at most. The key is a field's or a context's, or stream, name or level.
Fields
type Fields map[string]anyFields is what an event holds: any value JSON writes, by key.
Handler
type Handler struct {
// contains filtered or unexported fields
}Handler is a slog.Handler of a store's: each line printed as console.NewHandler prints it, and kept in its stream as an event named log, its message the line's, the call's attributes its fields and those of logger.With its context. A call never waits for the store: lines wait in a bounded buffer and go every second, or once half of it waits, and what does not fit, or a write that fails, is dropped and counted, and said in TinyStore's own lines, since no call waits to be told. The store's close hands over what it holds. It is a slog.Handler as any other: slog.SetDefault takes it, and with console.Off it sits beside a program's own handler.
handler := records.NewHandler(store, "api", console.Redact(console.Secrets...))
log := slog.New(handler)
log.Info("signed in", "user", 42)
handler.Event("signup", "plan", "pro")NewHandler
func NewHandler(store *tinystore.Store, stream string, options ...console.Option) *HandlerNewHandler is a store's handler of a stream, with console's options and Keep and Buffer. Its level follows the config log, which it opens in the background: a change of it reaches every handler of the store, in every process, until it is reset. A stream's name the store refuses panics, as a pattern regexp.MustCompile refuses does: it is the program's, not its input's.
Handler.Dropped
func (h *Handler) Dropped() intDropped is the lines dropped since the handler began: a full buffer, or a write that failed.
Handler.Enabled
func (h *Handler) Enabled(ctx context.Context, level slog.Level) boolHandler.Event
func (h *Handler) Event(name string, args ...any)Event writes an event of the stream: named for itself, with no level and no message, its fields slog's key and value pairs, at once and dropped under load as a line is. An event that must not be lost is Append's.
Handler.EventContext
func (h *Handler) EventContext(ctx context.Context, name string, args ...any)EventContext is Event in ctx, whose trace it takes.
Handler.Flush
func (h *Handler) Flush(ctx context.Context) errorFlush hands what the buffer holds to the store now, as the timer does every second; what a write that failed held is dropped and counted.
Handler.Handle
func (h *Handler) Handle(ctx context.Context, record slog.Record) errorHandler.WithAttrs
func (h *Handler) WithAttrs(attrs []slog.Attr) slog.HandlerHandler.WithGroup
func (h *Handler) WithGroup(name string) slog.HandlerLines
type Lines struct {
// contains filtered or unexported fields
}Lines is a writer of another program's output into a stream, as Events.Lines begins it: each line becomes an event, and a write never waits. It sends whole lines, so that what it has no room for, Dropped counts as lines. The store's close hands over what it holds.
Lines.Close
func (l *Lines) Close() errorClose ends the writer: what it holds goes, a last line without its newline too, and it returns once the store wrote them.
Lines.Dropped
func (l *Lines) Dropped() intDropped is the lines dropped: past what the writer holds, and, once it closed, by the store.
Lines.Write
func (l *Lines) Write(p []byte) (int, error)Write takes a piece of output, cut anywhere; it never waits.
Option
type Option interface {
// contains filtered or unexported methods
}Option is how a stream opens.
Page
type Page struct {
Events []Event
Next string
}Page is a page of events, and where the next begins: "" on the last.
Query
type Query struct {
// Since is the span before now; or From and To.
Since time.Duration
// From is the range's start, included, and To its end, excluded; open when zero.
From, To time.Time
// Streams is any of these streams, for every stream's read; a stream reads its own.
Streams []string
// Names is any of these names: {"log"} is the lines.
Names []string
// MinLevel is this level and worse; an event without a level is not found.
MinLevel slog.Leveler
TraceID string
Where Where
// Search is this text in the message, the name or a value, as a phrase, its case ignored.
Search string
// Newest reads newest first; oldest first without it.
Newest bool
// Limit is a page's events, 1000 and 10,000 at most; a top's values, ten
// and 1000 at most; field names' keys.
Limit int
// After is a page's Next, with the rest of the query as it was.
After string
// Every is the span of an aggregate's row: the range is one without it.
Every time.Duration
// By is keys whose every value has rows of its own.
By []string
// Stats is fields whose numbers a row sums.
Stats []string
// Distinct is fields whose different values a row counts.
Distinct []string
// Prefix narrows the keys FieldNames gives.
Prefix string
}Query is what a read finds: every condition given holds, and a condition left at its zero value is not given. A program that may lack a trace id checks it before it asks, since "" reads every trace.
records.Query{Since: time.Hour, MinLevel: slog.LevelWarn}
records.Query{From: start, To: end, Streams: []string{"api"}, Where: records.Where{"user": 42}}Row
type Row struct {
// At is where the row's span begins, counted from 1970 in UTC.
At time.Time
Count int
// By is each key's value, its numbers a json.Number; nil for events without it.
By map[string]any
Stats map[string]Stats
Distinct map[string]int
}Row is a row of an aggregate: a span of Every and a value of each key of By, with its count.
Stats
type Stats struct {
Samples int
Sum, Min, Max json.Number
Avg float64
}Stats is a field's numbers in a row: an integer's sum exact however large it grows, or a float's, as json.Number spells them; Samples are the numbers, which Avg divides Sum by.
Stream
type Stream struct {
Name string
Keep time.Duration
// RetainedFrom is its oldest event, or where its keep begins while it holds older.
RetainedFrom time.Time
Newest time.Time
}Stream is a stream with events: what it keeps, where that begins, and its newest event's time.
TailBatch
type TailBatch struct {
Events []Event
Missed int
}TailBatch is a tail's batch: the events written since the last, and how many it missed.
Top
type Top struct {
// Value is the JSON value, its numbers a json.Number.
Value any
Count int
}Top is one of a key's most frequent values, and how many events hold it.
Where
type Where map[string]anyWhere is what a query finds in an event's fields or context: each key with this value, by the JSON it was written as.
console.AddSource
const AddSource = addSource(true)AddSource adds where each line was logged, as slog's handlers spell it: source={"function":"main.run","file":"/app/main.go","line":42}, which a pretty line shows as source=app/main.go:42.
console.HideStream
const HideStream = hiddenStream(true)HideStream leaves the stream out of a pretty line; a JSON line and the store keep it.
console.KeepURLPasswords
const KeepURLPasswords = keptURLPasswords(true)KeepURLPasswords leaves the password of a URL inside a value as it is. Without it, postgres://ann:hunter2@db/app is kept as postgres://ann:[redacted]@db/app.
console.NoEnv
const NoEnv = noEnv(true)NoEnv reads no variable: what the code says is what the handler does.
console.Secrets
var Secrets = logline.SecretsSecrets is what Redact takes to hide the usual secrets. It hides a counter named like one too, token_count among them.
console.NewHandler
func NewHandler(stream string, options ...Option) slog.HandlerNewHandler writes a logger's lines to standard error, and keeps none.
console.Format
type Format intFormat is how the console writes a line. Without one, lines are pretty on a terminal and JSON otherwise.
console.Pretty
const (
Pretty Format = iota + 1 // 11:02:11.123 INFO api started port=3000
JSON // one object a line, for a collector
Off // nothing: a store's handler still keeps each line
)console.Format.Apply
func (f Format) Apply(s *logline.Settings)console.Option
type Option = logline.OptionOption changes a logger's lines: on the console, and in the store when the handler is a store's.
console.FromEnv
func FromEnv(prefix string) OptionFromEnv reads prefix_LOG_LEVEL, prefix_LOG_FORMAT and prefix_LOG_TIME, which win over the code. Without an environment option a handler reads LOG_LEVEL, LOG_FORMAT and LOG_TIME, as FromEnv("") does.
console.FromLookup
func FromLookup(prefix string, lookup func(name string) (string, bool)) OptionFromLookup reads the variables FromEnv names through lookup, the process's environment left alone.
console.Level
func Level(level slog.Leveler) OptionLevel keeps lines from level up; without it every line is kept.
console.Redact
func Redact(names ...string) OptionRedact hides the values of fields whose keys name a secret, at any depth of a JSON value. A key names one when some of its words in a row, written together, are a name's: the words of DB_PASSWORD, PasswordHash, api-key and APIKey are split at '_', '-', '.', spaces and capitals, the case ignored. The message is not searched.
Redact("password", "api key") hides password, DB_PASSWORD, PasswordHash, api_key, apiKey, APIKEY
Redact("token") hides bot_token, token_count, and not tokens_usedconsole.ReplaceAttr
func ReplaceAttr(replace func(groups []string, attr slog.Attr) slog.Attr) OptionReplaceAttr changes or drops each attribute before it is kept and shown, as slog.HandlerOptions' does: groups are the attribute's groups, outermost first, and a zero Attr drops it. It is not called for the time, the level or the message.
console.To
func To(w io.Writer) OptionTo writes the lines to w instead of standard error.
console.Time
type Time intTime is how a pretty line shows its time; a JSON line always has it.
console.TimeClock
const (
TimeClock Time = iota + 1 // 11:02:11.123, the default
TimeFull // 2026-10-02 11:02:11.123 +03:00
TimeOff // none, where docker or journald stamp each line
)console.Time.Apply
func (t Time) Apply(s *logline.Settings)