sblog

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

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

Go to latest
Published: Aug 3, 2025 License: MIT Imports: 11 Imported by: 0

README

sblog

import "github.com/barbell-math/smoothbrain-logging"

A very simple library that implements a logger with verbosity levels and an optional rotating file log writer.

Example (Log Debug)

s, _ := New(Opts{})
s.Debug("This is a debug message")
s.Debug(
	"This is a debug message",
	"Keys with nil values will be treated as messages", nil,
	"and will be printed on a separate line", nil,
)
s.Debug("This is a debug message logging a value", "value", 10)
s.Debug(
	"This is a debug message logging a multiple values",
	"value1", 10,
	"value2", 11,
)
s.Debug("This is a debug message", "Separate line", nil, "value", 10)

Example (Log Error)

s, _ := New(Opts{})
s.Error("This is an error message")
s.Error(
	"This is an error message",
	"Keys with nil values will be treated as messages", nil,
	"and will be printed on a separate line", nil,
)
s.Error("This is an error message logging a value", "value", 10)
s.Error(
	"This is an error message logging a multiple values",
	"value1", 10,
	"value2", 11,
)
s.Error("This is an error message", "Separate line", nil, "value", 10)

Example (Log Info)

s, _ := New(Opts{})
s.Info("This is an info message")
s.Info(
	"This is an info message",
	"Keys with nil values will be treated as messages", nil,
	"and will be printed on a separate line", nil,
)
s.Info("This is an info message logging a value", "value", 10)
s.Info(
	"This is an info message logging a multiple values",
	"value1", 10,
	"value2", 11,
)
s.Info("This is an info message", "Separate line", nil, "value", 10)

Example (Log Multi Error)

err := sberr.AppendError(
	sberr.Wrap(
		ExpectedDirErr, "This is the first error",
	),
	sberr.Wrap(
		ExpectedDirErr, "This is the second error",
	),
	sberr.WrapValueList(
		ExpectedDirErr,
		"This is the third error",
		sberr.WrapListVal{
			ItemName: "Item 1",
			Item:     1,
		},
		sberr.WrapListVal{
			ItemName: "Item 2",
			Item:     1.0,
		},
		sberr.WrapListVal{
			ItemName: "Item 3",
			Item:     "asdf",
		},
	),
)

s, _ := New(Opts{})
s.Error(err.Error())

Example (Log Verbose)

s, _ := New(Opts{CurVerbosityLevel: 2})
s.Log(
	context.TODO(),
	VLevel(0),
	"This is a level 0 verbose message, a.k.a. a debug message",
)
s.Log(context.TODO(), VLevel(1), "This is a level 1 verbose message")
s.Log(context.TODO(), VLevel(2), "This is a level 2 verbose message")
// This next line should not print
s.Log(context.TODO(), VLevel(3), "This is a level 3 verbose message")

s, _ = New(Opts{CurVerbosityLevel: 0})
s.Log(
	context.TODO(),
	VLevel(0),
	"This is a level 0 verbose message, a.k.a. a debug message",
)
// These next three lines should not print
s.Log(context.TODO(), VLevel(1), "This is a level 1 verbose message")
s.Log(context.TODO(), VLevel(2), "This is a level 2 verbose message")
s.Log(context.TODO(), VLevel(3), "This is a level 3 verbose message")

Example (Log Warn)

s, _ := New(Opts{})
s.Warn("This is a warn message")
s.Warn(
	"This is a warn message",
	"Keys with nil values will be treated as messages", nil,
	"and will be printed on a separate line", nil,
)
s.Warn("This is a warn message logging a value", "value", 10)
s.Warn(
	"This is a warn message logging a multiple values",
	"value1", 10,
	"value2", 11,
)
s.Warn("This is a warn message", "Separate line", nil, "value", 10)

Example (Persistant Logs)

s, _ := New(Opts{
	CurVerbosityLevel: 1,
	RotateWriterOpts: RotateWriterOpts{
		LogDir:  "./testData/",
		LogName: "persistantExample",
	},
})
s.Info("This should be saved to ./testData/persistantExample.0.log")
s.Warn("This should be saved to ./testData/persistantExample.0.log")
s.Error("This should be saved to ./testData/persistantExample.0.log")
s.Debug("This should be saved to ./testData/persistantExample.0.log")
s.Log(
	context.TODO(), VLevel(1),
	"This should be saved to ./testData/persistantExample.0.log",
)

Index

Variables

var (
    ExpectedDirErr = errors.New("A dir was expected")
)

func New

func New(opts Opts) (*slog.Logger, error)

Creates a new logger. The logs will always be printed to stdout/stderr. If `opts.RotateWriterOpts.LogDir` is an empty string no logs will be written to disk. If `opts.RotateWriterOpts.LogDir` is a valid dir then all logs from stdout and stderr will be mirrored to files in the supplied dir using a RotateWriter.

func VLevel

func VLevel(val uint) slog.Level

Translates the requested positive verbosity level from a range of [0,inf) to (-inf, -4]. This must be done for the level to be understood by the [slog] package.

type Opts

type Opts struct {
    // Sets the allowed maximum verbosity level. There is no bound to the
    // requested verbosity, but any verbosity levels greater than the level
    // set here will not be printed.
    CurVerbosityLevel uint
    // The time format to use when printing log messages.
    TimeFmt string
    RotateWriterOpts
}

type RotateWriter

Implements a rotating file writer. The logger will create log files in the following format:

<logDir>/<logName>.0.log
<logDir>/<logName>.1.log
...
<logDir>/<logName>.<maxNumLogs>.log

Where logDir, logName, and maxNumLogs are parameters that are specified through the RotateWriterOpts struct when NewRotateWriter is called. Once the maximum allowed number of logs have been reached the writer will start to cycle back through old logs, clearing each one as needed before writing new log data.

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

func NewRotateWriter
func NewRotateWriter(opts RotateWriterOpts) (*RotateWriter, error)

Creates a new rotating log writer. `opts.LogDir` must exist. Several defaults will be set from opts:

  • If opts.LogName=="" then it will be set to a default of "sblog"
  • If opts.MaxNumLogs==0 then it will be set to a default of 1
  • If opts.MaxLogSizeBytes==0 then it will be set to a default of 1 MB

func (*RotateWriter) Close
func (w *RotateWriter) Close() error

Closes the currently open log in the rotation. All other files in the log rotation are already closed.

func (*RotateWriter) Rotate
func (w *RotateWriter) Rotate() (err error)

Rotates the log, advancing to the next log in the rotation. If the end of the log rotation is reached the rotation will start over at the beginning, clearing out logs as necessary to continue writing data.

func (*RotateWriter) Write
func (w *RotateWriter) Write(output []byte) (int, error)

Writes data to the log rotation, advancing to the next log in the rotation as necessary.

type RotateWriterOpts

type RotateWriterOpts struct {
    // The dir that the log files should be placed in. The dir must exist.
    // It will not be created if it does not exist.
    LogDir string
    // The name to give all log files. All log files will then match the
    // following format:
    //
    //   <logName>.<N>.log
    //
    // Where N is the number of the log in the log rotation.
    LogName string
    // The maximum number of log files to allow. Once this limit has been
    // reached the log writer will start to cycle back through old logs,
    // clearing each one as needed.
    MaxNumLogs uint
    // The number of bytes that can be reached before a moving onto the next
    // log file in the log rotation. Log messages will not be split between
    // files, meaning the number of bytes in the file may be slightly more
    // than `MaxLogSizeBytes`.
    MaxLogSizeBytes uint64
}

Generated by gomarkdoc

Helpful Developer Cmds

To build the build system:

go build -o ./bs/bs ./bs

The build system can then be used as usual:

./bs/bs --help
./bs/bs buildbs # Builds the build system!

Documentation

Overview

A very simple library that implements a logger with verbosity levels and an optional rotating file log writer.

Example (LogDebug)
s, _ := New(Opts{})
s.Debug("This is a debug message")
s.Debug(
	"This is a debug message",
	"Keys with nil values will be treated as messages", nil,
	"and will be printed on a separate line", nil,
)
s.Debug("This is a debug message logging a value", "value", 10)
s.Debug(
	"This is a debug message logging a multiple values",
	"value1", 10,
	"value2", 11,
)
s.Debug("This is a debug message", "Separate line", nil, "value", 10)
Example (LogError)
s, _ := New(Opts{})
s.Error("This is an error message")
s.Error(
	"This is an error message",
	"Keys with nil values will be treated as messages", nil,
	"and will be printed on a separate line", nil,
)
s.Error("This is an error message logging a value", "value", 10)
s.Error(
	"This is an error message logging a multiple values",
	"value1", 10,
	"value2", 11,
)
s.Error("This is an error message", "Separate line", nil, "value", 10)
Example (LogInfo)
s, _ := New(Opts{})
s.Info("This is an info message")
s.Info(
	"This is an info message",
	"Keys with nil values will be treated as messages", nil,
	"and will be printed on a separate line", nil,
)
s.Info("This is an info message logging a value", "value", 10)
s.Info(
	"This is an info message logging a multiple values",
	"value1", 10,
	"value2", 11,
)
s.Info("This is an info message", "Separate line", nil, "value", 10)
Example (LogMultiError)
err := sberr.AppendError(
	sberr.Wrap(
		ExpectedDirErr, "This is the first error",
	),
	sberr.Wrap(
		ExpectedDirErr, "This is the second error",
	),
	sberr.WrapValueList(
		ExpectedDirErr,
		"This is the third error",
		sberr.WrapListVal{
			ItemName: "Item 1",
			Item:     1,
		},
		sberr.WrapListVal{
			ItemName: "Item 2",
			Item:     1.0,
		},
		sberr.WrapListVal{
			ItemName: "Item 3",
			Item:     "asdf",
		},
	),
)

s, _ := New(Opts{})
s.Error(err.Error())
Example (LogVerbose)
s, _ := New(Opts{CurVerbosityLevel: 2})
s.Log(
	context.TODO(),
	VLevel(0),
	"This is a level 0 verbose message, a.k.a. a debug message",
)
s.Log(context.TODO(), VLevel(1), "This is a level 1 verbose message")
s.Log(context.TODO(), VLevel(2), "This is a level 2 verbose message")
// This next line should not print
s.Log(context.TODO(), VLevel(3), "This is a level 3 verbose message")

s, _ = New(Opts{CurVerbosityLevel: 0})
s.Log(
	context.TODO(),
	VLevel(0),
	"This is a level 0 verbose message, a.k.a. a debug message",
)
// These next three lines should not print
s.Log(context.TODO(), VLevel(1), "This is a level 1 verbose message")
s.Log(context.TODO(), VLevel(2), "This is a level 2 verbose message")
s.Log(context.TODO(), VLevel(3), "This is a level 3 verbose message")
Example (LogWarn)
s, _ := New(Opts{})
s.Warn("This is a warn message")
s.Warn(
	"This is a warn message",
	"Keys with nil values will be treated as messages", nil,
	"and will be printed on a separate line", nil,
)
s.Warn("This is a warn message logging a value", "value", 10)
s.Warn(
	"This is a warn message logging a multiple values",
	"value1", 10,
	"value2", 11,
)
s.Warn("This is a warn message", "Separate line", nil, "value", 10)
Example (PersistantLogs)
s, _ := New(Opts{
	CurVerbosityLevel: 1,
	RotateWriterOpts: RotateWriterOpts{
		LogDir:  "./testData/",
		LogName: "persistantExample",
	},
})
s.Info("This should be saved to ./testData/persistantExample.0.log")
s.Warn("This should be saved to ./testData/persistantExample.0.log")
s.Error("This should be saved to ./testData/persistantExample.0.log")
s.Debug("This should be saved to ./testData/persistantExample.0.log")
s.Log(
	context.TODO(), VLevel(1),
	"This should be saved to ./testData/persistantExample.0.log",
)

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	ExpectedDirErr = errors.New("A dir was expected")
)

Functions

func New

func New(opts Opts) (*slog.Logger, error)

Creates a new logger. The logs will always be printed to stdout/stderr. If `opts.RotateWriterOpts.LogDir` is an empty string no logs will be written to disk. If `opts.RotateWriterOpts.LogDir` is a valid dir then all logs from stdout and stderr will be mirrored to files in the supplied dir using a RotateWriter.

func VLevel

func VLevel(val uint) slog.Level

Translates the requested positive verbosity level from a range of [0,inf) to (-inf, -4]. This must be done for the level to be understood by the slog package.

Types

type Opts

type Opts struct {
	// Sets the allowed maximum verbosity level. There is no bound to the
	// requested verbosity, but any verbosity levels greater than the level
	// set here will not be printed.
	CurVerbosityLevel uint
	// The time format to use when printing log messages.
	TimeFmt string
	RotateWriterOpts
}

type RotateWriter

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

Implements a rotating file writer. The logger will create log files in the following format:

<logDir>/<logName>.0.log
<logDir>/<logName>.1.log
...
<logDir>/<logName>.<maxNumLogs>.log

Where logDir, logName, and maxNumLogs are parameters that are specified through the RotateWriterOpts struct when NewRotateWriter is called. Once the maximum allowed number of logs have been reached the writer will start to cycle back through old logs, clearing each one as needed before writing new log data.

func NewRotateWriter

func NewRotateWriter(opts RotateWriterOpts) (*RotateWriter, error)

Creates a new rotating log writer. `opts.LogDir` must exist. Several defaults will be set from opts:

  • If opts.LogName=="" then it will be set to a default of "sblog"
  • If opts.MaxNumLogs==0 then it will be set to a default of 1
  • If opts.MaxLogSizeBytes==0 then it will be set to a default of 1 MB

func (*RotateWriter) Close

func (w *RotateWriter) Close() error

Closes the currently open log in the rotation. All other files in the log rotation are already closed.

func (*RotateWriter) Rotate

func (w *RotateWriter) Rotate() (err error)

Rotates the log, advancing to the next log in the rotation. If the end of the log rotation is reached the rotation will start over at the beginning, clearing out logs as necessary to continue writing data.

func (*RotateWriter) Write

func (w *RotateWriter) Write(output []byte) (int, error)

Writes data to the log rotation, advancing to the next log in the rotation as necessary.

type RotateWriterOpts

type RotateWriterOpts struct {
	// The dir that the log files should be placed in. The dir must exist.
	// It will not be created if it does not exist.
	LogDir string
	// The name to give all log files. All log files will then match the
	// following format:
	//
	//   <logName>.<N>.log
	//
	// Where N is the number of the log in the log rotation.
	LogName string
	// The maximum number of log files to allow. Once this limit has been
	// reached the log writer will start to cycle back through old logs,
	// clearing each one as needed.
	MaxNumLogs uint
	// The number of bytes that can be reached before a moving onto the next
	// log file in the log rotation. Log messages will not be split between
	// files, meaning the number of bytes in the file may be slightly more
	// than `MaxLogSizeBytes`.
	MaxLogSizeBytes uint64
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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