send

package
v0.2.4 Latest Latest
Warning

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

Go to latest
Published: Apr 14, 2023 License: Apache-2.0 Imports: 22 Imported by: 25

Documentation

Overview

Call Site Sender

Call site loggers provide a way to record the line number and file name where the logging call was made, which is particularly useful in tracing down log messages.

This sender does *not* attach this data to the Message object, and the call site information is only logged when formatting the message itself. Additionally the call site includes the file name and its enclosing directory.

When constructing the Sender you must specify a "depth" argument This sets the offset for the call site relative to the Sender's Send() method. Grip's default logger (e.g. the grip.Info() methods and friends) requires a depth of 2, while in *most* other cases you will want to use a depth of 1. The LogMany, and Emergency[Panic,Fatal] methods also include an extra level of indirection.

Create a call site logger with one of the following constructors:

NewCallSiteConsoleLogger(<name>, <depth>, <LevelInfo>)
MakeCallSiteConsoleLogger(<depth>)
NewCallSiteFileLogger(<name>, <fileName>, <depth>, <LevelInfo>)
MakeCallSiteFileLogger(<fileName>, <depth>)

Package send provides an interface for defining "senders" for different logging backends, as well as basic implementations for common logging approaches to use with the Grip logging interface. Backends currently include: syslog, systemd's journal, standard output, and file baased methods.

Index

Constants

This section is empty.

Variables

View Source
var ErrorTruncated = errors.New("buffer was truncated")

ErrorTruncated means that the limited buffer capacity was overwritten.

Functions

func AddToMulti

func AddToMulti(multi Sender, s Sender) error

AddToMulti is a helper function that takes two Sender instances, the first of which must be a multi or async group sender. If this is true, then AddToMulti adds the second Sender to the first Sender's list of Senders.

Returns an error if the first instance is not a multi sender, or if the async group sender has been closed.

func MakeStandard

func MakeStandard(s Sender) *log.Logger

MakeStandard produces a standard library logging instance that write to the underlying sender.

func ShouldLog added in v0.2.1

func ShouldLog(s Sender, m message.Composer) bool

Types

type Base

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

Base provides most of the functionality of the Sender interface, except for the Send method, to facilitate writing novel Sender implementations. All implementations of the functions

func (*Base) Close

func (b *Base) Close() error

Close calls the closer function if it is defined and it has not already been closed.

func (*Base) ErrorHandler

func (b *Base) ErrorHandler() ErrorHandler

ErrorHandler returns an error handling functioncalls the error handler, and is a wrapper around the embedded ErrorHandler function.

func (*Base) Flush

func (b *Base) Flush(ctx context.Context) error

Flush provides a default implementation of the Flush method for senders that don't cache messages locally.

func (*Base) Formatter

func (b *Base) Formatter() MessageFormatter

Formatter returns the formatter, defaulting to using the string form of the message if no formatter is configured.

func (*Base) Name

func (b *Base) Name() string

Name returns the name of the Sender.

func (*Base) Priority added in v0.2.1

func (b *Base) Priority() level.Priority

Level reports the currently configured level for the Sender.

func (*Base) SetCloseHook

func (b *Base) SetCloseHook(f func() error)

func (*Base) SetErrorHandler

func (b *Base) SetErrorHandler(eh ErrorHandler)

SetErrorHandler configures the error handling function for this Sender.

func (*Base) SetFormatter

func (b *Base) SetFormatter(mf MessageFormatter)

SetFormatter users to set the formatting function used to construct log messages.

func (*Base) SetName

func (b *Base) SetName(name string)

SetName allows clients to change the name of the Sender.

func (*Base) SetPriority added in v0.2.1

func (b *Base) SetPriority(p level.Priority)

SetPriority configures the level (default levels and threshold levels) for the Sender.

func (*Base) SetResetHook

func (b *Base) SetResetHook(f func())

type ErrorHandler

type ErrorHandler func(error, message.Composer)

ErrorHandler is a function that you can use define how a sender handles errors sending messages. Implementations of this type should perform a noop if the err object is nil.

func ErrorHandlerFromLogger

func ErrorHandlerFromLogger(l *log.Logger) ErrorHandler

func ErrorHandlerFromSender

func ErrorHandlerFromSender(s Sender) ErrorHandler

ErrorHandlerFromSender wraps an existing Sender for sending error messages.

type InMemorySender

type InMemorySender struct {
	Base
	// contains filtered or unexported fields
}

InMemorySender represents an in-memory buffered sender with a fixed message capacity.

func (*InMemorySender) Get

func (s *InMemorySender) Get() []message.Composer

Get returns all the current messages in the buffer.

func (*InMemorySender) GetCount

func (s *InMemorySender) GetCount(count int) ([]message.Composer, int, error)

GetCount returns at most count messages in the buffer as a stream. It returns the messages and the number of messages returned. If the function is called and reaches the end of the buffer, it returns io.EOF. If the position it is currently reading at has been truncated, this returns ErrorTruncated. To continue reading, the read stream must be reset using ResetRead.

func (*InMemorySender) GetRaw

func (s *InMemorySender) GetRaw() []any

GetRaw returns all the current messages in the buffer as empty interfaces.

func (*InMemorySender) GetString

func (s *InMemorySender) GetString() ([]string, error)

GetString returns all the current messages in the buffer as formatted strings.

func (*InMemorySender) ResetRead

func (s *InMemorySender) ResetRead()

ResetRead resets the read stream used in GetCount.

func (*InMemorySender) Send

func (s *InMemorySender) Send(msg message.Composer)

Send adds the given message to the buffer. If the buffer is at max capacity, it truncates the oldest message.

func (*InMemorySender) TotalBytesSent

func (s *InMemorySender) TotalBytesSent() int64

TotalBytesSent returns the total number of bytes sent.

type InternalMessage

type InternalMessage struct {
	Message message.Composer

	Logged   bool
	Priority level.Priority
	Rendered string
}

InternalMessage provides a complete representation of all information associated with a logging event.

type InternalSender

type InternalSender struct {
	Base
	// contains filtered or unexported fields
}

InternalSender implements a Sender object that makes it possible to access logging messages, in the InternalMessage format without logging to an output method. The Send method does not filter out under-priority and unloggable messages. Used for testing purposes.

func MakeInternalLogger

func MakeInternalLogger() *InternalSender

MakeInternalLogger constructs an internal sender object, typically for use in testing.

func NewInternalLogger

func NewInternalLogger(size int) *InternalSender

NewInternalLogger creates and returns a Sender implementation that does not log messages, but converts them to the InternalMessage format and puts them into an internal channel, that allows you to access the massages via the extra "GetMessage" method. Useful for testing.

func (*InternalSender) GetMessage

func (s *InternalSender) GetMessage() *InternalMessage

GetMessage pops the first message in the queue and returns.

func (*InternalSender) GetMessageSafe

func (s *InternalSender) GetMessageSafe() (*InternalMessage, bool)

func (*InternalSender) HasMessage

func (s *InternalSender) HasMessage() bool

HasMessage returns true if there is at least one message that has not be removed.

func (*InternalSender) Len

func (s *InternalSender) Len() int

Len returns the number of sent messages that have not been retrieved.

func (*InternalSender) Send

func (s *InternalSender) Send(m message.Composer)

Send sends a message. Unlike all other sender implementations, all messages are sent, but the InternalMessage format tracks "loggability" for testing purposes.

type MessageFormatter

type MessageFormatter func(message.Composer) (string, error)

MessageFormatter is a function type used by senders to construct the entire string returned as part of the output. This makes it possible to modify the logging format without needing to implement new Sender interfaces.

func MakeCallSiteFormatter

func MakeCallSiteFormatter(depth int) MessageFormatter

MakeCallSiteFormatter returns a MessageFormater that formats messages with the following format:

[p=<levvel>] [<fileName>:<lineNumber>]: <message>

It can never error.

func MakeDefaultFormatter

func MakeDefaultFormatter() MessageFormatter

MakeDefaultFormatter returns a MessageFormatter that will produce a message in the following format:

[p=<level>]: <message>

It can never error.

func MakeJSONFormatter

func MakeJSONFormatter() MessageFormatter

MakeJSONFormatter returns a MessageFormatter, that returns messages as the string form of a JSON document built using the Raw method of the Composer. Returns an error if there was a problem marshalling JSON.

func MakePlainFormatter

func MakePlainFormatter() MessageFormatter

MakePlainFormatter returns a MessageFormatter that simply returns the string format of the log message.

type Sender

type Sender interface {
	// Name returns the name of the logging system. Typically this
	// corresponds directly with the underlying logging capture system.
	Name() string
	//SetName sets the name of the logging system.
	SetName(string)

	// Method that actually sends messages (the string) to the logging
	// capture system. The Send() method filters out logged messages based
	// based on priority, typically using the generic
	// MessageInfo.ShouldLog() function.
	Send(message.Composer)

	// Flush flushes any potential buffered messages to the logging capture
	// system. If the Sender is not buffered, this function should noop and
	// return nil.
	Flush(context.Context) error

	// SetPriority sets the threshold of the sender. Typically,
	// loggers will not send messages that have a priority less
	// than this level.
	SetPriority(level.Priority)

	// Level returns the currently configured level for the sender.
	Priority() level.Priority

	// SetErrorHandler provides a method to inject error handling behavior
	// to a sender. Not all sender implementations use the error handler,
	// although some, use a default handler to write logging errors to
	// standard output.
	SetErrorHandler(ErrorHandler)
	ErrorHandler() ErrorHandler

	// SetFormatter allows users to inject formatting functions to modify
	// the output of the log sender by providing a function that takes a
	// message and returns string and error.
	SetFormatter(MessageFormatter)
	Formatter() MessageFormatter

	// If the logging sender holds any resources that require desecration
	// they should be cleaned up in the Close() method. Close() is called
	// by the SetSender() method before changing loggers. Sender implementations
	// that wrap other Senders may or may not close their underlying Senders.
	Close() error
}

The Sender interface describes how the Journaler type's method in primary "grip" package's methods interact with a logging output method. The Journaler type provides Sender() and SetSender() methods that allow client code to swap logging backend implementations dependency-injection style.

func FromStandard

func FromStandard(logger *log.Logger) Sender

FromStandard prodeces a sender implementation from the standard library logger.

func MakeAnnotating

func MakeAnnotating(s Sender, annotations map[string]any) Sender

MakeAnnotating adds the annotations defined in the annotations map to every argument.

Calling code should assume that the sender owns the annotations map and it should not attempt to modify that data after calling the sender constructor. Furthermore, since it owns the sender, callin Close on this sender will close the underlying sender.

While you can wrap an existing sender with the annotator, changes to the annotating sender (e.g. level, formater, error handler) will propagate to the embedded sender.

func MakeAsyncGroup added in v0.2.0

func MakeAsyncGroup(ctx context.Context, bufferSize int, senders ...Sender) Sender

MakeAsyncGroup produces an implementation of the Sender interface that, like the MultiSender, distributes a single message to a group of underlying sender implementations.

This sender does not guarantee ordering of messages. The buffer size controls the size of the buffer between each sender and the individual senders.

The sender takes ownership of the underlying Senders, so closing this sender closes all underlying Senders.

func MakeBuffered added in v0.2.0

func MakeBuffered(sender Sender, interval time.Duration, size int) Sender

MakeBuffered provides a Sender implementation that wraps an existing Sender sending messages in batches, on a specified buffer size or after an interval has passed.

If the interval is 0, the constructor sets an interval of 1 minute, and if it is less than 5 seconds, the constructor sets it to 5 seconds. If the size threshold is 0, then the constructor sets a threshold of 100.

This Sender does not own the underlying Sender, so users are responsible for closing the underlying Sender if/when it is appropriate to release its resources.

func MakeCallSite

func MakeCallSite(depth int) Sender

MakeCallSite constructs an unconfigured call site logger that writes output to standard output. You must set the name of the logger using SetName or your Journaler's SetSender method before using this logger.

func MakeCallSiteFile

func MakeCallSiteFile(fileName string, depth int) (Sender, error)

MakeCallSiteFile constructs an unconfigured call site logger that writes output to the specified hours. You must set the name of the logger using SetName or your Journaler's SetSender method before using this logger.

func MakeFile

func MakeFile(filePath string) (Sender, error)

MakeFile creates a file-based logger, writing output to the specified file. The Sender instance is not configured: Pass to Journaler.SetSender or call SetName before using.

func MakeFilter added in v0.2.0

func MakeFilter(sender Sender, ifn func(message.Composer)) Sender

MakeFilter constructs an intercepting sender implementation that wraps another sender, and passes all messages (regardless of loggability or level,) through a filtering function.

This implementation and the filtering function exist mostly to be able to inject metrics collection into existing logging pipelines, though the interceptor may be used for filtering or pre-processing as well.

func MakeJSON

func MakeJSON() Sender

MakeJSON builds a Sender instance that prints log messages in a JSON formatted to standard output. The JSON formated message is taken by calling the Raw() method on the message.Composer and Marshalling the results.

func MakeJSONFile

func MakeJSONFile(file string) (Sender, error)

MakeJSONFile creates an un-configured JSON logger that writes output to the specified file.

func MakeMulti

func MakeMulti(senders ...Sender) Sender

MakeMulti returns a multi sender implementation with Sender members, but does not force the senders to have conforming name or level values. Use NewMultiSender to construct a list of senders with consistent names and level configurations.

Use the AddToMulti helper to add additioanl senders to one of these multi Sender implementations after construction.

The Sender takes ownership of the underlying Senders, so closing this Sender closes all underlying Senders.

func MakePlain

func MakePlain() Sender

MakePlain returns an unconfigured sender without a prefix, using the plain log formatter. This Sender writes all output to standard error.

The underlying mechanism uses the standard library's logging facility.

func MakePlainFile

func MakePlainFile(filePath string) (Sender, error)

MakePlainFile writes all output to a file, but does not prepend any log formatting to each message.

The underlying mechanism uses the standard library's logging facility.

func MakePlainStdError

func MakePlainStdError() Sender

MakePlainStdError returns an unconfigured sender without a prefix, using the plain log formatter. This Sender writes all output to standard error.

The underlying mechanism uses the standard library's logging facility.

func MakeStdError

func MakeStdError() Sender

MakeStdError returns an unconfigured Sender implementation that writes all logging output to standard error.

func MakeStdOutput

func MakeStdOutput() Sender

MakeStdOutput returns an unconfigured native standard-out logger. You *must* call SetName on this instance before using it. (Journaler's SetSender will typically do this.)

func MakeTesting

func MakeTesting(t *testing.T) Sender

MakeTesting constructs a fully configured Sender implementation that logs using the testing.T's logging facility for better integration with unit tests. Construct and register such a sender for grip.Journaler instances that you use inside of tests to have logging that correctly respects go test's verbosity.

By default, this constructor creates a sender with a level threshold of "debug" and a default log level of "info."

func NewInMemorySender

func NewInMemorySender(name string, p level.Priority, capacity int) (Sender, error)

NewInMemorySender creates an in-memory buffered sender with the given capacity.

func NewMulti

func NewMulti(name string, senders []Sender) Sender

NewMulti configures a new sender implementation that takes a slice of Sender implementations that dispatches all messages to all implementations.

Use the AddToMulti helper to add additioanl senders to one of these multi Sender implementations after construction.

The Sender takes ownership of the underlying Senders, so closing this Sender closes all underlying Senders.

func WrapWriter

func WrapWriter(wr io.Writer) Sender

WrapWriter constructs a new unconfigured sender that directly wraps any writer implementation. These loggers prepend time and logger name information to the beginning of log lines.

As a special case, if the writer is a *WriterSender, then this method will unwrap and return the underlying sender from the writer.

func WrapWriterPlain

func WrapWriterPlain(wr io.Writer) Sender

WrapWriterPlain produces a simple writer that does not modify the log lines passed to the writer.

The underlying mechanism uses the standard library's logging facility.

type WriterSender

type WriterSender struct {
	Sender
	// contains filtered or unexported fields
}

WriterSender wraps another sender and also provides an io.Writer. (and because Sender is an io.Closer) the type also implements io.WriteCloser.

func MakeWriter

func MakeWriter(s Sender) *WriterSender

MakeWriter wraps another sender and also provides an io.Writer. (and because Sender is an io.Closer) the type also implements io.WriteCloser.

While WriteSender itself implements Sender, it also provides a Writer method, which allows you to use this Sender to capture file-like write operations.

Data sent via the Write method is buffered internally until its passed a byte slice that ends with the new line character. If the string form of the bytes passed to the write method (including all buffered messages) is only whitespace, then it is not sent.

If there are any bytes in the buffer when the Close method is called, this sender flushes the buffer. WriterSender does not own the underlying Sender, so users are responsible for closing the underlying Sender if/when it is appropriate to release its resources.

func (*WriterSender) Close

func (s *WriterSender) Close() error

Close writes any buffered messages to the underlying Sender. This does not close the underlying sender.

func (*WriterSender) Unwrap added in v0.1.1

func (s *WriterSender) Unwrap() Sender

func (*WriterSender) Write

func (s *WriterSender) Write(p []byte) (int, error)

Write captures a sequence of bytes to the send interface. It never errors.

Jump to

Keyboard shortcuts

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