• Stars
    star
    358
  • Rank 118,855 (Top 3 %)
  • Language
    Go
  • License
    MIT License
  • Created over 9 years ago
  • Updated over 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A 12-factor app logger built for performance and happy development

demo

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.
  • Faster. See benchmarks vs logrus and log15.
  • Structured. Key-value pairs are enforced. Logs JSON in production.
  • Configurable. Enable/disalbe Loggers and levels via env vars.
  • Friendlier. Happy, colorful and developer friendly logger in terminal.
  • Helpul. Traces, warnings and errors are emphasized with file, line number and callstack.
  • Efficient. Has level guards to avoid cost of building complex arguments.

Requirements

Go 1.3+

Installation

go get -u github.com/mgutz/logxi/v1

Getting Started

import "github.com/mgutz/logxi/v1"

// create package variable for Logger interface
var logger log.Logger

func main() {
    // use default logger
    who := "mario"
    log.Info("Hello", "who", who)

    // create a logger with a unique identifier which
    // can be enabled from environment variables
    logger = log.New("pkg")

    // specify a writer, use NewConcurrentWriter if it is not concurrent
    // safe
    modelLogger = log.NewLogger(log.NewConcurrentWriter(os.Stdout), "models")

    db, err := sql.Open("postgres", "dbname=testdb")
    if err != nil {
        modelLogger.Error("Could not open database", "err", err)
    }

    fruit := "apple"
    languages := []string{"go", "javascript"}
    if log.IsDebug() {
        // use key-value pairs after message
        logger.Debug("OK", "fruit", fruit, "languages", languages)
    }
}

logxi defaults to showing warnings and above. To view all logs

LOGXI=* go run main.go

Highlights

This logger package

  • Is fast in production environment

    A logger should be efficient and minimize performance tax. logxi encodes JSON 2X faster than logrus and log15 with primitive types. When diagnosing a problem in production, troubleshooting often means enabling small trace data in Debug and Info statements for some period of time.

    # primitive types
    BenchmarkLogxi          100000    20021 ns/op   2477 B/op    66 allocs/op
    BenchmarkLogrus          30000    46372 ns/op   8991 B/op   196 allocs/op
    BenchmarkLog15           20000    62974 ns/op   9244 B/op   236 allocs/op
    
    # nested object
    BenchmarkLogxiComplex    30000    44448 ns/op   6416 B/op   190 allocs/op
    BenchmarkLogrusComplex   20000    65006 ns/op  12231 B/op   278 allocs/op
    BenchmarkLog15Complex    20000    92880 ns/op  13172 B/op   311 allocs/op
    
  • Is developer friendly in the terminal. The HappyDevFormatter is colorful, prints file and line numbers for traces, warnings and errors. Arguments are printed in the order they are coded. Errors print the call stack.

    HappyDevFormatter is not too concerned with performance and delegates to JSONFormatter internally.

  • Logs machine parsable output in production environments. The default formatter for non terminals is JSONFormatter.

    TextFormatter may also be used which is MUCH faster than JSON but there is no guarantee it can be easily parsed.

  • Has level guards to avoid the cost of building arguments. Get in the habit of using guards.

    if log.IsDebug() {
        log.Debug("some ", "key1", expensive())
    }
    
  • Conforms to a logging interface so it can be replaced.

    type Logger interface {
        Trace(msg string, args ...interface{})
        Debug(msg string, args ...interface{})
        Info(msg string, args ...interface{})
        Warn(msg string, args ...interface{}) error
        Error(msg string, args ...interface{}) error
        Fatal(msg string, args ...interface{})
        Log(level int, msg string, args []interface{})
    
        SetLevel(int)
        IsTrace() bool
        IsDebug() bool
        IsInfo() bool
        IsWarn() bool
        // Error, Fatal not needed, those SHOULD always be logged
    }
    
  • Standardizes on key-value pair argument sequence

log.Debug("inside Fn()", "key1", value1, "key2", value2)

// instead of this log.WithFields(logrus.Fields{"m": "pkg", "key1": value1, "key2": value2}).Debug("inside fn()")

    logxi logs `FIX_IMBALANCED_PAIRS =>` if key-value pairs are imbalanced

    `log.Warn and log.Error` are special cases and return error:

    ```go
return log.Error(msg)               //=> fmt.Errorf(msg)
return log.Error(msg, "err", err)   //=> err
  • Supports Color Schemes (256 colors)

    log.New creates a logger that supports color schemes

    logger := log.New("mylog")
    

    To customize scheme

    # emphasize errors with white text on red background
    LOGXI_COLORS="ERR=white:red" yourapp
    
    # emphasize errors with pink = 200 on 256 colors table
    LOGXI_COLORS="ERR=200" yourapp
    
  • Is suppressable in unit tests

func TestErrNotFound() { log.Suppress(true) defer log.Suppress(false) ... }




## Configuration

### Enabling/Disabling Loggers

By default logxi logs entries whose level is `LevelWarn` or above when
using a terminal. For non-terminals, entries with level `LevelError` and
above are logged.

To quickly see all entries use short form

    # enable all, disable log named foo
    LOGXI=*,-foo yourapp

To better control logs in production, use long form which allows
for granular control of levels

    # the above statement is equivalent to this
    LOGXI=*=DBG,foo=OFF yourapp

`DBG` should obviously not be used in production unless for
troubleshooting. See `LevelAtoi` in `logger.go` for values.
For example, there is a problem in the data access layer
in production.

    # Set all to Error and set data related packages to Debug
    LOGXI=*=ERR,models=DBG,dat*=DBG,api=DBG yourapp

### Format

The format may be set via `LOGXI_FORMAT` environment
variable. Valid values are `"happy", "text", "JSON", "LTSV"`

    # Use JSON in production with custom time
    LOGXI_FORMAT=JSON,t=2006-01-02T15:04:05.000000-0700 yourapp

The "happy" formatter has more options

*   pretty - puts each key-value pair indented on its own line

    "happy" default to fitting key-value pair onto the same line. If
    result characters are longer than `maxcol` then the pair will be
    put on the next line and indented

*   maxcol - maximum number of columns before forcing a key to be on its
    own line. If you want everything on a single line, set this to high
    value like 1000. Default is 80.

*   context - the number of context lines to print on source. Set to -1
    to see only file:lineno. Default is 2.


### Color Schemes

The color scheme may be set with `LOGXI_COLORS` environment variable. For
example, the default dark scheme is emulated like this

    # on non-Windows, see Windows support below
    export LOGXI_COLORS=key=cyan+h,value,misc=blue+h,source=magenta,TRC,DBG,WRN=yellow,INF=green,ERR=red+h
    yourapp

    # color only errors
    LOGXI_COLORS=ERR=red yourapp

See [ansi](http://github.com/mgutz/ansi) package for styling. An empty
value, like "value" and "DBG" above means use default foreground and
background on terminal.

Keys

*   \*  - default color
*   TRC - trace color
*   DBG - debug color
*   WRN - warn color
*   INF - info color
*   ERR - error color
*   message - message color
*   key - key color
*   value - value color unless WRN or ERR
*   misc - time and log name color
*   source - source context color (excluding error line)

#### Windows

Use [ConEmu-Maximus5](https://github.com/Maximus5/ConEmu).
Read this page about [256 colors](https://code.google.com/p/conemu-maximus5/wiki/Xterm256Colors).

Colors in PowerShell and Command Prompt _work_ but not very pretty.

## Extending

What about hooks? There are least two ways to do this

*   Implement your own `io.Writer` to write to external services. Be sure to set
    the formatter to JSON to faciliate decoding with Go's built-in streaming
    decoder.
*   Create an external filter. See `v1/cmd/filter` as an example.

What about log rotation? 12 factor apps only concern themselves with
STDOUT. Use shell redirection operators to write to a file.

There are many utilities to rotate logs which accept STDIN as input. They can
do many things like send alerts, etc. The two obvious choices are Apache's `rotatelogs`
utility and `lograte`.

```sh
yourapp | rotatelogs yourapp 86400

Testing

# install godo task runner
go get -u gopkg.in/godo.v2/cmd/godo

# install dependencies
godo install -v

# run test
godo test

# run bench with allocs (requires manual cleanup of output)
godo bench-allocs

License

MIT License

More Repositories

1

dat

Go Postgres Data Access Toolkit
Go
611
star
2

ansi

Small, fast library to create ANSI colored strings and codes. [go, golang]
Go
413
star
3

vpsbench

Benchmarks VPS perfomance
Shell
322
star
4

execSync

node.js' missing execSync
JavaScript
152
star
5

mapper

Lightweight, blazing fast node.js ODM on top of mysql-libmysqlclient
JavaScript
124
star
6

nanoc3_blog

nanoc3 Blog Starter Kit
Ruby
88
star
7

str

Package str is a string library to build more Go awesomeness
Go
69
star
8

plv8-bedrock

PostgreSQL/plv8 CommonJS, migrations, unit tests. It really kicks the dolphin's ass.
JavaScript
45
star
9

dropwizard-atmosphere

Dropwizard example w/ atmosphere
JavaScript
42
star
10

node-settings

Simple, hierarchical environment-based app settings.
CoffeeScript
21
star
11

sbt-console-template

Get started with Scala with tests and console app using this sbt template.
Scala
20
star
12

mygrate

SQL file based database migrations for MySQL and PostgreSQL
CoffeeScript
17
star
13

goa

Golang assets pipeline
Go
16
star
14

backbone-knockout-examples

Backbone examples ported from Knockout.
JavaScript
14
star
15

vim-colors

My gVim colorschemes.
Vim Script
14
star
16

kohana-wp

Kohana 3 plugin for WordPress.
PHP
11
star
17

Mgutz.DapperPg

.NET 5 WebApi project with Dapper and PostgreSQL
C#
10
star
18

chromeapp

Create desktop apps using Chrome, WebSockets and Go
Go
8
star
19

minimist

port of substack/minimist to golang
Go
8
star
20

sshtunnel

simple go ssh tunnelling
Go
8
star
21

razor

Golang Razor compiled template functions
Go
7
star
22

bake

Bash make utility
Shell
6
star
23

gosu-colors

Dark and light colorscheme for VIM
Vim Script
5
star
24

vertx-web-hello

vert.x intellij run/debug example
Java
5
star
25

funcd

Function based template engine like Builder
JavaScript
5
star
26

owncloud-ssl

Installs ownCloud, an open source DropBox clone, onto a debian server.
4
star
27

mapper-pg

A lightweight PostgreSQL data mapper that likes SQL.
JavaScript
4
star
28

mapper-obtvse

Blog example for Mapper DAO
JavaScript
4
star
29

fsx

Function based JSX. Good for TypeScript, CoffeeScript
JavaScript
4
star
30

inj

KISS, `require` based dependency injection (DI) for node.js
JavaScript
4
star
31

luv

Project build utility like Rake for luvit
Lua
3
star
32

jo

Loosely typed JSON Object
Go
3
star
33

kohana-wp-examples

Kohana-WP WordPress examples
PHP
3
star
34

mgutz-colors

ANSI colors string library for sexy color output.
JavaScript
2
star
35

coffee-cake

Enhanced version of coffee-script's cake build tool
JavaScript
2
star
36

configpipe

Go configuration using a pipeline
Go
2
star
37

postgres-chinook-image

PostgreSQL image with chinook sample data.
Shell
2
star
38

gtk-theme-function

Function Metacity & GTK theme
JavaScript
1
star
39

go-minconf

Golang port of minconf
Go
1
star
40

plv8-mantle

Core for mgutz/plv8-bedrock
JavaScript
1
star
41

task

no config task runner
JavaScript
1
star