logbuffer

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Dec 10, 2020 License: MPL-2.0 Imports: 3 Imported by: 0

Documentation

Overview

Package logbuffer provides a structure and API for efficiently reading and writing logs that may be streamed to a server.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Buffer

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

Buffer is a data structure for buffering logs with concurrent read/write access.

Callers can use easy APIs to write and read data and the storage and access is managed underneath. If a reader falls behind a writer significantly, then the next read may "jump" forward to catch up. There is no way to explicitly detect a jump currently.

Writer

The writer calls Write on the buffer as it gets log entries. Multiple writers are safe to use. The buffer will always successfully write all entries, though it may result in extra allocations.

buf.Write(entries...)

Reader

A reader calls buf.Reader to get a Reader structure, and then calls Read to read values from the buffer. The Reader structure is used to maintain per-reader cursors so that multiple readers can exist at multiple points.

Internal Details

A buffer is structured as a sliding window over a set of "chunks". A chunk is a set of log entries. As you write into the buffer, the buffer will append to the current chunk until it is full, then move to the next chunk. When all the chunks are full, the buffer will allocate a new set of chunks.

The break into "chunks" is done for two reasons. The first is to prevent overallocation; we don't need to allocate a lot of buffer space, only enough for the current chunk. Second, to avoid lock contention. Once a chunk is full, it will never be written to again so we never need to acquire a lock to read the data. This makes reading backlogs very fast.

func New

func New() *Buffer

New creates a new Buffer.

func (*Buffer) Close

func (b *Buffer) Close() error

Close closes this log buffer. This will immediately close all active readers and further writes will do nothing.

func (*Buffer) Reader

func (b *Buffer) Reader(maxHistory int32) *Reader

Reader returns a shared reader for this buffer. The Reader provides an easy-to-use API to read log entries.

maxHistory limits the number of elements in the backlog. maxHistory of zero will move the cursur to the latest entry. maxHistory less than zero will not limit history at all and the full backlog will be available to read.

func (*Buffer) Write

func (b *Buffer) Write(entries ...Entry)

Write writes the set of entries into the buffer.

This is safe for concurrent access.

type Entry

type Entry interface{}

Entry is just an interface{} type. Buffer doesn't care what the entries are since it assumes they come in in some order and are read in that same order.

type Reader

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

Reader reads log entry values from a buffer.

Each Reader maintains its own read cursor. This allows multiple readers to exist across a Buffer at multiple points. Subsequent calls to Read may "jump" across time if a reader falls behind the writer.

It is not safe to call Read concurrently. If you want concurrent read access you can either create multiple readers or protect Read with a lock. You may call Close concurrently with Read.

func (*Reader) Close

func (r *Reader) Close() error

Close closes the reader. This will cause all future Read calls to return immediately with a nil result. This will also immediately unblock any currently blocked Reads.

This is safe to call concurrently with Read.

func (*Reader) CloseContext

func (r *Reader) CloseContext(ctx context.Context)

CloseContext will block until ctx is done and then close the reader. This can be called multiple times to register multiple context values to close the reader on.

func (*Reader) Read

func (r *Reader) Read(max int, block bool) []Entry

Read returns a batch of log entries, up to "max" amount. If "max" isn't available, this will return any number that currently exists. If zero exist and block is true, this will block waiting for available entries. If block is false and no more log entries exist, this will return nil.

Jump to

Keyboard shortcuts

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