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
- Variables
- func AddToMulti(multi Sender, s Sender) error
- func MakeStandard(s Sender) *log.Logger
- func MakeWriter(s Sender) *writerSenderImpl
- func ShouldLog(s Sender, m message.Composer) bool
- func WrapError(err error, m message.Composer) error
- type Base
- func (b *Base) Close() error
- func (b *Base) Flush(ctx context.Context) error
- func (b *Base) Format(m message.Composer) (string, error)
- func (b *Base) GetErrorHandler() ErrorHandler
- func (b *Base) GetFormatter() MessageFormatter
- func (b *Base) HandleError(err error)
- func (b *Base) HandleErrorOK(err error) bool
- func (b *Base) Name() string
- func (b *Base) Priority() level.Priority
- func (b *Base) SetCloseHook(f func() error)
- func (b *Base) SetErrorHandler(eh ErrorHandler)
- func (b *Base) SetFormatter(mf MessageFormatter)
- func (b *Base) SetName(name string)
- func (b *Base) SetPriority(p level.Priority)
- type ErrorHandler
- type InMemorySender
- func (s *InMemorySender) Get() []message.Composer
- func (s *InMemorySender) GetCount(count int) ([]message.Composer, int, error)
- func (s *InMemorySender) GetRaw() []any
- func (s *InMemorySender) GetString() ([]string, error)
- func (s *InMemorySender) ResetRead()
- func (s *InMemorySender) Send(msg message.Composer)
- func (s *InMemorySender) TotalBytesSent() int64
- type InternalMessage
- type InternalSender
- type MessageConverter
- type MessageFormatter
- type Sender
- func FromStandard(logger *log.Logger) Sender
- func MakeAnnotating(s Sender, annotations map[string]any) Sender
- func MakeAsyncGroup(ctx context.Context, bufferSize int, senders ...Sender) Sender
- func MakeBuffered(sender Sender, interval time.Duration, size int) Sender
- func MakeBytesBuffer(buf *bytes.Buffer) Sender
- func MakeCallSite(depth int) Sender
- func MakeCallSiteFile(fileName string, depth int) (Sender, error)
- func MakeFile(filePath string) (Sender, error)
- func MakeFilter(sender Sender, ifn func(message.Composer)) Sender
- func MakeJSON() Sender
- func MakeJSONFile(file string) (Sender, error)
- func MakeMulti(senders ...Sender) Sender
- func MakePlain() Sender
- func MakePlainFile(filePath string) (Sender, error)
- func MakePlainStdError() Sender
- func MakeStdError() Sender
- func MakeStdOutput() Sender
- func MakeTesting(t *testing.T) Sender
- func NewInMemorySender(name string, p level.Priority, capacity int) (Sender, error)
- func NewMulti(name string, senders []Sender) Sender
- func NopSender() Sender
- func WithOptionSender(s Sender, options ...message.Option) Sender
- func WrapWriter(wr io.Writer) Sender
- func WrapWriterPlain(wr io.Writer) Sender
- type WriterSender
Constants ¶
const ErrGripMessageSendError ers.Error = "unable to send grip log message"
Variables ¶
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.
var ErrorTruncated = errors.New("buffer was truncated")
ErrorTruncated means that the limited buffer capacity was overwritten.
Functions ¶
func AddToMulti ¶
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 ¶
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.
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 ¶
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 ¶
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) 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 (*Base) HandleErrorOK ¶ added in v0.3.5
func (*Base) Priority ¶ added in v0.2.1
Level reports the currently configured level for the Sender.
func (*Base) SetCloseHook ¶
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 ¶
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
SetPriority configures the level (default levels and threshold levels) for the Sender.
type ErrorHandler ¶
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 ¶
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
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 ¶
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 ¶
FromStandard prodeces a sender implementation from the standard library logger.
func MakeAnnotating ¶
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
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
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
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 ¶
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 ¶
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 ¶
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
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 ¶
MakeJSONFile creates an un-configured JSON logger that writes output to the specified file.
func MakeMulti ¶
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 ¶
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 ¶
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 ¶
NewInMemorySender creates an in-memory buffered sender with the given capacity.
func NewMulti ¶
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 WrapWriter ¶
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 ¶
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