send

package
v0.3.7 Latest Latest
Warning

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

Go to latest
Published: Nov 5, 2023 License: Apache-2.0 Imports: 24 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

View Source
const ErrGripMessageSendError ers.Error = "unable to send grip log message"

Variables

View Source
var ErrAlreadyClosed = errors.New("sender already closed")

ErrAlreadyClosed is a component of the err returend from Base.Close() when Close is called more than once.

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 MakeWriter

func MakeWriter(s Sender) *writerSenderImpl

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 ShouldLog added in v0.2.1

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

func WrapError added in v0.3.5

func WrapError(err error, m message.Composer) error

WrapError wraps an error with the message composer and produces a combined error that includes the string form of the message (as an error,) ErrGripMessageSendError, and the underlying error. When the input error is nil, the error is nil.

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. A sender, relying on the Base.Close infrastructure can is closed once closed cannot be reopened or re-used. Subsequent attempts to close a sender will return an error object that contains both the original error and an error rooted in ErrAlreadyClosed.

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. This is a noop by default.

func (*Base) Format added in v0.3.5

func (b *Base) Format(m message.Composer) (string, error)

func (*Base) GetErrorHandler added in v0.3.5

func (b *Base) GetErrorHandler() ErrorHandler

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

func (*Base) GetFormatter added in v0.3.5

func (b *Base) GetFormatter() MessageFormatter

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

func (*Base) HandleError added in v0.3.5

func (b *Base) HandleError(err error)

func (*Base) HandleErrorOK added in v0.3.5

func (b *Base) HandleErrorOK(err error) bool

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)

SetCloseHook defines the behavior of the Close() method in the Base implementation.

The Base implementation ensures that this function is called exactly once when the Sender is closed. However, the error returned by this function is cached, and part of the return value of subsequent calls to Close().

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.

Previously this also called the ResetHook, but Sender implementors. should now do this manually, if/when needed.

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.

type ErrorHandler

type ErrorHandler fun.Handler[error]

ErrorHandler is a function that you can use to process errors encountered sending messages. When errors are encountered the messages are discarded unless an alternate sender (via a multi-sender implementation) or fallback is configured. Implementations of this type should perform a noop if the error 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.

func ErrorHandlerWriter added in v0.2.5

func ErrorHandlerWriter(writer io.Writer) ErrorHandler

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
	Filter func(message.Composer)
	// 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 MakeInternal added in v0.2.7

func MakeInternal() *InternalSender

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

func NewInternal added in v0.2.7

func NewInternal(size int) *InternalSender

NewInternal 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 MessageConverter added in v0.2.5

type MessageConverter func(any) message.Composer

MessageConverter defines the converter provided by the sender to higher level interfaces (e.g. grip.Logger) that will always produce a valid message.Composer from an arbitrary input.

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=<level>] [<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 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. If the underlying sender method encounters an
	// error, that error is handed to this function, which
	// processes. Sender implementations should then  Not all sender implementations use the error handler,
	// although some, use a default handler to write logging errors to
	// standard output.
	SetErrorHandler(ErrorHandler)
	GetErrorHandler() 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)
	GetFormatter() 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 a lower level message sending interface used by the Logger to send messages. Implementations in the send package, in addition to a number of senders implemented in the x/ hierarchy, allow Loggers to target consumers in a number of different forms directly.

The send.Base implementation provides implementations for all methods in the interface except Send. Most implementations will only implement Send, and sometimes Flush, in addition to exposing/composing Base.

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 MakeBytesBuffer added in v0.3.5

func MakeBytesBuffer(buf *bytes.Buffer) Sender

MakeBytesBuffer creates a sender that writes data to the provided bytes.Buffer. The sender uses the message formatter, and resepects level logging.

A new line is added between each message as written.

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.

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 NopSender added in v0.3.5

func NopSender() Sender

NopSender creates a valid sender implementation where all Send operations are a noop. All other operations are valid.

func WithOptionSender added in v0.3.5

func WithOptionSender(s Sender, options ...message.Option) Sender

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 interface {
	Sender
	io.WriteCloser
	// the Get/Set methods on the WriterSender control the
	// priority of messages sent to the sender.
	adt.AtomicValue[level.Priority]
}

WriterSender wraps another sender and also provides an io.Writer. (and because Sender is an io.Closer) the type also implements io.WriteCloser. Set the Level field to control the level that the data is logged at. If not specified, the sender will use the Sender's configured priority threshold.

If you do not use the `MakeWriter

Jump to

Keyboard shortcuts

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