Documentation ¶
Overview ¶
Package logtic is a yet another logging library for golang projects.
Important: Following Go 1.21 and the introduction of the log/slog package, new projects should prefer to use that over logtic. This package will continue to be supported in terms of bugfixes and security fixes only. No new functionality will be added.
The goal of logtic is to be as transparent and easy to use as possible, allowing applications and libraries to seamlessly log to a single file. Logtic can be used in libraries and won't cause any problems if the parent application isn't using logtic.
Logtic supports multiple sources, which annotate the outputted log lines. It also supports defining a minimum desired log level, which can be changed at any time. Events printed to the terminal output support color-coded severities.
Events can be printed as formatted strings, like with `fmt.Printf`, or can be parameterized events which can be easily parsed by log analysis tools such as Splunk.
By default, logtic will only print to stdout and stderr, but when configured it can also write to a log file. Log files include the date-time for each event in RFC-3339 format.
Logtic provides a default logging instance but also supports unique instances that can operate in parallel, writing to unique files and having unique settings.
Log files can be rotated using the provided rotate method.
Logtic is optimized for Linux & Unix environments but offers limited support for Windows.
Example ¶
Common setup for file-based logging
package main import ( "github.com/ecnepsnai/logtic" ) func main() { // Set the log file path and default log level (if desired) logtic.Log.FilePath = "./file.log" logtic.Log.Level = logtic.LevelInfo if err := logtic.Log.Open(); err != nil { // There was an error opening the log file for writing panic(err) } log := logtic.Log.Connect("MyApp") log.Warn("Print something %s", "COOL!") // Don't forget to close the log file when your application exits logtic.Log.Close() }
Output:
Index ¶
- Constants
- Variables
- func FormatBytesB(b uint64) string
- func FormatBytesD(b uint64) string
- func StringFromParameters(parameters map[string]interface{}) string
- type LogLevel
- type Logger
- type LoggerOptions
- type Source
- func (s *Source) Debug(format string, a ...interface{})
- func (s *Source) Error(format string, a ...interface{})
- func (s *Source) Fatal(format string, a ...interface{})
- func (s *Source) GoLogger(level LogLevel) *log.Logger
- func (s *Source) Info(format string, a ...interface{})
- func (s *Source) PDebug(event string, parameters map[string]interface{})
- func (s *Source) PError(event string, parameters map[string]interface{})
- func (s *Source) PFatal(event string, parameters map[string]interface{})
- func (s *Source) PInfo(event string, parameters map[string]interface{})
- func (s *Source) PPanic(event string, parameters map[string]interface{})
- func (s *Source) PWarn(event string, parameters map[string]interface{})
- func (s *Source) PWrite(level LogLevel, event string, parameters map[string]interface{})
- func (s *Source) Panic(format string, a ...interface{})
- func (s *Source) Warn(format string, a ...interface{})
- func (s *Source) Write(level LogLevel, format string, a ...interface{})
Examples ¶
Constants ¶
const ( // LevelDebug debug messages for troubleshooting application behaviour LevelDebug = LogLevel(3) // LevelInfo informational messages for normal operation of the application LevelInfo = LogLevel(2) // LevelWarn warning messages for potential issues LevelWarn = LogLevel(1) // LevelError error messages for problems LevelError = LogLevel(0) )
Variables ¶
var Log = New()
Log is the default logging instance.
Functions ¶
func FormatBytesB ¶ added in v1.6.0
FormatBytesB takes in a number of bytes and returns a human readable string with binary units (up-to Exbibyte)
Example ¶
package main import ( "fmt" "github.com/ecnepsnai/logtic" ) func main() { fmt.Println(logtic.FormatBytesB(10485760)) }
Output: 10.0 MiB
func FormatBytesD ¶ added in v1.6.0
FormatBytesB takes in a number of bytes and returns a human readable string with decimal units (up-to Exabyte)
Example ¶
package main import ( "fmt" "github.com/ecnepsnai/logtic" ) func main() { fmt.Println(logtic.FormatBytesD(10000000)) }
Output: 10.0 MB
func StringFromParameters ¶ added in v1.6.0
StringFromParameters return a key=value string for the given parameters. Depending on the type of the parameter value, it may be wrapped in single quotes. Byte slices are represented as hexadecimal strings. Parameters are always alphabetically sorted in the outputted string.
Example ¶
package main import ( "fmt" "time" "github.com/ecnepsnai/logtic" ) func main() { fmt.Println(logtic.StringFromParameters(map[string]interface{}{ "hello": "world!", "meaning_of_life": 42, "pie": 3.12, "does_golang_rock": true, "secret_sauce": []byte("mayo ketchup sriracha"), "unix_epoch": time.Unix(0, 0).UTC(), "prime_numbers": []int{2, 3, 5, 7, 11}, })) }
Output: does_golang_rock='true' hello='world!' meaning_of_life=42 pie=3.120000 prime_numbers='[2 3 5 7 11]' secret_sauce=6d61796f206b657463687570207372697261636861 unix_epoch='1970-01-01T00:00:00Z'
Types ¶
type Logger ¶ added in v1.7.0
type Logger struct { // The path to the log file. FilePath string // The minimum level of events captured in the log file and printed to console. Inclusive. Level LogLevel // The file mode (permissions) used for the log file and rotated log files. FileMode os.FileMode // Options various options for this logger Options LoggerOptions // Stdout the writer to use for standard output. Defaults to the system stdout. Stdout io.Writer // Stdout the writer to use for standard error. Defaults to the system stderr. Stderr io.Writer // contains filtered or unexported fields }
Logger describes a logging instance
func New ¶ added in v1.7.0
func New() *Logger
New will create a new logging instance with all default options. You should only use new if you want a separate logging instance from the default instance, which is automatically created for you.
func (*Logger) Close ¶ added in v1.7.0
func (l *Logger) Close()
Close will flush and close this logging instance.
func (*Logger) Connect ¶ added in v1.7.0
Connect will prepare a new logtic source with the given name for this logging instance. Sources can be written even if there is no open logtic log instance.
Example ¶
This example shows how to connect a new source to a logtic instance
package main import ( "github.com/ecnepsnai/logtic" ) func main() { // You can connect to logtic before a log file has been opened // however, any events will not be captured until logtic.Log.Open() // has been called source1 := logtic.Log.Connect("Source1") source2 := logtic.Log.Connect("Source2") source1.Warn("Important warning") source2.Error("Something went wrong") }
Output:
func (*Logger) Open ¶ added in v1.7.0
Open will open the file specified by FilePath on this logging instance. The file will be created if it does not already exist, otherwise it will be appended to.
Example ¶
This example shows how to set up a unique logging instance, separate form the default instance
package main import ( "github.com/ecnepsnai/logtic" ) func main() { logger := logtic.New() // You must tell logtic where the log file is // before any events will be captured logger.FilePath = "./file.log" // The default level is Error, you can change that at any time logger.Level = logtic.LevelInfo if err := logger.Open(); err != nil { // There was an error opening the log file for writing panic(err) } }
Output:
Example (WithoutFile) ¶
This example shows how to prepare logtic to only print to the console, without writing to a log file
package main import ( "os" "github.com/ecnepsnai/logtic" ) func main() { logger := logtic.New() // You don't have to specify os.DevNull, however it is good pratice to be explicit that it is // not being written to any file logger.FilePath = os.DevNull // The default level is Error, you can change that at any time logger.Level = logtic.LevelInfo if err := logger.Open(); err != nil { // You probably should panic here, or exit the app // as failing to open a file to DevNull is a bad sign panic(err) } }
Output:
func (*Logger) Reset ¶ added in v1.7.0
func (l *Logger) Reset()
Reset will reset this logging instance to its original state. Open files will be closed.
func (*Logger) Rotate ¶ added in v1.7.0
Rotate will rotate the log file of this logging instance. The current log file will be renamed and suffixed with the current date in a YYYY-MM-DD format. A new log file will be opened with the original file path and used for all subsequent writes. Writes will be blocked while the rotation is in progress. If a file matching the name of what would be used for the rotated file, a dash and numerical suffix is added to the end of the name.
If an error is returned during rotation it is highly recommended that you either panic or call logger.Reset() as logtic may be in an undefined state and log calls may cause panics.
If no log file has been opened on this logger, calls to Rotate do nothing.
Example ¶
This example shows how to trigger a log file rotation
package main import ( "github.com/ecnepsnai/logtic" ) func main() { logtic.Log.FilePath = "/path/to/log/file.log" if err := logtic.Log.Open(); err != nil { panic(err) } if err := logtic.Log.Rotate(); err != nil { // There was an error rotating the log // It's recommended that you panic or exit here, as logtic is now in an undefined state panic(err) } }
Output:
type LoggerOptions ¶ added in v1.8.0
type LoggerOptions struct { // Should logtic not use color when printing events to stdout/stderr. Enabled by default. Color bool // Should logtic escape control characters automatically. For example, replaces actual newlines with a literal \n. // Enabled by default. EscapeCharacters bool // Should logtic automatically gzip log files after rotation. Disabled by default. // // Deprecated: Built-in gzip support will be removed in a future update. Compress rotated log files using tooling // on the host system. GZipRotatedLogs bool }
LoggerOptions describe logger options
type Source ¶
Source describes a source for log events
func (*Source) Debug ¶
Debug will log a debug formatted message.
Example ¶
package main import ( "github.com/ecnepsnai/logtic" ) func main() { log := logtic.Log.Connect("Example") log.Debug("This is a %s message", "debug") // Terminal output: [DEBUG][Example] This is a debug message // File output: 2021-03-15T21:43:34-07:00 [DEBUG][Example] This is a debug message }
Output:
func (*Source) Error ¶
Error will log an error formatted message. Errors are printed to stderr.
Example ¶
package main import ( "github.com/ecnepsnai/logtic" ) func main() { log := logtic.Log.Connect("Example") log.Error("This is a %s message", "error") // Terminal output: [ERROR][Example] This is a error message // File output: 2021-03-15T21:43:34-07:00 [ERROR][Example] This is a error message }
Output:
func (*Source) Fatal ¶
Fatal will log a fatal formatted error message and exit the application with status 1. Fatal messages are printed to stderr.
Example ¶
package main import ( "github.com/ecnepsnai/logtic" ) func main() { log := logtic.Log.Connect("Example") log.Fatal("This is a %s message", "fatal") // Terminal output: [FATAL][Example] This is a fatal message // File output: 2021-03-15T21:43:34-07:00 [FATAL][Example] This is a fatal message }
Output:
func (*Source) GoLogger ¶ added in v1.9.2
GoLogger returns a logger that acts as a proxy between the go/log package and logtic. Printf events sent to this logger will be forwarded to this source with the given level.
func (*Source) Info ¶
Info will log an informational formatted message.
Example ¶
package main import ( "github.com/ecnepsnai/logtic" ) func main() { log := logtic.Log.Connect("Example") log.Info("This is a %s message", "info") // Terminal output: [INFO][Example] This is a info message // File output: 2021-03-15T21:43:34-07:00 [INFO][Example] This is a info message }
Output:
func (*Source) PDebug ¶ added in v1.6.0
PDebug will log a debug parameterized message. Parameterized messages are formatted as key=value strings. Depending on the type of the parameter value, it may be wrapped in single quotes. Byte slices are represented as hexadecimal strings. Parameters are always alphabetically sorted in the outputted string.
Example ¶
package main import ( "github.com/ecnepsnai/logtic" ) func main() { log := logtic.Log.Connect("Example") log.PDebug("Debug event", map[string]interface{}{ "param1": "string", "param2": 123, }) // Terminal output: [DEBUG][Example] Debug event: param1='string' param2=123 // File output: 2021-03-15T21:43:34-07:00 [DEBUG][Example] Debug event: param1='string' param2=123 }
Output:
func (*Source) PError ¶ added in v1.6.0
PError will log an error parameterized message. Errors are printed to stderr. Parameterized messages are formatted as key=value strings. Depending on the type of the parameter value, it may be wrapped in single quotes. Byte slices are represented as hexadecimal strings. Parameters are always alphabetically sorted in the outputted string.
Example ¶
package main import ( "github.com/ecnepsnai/logtic" ) func main() { log := logtic.Log.Connect("Example") log.PError("Error event", map[string]interface{}{ "param1": "string", "param2": 123, }) // Terminal output: [ERROR][Example] Error event: param1='string' param2=123 // File output: 2021-03-15T21:43:34-07:00 [ERROR][Example] Error event: param1='string' param2=123 }
Output:
func (*Source) PFatal ¶ added in v1.6.0
PFatal will log a fatal parameterized error message and exit the application with status 1. Fatal messages are printed to stderr. Parameterized messages are formatted as key=value strings. Depending on the type of the parameter value, it may be wrapped in single quotes. Byte slices are represented as hexadecimal strings. Parameters are always alphabetically sorted in the outputted string.
Example ¶
package main import ( "github.com/ecnepsnai/logtic" ) func main() { log := logtic.Log.Connect("Example") log.PFatal("Fatal event", map[string]interface{}{ "param1": "string", "param2": 123, }) // Terminal output: [FATAL][Example] Fatal event: param1='string' param2=123 // File output: 2021-03-15T21:43:34-07:00 [FATAL][Example] Fatal event: param1='string' param2=123 }
Output:
func (*Source) PInfo ¶ added in v1.6.0
PInfo will log an informational parameterized message. Parameterized messages are formatted as key=value strings. Depending on the type of the parameter value, it may be wrapped in single quotes. Byte slices are represented as hexadecimal strings. Parameters are always alphabetically sorted in the outputted string.
Example ¶
package main import ( "github.com/ecnepsnai/logtic" ) func main() { log := logtic.Log.Connect("Example") log.PInfo("Info event", map[string]interface{}{ "param1": "string", "param2": 123, }) // Terminal output: [INFO][Example] Info event: param1='string' param2=123 // File output: 2021-03-15T21:43:34-07:00 [INFO][Example] Info event: param1='string' param2=123 }
Output:
func (*Source) PPanic ¶ added in v1.6.0
PPanic functions like source.PFatal() but panics rather than exits. Parameterized messages are formatted as key=value strings. Depending on the type of the parameter value, it may be wrapped in single quotes. Byte slices are represented as hexadecimal strings. Parameters are always alphabetically sorted in the outputted string.
Example ¶
package main import ( "github.com/ecnepsnai/logtic" ) func main() { log := logtic.Log.Connect("Example") log.PPanic("Panic event", map[string]interface{}{ "param1": "string", "param2": 123, }) // Terminal output: [FATAL][Example] Panic event: param1='string' param2=123 // File output: 2021-03-15T21:43:34-07:00 [FATAL][Example] Panic event: param1='string' param2=123 }
Output:
func (*Source) PWarn ¶ added in v1.6.0
PWarn will log a warning parameterized message. Parameterized messages are formatted as key=value strings. Depending on the type of the parameter value, it may be wrapped in single quotes. Byte slices are represented as hexadecimal strings. Parameters are always alphabetically sorted in the outputted string.
Example ¶
package main import ( "github.com/ecnepsnai/logtic" ) func main() { log := logtic.Log.Connect("Example") log.PWarn("Warning event", map[string]interface{}{ "param1": "string", "param2": 123, }) // Terminal output: [WARN][Example] Warning event: param1='string' param2=123 // File output: 2021-03-15T21:43:34-07:00 [WARN][Example] Warning event: param1='string' param2=123 }
Output:
func (*Source) PWrite ¶ added in v1.6.0
PWrite will call the matching write function for the given level, printing the provided message. For example:
source.PWrite(logtic.LevelDebug, "My Event", map[string]interface{}{"key": "value"})
is the same as:
source.PDebug("My Event", map[string]interface{}{"key": "value"})
func (*Source) Panic ¶
Panic functions like source.Fatal() but panics rather than exits.
Example ¶
package main import ( "github.com/ecnepsnai/logtic" ) func main() { log := logtic.Log.Connect("Example") log.Panic("This is a %s message", "fatal") // Terminal output: [FATAL][Example] This is a fatal message // File output: 2021-03-15T21:43:34-07:00 [FATAL][Example] This is a fatal message }
Output:
func (*Source) Warn ¶
Warn will log a warning formatted message.
Example ¶
package main import ( "github.com/ecnepsnai/logtic" ) func main() { log := logtic.Log.Connect("Example") log.Warn("This is a %s message", "warning") // Terminal output: [WARN][Example] This is a warning message // File output: 2021-03-15T21:43:34-07:00 [WARN][Example] This is a warning message }
Output: