forked from mirror/logrus
readme: update
This commit is contained in:
parent
f803b61ca1
commit
52eb6b2fe6
171
README.md
171
README.md
|
@ -1,75 +1,132 @@
|
||||||
# Logrus
|
# Logrus
|
||||||
|
|
||||||
Logrus is a simple, opinionated logging package for Go. Features include:
|
Logrus is a simple, opinionated logging package for Go which is completely API
|
||||||
|
compatible with the standard library logger. It has six logging levels: Debug,
|
||||||
|
Info, Warn, Error, Fatal and Panic. It supports custom logging formatters, and
|
||||||
|
ships with JSON and nicely formatted text by default. It encourages the use of
|
||||||
|
logging key value pairs for discoverability. Logrus allows you to add hooks to
|
||||||
|
logging events at different levels, for instance to notify an external error
|
||||||
|
tracker.
|
||||||
|
|
||||||
* **Level logging**. Logrus has the levels: Debug, Info, Warning and Fatal.
|
#### Fields
|
||||||
* **Exceptions**. Warnings will log as an exception along with logging it to
|
|
||||||
out, without quitting. Fatal will do the same, but call `os.Exit(1)` after
|
|
||||||
emitting the exception.
|
|
||||||
* **JSON**. Logrus currently logs as JSON by default.
|
|
||||||
|
|
||||||
The API is completely compatible with the Go standard lib logger, with only the
|
Logrus encourages careful, informative logging. It encourages the use of logging
|
||||||
features above added.
|
fields, instead of long, unparseable error messages. For example, instead of:
|
||||||
|
`log.Fatalf("Failed to send event %s to topic %s with key %d")`, you should log
|
||||||
## Motivation
|
the much more discoverable:
|
||||||
|
|
||||||
The motivation for this library came out of a pattern seen in Go applications me
|
|
||||||
and others have been writing with functions such as:
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func reportFatalError(err error) {
|
log = logrus.New()
|
||||||
airbrake.Notify(err)
|
log.WithFields(&logrus.Fields{
|
||||||
log.Fatal(err)
|
"event": event,
|
||||||
}
|
"topic": topic,
|
||||||
|
"key": key
|
||||||
|
}).Fatal("Failed to send event")
|
||||||
|
```
|
||||||
|
|
||||||
func reportWarning(err error) {
|
We've found this API forces you to think about logging in a way that produces
|
||||||
airbrake.Notify(err)
|
much more useful logging messages. The `WithFields` call is optional.
|
||||||
|
|
||||||
|
#### Hooks
|
||||||
|
|
||||||
|
You can add hooks for logging levels. For example to send errors, to an
|
||||||
|
exception tracking service:
|
||||||
|
|
||||||
|
```go
|
||||||
|
log.AddHook("error", func(entry logrus.Entry) {
|
||||||
|
err := airbrake.Notify(errors.New(entry.String()))
|
||||||
|
if err != nil {
|
||||||
|
log.WithFields(logrus.Fields{
|
||||||
|
"source": "airbrake",
|
||||||
|
"endpoint": airbrake.Endpoint,
|
||||||
|
}).Info("Failed to send error to Airbrake")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Errors
|
||||||
|
|
||||||
|
You can also use Logrus to return errors with fields. For instance:
|
||||||
|
|
||||||
|
```go
|
||||||
|
err := record.Destroy()
|
||||||
|
if err != nil {
|
||||||
|
return log.WithFields(&logrus.Fields{
|
||||||
|
"id": record.Id,
|
||||||
|
"method": "destroy"
|
||||||
|
}).AsError("Failed to destroy record")
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
JSON logging is excellent for parsing logs for analysis and troubleshooting.
|
Will return a `logrus.Error` object. Passing it to
|
||||||
It's supported natively by log aggregators such as logstash and Splunk. Logging
|
`log.{Info,Warn,Error,Fatal,Panic}` will log it according to the formatter set
|
||||||
JSON with logrus with the `WithFields` and `WithField` API in logrus forces you
|
for the environment.
|
||||||
to think about what context to log, to provide valuable troubleshoot information
|
|
||||||
later.
|
|
||||||
|
|
||||||
## Example
|
#### Level logging
|
||||||
|
|
||||||
|
Logrus has six levels: Debug, Info, Warning, Error, Fatal and Panic.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
log.Info("Something noteworthy happened!")
|
||||||
"github.com/Sirupsen/logrus"
|
log.Warn("You should probably take a look at this.")
|
||||||
)
|
log.Error("Something failed but I'm not quitting.")
|
||||||
|
log.Fatal("Bye.")
|
||||||
|
log.Panic("I'm bailing.")
|
||||||
|
```
|
||||||
|
|
||||||
var logger logrus.New()
|
#### Entries
|
||||||
func main() {
|
|
||||||
logger.WithFields(Fields{
|
|
||||||
"animal": "walrus",
|
|
||||||
"location": "New York Aquarium",
|
|
||||||
"weather": "rain",
|
|
||||||
"name": "Wally",
|
|
||||||
"event": "escape",
|
|
||||||
}).Info("Walrus has escaped the aquarium! Action required!")
|
|
||||||
// {
|
|
||||||
// "level": "info",
|
|
||||||
// "animal": "walrus",
|
|
||||||
// "location": "New York Aquarium",
|
|
||||||
// "weather":"rain",
|
|
||||||
// "name": "Wally",
|
|
||||||
// "event":"escape",
|
|
||||||
// "msg": "Walrus has escaped the aquarium! Action required!")
|
|
||||||
// "time": "2014-02-23 19:57:35.862271048 -0500 EST"
|
|
||||||
// }
|
|
||||||
|
|
||||||
logger.WithField("source", "kafka").Infof("Connection to Kafka failed with %s", "some error")
|
Besides the fields added with `WithField` or `WithFields` some fields are
|
||||||
// {
|
automatically added to all logging events:
|
||||||
// "level": "info",
|
|
||||||
// "source": "kafka",
|
1. `time`. The timestamp when the entry was created.
|
||||||
// "msg": "Connection to Kafka failed with some error",
|
2. `msg`. The logging message passed to `{Info,Warn,Error,Fatal,Panic}` after
|
||||||
// "time": "2014-02-23 19:57:35.862271048 -0500 EST"
|
the `AddFields` call. E.g. `Failed to send event.`
|
||||||
// }
|
3. `level`. The logging level. E.g. `info`.
|
||||||
|
4. `file`. The file (and line) where the logging entry was created. E.g.,
|
||||||
|
`main.go:82`.
|
||||||
|
|
||||||
|
#### Environments
|
||||||
|
|
||||||
|
Logrus has no notion of environment. If you wish for hooks and formatters to
|
||||||
|
only be used in specific environments, you should handle that yourself. For
|
||||||
|
example, if your application has a global variable `Environment`, which is a
|
||||||
|
string representation of the environment you could do:
|
||||||
|
|
||||||
|
```go
|
||||||
|
init() {
|
||||||
|
// do something here to set environment depending on an environment variable
|
||||||
|
// or command-line flag
|
||||||
|
|
||||||
|
if Environment == "production" {
|
||||||
|
log.SetFormatter(logrus.JSONFormatter)
|
||||||
|
} else {
|
||||||
|
// The TextFormatter is default, you don't actually have to do this.
|
||||||
|
log.SetFormatter(logrus.TextFormatter)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Using `Warning` and `Fatal` to log to `airbrake` requires setting
|
#### Formats
|
||||||
`airbrake.Endpoint` and `airbrake.ApiKey`. See
|
|
||||||
[tobi/airbrake-go](https://github.com/tobi/airbrake-go).
|
The built in logging formatters are:
|
||||||
|
|
||||||
|
* `logrus.TextFormatter`. Logs the event in colors if stdout is a tty, otherwise
|
||||||
|
without colors. Default for the development environment. <screenshot>
|
||||||
|
* `logrus.JSONFormatter`. Default for the production environment. <screnshot>
|
||||||
|
|
||||||
|
You can define your formatter taking an entry. `entry.Data` is a `Fields` type
|
||||||
|
which is a `map[string]interface{}` with all your fields as well as the default
|
||||||
|
ones (see Entries above):
|
||||||
|
|
||||||
|
```go
|
||||||
|
log.SetFormatter(func(entry *logrus.Entry) {
|
||||||
|
serialized, err = json.Marshal(entry.Data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, log.WithFields(&logrus.Fields{
|
||||||
|
"source": "log formatter",
|
||||||
|
"entry": entry.Data
|
||||||
|
}).AsError("Failed to serialize log entry to JSON")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
Loading…
Reference in New Issue