A logger, for Go

Go-Log

Build Status

A logger, for Go!

It's sort of log and code.google.com/p/log4go compatible, so in most cases can be used without any code changes.

Breaking change

go-log was inconsistent with the default Go 'log' package, and log.Fatal calls didn't trigger an os.Exit(1).

This has been fixed in the current release of go-log, which might break backwards compatibility.

You can disable the fix by setting ExitOnFatal to false, e.g.

log.Logger().ExitOnFatal = false

Getting started

Install go-log:

go get github.com/ian-kent/go-log/log

Use the logger in your application:

import(
  "github.com/ian-kent/go-log/log"
)

// Pass a log message and arguments directly
log.Debug("Example log message: %s", "example arg")

// Pass a function which returns a log message and arguments
log.Debug(func(){[]interface{}{"Example log message: %s", "example arg"}})
log.Debug(func(i ...interface{}){[]interface{}{"Example log message: %s", "example arg"}})

You can also get the logger instance:

logger := log.Logger()
logger.Debug("Yey!")

Or get a named logger instance:

logger := log.Logger("foo.bar")

Log levels

The default log level is DEBUG.

To get the current log level:

level := logger.Level()

Or to set the log level:

// From a LogLevel
logger.SetLevel(levels.TRACE)

// From a string
logger.SetLevel(log.Stol("TRACE"))

Log appenders

The default log appender is appenders.Console(), which logs the raw message to STDOUT.

To get the current log appender:

appender := logger.Appender()

If the appender is nil, the parent loggers appender will be used instead.

If the appender eventually resolves to nil, log data will be silently dropped.

You can set the log appender:

logger.SetAppender(appenders.Console())

Rolling file appender

Similar to log4j's rolling file appender, you can use

// Append to (or create) file
logger.SetAppender(appenders.RollingFile("filename.log", true))

// Truncate (or create) file
logger.SetAppender(appenders.RollingFile("filename.log", false))

You can also control the number of log files which are kept:

r := appenders.RollingFile("filename.log", true)
r.MaxBackupIndex = 2 // filename.log, filename.log.1, filename.log.2

And the maximum log file size (in bytes):

r := appenders.RollingFile("filename.log", true)
r.MaxFileSize = 1024 // 1KB, defaults to 100MB

Fluentd appender

The fluentd appender lets you write log data directly to fluentd:

logger.SetAppender(appenders.Fluentd(fluent.Config{}))

It uses github.com/t-k/fluent-logger-golang.

The tag is currently fixed to 'go-log', and the data structure sent to fluentd is simple:

{
  message: "<output from layout>"
}

Layouts

Each appender has its own layout. This allows the log data to be transformed as it is written to the appender.

The default layout is layout.Basic(), which passes the log message and its arguments through fmt.Sprintf.

To get the current log appender layout:

appender := logger.Appender()
layout := appender.Layout()

To set the log appender layout:

appender.SetLayout(layout.Basic())

You can also use layout.Pattern(pattern string), which accepts a pattern format similar to log4j:

Code Description
%c The package the log statement is in
%C Currently also the package the log statement is in
%d The current date/time, using time.Now().String()
%F The filename the log statement is in
%l The location of the log statement, e.g. package/somefile.go:12
%L The line number the log statement is on
%m The log message and its arguments formatted with fmt.Sprintf
%n A new-line character
%p Priority - the log level
%r ms since logger was created

Logger inheritance

Loggers are namespaced with a ., following similar rules to Log4j.

If you create a logger named foo, it will automatically inherit the log settings (levels and appender) of the root logger.

If you then create a logger named foo.bar, it will inherit the log settings of foo, which in turn inherits the log settings from the root logger.

You can break this by setting the log level or setting an appender on a child logger, e.g.:

logger := log.Logger("foo.bar")
logger.SetLevel(levels.TRACE)
logger.SetAppender(appenders.Console())

If you then created a logger named foo.bar.qux, it would inherit the trace level and console appender of the foo.bar logger.

Roadmap

  • log4j configuration support
    • .properties
    • .xml
    • .json
  • layouts
    • fixmes/todos in pattern layout
  • appenders
    • add socket appender
    • fixmes/todos and tests for fluentd appender
  • optimise logger creation
    • collapse loggers when parent namespace is unused
    • reorganise loggers when new child tree is created
  • add godoc documentation

Contributing

Before submitting a pull request:

  • Format your code: go fmt ./...
  • Make sure tests pass: go test ./...

Licence

Copyright ©‎ 2014, Ian Kent (http://www.iankent.eu).

Released under MIT license, see LICENSE for details.

Owner
Ian Kent
Love code... mostly Go, now a bit of Elm. Created @mailhog and @websysd
Ian Kent
Comments
  • The implemention of the interface in this project includes the interface itself

    The implemention of the interface in this project includes the interface itself

    type Logger interface { Level() levels.LogLevel Name() string FullName() string ... } type logger struct { Logger level levels.LogLevel name string enabled map[levels.LogLevel]bool appender Appender children []Logger parent Logger ExitOnFatal bool } In the type logger, Logger is if unnecessary or not.

  • Create multiple_appender.go

    Create multiple_appender.go

    Create a simple multiple appender. We construct it with a Layout and list/slice of Appenders. Its Write method will just loop over all appenders and perform their Write.

  • Fix Windows 7 crash

    Fix Windows 7 crash

    runtime.Caller returns filename with forward slashes so split with filepath.Separator in Windows 7 returns array with 1 item and program panic on line 47.

  • panic if first argument isn't string

    panic if first argument isn't string

    panic: interface conversion: interface is *url.Error, not string
    
    goroutine 22 [running]:
    runtime.panic(0x7c69e0, 0xc2080c0b00)
        /usr/local/Cellar/go/1.3.1/libexec/src/pkg/runtime/panic.c:279 +0xf5
    github.com/ian-kent/go-log/logger.(*logger).write(0xc2080bec40, 0x5, 0xc2080f2730, 0x1, 0x1)
        /Users/ikent/dev/src/github.com/ian-kent/go-log/logger/logger.go:107 +0x97
    github.com/ian-kent/go-log/logger.(*logger).Log(0xc2080bec40, 0x5, 0xc2080f2730, 0x1, 0x1)
        /Users/ikent/dev/src/github.com/ian-kent/go-log/logger/logger.go:127 +0xc3
    github.com/ian-kent/go-log/log.Log(0x5, 0xc2080f2730, 0x1, 0x1)
        /Users/ikent/dev/src/github.com/ian-kent/go-log/log/log.go:42 +0x70
    github.com/ian-kent/go-log/log.Trace(0xc2080f2730, 0x1, 0x1)
        /Users/ikent/dev/src/github.com/ian-kent/go-log/log/log.go:50 +0x44
    github.com/ian-kent/gopan/getpan/getpan.(*Source).Find(0xc2080c0640, 0xc20801b8b0, 0x0, 0x0, 0x0)
        /Users/ikent/dev/src/github.com/ian-kent/gopan/getpan/getpan/sources.go:214 +0x2204
    github.com/ian-kent/gopan/getpan/getpan.(*Dependency).Resolve(0xc20801b8b0, 0x0, 0x0)
        /Users/ikent/dev/src/github.com/ian-kent/gopan/getpan/getpan/dependency.go:331 +0x27d
    github.com/ian-kent/gopan/getpan/getpan.func·003(0xc20801b8b0)
        /Users/ikent/dev/src/github.com/ian-kent/gopan/getpan/getpan/dependency.go:224 +0x3e3
    created by github.com/ian-kent/gopan/getpan/getpan.(*DependencyList).Resolve
        /Users/ikent/dev/src/github.com/ian-kent/gopan/getpan/getpan/dependency.go:310 +0x470
    
  • Issue 009: Wrong File/Line from logger.Debug()

    Issue 009: Wrong File/Line from logger.Debug()

    logger.Debug(x) -- or other logger entry function -- calls logger.Log, which calls logger.Write, which calls appender.Write, which calls layout.Format, which calls layout.getCaller, which calls runtime.Caller.

    Therefore the correct number of stack frames to ascend to get to the caller of Debug -- or other logger entry function -- is 6.

    See https://github.com/ian-kent/go-log/issues/9

    See also https://golang.org/pkg/runtime/#Caller

    This code reproduces the bug:

    package main
    
    import(
        "github.com/ian-kent/go-log/appenders"
        "github.com/ian-kent/go-log/layout"
        "github.com/ian-kent/go-log/log"
    )
    
    func main() {
        logger := log.Logger()
        logger.SetLevel(log.Stol("DEBUG"))
        appender := appenders.RollingFile("sample.log", true)
        appender.MaxFileSize = 1024
        appender.SetLayout(layout.Pattern("%p %l %m "))
        logger.SetAppender(appender)
        logger.Debug("Reading configuration")
    }
    

    Result of runtime.Caller(n) in pattern.go for 0 >= n >= 7:

    Caller(0): DEBUG layout/pattern.go:50 Reading configuration Caller(1): DEBUG layout/pattern.go:70 Reading configuration Caller(2): DEBUG appenders/rollingfile.go:51 Reading configuration Caller(3): DEBUG logger/logger.go:129 Reading configuration Caller(4): DEBUG logger/logger.go:154 Reading configuration Caller(5): DEBUG logger/logger.go:213 Reading configuration Caller(6): DEBUG go-log/bug009.go:16 Reading configuration Caller(7): DEBUG runtime/proc.go:185 Reading configuration

  • add instruction to set customizable pattern

    add instruction to set customizable pattern

    Old readme is misleading here. I was thinking Pattern is a method provided in the layout object returned from appender.Layout(). Actually it's provided in layout package.

  •  Invalid line details when I use  %l  as layout pattren

    Invalid line details when I use %l as layout pattren

    My logger Configuration logger := log.Logger() logger.SetLevel(log.Stol("DEBUG") appender := appenders.RollingFile("sample.log", true) appender.MaxFileSize = 1024 appender.SetLayout(layout.Pattern("%p %l %m ")) logger.SetAppender(appender)

    Logger Usage sample code 18 func main() { 19 logger := logging.GetLogger() 20 logger.Debug("Reading configuration file")

    It is showing incorrect details DEBUG appenders/rollingfile.go:51 Reading configuration file

    It should display as follows DEBUG appenders/main.go:20 Reading configuration file

Logger - A thin wrapper of uber-go/zap logger for personal project

a thin wraper of uber-go/zap logger for personal project 0. thanks uber-go/zap B

Sep 17, 2022
A logger, for Go

Go-Log A logger, for Go! It's sort of log and code.google.com/p/log4go compatible, so in most cases can be used without any code changes. Breaking cha

Oct 7, 2022
Simple logger for Go programs. Allows custom formats for messages.
Simple logger for Go programs. Allows custom formats for messages.

go-logger A simple go logger for easy logging in your programs. Allows setting custom format for messages. Preview Install go get github.com/apsdehal/

Dec 17, 2022
Loggly Hooks for GO Logrus logger

Loggly Hooks for Logrus Usage package main import ( "github.com/sirupsen/logrus" "github.com/sebest/logrusly" ) var logglyToken string = "YOUR_LOG

Sep 26, 2022
A 12-factor app logger built for performance and happy development
A 12-factor app logger built for performance and happy development

logxi log XI is a structured 12-factor app logger built for speed and happy development. Simpler. Sane no-configuration defaults out of the box. Faste

Nov 27, 2022
Dead simple, super fast, zero allocation and modular logger for Golang

Onelog Onelog is a dead simple but very efficient JSON logger. It is one of the fastest JSON logger out there. Also, it is one of the logger with the

Sep 26, 2022
A logger for Go SQL database driver without modify existing *sql.DB stdlib usage.
A logger for Go SQL database driver without modify existing *sql.DB stdlib usage.

SQLDB-Logger A logger for Go SQL database driver without modify existing *sql.DB stdlib usage. Colored console writer output above only for sample/dev

Jan 3, 2023
xlog is a logger for net/context aware HTTP applications
xlog is a logger for net/context aware HTTP applications

⚠️ Check zerolog, the successor of xlog. HTTP Handler Logger xlog is a logger for net/context aware HTTP applications. Unlike most loggers, xlog will

Sep 26, 2022
Zero Allocation JSON Logger
Zero Allocation JSON Logger

Zero Allocation JSON Logger The zerolog package provides a fast and simple logger dedicated to JSON output. Zerolog's API is designed to provide both

Jan 1, 2023
A powerful zero-dependency json logger.

ZKits Logger Library About This package is a library of ZKits project. This is a zero-dependency standard JSON log library that supports structured JS

Dec 14, 2022
Configurable Logger for Go

Timber! This is a logger implementation that supports multiple log levels, multiple output destinations with configurable formats and levels for each.

Jun 28, 2022
A feature-rich and easy to use logger for golang
A feature-rich and easy to use logger for golang

A feature-rich and easy to use logger for golang ?? Install ?? Common Logs lumber.Success() lumber.Info() lumber.Debug() lumber.Warning()

Dec 31, 2022
A minimal and extensible structured logger

⚠️ PRE-RELEASE ⚠️ DO NOT IMPORT THIS MODULE YOUR PROJECT WILL BREAK package log package log provides a minimal interface for structured logging in ser

Jan 7, 2023
HTTP request logger for Golang
HTTP request logger for Golang

Horus ?? Introduction Horus is a request logger and viewer for Go. It allows developers log and view http requests made to their web application. Inst

Dec 27, 2022
Simple Yet Powerful Logger

sypl sypl provides a Simple Yet Powerful Logger built on top of the Golang sypl. A sypl logger can have many Outputs, and each Output is responsible f

Sep 23, 2022
simple concurrent logger

XMUS-LOGGER pure golang logger compatible with golang io standards. USAGE : logOptions := logger.LoggerOptions{ LogLevel: 6, // read more about lo

Aug 1, 2022
Binalyze logger is an easily customizable wrapper for logrus with log rotation

logger logger is an easily customizable wrapper for logrus with log rotation Usage There is only one function to initialize logger. logger.Init() When

Oct 2, 2022
🪵 A dead simple, pretty, and feature-rich logger for golang
🪵 A dead simple, pretty, and feature-rich logger for golang

?? lumber ?? A dead simple, pretty, and feature-rich logger for golang ?? Install ?? Logging Functions lumber.Success() lumber.Info() lumber.Debug() l

Jul 20, 2022
Multi-level logger based on go std log

mlog the mlog is multi-level logger based on go std log. It is: Simple Easy to use NOTHING ELSE package main import ( log "github.com/ccpaging/lo

May 18, 2022