ultralogger

package module
v2.0.0-alpha-3 Latest Latest
Warning

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

Go to latest
Published: Nov 10, 2024 License: MIT Imports: 7 Imported by: 0

README

UltraLogger

Logo

Go Reference

Overview

UltraLogger is a versatile, flexible, and efficient logging library for Go that supports multiple log levels, custom formatting, and output destinations. It is designed to be easy to use while providing advanced features such as colorized output, customizable log levels, and detailed error handling.

UltraLogger only uses the stdlib and is written in pure Go.

Features

  • Multiple Log Levels: DEBUG, INFO, WARN, ERROR, PANIC, and FATAL levels.
  • Custom Formatting: Flexible formatting options including custom date/time formats, tag padding, and bracket types.
  • Colorization: Colorizes log output based on severity level for better visibility.
  • Output Redirection: Supports writing logs to various io.Writer destinations such as files or standard output.
  • Silent Mode: Allows disabling all logging when set.
  • Error Handling: Implements robust error handling and fallback mechanisms for logging errors.

Installation

To install UltraLogger, use go get:

go get github.com/fmdunlap/ultralogger

Usage

Here's a basic example of how to use UltraLogger:

package main

import (
    "os"
    "github.com/fmdunlap/ultralogger"
)

func main() {
    logger := ultralogger.NewUltraLogger(os.Stdout)
    
    logger.Info("This is an info message.")  // Output: 2006-01-02 15:04:05 <INFO> This is an info message.
    logger.Debug("This is a debug message.") // Output: 2006-01-02 15:04:05 <DEBUG> This is a debug message.
    logger.Warn("This is a warning message.") // Output: 2006-01-02 15:04:05 <WARN> This is a warning message.
    
    logger.Infof("This is an info message with %s!", "formatting") // Output: 2006-01-02 15:04:05 <INFO> This is an info message with formatting!
}

Configuration

Ultralogger provides various configuration options to customize logging behaviour.

Minimum Log Level
logger := ultralogger.NewUltraLogger(os.Stdout).MinLogLevel(ultralogger.LogLevelDebug)
Tags
logger.SetTag("MyTag")
logger.Info("Message")   // -> 2006-01-02 15:04:05 [MyTag] <INFO> Message

logger.SetTag("Another")
logger.Infof("Ultralogger is %s!", "super cool") // -> 2006-01-02 15:04:05 [Another] <INFO> Ultralogger is super cool!
Formatting
Date and Time
logger.SetDateFormat("01/02/2006")
logger.ShowTime(false)

logger.Info("Message") // -> 01/02/2006 <INFO> Message

_, err := logger.ShowTime(true).SetTimeFormat("15|04|05")
if err != nil {
    // Handle error if the time format is invalid
}

logger.Info("Message") // -> 01/02/2006 15|04|05 <INFO> Message

logger.SetDateTimeSeparator("@")
logger.Info("Message") // -> 01/02/2006@15|04|05 <INFO> Message
Tag Padding
// Many style config funcs can be chained together. This is just an example.
logger.SetTag("MyTag").EnabledTagPadding(true).SetTagPadSize(10)

logger.Info("Message") // -> 2006-01-02 15:04:05 [MyTag]   <INFO> Message
logger.Error("Error!") // -> 2006-01-02 15:04:05 [MyTag]   <ERROR> Warning!
Tag Bracket Type
logger.SetTag("MyTag").SetTagBracketType(ultralogger.BracketTypeSquare)
logger.Info("Message") // -> 2006-01-02 15:04:05 [MyTag] <INFO> Message
Log Bracket Type
logger.SetLogBracketType(ultralogger.BracketTypeRound)
logger.Info("Message") // -> 2006-01-02 15:04:05 (INFO) Message
Bracket Types
ultralogger.BracketTypeNone // "tag"
ultralogger.BracketTypeSquare // "[tag]"
ultralogger.BracketTypeRound // "(tag)"
ultralogger.BracketTypeCurly // "{tag}"
ultralogger.BracketTypeAngle // "<tag>"
Terminal Colorization
logger := ultralogger.NewStdoutLogger()
logger.SetMinLevel(ultralogger.DebugLevel)
logger.SetColorize(true)

logger.Debug("Debug")
logger.Info("Message")
logger.Warn("Warning")
logger.Error("Error!")
logger.Panic("Panic!")

Colorized Output

You can also set custom colors for each log level!

logger := ultralogger.NewStdoutLogger()
logger.SetMinLevel(ultralogger.DebugLevel)
logger.SetColorize(true)

// Set custom colors for each log level
logger.SetLevelColor(ultralogger.DebugLevel, ultralogger.ColorCyan)
logger.Debug("Cyan is peaceful. Like the messages ad the debug level!")

// Set custom colors for all log levels
logger.SetLevelColors(map[ultralogger.Level]ultralogger.Color{
    ultralogger.WarnLevel: ultralogger.ColorGreen,
    ultralogger.ErrorLevel: ultralogger.ColorBlue,
    ultralogger.PanicLevel: ultralogger.ColorRed,
})

logger.Warn("Green might not be the best warning color...")
logger.Error("I'll be blue if I see this error!")
logger.Panic("RED IS THE BEST PANIC COLOR!")

Custom Colors

Output Destinations
// Files
logger := ultralogger.NewFileLogger("somefile.log")

// Stdout
logger := ultralogger.NewStdoutLogger()

// ByteBuffer
buf := new(bytes.Buffer)
logger := ultralogger.NewUltraLogger(buf)

logger.Info("Debug to byte buffer")

fmt.Printf("Buffer: %s\n", buf.String()) // Buffer: 2006-01-02 15:04:05 <INFO> Debug to byte buffer
Silent Mode
logger := ultralogger.NewStdoutLogger()
logger.SetMinLevel(ultralogger.WarnLevel)

logger.Info("Message") // -> 2006-01-02 15:04:05 <INFO> Message
logger.Warn("Message") // -> Nothing will be printed to the output
PanicOnPanicLevel Mode
logger := ultralogger.NewStdoutLogger()
logger.SetMinLevel(ultralogger.WarnLevel)
logger.SetPanicOnPanicLevel(true)

logger.Panic("Panic!") // -> 2006-01-02 15:04:05 <PANIC> Panic! (and then panics)

logger.SetPanicOnPanicLevel(false)
logger.Panic("Panic!") // -> 2006-01-02 15:04:05 <PANIC> Panic! (and then does not panic)

TODO

  • Improve Color handling. Colors are currently using ASNI color cods, which isn' the most modern way to do this.
  • Optimize logging speed.
  • Make logging fields configurable (ability to add fields, change content, change field color, change field order,etc.)
  • Add the ability to pass option funcs to the constructors to allow for more flexibility.
  • Custom bracket types!
  • OnLogLevel handlers to allow for more advanced logging.

License

MIT. See LICENSE for more details.

But also, it's MIT. Go nuts.

Contributing

Feel free to open an issue or PR if you have any suggestions or improvements!

Documentation

Index

Constants

This section is empty.

Variables

View Source
var AnsiBold = ansiSetting("1")
View Source
var AnsiDim = ansiSetting("2")
View Source
var AnsiItalic = ansiSetting("3")
View Source
var AnsiSlowBlink = ansiSetting("5")
View Source
var AnsiStrikethrough = ansiSetting("9")
View Source
var AnsiUnderline = ansiSetting("4")
View Source
var BackgroundBlack = AnsiBackgroundColor("40")
View Source
var BackgroundBlue = AnsiBackgroundColor("44")
View Source
var BackgroundCyan = AnsiBackgroundColor("46")
View Source
var BackgroundGreen = AnsiBackgroundColor("42")
View Source
var BackgroundMagenta = AnsiBackgroundColor("45")
View Source
var BackgroundRed = AnsiBackgroundColor("41")
View Source
var BackgroundWhite = AnsiBackgroundColor("47")
View Source
var BackgroundYellow = AnsiBackgroundColor("43")
View Source
var BracketAngle = SimpleBracket{"<", ">"}
View Source
var BracketCurly = SimpleBracket{"{", "}"}
View Source
var BracketNone = SimpleBracket{"", ""}
View Source
var BracketRound = SimpleBracket{"(", ")"}
View Source
var BracketSquare = SimpleBracket{"[", "]"}
View Source
var ColorBlue = AnsiColor{/* contains filtered or unexported fields */}
View Source
var ColorCyan = AnsiColor{/* contains filtered or unexported fields */}
View Source
var ColorDefault = AnsiColor{/* contains filtered or unexported fields */}
View Source
var ColorGreen = AnsiColor{/* contains filtered or unexported fields */}
View Source
var ColorMagenta = AnsiColor{/* contains filtered or unexported fields */}
View Source
var ColorRed = AnsiColor{/* contains filtered or unexported fields */}
View Source
var ColorWhite = AnsiColor{/* contains filtered or unexported fields */}
View Source
var ColorYellow = AnsiColor{/* contains filtered or unexported fields */}
View Source
var ColorizationNotSupportedError = errors.New("formatter does not support colorization")
View Source
var FileNotSpecifiedError = errors.New("filename not provided to NewFileLogger")

Functions

This section is empty.

Types

type AnsiBackgroundColor

type AnsiBackgroundColor = []byte

func BackgroundRGB

func BackgroundRGB(r, g, b int) AnsiBackgroundColor

type AnsiColor

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

func RGB

func RGB(r, g, b int) AnsiColor

func (AnsiColor) Bold

func (ac AnsiColor) Bold() AnsiColor

func (AnsiColor) Colorize

func (ac AnsiColor) Colorize(str string) string

TODO: Benchmark different ways of doing this. Went for the single buffer approach for now.

func (AnsiColor) Dim

func (ac AnsiColor) Dim() AnsiColor

func (AnsiColor) Italic

func (ac AnsiColor) Italic() AnsiColor

func (AnsiColor) SetBackground

func (ac AnsiColor) SetBackground(background AnsiBackgroundColor) AnsiColor
func (ac AnsiColor) SlowBlink() AnsiColor

func (AnsiColor) Underline

func (ac AnsiColor) Underline() AnsiColor

type Bracket

type Bracket interface {
	Open() string
	Close() string
	Wrap(content string) string
}

type Color

type Color interface {
	Colorize(str string) string
}

type ColorizedFormatter

type ColorizedFormatter interface {
	Formatter
	EnableColorization(colorize bool) error
	SetLevelColors(colors map[Level]Color) error
}

func NewColorizedFormatter

func NewColorizedFormatter(
	prefixFields []Field,
	suffixFields []Field,
	enableColor bool,
) (ColorizedFormatter, error)

type Field

type Field interface {
	FieldPrinter() (FieldPrinterFunc, error)
}

type FieldDateTime

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

func NewDateTimeField

func NewDateTimeField(dateTimeFormat string) *FieldDateTime

func (*FieldDateTime) FieldPrinter

func (f *FieldDateTime) FieldPrinter() (FieldPrinterFunc, error)

func (*FieldDateTime) SetDateTimeFormat

func (f *FieldDateTime) SetDateTimeFormat(format string) Field

type FieldLevel

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

func NewLevelField

func NewLevelField(bracket Bracket) *FieldLevel

func (*FieldLevel) FieldPrinter

func (f *FieldLevel) FieldPrinter() (FieldPrinterFunc, error)

type FieldPrinterFunc

type FieldPrinterFunc func(PrintArgs) string

type FieldTag

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

func NewTagField

func NewTagField(tag string, opts ...TagFieldOpt) *FieldTag

func (*FieldTag) FieldPrinter

func (f *FieldTag) FieldPrinter() (FieldPrinterFunc, error)

type FileNotFoundError

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

func (*FileNotFoundError) Error

func (e *FileNotFoundError) Error() string

type Formatter

type Formatter interface {
	Format(level Level, msg string) string
	Formatf(level Level, format string, args ...any) string
	SetPrefixFields(fields ...Field) error
	SetSuffixFields(fields ...Field) error
}

type Level

type Level int

Level is a type representing the level of a log message.

It can be one of the following:

  • Debug
  • Info
  • Warn
  • Error
  • Panic

Levels determine the priority of a log message, and can be hidden if a logger's minimum level is set to a higher level than the message's level.

For example, if a logger's minimum level is set to Warn, then a message with a level of Info will not be written to the output.

const (
	Debug Level = iota
	Info
	Warn
	Error
	Panic
)

func AllLevels

func AllLevels() []Level

AllLevels returns a slice of all available levels.

func ParseLevel

func ParseLevel(levelStr string) (Level, error)

ParseLevel parses a string into a Level. Returns an error if the string is not a valid Level.

func (Level) String

func (l Level) String() string

type LevelParsingError

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

func (*LevelParsingError) Error

func (e *LevelParsingError) Error() string

type Logger

type Logger interface {
	// Log logs at the specified level without formatting.
	Log(level Level, msg string)

	// Logf logs at the specified level with formatted message.
	Logf(level Level, format string, args ...any)

	// Debug logs a debug-level message.
	Debug(msg string)

	// Debugf logs a debug-level message with formatting.
	Debugf(format string, args ...any)

	// Info logs an info-level message.
	Info(msg string)

	// Infof logs an info-level message with formatting.
	Infof(format string, args ...any)

	// Warn logs a warning-level message.
	Warn(msg string)

	// Warnf logs a warning-level message with formatting.
	Warnf(format string, args ...any)

	// Error logs an error-level message.
	Error(msg string)

	// Errorf logs an error-level message with formatting.
	Errorf(format string, args ...any)

	// Panic logs a panic-level message and then panics.
	Panic(msg string)

	// Panicf logs a panic-level message with formatting and then panics.
	Panicf(format string, args ...any)

	// Slog returns the string representation of a log message with the given level and message.
	Slog(level Level, msg string) string

	// Slogf returns the string representation of a formatted log message with the given level and sprint string.
	Slogf(level Level, format string, args ...any) string

	// Slogln returns the string representation of a log message with the given level and message, followed by a newline.
	Slogln(level Level, msg string) string

	// SetMinLevel sets the minimum logging level that will be output.
	SetMinLevel(level Level)
}

Logger defines the interface for a structured ultraLogger in Go.

This interface is useful for either creating your own logger or for using an existing logger, and preventing changes to the loggers formatting settings.

func NewFileLogger

func NewFileLogger(filename string) (Logger, error)

NewFileLogger returns a new Logger that writes to a file.

If the filename is empty, FileNotSpecifiedError is returned. If the file does not exist, FileNotFoundError is returned.

func NewLogger

func NewLogger(opts ...LoggerOption) (Logger, error)

NewLogger returns a new Logger that writes to stdout

type LoggerInitializationError

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

func (*LoggerInitializationError) Error

func (e *LoggerInitializationError) Error() string

type LoggerOption

type LoggerOption func(l *ultraLogger) error

func WithColorization

func WithColorization(colorize bool) LoggerOption

func WithDestination

func WithDestination(writer io.Writer) LoggerOption

func WithFallbackEnabled

func WithFallbackEnabled(fallback bool) LoggerOption

func WithFormatter

func WithFormatter(formatter Formatter) LoggerOption

func WithLevelColors

func WithLevelColors(colors map[Level]Color) LoggerOption

func WithMinLevel

func WithMinLevel(level Level) LoggerOption

func WithPanicOnPanicLevel

func WithPanicOnPanicLevel(panicOnPanicLevel bool) LoggerOption

func WithPrefixFields

func WithPrefixFields(fields ...Field) LoggerOption

func WithSilent

func WithSilent(silent bool) LoggerOption

func WithSuffixFields

func WithSuffixFields(fields ...Field) LoggerOption

type PrintArgs

type PrintArgs struct {
	Level Level
}

type SimpleBracket

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

func (SimpleBracket) Close

func (sb SimpleBracket) Close() string

func (SimpleBracket) Open

func (sb SimpleBracket) Open() string

func (SimpleBracket) Wrap

func (sb SimpleBracket) Wrap(content string) string

type TagFieldOpt

type TagFieldOpt func(tf *FieldTag)

func WithBracket

func WithBracket(bracket Bracket) TagFieldOpt

func WithPadChar

func WithPadChar(padChar string) TagFieldOpt

func WithPadSettings

func WithPadSettings(padSettings TagPadSettings) TagFieldOpt

func WithPrefixPadSize

func WithPrefixPadSize(prefixPadSize int) TagFieldOpt

func WithSuffixPadSize

func WithSuffixPadSize(suffixPadSize int) TagFieldOpt

type TagPadSettings

type TagPadSettings struct {
	PadChar       string
	PrefixPadSize int
	SuffixPadSize int
}

Jump to

Keyboard shortcuts

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