log

package module
v0.0.0-...-a92fb89 Latest Latest
Warning

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

Go to latest
Published: Sep 6, 2026 License: MIT Imports: 12 Imported by: 20

README

mlog

mlog (multi-logger) is a fork of github.com/go-ozzo/ozzo-log

Documentation

Overview

package mlog is labelled as package log.

Package log implements logging with severity levels and message categories.

Example
package main

import (
	L "github.com/fbaube/mlog"
)

func main() {
	// MAYBE not necessary! Does running an Example func invoke L.init() ?
	LL := L.NewLogger()
	// Add two loggers that write to Stdout
	LL.Targets = append(L.L.Targets, L.NewConsoleTarget())
	LL.Targets = append(L.L.Targets, L.NewConsoleTarget())
	LL.Open()
	LL.Info("%d", len(L.L.Targets))
	LL.Dbg("Debug message")
	LL.Error("Error message")
}
Output:
2
Debug message
Error message

Index

Examples

Constants

This section is empty.

Variables

View Source
var CtlSeqTextBrushes = map[LU.Level]ControlSequenceTextBrush{
	LU.LevelDebug: newControlSequenceTextBrush("30;2"),

	LU.LevelInfo:    newControlSequenceTextBrush("36"),
	LU.LevelOkay:    newControlSequenceTextBrush("32"),
	LU.LevelWarning: newControlSequenceTextBrush("31"),
	LU.LevelError:   newControlSequenceTextBrush("31;1"),
	LU.LevelPanic:   newControlSequenceTextBrush("1;95"),
	LU.GreenBG:      newControlSequenceTextBrush("42;2;4"),
}

Functions

func DefaultDetailsFormatter

func DefaultDetailsFormatter(l *Logger, e *Entry, spcl []string) string

DefaultDetailsFormatter is the default formatter used to format every log message when the Target is details-capable. In this formatter, we assume that the Logger IS a Details Logger.

Note that this only really works with single threading, or else the log messages of different Details sets get all mised up.

func DefaultFormatter

func DefaultFormatter(l *Logger, e *Entry) string

DefaultFormatter is the default formatter used to format every log message. This formatter assumes no Target is a DetailsTarget.

func GetCallStack

func GetCallStack(skip int, frames int, filter string) string

GetCallStack returns the current call stack information as a string. The skip parameter specifies how many top frames should be skipped, while the frames parameter specifies at most how many frames should be returned.

func LogTextQuote

func LogTextQuote(*Entry, string)

func SetMaxLevel

func SetMaxLevel(lvl LU.Level)

Types

type ConsoleTarget

type ConsoleTarget struct {
	*Filter
	ColorMode bool      // whether to use colors to differentiate log levels
	Writer    io.Writer // the writer to write log messages

	DetailsInfo // NEW
	// contains filtered or unexported fields
}

ConsoleTarget writes filtered log messages to console window.

func NewConsoleTarget

func NewConsoleTarget() *ConsoleTarget

NewConsoleTarget creates a ConsoleTarget (i.e. Stdout). The new ConsoleTarget takes these default options: MaxLevel: LU,LevelDebug, ColorMode: true, Writer: os.Stdout .

Example
package main

import (
	log "github.com/fbaube/mlog"
)

func main() {
	logger := log.NewLogger()

	// creates a ConsoleTarget with color mode being disabled
	target := log.NewConsoleTarget()
	target.ColorMode = false

	logger.Targets = append(logger.Targets, target)

	logger.Open()

	// ... logger is ready to use ...
}

func (*ConsoleTarget) Close

func (t *ConsoleTarget) Close()

Close closes the console target.

func (*ConsoleTarget) CloseDetailsBlock

func (t *ConsoleTarget) CloseDetailsBlock(string)

func (*ConsoleTarget) CloseLogDetailsBlock

func (t *ConsoleTarget) CloseLogDetailsBlock(s string)

func (*ConsoleTarget) DoesDetails

func (t *ConsoleTarget) DoesDetails() bool

func (*ConsoleTarget) Flush

func (t *ConsoleTarget) Flush()

Flush is a no-op.

func (*ConsoleTarget) LogTextQuote

func (t *ConsoleTarget) LogTextQuote(E *Entry, s string)

func (*ConsoleTarget) Open

func (t *ConsoleTarget) Open(io.Writer) error

Open prepares ConsoleTarget for processing log messages.

func (*ConsoleTarget) Process

func (t *ConsoleTarget) Process(e *Entry)

Process writes a log message using Writer.

func (*ConsoleTarget) SetCategory

func (t *ConsoleTarget) SetCategory(s string)

func (*ConsoleTarget) SetSubcategory

func (t *ConsoleTarget) SetSubcategory(s string)

func (*ConsoleTarget) StartDetailsBlock

func (t *ConsoleTarget) StartDetailsBlock(*Entry)

func (*ConsoleTarget) StartLogDetailsBlock

func (t *ConsoleTarget) StartLogDetailsBlock(sCatg string, E *Entry)

type ControlSequenceTextBrush

type ControlSequenceTextBrush StrInStrOut

type DetailsFormatter

type DetailsFormatter func(*Logger, *Entry, []string) string

DetailsFormatter formats a log message into an appropriate string, but also handles Details nicely (in a manner TBD), and accepts a third argument of a string that may be specified per-message.

type DetailsInfo

type DetailsInfo struct {
	DoingDetails     bool
	MinLogLevel      LU.Level
	Category         string
	Subcategory      string
	DetailsFormatter // message formatter
}

DetailsInfo is embedded in details-capable Target's. It applies only to "log details", which logging is stateful, not to "text quotes", which logging is an atomic operation.

type DetailsTarget

type DetailsTarget interface {
	Target
	StartLogDetailsBlock(string, *Entry) // s = Category e.g. "[01]" and clear Subcat
	CloseLogDetailsBlock(string)
	LogTextQuote(*Entry, string)
	// SetCategory is used per-Contentity, e.g. "[00]", "[01]", ...
	SetCategory(string)
	// SetSubcategory is used per- Contentity processing stage, e.g. "[st1b]"
	SetSubcategory(string)
}

DetailsTarget is a target where the logger can both (1) Open a collapsible, ignorable set of log detail messages, and (2) Quote a collapsible, ignorable block of text (atomic operation!).

In a Console target, do this by omitting the first three (or six) characters of the timestamp, providing visual indenting. For (1) use " - " or " * ", so that it resembles a list. For (2) use " " " or " ' ", so that it is obv a quote.

In an HTML target, do this by opening a "<details> block" and in the very same log message, opening the <summary> element. Then subsequent log messages (or the accompanying text block) can be written to the body of the <details> element (separated by <br/> tags, rather than by newlines as in most log targets) until the <details> element is closed.

As an enhancement, a set of log detail messages tracks its minimum (i.e. most severe) logging level, with a summary line at the end.

The five function calls could be ignored as no-ops by targets that do not implemement the interface. However it is simpler and clearer, and follows the existing processing architecture, to make the call for every Target in a Logger, but then in the Logger method call, check each Target for being a DetailsTarget.

type Entry

type Entry struct {
	Level            LU.Level
	Category         string
	Message          string
	Time             time.Time
	CallStack        string
	FormattedMessage string
}

Entry represents a log entry.

func (*Entry) String

func (e *Entry) String() string

String returns the string representation of the log entry

type FileTarget

type FileTarget struct {
	*Filter
	// the log file name. When Rotate is true, log file name will be suffixed
	// to differentiate different backup copies (e.g. app.log.1)
	FileName string
	// whether to enable file rotating at specific time interval or when maximum file size is reached.
	Rotate bool
	// how many log files should be kept when Rotate is true (the current log file is not included).
	// This field is ignored when Rotate is false.
	BackupCount int
	// maximum number of bytes allowed for a log file. Zero means no limit.
	// This field is ignored when Rotate is false.
	MaxBytes int64

	Category    string
	Subcategory string
	// contains filtered or unexported fields
}

FileTarget writes filtered log messages to a file. FileTarget supports file rotation by keeping certain number of backup log files.

func NewFileTarget

func NewFileTarget() *FileTarget

NewFileTarget creates a FileTarget. The new FileTarget takes these default options: MaxLevel: LevelNotice, Rotate: true, BackupCount: 10, MaxBytes: 1 << 20 After calling this, you must fill in the FileName field.

Example
package main

import (
	log "github.com/fbaube/mlog"
)

func main() {
	logger := log.NewLogger()

	// creates a FileTarget which keeps log messages in the app.log file
	target := log.NewFileTarget()
	target.FileName = "app.log"

	logger.Targets = append(logger.Targets, target)

	logger.Open()

	// ... logger is ready to use ...
}

func (*FileTarget) Close

func (t *FileTarget) Close()

Close closes the file target.

func (*FileTarget) CloseDetailsBlock

func (t *FileTarget) CloseDetailsBlock(string)

func (*FileTarget) DoesDetails

func (t *FileTarget) DoesDetails() bool

func (*FileTarget) Flush

func (t *FileTarget) Flush()

Flush is a no-op but SHOULD have a call to flush the file.

func (*FileTarget) Open

func (t *FileTarget) Open(errWriter io.Writer) error

Open prepares FileTarget for processing log messages.

func (*FileTarget) Process

func (t *FileTarget) Process(e *Entry)

Process saves an allowed log message into the log file.

func (*FileTarget) SetCategory

func (t *FileTarget) SetCategory(s string)

func (*FileTarget) SetSubcategory

func (t *FileTarget) SetSubcategory(s string)

func (*FileTarget) StartDetailsBlock

func (t *FileTarget) StartDetailsBlock(*Entry)

type Filter

type Filter struct {
	MaxLevel   LU.Level // the maximum severity level that is allowed
	Categories []string // the allowed message categories. Categories can use "*" as a suffix for wildcard matching.
	// contains filtered or unexported fields
}

Filter checks if a log message meets the level and category requirements.

func (*Filter) Allow

func (t *Filter) Allow(e *Entry) bool

Allow checks if a message meets the severity level and category requirements.

func (*Filter) Init

func (t *Filter) Init()

Init initializes the filter. Init must be called before Allow is called.

type Formatter

type Formatter func(*Logger, *Entry) string

Formatter formats a log message into an appropriate string.

type HtmlTarget

type HtmlTarget struct {
	*Filter
	// the target HTML element's ID attribute.
	FieldID string
	Writer  io.Writer // the writer to write log messages

	DetailsInfo
	// contains filtered or unexported fields
}

type Logger

type Logger struct {
	Category  string    // the category associated with this logger
	Formatter Formatter // message formatter
	// contains filtered or unexported fields
}

Logger records log messages and dispatches them to various targets for further processing.

var L *Logger

L is the predefined default global logger.

func NewLogger

func NewLogger() *Logger

NewLogger creates a root logger. The new logger takes these default options: ErrorWriter: os.Stderr, BufferSize: 1024, MaxLevel: LU.LevelDebug, Category: app, Formatter: DefaultFormatter

func NewNullLogger

func NewNullLogger() *Logger

NewNullLogger creates a no-op logger. .

func (Logger) Close

func (l Logger) Close()

Close closes the logger and the targets. Existing messages will be processed before the targets are closed. New incoming messages will be discarded after calling this method.

func (*Logger) Debug

func (l *Logger) Debug(format string, a ...interface{})

Debug logs a message for debugging purpose. Please refer to Error() for how to use this method.

func (*Logger) Error

func (l *Logger) Error(format string, a ...interface{})

Error logs a message indicating an error condition. This method takes one or multiple parameters. If a single parameter is provided, it IS the log message. If multiple parameters are provided, they are passed to fmt.Sprintf() to generate the log message.

Example
package main

import (
	log "github.com/fbaube/mlog"
)

func main() {
	logger := log.NewLogger()

	logger.Targets = append(logger.Targets, log.NewConsoleTarget())

	logger.Open()

	// log without formatting
	logger.Error("a plain message")
	// log with formatting
	logger.Error("the value is: %v", 100)
}

func (Logger) Flush

func (l Logger) Flush()

Flush flushes the logger and the targets.

func (*Logger) GetLogger

func (l *Logger) GetLogger(category string, formatter ...Formatter) *Logger

GetLogger creates a logger with the specified category and log formatter. Messages logged thru this logger will carry the same category name. The formatter, if not specified, will inherit from the calling logger. It will be used to format all messages logged thru this logger.

func (*Logger) Info

func (l *Logger) Info(format string, a ...interface{})

Info logs a message for a normal but meaningful condition.

func (*Logger) Log

func (l *Logger) Log(level LU.Level, format string, a ...interface{})

Log logs a message of a specified severity level.

func (*Logger) LogWithString

func (l *Logger) LogWithString(level LU.Level, format string, special string, a ...interface{})

func (*Logger) Okay

func (l *Logger) Okay(format string, a ...interface{})

Okay logs a message indicating an okay condition.

func (Logger) Open

func (l Logger) Open() error

Open prepares the logger and the targets for logging purpose. Open must be called before any message can be logged.

func (*Logger) Panic

func (l *Logger) Panic(format string, a ...interface{})

Panic logs a message indicating the system is dying, but does NOT actually execute a call to panic(..)

func (Logger) SetCategory

func (l Logger) SetCategory(s string)

SetCategory is for DetailsTarget's.

func (Logger) SetSubcategory

func (l Logger) SetSubcategory(s string)

SetSubcategory is for DetailsTarget's.

func (*Logger) Warning

func (l *Logger) Warning(format string, a ...interface{})

Warning logs a message indicating a warning condition.

type MailTarget

type MailTarget struct {
	*Filter
	Host       string   // SMTP server address
	Username   string   // SMTP server login username
	Password   string   // SMTP server login password
	Subject    string   // the mail subject
	Sender     string   // the mail sender
	Recipients []string // the mail recipients
	BufferSize int      // the size of the message channel.
	// contains filtered or unexported fields
}

MailTarget sends log messages in emails via an SMTP server.

func NewMailTarget

func NewMailTarget() *MailTarget

NewMailTarget creates a MailTarget. The new MailTarget takes these default options: MaxLevel: LevelDbg, BufferSize: 1024. You must specify these fields: Host, Username, Subject, Sender, and Recipients.

Example
package main

import (
	log "github.com/fbaube/mlog"
)

func main() {
	logger := log.NewLogger()

	// creates a MailTarget which sends emails to admin@example.com
	target := log.NewMailTarget()
	target.Host = "smtp.example.com"
	target.Username = "foo"
	target.Password = "bar"
	target.Subject = "log messages for foobar"
	target.Sender = "admin@example.com"
	target.Recipients = []string{"admin@example.com"}

	logger.Targets = append(logger.Targets, target)

	logger.Open()

	// ... logger is ready to use ...
}

func (*MailTarget) Close

func (t *MailTarget) Close()

Close closes the mail target.

func (*MailTarget) DoesDetails

func (t *MailTarget) DoesDetails() bool

func (*MailTarget) Flush

func (t *MailTarget) Flush()

Flush is a no-op.

func (*MailTarget) Open

func (t *MailTarget) Open(errWriter io.Writer) error

Open prepares MailTarget for processing log messages.

func (*MailTarget) Process

func (t *MailTarget) Process(e *Entry)

Process puts filtered log messages into a channel for sending in emails.

type NetworkTarget

type NetworkTarget struct {
	*Filter
	// the network to connect to. Valid networks include
	// tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only),
	// "udp", "udp4" (IPv4-only), "udp6" (IPv6-only), "ip", "ip4"
	// (IPv4-only), "ip6" (IPv6-only), "unix", "unixgram" and
	// "unixpacket".
	Network string
	// the address on the network to connect to.
	// For TCP and UDP networks, addresses have the form host:port.
	// If host is a literal IPv6 address it must be enclosed
	// in square brackets as in "[::1]:80" or "[ipv6-host%zone]:80".
	Address string
	// whether to use a persistent network connection.
	// If this is false, for every message to be sent, a network
	// connection will be open and closed.
	Persistent bool
	// the size of the message channel.
	BufferSize int
	// contains filtered or unexported fields
}

NetworkTarget sends log messages over a network connection.

func NewNetworkTarget

func NewNetworkTarget() *NetworkTarget

NewNetworkTarget creates a NetworkTarget. The new NetworkTarget takes these default options: MaxLevel: LevelDbg, Persistent: true, BufferSize: 1024. You must specify the Network and Address fields.

Example
package main

import (
	log "github.com/fbaube/mlog"
)

func main() {
	logger := log.NewLogger()

	// creates a NetworkTarget which uses tcp network and address :10234
	target := log.NewNetworkTarget()
	target.Network = "tcp"
	target.Address = ":10234"

	logger.Targets = append(logger.Targets, target)

	logger.Open()

	// ... logger is ready to use ...
}

func (*NetworkTarget) Close

func (t *NetworkTarget) Close()

Close closes the network target.

func (*NetworkTarget) DoesDetails

func (t *NetworkTarget) DoesDetails() bool

func (*NetworkTarget) Flush

func (t *NetworkTarget) Flush()

Flush is a no-op.

func (*NetworkTarget) Open

func (t *NetworkTarget) Open(errWriter io.Writer) error

Open prepares NetworkTarget for processing log messages.

func (*NetworkTarget) Process

func (t *NetworkTarget) Process(e *Entry)

Process puts filtered log messages into a channel for sending over network.

type StrInStrOut

type StrInStrOut func(string) string

StrInStrOut is String In, String Out. In this app, a ControlSequenceTextBrush StrInStrOut wraps simple text in console control characters to apply color and effects, and then resets them at the end of the text.

type Target

type Target interface {
	// Open prepares the target for processing log messages.
	// Called when Logger.Open() is called.
	// If an error is returned, the target will be removed from the
	// logger. errWriter should be used to write errors found while
	// processing log messages, and should probably default to Stderr.
	Open(errWriter io.Writer) error
	// Process processes an incoming log message.
	Process(*Entry)
	// Close closes a target.
	// Called when Logger.Close() is called. Each target gets
	// a chance to flush its log messages to its destination.
	Close()
	// Flush is NEW and added so that logging plays nicely with
	// other sources of text.
	Flush()
	// DoesDetails is NEW and has a value per-struct, not per-instance.
	DoesDetails() bool
}

Target represents a target where the logger can send log messages to for further processing.

Jump to

Keyboard shortcuts

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