{"id":13413335,"url":"https://github.com/rs/xlog","last_synced_at":"2025-04-09T14:06:47.158Z","repository":{"id":57481146,"uuid":"44735328","full_name":"rs/xlog","owner":"rs","description":"xlog is a logger for net/context aware HTTP applications","archived":false,"fork":false,"pushed_at":"2024-07-04T09:49:19.000Z","size":147,"stargazers_count":138,"open_issues_count":3,"forks_count":12,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-04-02T11:08:24.936Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-10-22T09:26:45.000Z","updated_at":"2025-03-01T14:57:44.000Z","dependencies_parsed_at":"2024-10-16T12:41:27.578Z","dependency_job_id":"220f612b-8cc8-4c82-a011-09135c6c4d37","html_url":"https://github.com/rs/xlog","commit_stats":{"total_commits":105,"total_committers":11,"mean_commits":9.545454545454545,"dds":"0.20952380952380956","last_synced_commit":"131980fab91b04c953b9dcb438298a7f06cf76cb"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rs%2Fxlog","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rs%2Fxlog/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rs%2Fxlog/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rs%2Fxlog/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rs","download_url":"https://codeload.github.com/rs/xlog/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248054223,"owners_count":21039952,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-30T20:01:38.044Z","updated_at":"2025-04-09T14:06:47.130Z","avatar_url":"https://github.com/rs.png","language":"Go","readme":":warning: **Check [zerolog](https://github.com/rs/zerolog), the successor of xlog.**\n\n\n# HTTP Handler Logger\n\n[![godoc](http://img.shields.io/badge/godoc-reference-blue.svg?style=flat)](https://godoc.org/github.com/rs/xlog) [![license](http://img.shields.io/badge/license-MIT-red.svg?style=flat)](https://raw.githubusercontent.com/rs/xlog/master/LICENSE) [![Build Status](https://travis-ci.org/rs/xlog.svg?branch=master)](https://travis-ci.org/rs/xlog) [![Coverage](http://gocover.io/_badge/github.com/rs/xlog)](http://gocover.io/github.com/rs/xlog)\n\n`xlog` is a logger for [net/context](https://godoc.org/golang.org/x/net/context) aware HTTP applications.\n\nUnlike 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.\n\nRead more about `xlog` on [Dailymotion engineering blog](http://engineering.dailymotion.com/our-way-to-go/).\n\n![](screenshot.png)\n\n## Features\n\n- Per request log context\n- Per request and/or per message key/value fields\n- Log levels (Debug, Info, Warn, Error)\n- Color output when terminal is detected\n- Custom output (JSON, [logfmt](https://github.com/kr/logfmt), …)\n- Automatic gathering of request context like User-Agent, IP etc.\n- Drops message rather than blocking execution\n- Easy access logging thru [github.com/rs/xaccess](https://github.com/rs/xaccess)\n\nWorks with both Go 1.7+ (with `net/context` support) and Go 1.6 if used with [github.com/rs/xhandler](https://github.com/rs/xhandler).\n\n## Install\n\n    go get github.com/rs/xlog\n\n## Usage\n\n```go\nc := alice.New()\n\nhost, _ := os.Hostname()\nconf := xlog.Config{\n    // Log info level and higher\n    Level: xlog.LevelInfo,\n    // Set some global env fields\n    Fields: xlog.F{\n        \"role\": \"my-service\",\n        \"host\": host,\n    },\n    // Output everything on console\n    Output: xlog.NewOutputChannel(xlog.NewConsoleOutput()),\n}\n\n// Install the logger handler\nc = c.Append(xlog.NewHandler(conf))\n\n// Optionally plug the xlog handler's input to Go's default logger\nlog.SetFlags(0)\nxlogger := xlog.New(conf)\nlog.SetOutput(xlogger)\n\n// Install some provided extra handler to set some request's context fields.\n// Thanks to those handler, all our logs will come with some pre-populated fields.\nc = c.Append(xlog.MethodHandler(\"method\"))\nc = c.Append(xlog.URLHandler(\"url\"))\nc = c.Append(xlog.RemoteAddrHandler(\"ip\"))\nc = c.Append(xlog.UserAgentHandler(\"user_agent\"))\nc = c.Append(xlog.RefererHandler(\"referer\"))\nc = c.Append(xlog.RequestIDHandler(\"req_id\", \"Request-Id\"))\n\n// Here is your final handler\nh := c.Then(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n    // Get the logger from the request's context. You can safely assume it\n    // will be always there: if the handler is removed, xlog.FromContext\n    // will return a NopLogger\n    l := xlog.FromRequest(r)\n\n    // Then log some errors\n    if err := errors.New(\"some error from elsewhere\"); err != nil {\n        l.Errorf(\"Here is an error: %v\", err)\n    }\n\n    // Or some info with fields\n    l.Info(\"Something happend\", xlog.F{\n        \"user\":   \"current user id\",\n        \"status\": \"ok\",\n    })\n    // Output:\n    // {\n    //   \"message\": \"Something happend\",\n    //   \"level\": \"info\",\n    //   \"file\": \"main.go:34\",\n    //   \"time\": time.Time{...},\n    //   \"user\": \"current user id\",\n    //   \"status\": \"ok\",\n    //   \"ip\": \"1.2.3.4\",\n    //   \"user-agent\": \"Mozilla/1.2.3...\",\n    //   \"referer\": \"http://somewhere.com/path\",\n    //   \"role\": \"my-service\",\n    //   \"host\": \"somehost\"\n    // }\n}))\nhttp.Handle(\"/\", h)\n\nif err := http.ListenAndServe(\":8080\", nil); err != nil {\n    xlogger.Fatal(err)\n}\n```\n\n### Copy Logger\n\nYou may want to get a copy of the current logger to pass a modified version to a function without touching the original:\n\n```go\nl := xlog.FromContext(ctx)\nl2 := xlog.Copy(l)\nl2.SetField(\"foo\", \"bar\")\n```\n\nMake 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:\n\n```go\nl := xlog.FromContext(ctx)\nl2 := xlog.Copy(l)\ngo func() {\n    // use the safe copy\n    l2.Info(\"something\")\n}()\n```\n\n### Global Logger\n\nYou may use the standard Go logger and plug `xlog` as it's output as `xlog` implements `io.Writer`:\n\n```go\nxlogger := xlog.New(conf)\nlog.SetOutput(xlogger)\n```\n\nThis 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.\n\nAnother option for code you manage but which is outside of a HTTP request handler is to use the `xlog` provided default logger:\n\n```go\nxlog.Debugf(\"some message with %s\", variable, xlog.F{\"and\": \"field support\"})\n```\n\nThis 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:\n\n```go\nxlog.SetLogger(xlog.New(xlog.Config{\n    Level: xlog.LevelInfo,\n    Output: xlog.NewConsoleOutput(),\n    Fields: xlog.F{\n        \"role\": \"my-service\",\n    },\n}))\n```\n\n### Configure Output\n\nBy default, output is setup to output debug and info message on `STDOUT` and warning and errors to `STDERR`. You can easily change this setup.\n\nXLog output can be customized using composable output handlers. Thanks to the [LevelOutput](https://godoc.org/github.com/rs/xlog#LevelOutput), [MultiOutput](https://godoc.org/github.com/rs/xlog#MultiOutput) and [FilterOutput](https://godoc.org/github.com/rs/xlog#FilterOutput), it is easy to route messages precisely.\n\n```go\nconf := xlog.Config{\n    Output: xlog.NewOutputChannel(xlog.MultiOutput{\n        // Send all logs with field type=mymodule to a remote syslog\n        0: xlog.FilterOutput{\n            Cond: func(fields map[string]interface{}) bool {\n                return fields[\"type\"] == \"mymodule\"\n            },\n            Output: xlog.NewSyslogOutput(\"tcp\", \"1.2.3.4:1234\", \"mymodule\"),\n        },\n        // Setup different output per log level\n        1: xlog.LevelOutput{\n            // Send errors to the console\n            Error: xlog.NewConsoleOutput(),\n            // Send syslog output for error level\n            Info: xlog.NewSyslogOutput(\"\", \"\", \"\"),\n        },\n    }),\n})\n\nh = xlog.NewHandler(conf)\n```\n\n#### Built-in Output Modules\n\n| Name | Description |\n|------|-------------|\n| [OutputChannel](https://godoc.org/github.com/rs/xlog#OutputChannel) | Buffers messages before sending. This output should always be the output directly set to xlog's configuration.\n| [MultiOutput](https://godoc.org/github.com/rs/xlog#MultiOutput) | Routes the same message to several outputs. If one or more outputs return error, the last error is returned.\n| [FilterOutput](https://godoc.org/github.com/rs/xlog#FilterOutput) | Tests a condition on the message and forward it to the child output if true.\n| [LevelOutput](https://godoc.org/github.com/rs/xlog#LevelOutput) | Routes messages per level outputs.\n| [ConsoleOutput](https://godoc.org/github.com/rs/xlog#NewConsoleOutput) | 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.\n| [JSONOutput](https://godoc.org/github.com/rs/xlog#NewJSONOutput) | Serialize messages in JSON.\n| [LogfmtOutput](https://godoc.org/github.com/rs/xlog#NewLogfmtOutput) | Serialize messages using Heroku like [logfmt](https://github.com/kr/logfmt).\n| [LogstashOutput](https://godoc.org/github.com/rs/xlog#NewLogstashOutput) | Serialize JSON message using Logstash 2.0 (schema v1) structured format.\n| [SyslogOutput](https://godoc.org/github.com/rs/xlog#NewSyslogOutput) | Send messages to syslog.\n| [UIDOutput](https://godoc.org/github.com/rs/xlog#NewUIDOutput) | Append a globally unique id to every message and forward it to the next output.\n\n## Third Party Extensions\n\n| Project | Author | Description |\n|---------|--------|-------------|\n| [gRPClog](https://github.com/clawio/grpcxlog) | [Hugo González Labrador](https://github.com/labkode) | An adapter to use xlog as the logger for grpclog.\n| [xlog-nsq](https://github.com/rs/xlog-nsq) | [Olivier Poitrey](https://github.com/rs) | An xlog to [NSQ](http://nsq.io) output.\n| [xlog-sentry](https://github.com/trong/xlog-sentry) | [trong](https://github.com/trong) | An xlog to [Sentry](https://getsentry.com/) output.\n\n## Licenses\n\nAll source code is licensed under the [MIT License](https://raw.github.com/rs/xlog/master/LICENSE).\n","funding_links":[],"categories":["Logging","Logging 日志库","\u003cspan id=\"日志-logging\"\u003e日志 Logging\u003c/span\u003e","日志记录","日志","Relational Databases","日誌"],"sub_categories":["Search and Analytic Databases","Advanced Console UIs","SQL 查询语句构建库","\u003cspan id=\"高级控制台用户界面-advanced-console-uis\"\u003e高级控制台用户界面 Advanced Console UIs\u003c/span\u003e","检索及分析资料库","高级控制台界面","交流","高級控制台界面"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frs%2Fxlog","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frs%2Fxlog","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frs%2Fxlog/lists"}