ProductPromotion
Logo

Go.Lang

made by https://0x3d.site

GitHub - rs/xlog: xlog is a logger for net/context aware HTTP applications
xlog is a logger for net/context aware HTTP applications - rs/xlog
Visit Site

GitHub - rs/xlog: xlog is a logger for net/context aware HTTP applications

GitHub - rs/xlog: xlog is a logger for net/context aware HTTP applications

:warning: Check zerolog, the successor of xlog.

HTTP Handler Logger

godoc license Build Status Coverage

xlog is a logger for net/context aware HTTP applications.

Unlike most loggers, xlog will never block your application because one its outputs is lagging. The log commands are connected to their outputs through a buffered channel and will prefer to discard messages if the buffer get full. All message formatting, serialization and transport happen in a dedicated go routine.

Read more about xlog on Dailymotion engineering blog.

Features

  • Per request log context
  • Per request and/or per message key/value fields
  • Log levels (Debug, Info, Warn, Error)
  • Color output when terminal is detected
  • Custom output (JSON, logfmt, …)
  • Automatic gathering of request context like User-Agent, IP etc.
  • Drops message rather than blocking execution
  • Easy access logging thru github.com/rs/xaccess

Works with both Go 1.7+ (with net/context support) and Go 1.6 if used with github.com/rs/xhandler.

Install

go get github.com/rs/xlog

Usage

c := alice.New()

host, _ := os.Hostname()
conf := xlog.Config{
    // Log info level and higher
    Level: xlog.LevelInfo,
    // Set some global env fields
    Fields: xlog.F{
        "role": "my-service",
        "host": host,
    },
    // Output everything on console
    Output: xlog.NewOutputChannel(xlog.NewConsoleOutput()),
}

// Install the logger handler
c = c.Append(xlog.NewHandler(conf))

// Optionally plug the xlog handler's input to Go's default logger
log.SetFlags(0)
xlogger := xlog.New(conf)
log.SetOutput(xlogger)

// Install some provided extra handler to set some request's context fields.
// Thanks to those handler, all our logs will come with some pre-populated fields.
c = c.Append(xlog.MethodHandler("method"))
c = c.Append(xlog.URLHandler("url"))
c = c.Append(xlog.RemoteAddrHandler("ip"))
c = c.Append(xlog.UserAgentHandler("user_agent"))
c = c.Append(xlog.RefererHandler("referer"))
c = c.Append(xlog.RequestIDHandler("req_id", "Request-Id"))

// Here is your final handler
h := c.Then(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    // Get the logger from the request's context. You can safely assume it
    // will be always there: if the handler is removed, xlog.FromContext
    // will return a NopLogger
    l := xlog.FromRequest(r)

    // Then log some errors
    if err := errors.New("some error from elsewhere"); err != nil {
        l.Errorf("Here is an error: %v", err)
    }

    // Or some info with fields
    l.Info("Something happend", xlog.F{
        "user":   "current user id",
        "status": "ok",
    })
    // Output:
    // {
    //   "message": "Something happend",
    //   "level": "info",
    //   "file": "main.go:34",
    //   "time": time.Time{...},
    //   "user": "current user id",
    //   "status": "ok",
    //   "ip": "1.2.3.4",
    //   "user-agent": "Mozilla/1.2.3...",
    //   "referer": "http://somewhere.com/path",
    //   "role": "my-service",
    //   "host": "somehost"
    // }
}))
http.Handle("/", h)

if err := http.ListenAndServe(":8080", nil); err != nil {
    xlogger.Fatal(err)
}

Copy Logger

You may want to get a copy of the current logger to pass a modified version to a function without touching the original:

l := xlog.FromContext(ctx)
l2 := xlog.Copy(l)
l2.SetField("foo", "bar")

Make sure you copy a request context logger if you plan to use it in a go routine that may still exist after the end of the current request. Contextual loggers are reused after each requests to lower the pressure on the garbage collector. If you would use such a logger in a go routine, you may end up using a logger from another request/context or worse, a nil pointer:

l := xlog.FromContext(ctx)
l2 := xlog.Copy(l)
go func() {
    // use the safe copy
    l2.Info("something")
}()

Global Logger

You may use the standard Go logger and plug xlog as it's output as xlog implements io.Writer:

xlogger := xlog.New(conf)
log.SetOutput(xlogger)

This has the advantage to make all your existing code or libraries already using Go's standard logger to use xlog with no change. The drawback though, is that you won't have control on the logging level and won't be able to add custom fields (other than ones set on the logger itself via configuration or SetFields()) for those messages.

Another option for code you manage but which is outside of a HTTP request handler is to use the xlog provided default logger:

xlog.Debugf("some message with %s", variable, xlog.F{"and": "field support"})

This way you have access to all the possibilities offered by xlog without having to carry the logger instance around. The default global logger has no fields set and has its output set to the console with no buffering channel. You may want to change that using the xlog.SetLogger() method:

xlog.SetLogger(xlog.New(xlog.Config{
    Level: xlog.LevelInfo,
    Output: xlog.NewConsoleOutput(),
    Fields: xlog.F{
        "role": "my-service",
    },
}))

Configure Output

By default, output is setup to output debug and info message on STDOUT and warning and errors to STDERR. You can easily change this setup.

XLog output can be customized using composable output handlers. Thanks to the LevelOutput, MultiOutput and FilterOutput, it is easy to route messages precisely.

conf := xlog.Config{
    Output: xlog.NewOutputChannel(xlog.MultiOutput{
        // Send all logs with field type=mymodule to a remote syslog
        0: xlog.FilterOutput{
            Cond: func(fields map[string]interface{}) bool {
                return fields["type"] == "mymodule"
            },
            Output: xlog.NewSyslogOutput("tcp", "1.2.3.4:1234", "mymodule"),
        },
        // Setup different output per log level
        1: xlog.LevelOutput{
            // Send errors to the console
            Error: xlog.NewConsoleOutput(),
            // Send syslog output for error level
            Info: xlog.NewSyslogOutput("", "", ""),
        },
    }),
})

h = xlog.NewHandler(conf)

Built-in Output Modules

Name Description
OutputChannel Buffers messages before sending. This output should always be the output directly set to xlog's configuration.
MultiOutput Routes the same message to several outputs. If one or more outputs return error, the last error is returned.
FilterOutput Tests a condition on the message and forward it to the child output if true.
LevelOutput Routes messages per level outputs.
ConsoleOutput Prints messages in a human readable form on the stdout with color when supported. Fallback to logfmt output if the stdout isn't a terminal.
JSONOutput Serialize messages in JSON.
LogfmtOutput Serialize messages using Heroku like logfmt.
LogstashOutput Serialize JSON message using Logstash 2.0 (schema v1) structured format.
SyslogOutput Send messages to syslog.
UIDOutput Append a globally unique id to every message and forward it to the next output.

Third Party Extensions

Project Author Description
gRPClog Hugo González Labrador An adapter to use xlog as the logger for grpclog.
xlog-nsq Olivier Poitrey An xlog to NSQ output.
xlog-sentry trong An xlog to Sentry output.

Licenses

All source code is licensed under the MIT License.

Articles
to learn more about the golang concepts.

Resources
which are currently available to browse on.

mail [email protected] to add your project or resources here 🔥.

FAQ's
to know more about the topic.

mail [email protected] to add your project or resources here 🔥.

Queries
or most google FAQ's about GoLang.

mail [email protected] to add more queries here 🔍.

More Sites
to check out once you're finished browsing here.

0x3d
https://www.0x3d.site/
0x3d is designed for aggregating information.
NodeJS
https://nodejs.0x3d.site/
NodeJS Online Directory
Cross Platform
https://cross-platform.0x3d.site/
Cross Platform Online Directory
Open Source
https://open-source.0x3d.site/
Open Source Online Directory
Analytics
https://analytics.0x3d.site/
Analytics Online Directory
JavaScript
https://javascript.0x3d.site/
JavaScript Online Directory
GoLang
https://golang.0x3d.site/
GoLang Online Directory
Python
https://python.0x3d.site/
Python Online Directory
Swift
https://swift.0x3d.site/
Swift Online Directory
Rust
https://rust.0x3d.site/
Rust Online Directory
Scala
https://scala.0x3d.site/
Scala Online Directory
Ruby
https://ruby.0x3d.site/
Ruby Online Directory
Clojure
https://clojure.0x3d.site/
Clojure Online Directory
Elixir
https://elixir.0x3d.site/
Elixir Online Directory
Elm
https://elm.0x3d.site/
Elm Online Directory
Lua
https://lua.0x3d.site/
Lua Online Directory
C Programming
https://c-programming.0x3d.site/
C Programming Online Directory
C++ Programming
https://cpp-programming.0x3d.site/
C++ Programming Online Directory
R Programming
https://r-programming.0x3d.site/
R Programming Online Directory
Perl
https://perl.0x3d.site/
Perl Online Directory
Java
https://java.0x3d.site/
Java Online Directory
Kotlin
https://kotlin.0x3d.site/
Kotlin Online Directory
PHP
https://php.0x3d.site/
PHP Online Directory
React JS
https://react.0x3d.site/
React JS Online Directory
Angular
https://angular.0x3d.site/
Angular JS Online Directory