mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-23 03:17:43 +08:00
Merge pull request #1889 from ipfs/fix/log-writer
fix bug in mirrorwriter removal
This commit is contained in:
commit
bf415b0dff
11
Godeps/Godeps.json
generated
11
Godeps/Godeps.json
generated
@ -14,11 +14,6 @@
|
||||
"Comment": "null-5",
|
||||
"Rev": "75cd24fc2f2c2a2088577d12123ddee5f54e0675"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/Sirupsen/logrus",
|
||||
"Comment": "v0.7.3-2-g26709e2",
|
||||
"Rev": "26709e2714106fb8ad40b773b711ebce25b78914"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/alecthomas/kingpin",
|
||||
"Comment": "v2.1.0-2-gaedd543",
|
||||
@ -138,7 +133,7 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/ipfs/go-log",
|
||||
"Rev": "ee5cb9834b33bcf29689183e0323e328c8b8de29"
|
||||
"Rev": "bf32e06c2f9c81eb33460bc08305aa946f0d893d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/jackpal/go-nat-pmp",
|
||||
@ -322,6 +317,10 @@
|
||||
"ImportPath": "github.com/whyrusleeping/chunker",
|
||||
"Rev": "537e901819164627ca4bb5ce4e3faa8ce7956564"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/whyrusleeping/go-logging",
|
||||
"Rev": "128b9855511a4ea3ccbcf712695baf2bab72e134"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/whyrusleeping/go-metrics",
|
||||
"Rev": "1cd8009604ec2238b5a71305a0ecd974066e0e16"
|
||||
|
||||
1
Godeps/_workspace/src/github.com/Sirupsen/logrus/.gitignore
generated
vendored
1
Godeps/_workspace/src/github.com/Sirupsen/logrus/.gitignore
generated
vendored
@ -1 +0,0 @@
|
||||
logrus
|
||||
8
Godeps/_workspace/src/github.com/Sirupsen/logrus/.travis.yml
generated
vendored
8
Godeps/_workspace/src/github.com/Sirupsen/logrus/.travis.yml
generated
vendored
@ -1,8 +0,0 @@
|
||||
language: go
|
||||
go:
|
||||
- 1.2
|
||||
- 1.3
|
||||
- 1.4
|
||||
- tip
|
||||
install:
|
||||
- go get -t ./...
|
||||
7
Godeps/_workspace/src/github.com/Sirupsen/logrus/CHANGELOG.md
generated
vendored
7
Godeps/_workspace/src/github.com/Sirupsen/logrus/CHANGELOG.md
generated
vendored
@ -1,7 +0,0 @@
|
||||
# 0.7.3
|
||||
|
||||
formatter/\*: allow configuration of timestamp layout
|
||||
|
||||
# 0.7.2
|
||||
|
||||
formatter/text: Add configuration option for time format (#158)
|
||||
21
Godeps/_workspace/src/github.com/Sirupsen/logrus/LICENSE
generated
vendored
21
Godeps/_workspace/src/github.com/Sirupsen/logrus/LICENSE
generated
vendored
@ -1,21 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Simon Eskildsen
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
349
Godeps/_workspace/src/github.com/Sirupsen/logrus/README.md
generated
vendored
349
Godeps/_workspace/src/github.com/Sirupsen/logrus/README.md
generated
vendored
@ -1,349 +0,0 @@
|
||||
# Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:"/> [](https://travis-ci.org/Sirupsen/logrus) [][godoc]
|
||||
|
||||
Logrus is a structured logger for Go (golang), completely API compatible with
|
||||
the standard library logger. [Godoc][godoc]. **Please note the Logrus API is not
|
||||
yet stable (pre 1.0). Logrus itself is completely stable and has been used in
|
||||
many large deployments. The core API is unlikely to change much but please
|
||||
version control your Logrus to make sure you aren't fetching latest `master` on
|
||||
every build.**
|
||||
|
||||
Nicely color-coded in development (when a TTY is attached, otherwise just
|
||||
plain text):
|
||||
|
||||

|
||||
|
||||
With `log.Formatter = new(logrus.JSONFormatter)`, for easy parsing by logstash
|
||||
or Splunk:
|
||||
|
||||
```json
|
||||
{"animal":"walrus","level":"info","msg":"A group of walrus emerges from the
|
||||
ocean","size":10,"time":"2014-03-10 19:57:38.562264131 -0400 EDT"}
|
||||
|
||||
{"level":"warning","msg":"The group's number increased tremendously!",
|
||||
"number":122,"omg":true,"time":"2014-03-10 19:57:38.562471297 -0400 EDT"}
|
||||
|
||||
{"animal":"walrus","level":"info","msg":"A giant walrus appears!",
|
||||
"size":10,"time":"2014-03-10 19:57:38.562500591 -0400 EDT"}
|
||||
|
||||
{"animal":"walrus","level":"info","msg":"Tremendously sized cow enters the ocean.",
|
||||
"size":9,"time":"2014-03-10 19:57:38.562527896 -0400 EDT"}
|
||||
|
||||
{"level":"fatal","msg":"The ice breaks!","number":100,"omg":true,
|
||||
"time":"2014-03-10 19:57:38.562543128 -0400 EDT"}
|
||||
```
|
||||
|
||||
With the default `log.Formatter = new(logrus.TextFormatter)` when a TTY is not
|
||||
attached, the output is compatible with the
|
||||
[logfmt](http://godoc.org/github.com/kr/logfmt) format:
|
||||
|
||||
```text
|
||||
time="2015-03-26T01:27:38-04:00" level=debug msg="Started observing beach" animal=walrus number=8
|
||||
time="2015-03-26T01:27:38-04:00" level=info msg="A group of walrus emerges from the ocean" animal=walrus size=10
|
||||
time="2015-03-26T01:27:38-04:00" level=warning msg="The group's number increased tremendously!" number=122 omg=true
|
||||
time="2015-03-26T01:27:38-04:00" level=debug msg="Temperature changes" temperature=-4
|
||||
time="2015-03-26T01:27:38-04:00" level=panic msg="It's over 9000!" animal=orca size=9009
|
||||
time="2015-03-26T01:27:38-04:00" level=fatal msg="The ice breaks!" err=&{0x2082280c0 map[animal:orca size:9009] 2015-03-26 01:27:38.441574009 -0400 EDT panic It's over 9000!} number=100 omg=true
|
||||
exit status 1
|
||||
```
|
||||
|
||||
#### Example
|
||||
|
||||
The simplest way to use Logrus is simply the package-level exported logger:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
log "github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
func main() {
|
||||
log.WithFields(log.Fields{
|
||||
"animal": "walrus",
|
||||
}).Info("A walrus appears")
|
||||
}
|
||||
```
|
||||
|
||||
Note that it's completely api-compatible with the stdlib logger, so you can
|
||||
replace your `log` imports everywhere with `log "github.com/Sirupsen/logrus"`
|
||||
and you'll now have the flexibility of Logrus. You can customize it all you
|
||||
want:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/Sirupsen/logrus/hooks/airbrake"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Log as JSON instead of the default ASCII formatter.
|
||||
log.SetFormatter(&log.JSONFormatter{})
|
||||
|
||||
// Use the Airbrake hook to report errors that have Error severity or above to
|
||||
// an exception tracker. You can create custom hooks, see the Hooks section.
|
||||
log.AddHook(airbrake.NewHook("https://example.com", "xyz", "development"))
|
||||
|
||||
// Output to stderr instead of stdout, could also be a file.
|
||||
log.SetOutput(os.Stderr)
|
||||
|
||||
// Only log the warning severity or above.
|
||||
log.SetLevel(log.WarnLevel)
|
||||
}
|
||||
|
||||
func main() {
|
||||
log.WithFields(log.Fields{
|
||||
"animal": "walrus",
|
||||
"size": 10,
|
||||
}).Info("A group of walrus emerges from the ocean")
|
||||
|
||||
log.WithFields(log.Fields{
|
||||
"omg": true,
|
||||
"number": 122,
|
||||
}).Warn("The group's number increased tremendously!")
|
||||
|
||||
log.WithFields(log.Fields{
|
||||
"omg": true,
|
||||
"number": 100,
|
||||
}).Fatal("The ice breaks!")
|
||||
|
||||
// A common pattern is to re-use fields between logging statements by re-using
|
||||
// the logrus.Entry returned from WithFields()
|
||||
contextLogger := log.WithFields(log.Fields{
|
||||
"common": "this is a common field",
|
||||
"other": "I also should be logged always",
|
||||
})
|
||||
|
||||
contextLogger.Info("I'll be logged with common and other field")
|
||||
contextLogger.Info("Me too")
|
||||
}
|
||||
```
|
||||
|
||||
For more advanced usage such as logging to multiple locations from the same
|
||||
application, you can also create an instance of the `logrus` Logger:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Create a new instance of the logger. You can have any number of instances.
|
||||
var log = logrus.New()
|
||||
|
||||
func main() {
|
||||
// The API for setting attributes is a little different than the package level
|
||||
// exported logger. See Godoc.
|
||||
log.Out = os.Stderr
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"animal": "walrus",
|
||||
"size": 10,
|
||||
}).Info("A group of walrus emerges from the ocean")
|
||||
}
|
||||
```
|
||||
|
||||
#### Fields
|
||||
|
||||
Logrus encourages careful, structured logging though logging 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 the much more
|
||||
discoverable:
|
||||
|
||||
```go
|
||||
log.WithFields(log.Fields{
|
||||
"event": event,
|
||||
"topic": topic,
|
||||
"key": key,
|
||||
}).Fatal("Failed to send event")
|
||||
```
|
||||
|
||||
We've found this API forces you to think about logging in a way that produces
|
||||
much more useful logging messages. We've been in countless situations where just
|
||||
a single added field to a log statement that was already there would've saved us
|
||||
hours. The `WithFields` call is optional.
|
||||
|
||||
In general, with Logrus using any of the `printf`-family functions should be
|
||||
seen as a hint you should add a field, however, you can still use the
|
||||
`printf`-family functions with Logrus.
|
||||
|
||||
#### Hooks
|
||||
|
||||
You can add hooks for logging levels. For example to send errors to an exception
|
||||
tracking service on `Error`, `Fatal` and `Panic`, info to StatsD or log to
|
||||
multiple places simultaneously, e.g. syslog.
|
||||
|
||||
Logrus comes with [built-in hooks](hooks/). Add those, or your custom hook, in
|
||||
`init`:
|
||||
|
||||
```go
|
||||
import (
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/Sirupsen/logrus/hooks/airbrake"
|
||||
"github.com/Sirupsen/logrus/hooks/syslog"
|
||||
"log/syslog"
|
||||
)
|
||||
|
||||
func init() {
|
||||
log.AddHook(airbrake.NewHook("https://example.com", "xyz", "development"))
|
||||
|
||||
hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
|
||||
if err != nil {
|
||||
log.Error("Unable to connect to local syslog daemon")
|
||||
} else {
|
||||
log.AddHook(hook)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
| Hook | Description |
|
||||
| ----- | ----------- |
|
||||
| [Airbrake](https://github.com/Sirupsen/logrus/blob/master/hooks/airbrake/airbrake.go) | Send errors to an exception tracking service compatible with the Airbrake API. Uses [`airbrake-go`](https://github.com/tobi/airbrake-go) behind the scenes. |
|
||||
| [Papertrail](https://github.com/Sirupsen/logrus/blob/master/hooks/papertrail/papertrail.go) | Send errors to the Papertrail hosted logging service via UDP. |
|
||||
| [Syslog](https://github.com/Sirupsen/logrus/blob/master/hooks/syslog/syslog.go) | Send errors to remote syslog server. Uses standard library `log/syslog` behind the scenes. |
|
||||
| [BugSnag](https://github.com/Sirupsen/logrus/blob/master/hooks/bugsnag/bugsnag.go) | Send errors to the Bugsnag exception tracking service. |
|
||||
| [Hiprus](https://github.com/nubo/hiprus) | Send errors to a channel in hipchat. |
|
||||
| [Logrusly](https://github.com/sebest/logrusly) | Send logs to [Loggly](https://www.loggly.com/) |
|
||||
| [Slackrus](https://github.com/johntdyer/slackrus) | Hook for Slack chat. |
|
||||
| [Journalhook](https://github.com/wercker/journalhook) | Hook for logging to `systemd-journald` |
|
||||
| [Graylog](https://github.com/gemnasium/logrus-hooks/tree/master/graylog) | Hook for logging to [Graylog](http://graylog2.org/) |
|
||||
|
||||
#### Level logging
|
||||
|
||||
Logrus has six logging levels: Debug, Info, Warning, Error, Fatal and Panic.
|
||||
|
||||
```go
|
||||
log.Debug("Useful debugging information.")
|
||||
log.Info("Something noteworthy happened!")
|
||||
log.Warn("You should probably take a look at this.")
|
||||
log.Error("Something failed but I'm not quitting.")
|
||||
// Calls os.Exit(1) after logging
|
||||
log.Fatal("Bye.")
|
||||
// Calls panic() after logging
|
||||
log.Panic("I'm bailing.")
|
||||
```
|
||||
|
||||
You can set the logging level on a `Logger`, then it will only log entries with
|
||||
that severity or anything above it:
|
||||
|
||||
```go
|
||||
// Will log anything that is info or above (warn, error, fatal, panic). Default.
|
||||
log.SetLevel(log.InfoLevel)
|
||||
```
|
||||
|
||||
It may be useful to set `log.Level = logrus.DebugLevel` in a debug or verbose
|
||||
environment if your application has that.
|
||||
|
||||
#### Entries
|
||||
|
||||
Besides the fields added with `WithField` or `WithFields` some fields are
|
||||
automatically added to all logging events:
|
||||
|
||||
1. `time`. The timestamp when the entry was created.
|
||||
2. `msg`. The logging message passed to `{Info,Warn,Error,Fatal,Panic}` after
|
||||
the `AddFields` call. E.g. `Failed to send event.`
|
||||
3. `level`. The logging level. E.g. `info`.
|
||||
|
||||
#### 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
|
||||
import (
|
||||
log "github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This configuration is how `logrus` was intended to be used, but JSON in
|
||||
production is mostly only useful if you do log aggregation with tools like
|
||||
Splunk or Logstash.
|
||||
|
||||
#### Formatters
|
||||
|
||||
The built-in logging formatters are:
|
||||
|
||||
* `logrus.TextFormatter`. Logs the event in colors if stdout is a tty, otherwise
|
||||
without colors.
|
||||
* *Note:* to force colored output when there is no TTY, set the `ForceColors`
|
||||
field to `true`. To force no colored output even if there is a TTY set the
|
||||
`DisableColors` field to `true`
|
||||
* `logrus.JSONFormatter`. Logs fields as JSON.
|
||||
* `logrus_logstash.LogstashFormatter`. Logs fields as Logstash Events (http://logstash.net).
|
||||
|
||||
```go
|
||||
logrus.SetFormatter(&logrus_logstash.LogstashFormatter{Type: “application_name"})
|
||||
```
|
||||
|
||||
Third party logging formatters:
|
||||
|
||||
* [`zalgo`](https://github.com/aybabtme/logzalgo): invoking the P͉̫o̳̼̊w̖͈̰͎e̬͔̭͂r͚̼̹̲ ̫͓͉̳͈ō̠͕͖̚f̝͍̠ ͕̲̞͖͑Z̖̫̤̫ͪa͉̬͈̗l͖͎g̳̥o̰̥̅!̣͔̲̻͊̄ ̙̘̦̹̦.
|
||||
|
||||
You can define your formatter by implementing the `Formatter` interface,
|
||||
requiring a `Format` method. `Format` takes an `*Entry`. `entry.Data` is a
|
||||
`Fields` type (`map[string]interface{}`) with all your fields as well as the
|
||||
default ones (see Entries section above):
|
||||
|
||||
```go
|
||||
type MyJSONFormatter struct {
|
||||
}
|
||||
|
||||
log.SetFormatter(new(MyJSONFormatter))
|
||||
|
||||
func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
||||
// Note this doesn't include Time, Level and Message which are available on
|
||||
// the Entry. Consult `godoc` on information about those fields or read the
|
||||
// source of the official loggers.
|
||||
serialized, err := json.Marshal(entry.Data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
|
||||
}
|
||||
return append(serialized, '\n'), nil
|
||||
}
|
||||
```
|
||||
|
||||
#### Logger as an `io.Writer`
|
||||
|
||||
Logrus can be transormed into an `io.Writer`. That writer is the end of an `io.Pipe` and it is your responsibility to close it.
|
||||
|
||||
```go
|
||||
w := logger.Writer()
|
||||
defer w.Close()
|
||||
|
||||
srv := http.Server{
|
||||
// create a stdlib log.Logger that writes to
|
||||
// logrus.Logger.
|
||||
ErrorLog: log.New(w, "", 0),
|
||||
}
|
||||
```
|
||||
|
||||
Each line written to that writer will be printed the usual way, using formatters
|
||||
and hooks. The level for those entries is `info`.
|
||||
|
||||
#### Rotation
|
||||
|
||||
Log rotation is not provided with Logrus. Log rotation should be done by an
|
||||
external program (like `logrotate(8)`) that can compress and delete old log
|
||||
entries. It should not be a feature of the application-level logger.
|
||||
|
||||
|
||||
[godoc]: https://godoc.org/github.com/Sirupsen/logrus
|
||||
252
Godeps/_workspace/src/github.com/Sirupsen/logrus/entry.go
generated
vendored
252
Godeps/_workspace/src/github.com/Sirupsen/logrus/entry.go
generated
vendored
@ -1,252 +0,0 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
// An entry is the final or intermediate Logrus logging entry. It contains all
|
||||
// the fields passed with WithField{,s}. It's finally logged when Debug, Info,
|
||||
// Warn, Error, Fatal or Panic is called on it. These objects can be reused and
|
||||
// passed around as much as you wish to avoid field duplication.
|
||||
type Entry struct {
|
||||
Logger *Logger
|
||||
|
||||
// Contains all the fields set by the user.
|
||||
Data Fields
|
||||
|
||||
// Time at which the log entry was created
|
||||
Time time.Time
|
||||
|
||||
// Level the log entry was logged at: Debug, Info, Warn, Error, Fatal or Panic
|
||||
Level Level
|
||||
|
||||
// Message passed to Debug, Info, Warn, Error, Fatal or Panic
|
||||
Message string
|
||||
}
|
||||
|
||||
func NewEntry(logger *Logger) *Entry {
|
||||
return &Entry{
|
||||
Logger: logger,
|
||||
// Default is three fields, give a little extra room
|
||||
Data: make(Fields, 5),
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a reader for the entry, which is a proxy to the formatter.
|
||||
func (entry *Entry) Reader() (*bytes.Buffer, error) {
|
||||
serialized, err := entry.Logger.Formatter.Format(entry)
|
||||
return bytes.NewBuffer(serialized), err
|
||||
}
|
||||
|
||||
// Returns the string representation from the reader and ultimately the
|
||||
// formatter.
|
||||
func (entry *Entry) String() (string, error) {
|
||||
reader, err := entry.Reader()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return reader.String(), err
|
||||
}
|
||||
|
||||
// Add a single field to the Entry.
|
||||
func (entry *Entry) WithField(key string, value interface{}) *Entry {
|
||||
return entry.WithFields(Fields{key: value})
|
||||
}
|
||||
|
||||
// Add a map of fields to the Entry.
|
||||
func (entry *Entry) WithFields(fields Fields) *Entry {
|
||||
data := Fields{}
|
||||
for k, v := range entry.Data {
|
||||
data[k] = v
|
||||
}
|
||||
for k, v := range fields {
|
||||
data[k] = v
|
||||
}
|
||||
return &Entry{Logger: entry.Logger, Data: data}
|
||||
}
|
||||
|
||||
func (entry *Entry) log(level Level, msg string) {
|
||||
entry.Time = time.Now()
|
||||
entry.Level = level
|
||||
entry.Message = msg
|
||||
|
||||
if err := entry.Logger.Hooks.Fire(level, entry); err != nil {
|
||||
entry.Logger.mu.Lock()
|
||||
fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err)
|
||||
entry.Logger.mu.Unlock()
|
||||
}
|
||||
|
||||
reader, err := entry.Reader()
|
||||
if err != nil {
|
||||
entry.Logger.mu.Lock()
|
||||
fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err)
|
||||
entry.Logger.mu.Unlock()
|
||||
}
|
||||
|
||||
entry.Logger.mu.Lock()
|
||||
defer entry.Logger.mu.Unlock()
|
||||
|
||||
_, err = io.Copy(entry.Logger.Out, reader)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err)
|
||||
}
|
||||
|
||||
// To avoid Entry#log() returning a value that only would make sense for
|
||||
// panic() to use in Entry#Panic(), we avoid the allocation by checking
|
||||
// directly here.
|
||||
if level <= PanicLevel {
|
||||
panic(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Debug(args ...interface{}) {
|
||||
if entry.Logger.Level >= DebugLevel {
|
||||
entry.log(DebugLevel, fmt.Sprint(args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Print(args ...interface{}) {
|
||||
entry.Info(args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Info(args ...interface{}) {
|
||||
if entry.Logger.Level >= InfoLevel {
|
||||
entry.log(InfoLevel, fmt.Sprint(args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Warn(args ...interface{}) {
|
||||
if entry.Logger.Level >= WarnLevel {
|
||||
entry.log(WarnLevel, fmt.Sprint(args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Warning(args ...interface{}) {
|
||||
entry.Warn(args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Error(args ...interface{}) {
|
||||
if entry.Logger.Level >= ErrorLevel {
|
||||
entry.log(ErrorLevel, fmt.Sprint(args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Fatal(args ...interface{}) {
|
||||
if entry.Logger.Level >= FatalLevel {
|
||||
entry.log(FatalLevel, fmt.Sprint(args...))
|
||||
}
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func (entry *Entry) Panic(args ...interface{}) {
|
||||
if entry.Logger.Level >= PanicLevel {
|
||||
entry.log(PanicLevel, fmt.Sprint(args...))
|
||||
}
|
||||
panic(fmt.Sprint(args...))
|
||||
}
|
||||
|
||||
// Entry Printf family functions
|
||||
|
||||
func (entry *Entry) Debugf(format string, args ...interface{}) {
|
||||
if entry.Logger.Level >= DebugLevel {
|
||||
entry.Debug(fmt.Sprintf(format, args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Infof(format string, args ...interface{}) {
|
||||
if entry.Logger.Level >= InfoLevel {
|
||||
entry.Info(fmt.Sprintf(format, args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Printf(format string, args ...interface{}) {
|
||||
entry.Infof(format, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Warnf(format string, args ...interface{}) {
|
||||
if entry.Logger.Level >= WarnLevel {
|
||||
entry.Warn(fmt.Sprintf(format, args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Warningf(format string, args ...interface{}) {
|
||||
entry.Warnf(format, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Errorf(format string, args ...interface{}) {
|
||||
if entry.Logger.Level >= ErrorLevel {
|
||||
entry.Error(fmt.Sprintf(format, args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Fatalf(format string, args ...interface{}) {
|
||||
if entry.Logger.Level >= FatalLevel {
|
||||
entry.Fatal(fmt.Sprintf(format, args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Panicf(format string, args ...interface{}) {
|
||||
if entry.Logger.Level >= PanicLevel {
|
||||
entry.Panic(fmt.Sprintf(format, args...))
|
||||
}
|
||||
}
|
||||
|
||||
// Entry Println family functions
|
||||
|
||||
func (entry *Entry) Debugln(args ...interface{}) {
|
||||
if entry.Logger.Level >= DebugLevel {
|
||||
entry.Debug(entry.sprintlnn(args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Infoln(args ...interface{}) {
|
||||
if entry.Logger.Level >= InfoLevel {
|
||||
entry.Info(entry.sprintlnn(args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Println(args ...interface{}) {
|
||||
entry.Infoln(args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Warnln(args ...interface{}) {
|
||||
if entry.Logger.Level >= WarnLevel {
|
||||
entry.Warn(entry.sprintlnn(args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Warningln(args ...interface{}) {
|
||||
entry.Warnln(args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Errorln(args ...interface{}) {
|
||||
if entry.Logger.Level >= ErrorLevel {
|
||||
entry.Error(entry.sprintlnn(args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Fatalln(args ...interface{}) {
|
||||
if entry.Logger.Level >= FatalLevel {
|
||||
entry.Fatal(entry.sprintlnn(args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Panicln(args ...interface{}) {
|
||||
if entry.Logger.Level >= PanicLevel {
|
||||
entry.Panic(entry.sprintlnn(args...))
|
||||
}
|
||||
}
|
||||
|
||||
// Sprintlnn => Sprint no newline. This is to get the behavior of how
|
||||
// fmt.Sprintln where spaces are always added between operands, regardless of
|
||||
// their type. Instead of vendoring the Sprintln implementation to spare a
|
||||
// string allocation, we do the simplest thing.
|
||||
func (entry *Entry) sprintlnn(args ...interface{}) string {
|
||||
msg := fmt.Sprintln(args...)
|
||||
return msg[:len(msg)-1]
|
||||
}
|
||||
53
Godeps/_workspace/src/github.com/Sirupsen/logrus/entry_test.go
generated
vendored
53
Godeps/_workspace/src/github.com/Sirupsen/logrus/entry_test.go
generated
vendored
@ -1,53 +0,0 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestEntryPanicln(t *testing.T) {
|
||||
errBoom := fmt.Errorf("boom time")
|
||||
|
||||
defer func() {
|
||||
p := recover()
|
||||
assert.NotNil(t, p)
|
||||
|
||||
switch pVal := p.(type) {
|
||||
case *Entry:
|
||||
assert.Equal(t, "kaboom", pVal.Message)
|
||||
assert.Equal(t, errBoom, pVal.Data["err"])
|
||||
default:
|
||||
t.Fatalf("want type *Entry, got %T: %#v", pVal, pVal)
|
||||
}
|
||||
}()
|
||||
|
||||
logger := New()
|
||||
logger.Out = &bytes.Buffer{}
|
||||
entry := NewEntry(logger)
|
||||
entry.WithField("err", errBoom).Panicln("kaboom")
|
||||
}
|
||||
|
||||
func TestEntryPanicf(t *testing.T) {
|
||||
errBoom := fmt.Errorf("boom again")
|
||||
|
||||
defer func() {
|
||||
p := recover()
|
||||
assert.NotNil(t, p)
|
||||
|
||||
switch pVal := p.(type) {
|
||||
case *Entry:
|
||||
assert.Equal(t, "kaboom true", pVal.Message)
|
||||
assert.Equal(t, errBoom, pVal.Data["err"])
|
||||
default:
|
||||
t.Fatalf("want type *Entry, got %T: %#v", pVal, pVal)
|
||||
}
|
||||
}()
|
||||
|
||||
logger := New()
|
||||
logger.Out = &bytes.Buffer{}
|
||||
entry := NewEntry(logger)
|
||||
entry.WithField("err", errBoom).Panicf("kaboom %v", true)
|
||||
}
|
||||
50
Godeps/_workspace/src/github.com/Sirupsen/logrus/examples/basic/basic.go
generated
vendored
50
Godeps/_workspace/src/github.com/Sirupsen/logrus/examples/basic/basic.go
generated
vendored
@ -1,50 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
var log = logrus.New()
|
||||
|
||||
func init() {
|
||||
log.Formatter = new(logrus.JSONFormatter)
|
||||
log.Formatter = new(logrus.TextFormatter) // default
|
||||
log.Level = logrus.DebugLevel
|
||||
}
|
||||
|
||||
func main() {
|
||||
defer func() {
|
||||
err := recover()
|
||||
if err != nil {
|
||||
log.WithFields(logrus.Fields{
|
||||
"omg": true,
|
||||
"err": err,
|
||||
"number": 100,
|
||||
}).Fatal("The ice breaks!")
|
||||
}
|
||||
}()
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"animal": "walrus",
|
||||
"number": 8,
|
||||
}).Debug("Started observing beach")
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"animal": "walrus",
|
||||
"size": 10,
|
||||
}).Info("A group of walrus emerges from the ocean")
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"omg": true,
|
||||
"number": 122,
|
||||
}).Warn("The group's number increased tremendously!")
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"temperature": -4,
|
||||
}).Debug("Temperature changes")
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"animal": "orca",
|
||||
"size": 9009,
|
||||
}).Panic("It's over 9000!")
|
||||
}
|
||||
31
Godeps/_workspace/src/github.com/Sirupsen/logrus/examples/hook/hook.go
generated
vendored
31
Godeps/_workspace/src/github.com/Sirupsen/logrus/examples/hook/hook.go
generated
vendored
@ -1,31 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/Sirupsen/logrus"
|
||||
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/airbrake"
|
||||
)
|
||||
|
||||
var log = logrus.New()
|
||||
|
||||
func init() {
|
||||
log. // default
|
||||
Formatter = new(logrus.TextFormatter)
|
||||
log.Hooks.Add(airbrake.NewHook("https://example.com", "xyz", "development"))
|
||||
}
|
||||
|
||||
func main() {
|
||||
log.WithFields(logrus.Fields{
|
||||
"animal": "walrus",
|
||||
"size": 10,
|
||||
}).Info("A group of walrus emerges from the ocean")
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"omg": true,
|
||||
"number": 122,
|
||||
}).Warn("The group's number increased tremendously!")
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"omg": true,
|
||||
"number": 100,
|
||||
}).Fatal("The ice breaks!")
|
||||
}
|
||||
188
Godeps/_workspace/src/github.com/Sirupsen/logrus/exported.go
generated
vendored
188
Godeps/_workspace/src/github.com/Sirupsen/logrus/exported.go
generated
vendored
@ -1,188 +0,0 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
var (
|
||||
// std is the name of the standard logger in stdlib `log`
|
||||
std = New()
|
||||
)
|
||||
|
||||
func StandardLogger() *Logger {
|
||||
return std
|
||||
}
|
||||
|
||||
// SetOutput sets the standard logger output.
|
||||
func SetOutput(out io.Writer) {
|
||||
std.mu.Lock()
|
||||
defer std.mu.Unlock()
|
||||
std.Out = out
|
||||
}
|
||||
|
||||
// SetFormatter sets the standard logger formatter.
|
||||
func SetFormatter(formatter Formatter) {
|
||||
std.mu.Lock()
|
||||
defer std.mu.Unlock()
|
||||
std.Formatter = formatter
|
||||
}
|
||||
|
||||
// SetLevel sets the standard logger level.
|
||||
func SetLevel(level Level) {
|
||||
std.mu.Lock()
|
||||
defer std.mu.Unlock()
|
||||
std.Level = level
|
||||
}
|
||||
|
||||
// GetLevel returns the standard logger level.
|
||||
func GetLevel() Level {
|
||||
std.mu.Lock()
|
||||
defer std.mu.Unlock()
|
||||
return std.Level
|
||||
}
|
||||
|
||||
// AddHook adds a hook to the standard logger hooks.
|
||||
func AddHook(hook Hook) {
|
||||
std.mu.Lock()
|
||||
defer std.mu.Unlock()
|
||||
std.Hooks.Add(hook)
|
||||
}
|
||||
|
||||
// WithField creates an entry from the standard logger and adds a field to
|
||||
// it. If you want multiple fields, use `WithFields`.
|
||||
//
|
||||
// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal
|
||||
// or Panic on the Entry it returns.
|
||||
func WithField(key string, value interface{}) *Entry {
|
||||
return std.WithField(key, value)
|
||||
}
|
||||
|
||||
// WithFields creates an entry from the standard logger and adds multiple
|
||||
// fields to it. This is simply a helper for `WithField`, invoking it
|
||||
// once for each field.
|
||||
//
|
||||
// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal
|
||||
// or Panic on the Entry it returns.
|
||||
func WithFields(fields Fields) *Entry {
|
||||
return std.WithFields(fields)
|
||||
}
|
||||
|
||||
// Debug logs a message at level Debug on the standard logger.
|
||||
func Debug(args ...interface{}) {
|
||||
std.Debug(args...)
|
||||
}
|
||||
|
||||
// Print logs a message at level Info on the standard logger.
|
||||
func Print(args ...interface{}) {
|
||||
std.Print(args...)
|
||||
}
|
||||
|
||||
// Info logs a message at level Info on the standard logger.
|
||||
func Info(args ...interface{}) {
|
||||
std.Info(args...)
|
||||
}
|
||||
|
||||
// Warn logs a message at level Warn on the standard logger.
|
||||
func Warn(args ...interface{}) {
|
||||
std.Warn(args...)
|
||||
}
|
||||
|
||||
// Warning logs a message at level Warn on the standard logger.
|
||||
func Warning(args ...interface{}) {
|
||||
std.Warning(args...)
|
||||
}
|
||||
|
||||
// Error logs a message at level Error on the standard logger.
|
||||
func Error(args ...interface{}) {
|
||||
std.Error(args...)
|
||||
}
|
||||
|
||||
// Panic logs a message at level Panic on the standard logger.
|
||||
func Panic(args ...interface{}) {
|
||||
std.Panic(args...)
|
||||
}
|
||||
|
||||
// Fatal logs a message at level Fatal on the standard logger.
|
||||
func Fatal(args ...interface{}) {
|
||||
std.Fatal(args...)
|
||||
}
|
||||
|
||||
// Debugf logs a message at level Debug on the standard logger.
|
||||
func Debugf(format string, args ...interface{}) {
|
||||
std.Debugf(format, args...)
|
||||
}
|
||||
|
||||
// Printf logs a message at level Info on the standard logger.
|
||||
func Printf(format string, args ...interface{}) {
|
||||
std.Printf(format, args...)
|
||||
}
|
||||
|
||||
// Infof logs a message at level Info on the standard logger.
|
||||
func Infof(format string, args ...interface{}) {
|
||||
std.Infof(format, args...)
|
||||
}
|
||||
|
||||
// Warnf logs a message at level Warn on the standard logger.
|
||||
func Warnf(format string, args ...interface{}) {
|
||||
std.Warnf(format, args...)
|
||||
}
|
||||
|
||||
// Warningf logs a message at level Warn on the standard logger.
|
||||
func Warningf(format string, args ...interface{}) {
|
||||
std.Warningf(format, args...)
|
||||
}
|
||||
|
||||
// Errorf logs a message at level Error on the standard logger.
|
||||
func Errorf(format string, args ...interface{}) {
|
||||
std.Errorf(format, args...)
|
||||
}
|
||||
|
||||
// Panicf logs a message at level Panic on the standard logger.
|
||||
func Panicf(format string, args ...interface{}) {
|
||||
std.Panicf(format, args...)
|
||||
}
|
||||
|
||||
// Fatalf logs a message at level Fatal on the standard logger.
|
||||
func Fatalf(format string, args ...interface{}) {
|
||||
std.Fatalf(format, args...)
|
||||
}
|
||||
|
||||
// Debugln logs a message at level Debug on the standard logger.
|
||||
func Debugln(args ...interface{}) {
|
||||
std.Debugln(args...)
|
||||
}
|
||||
|
||||
// Println logs a message at level Info on the standard logger.
|
||||
func Println(args ...interface{}) {
|
||||
std.Println(args...)
|
||||
}
|
||||
|
||||
// Infoln logs a message at level Info on the standard logger.
|
||||
func Infoln(args ...interface{}) {
|
||||
std.Infoln(args...)
|
||||
}
|
||||
|
||||
// Warnln logs a message at level Warn on the standard logger.
|
||||
func Warnln(args ...interface{}) {
|
||||
std.Warnln(args...)
|
||||
}
|
||||
|
||||
// Warningln logs a message at level Warn on the standard logger.
|
||||
func Warningln(args ...interface{}) {
|
||||
std.Warningln(args...)
|
||||
}
|
||||
|
||||
// Errorln logs a message at level Error on the standard logger.
|
||||
func Errorln(args ...interface{}) {
|
||||
std.Errorln(args...)
|
||||
}
|
||||
|
||||
// Panicln logs a message at level Panic on the standard logger.
|
||||
func Panicln(args ...interface{}) {
|
||||
std.Panicln(args...)
|
||||
}
|
||||
|
||||
// Fatalln logs a message at level Fatal on the standard logger.
|
||||
func Fatalln(args ...interface{}) {
|
||||
std.Fatalln(args...)
|
||||
}
|
||||
48
Godeps/_workspace/src/github.com/Sirupsen/logrus/formatter.go
generated
vendored
48
Godeps/_workspace/src/github.com/Sirupsen/logrus/formatter.go
generated
vendored
@ -1,48 +0,0 @@
|
||||
package logrus
|
||||
|
||||
import "time"
|
||||
|
||||
const DefaultTimestampFormat = time.RFC3339
|
||||
|
||||
// The Formatter interface is used to implement a custom Formatter. It takes an
|
||||
// `Entry`. It exposes all the fields, including the default ones:
|
||||
//
|
||||
// * `entry.Data["msg"]`. The message passed from Info, Warn, Error ..
|
||||
// * `entry.Data["time"]`. The timestamp.
|
||||
// * `entry.Data["level"]. The level the entry was logged at.
|
||||
//
|
||||
// Any additional fields added with `WithField` or `WithFields` are also in
|
||||
// `entry.Data`. Format is expected to return an array of bytes which are then
|
||||
// logged to `logger.Out`.
|
||||
type Formatter interface {
|
||||
Format(*Entry) ([]byte, error)
|
||||
}
|
||||
|
||||
// This is to not silently overwrite `time`, `msg` and `level` fields when
|
||||
// dumping it. If this code wasn't there doing:
|
||||
//
|
||||
// logrus.WithField("level", 1).Info("hello")
|
||||
//
|
||||
// Would just silently drop the user provided level. Instead with this code
|
||||
// it'll logged as:
|
||||
//
|
||||
// {"level": "info", "fields.level": 1, "msg": "hello", "time": "..."}
|
||||
//
|
||||
// It's not exported because it's still using Data in an opinionated way. It's to
|
||||
// avoid code duplication between the two default formatters.
|
||||
func prefixFieldClashes(data Fields) {
|
||||
_, ok := data["time"]
|
||||
if ok {
|
||||
data["fields.time"] = data["time"]
|
||||
}
|
||||
|
||||
_, ok = data["msg"]
|
||||
if ok {
|
||||
data["fields.msg"] = data["msg"]
|
||||
}
|
||||
|
||||
_, ok = data["level"]
|
||||
if ok {
|
||||
data["fields.level"] = data["level"]
|
||||
}
|
||||
}
|
||||
88
Godeps/_workspace/src/github.com/Sirupsen/logrus/formatter_bench_test.go
generated
vendored
88
Godeps/_workspace/src/github.com/Sirupsen/logrus/formatter_bench_test.go
generated
vendored
@ -1,88 +0,0 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// smallFields is a small size data set for benchmarking
|
||||
var smallFields = Fields{
|
||||
"foo": "bar",
|
||||
"baz": "qux",
|
||||
"one": "two",
|
||||
"three": "four",
|
||||
}
|
||||
|
||||
// largeFields is a large size data set for benchmarking
|
||||
var largeFields = Fields{
|
||||
"foo": "bar",
|
||||
"baz": "qux",
|
||||
"one": "two",
|
||||
"three": "four",
|
||||
"five": "six",
|
||||
"seven": "eight",
|
||||
"nine": "ten",
|
||||
"eleven": "twelve",
|
||||
"thirteen": "fourteen",
|
||||
"fifteen": "sixteen",
|
||||
"seventeen": "eighteen",
|
||||
"nineteen": "twenty",
|
||||
"a": "b",
|
||||
"c": "d",
|
||||
"e": "f",
|
||||
"g": "h",
|
||||
"i": "j",
|
||||
"k": "l",
|
||||
"m": "n",
|
||||
"o": "p",
|
||||
"q": "r",
|
||||
"s": "t",
|
||||
"u": "v",
|
||||
"w": "x",
|
||||
"y": "z",
|
||||
"this": "will",
|
||||
"make": "thirty",
|
||||
"entries": "yeah",
|
||||
}
|
||||
|
||||
func BenchmarkSmallTextFormatter(b *testing.B) {
|
||||
doBenchmark(b, &TextFormatter{DisableColors: true}, smallFields)
|
||||
}
|
||||
|
||||
func BenchmarkLargeTextFormatter(b *testing.B) {
|
||||
doBenchmark(b, &TextFormatter{DisableColors: true}, largeFields)
|
||||
}
|
||||
|
||||
func BenchmarkSmallColoredTextFormatter(b *testing.B) {
|
||||
doBenchmark(b, &TextFormatter{ForceColors: true}, smallFields)
|
||||
}
|
||||
|
||||
func BenchmarkLargeColoredTextFormatter(b *testing.B) {
|
||||
doBenchmark(b, &TextFormatter{ForceColors: true}, largeFields)
|
||||
}
|
||||
|
||||
func BenchmarkSmallJSONFormatter(b *testing.B) {
|
||||
doBenchmark(b, &JSONFormatter{}, smallFields)
|
||||
}
|
||||
|
||||
func BenchmarkLargeJSONFormatter(b *testing.B) {
|
||||
doBenchmark(b, &JSONFormatter{}, largeFields)
|
||||
}
|
||||
|
||||
func doBenchmark(b *testing.B, formatter Formatter, fields Fields) {
|
||||
entry := &Entry{
|
||||
Time: time.Time{},
|
||||
Level: InfoLevel,
|
||||
Message: "message",
|
||||
Data: fields,
|
||||
}
|
||||
var d []byte
|
||||
var err error
|
||||
for i := 0; i < b.N; i++ {
|
||||
d, err = formatter.Format(entry)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
b.SetBytes(int64(len(d)))
|
||||
}
|
||||
}
|
||||
56
Godeps/_workspace/src/github.com/Sirupsen/logrus/formatters/logstash/logstash.go
generated
vendored
56
Godeps/_workspace/src/github.com/Sirupsen/logrus/formatters/logstash/logstash.go
generated
vendored
@ -1,56 +0,0 @@
|
||||
package logstash
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Formatter generates json in logstash format.
|
||||
// Logstash site: http://logstash.net/
|
||||
type LogstashFormatter struct {
|
||||
Type string // if not empty use for logstash type field.
|
||||
|
||||
// TimestampFormat sets the format used for timestamps.
|
||||
TimestampFormat string
|
||||
}
|
||||
|
||||
func (f *LogstashFormatter) Format(entry *logrus.Entry) ([]byte, error) {
|
||||
entry.Data["@version"] = 1
|
||||
|
||||
if f.TimestampFormat == "" {
|
||||
f.TimestampFormat = logrus.DefaultTimestampFormat
|
||||
}
|
||||
|
||||
entry.Data["@timestamp"] = entry.Time.Format(f.TimestampFormat)
|
||||
|
||||
// set message field
|
||||
v, ok := entry.Data["message"]
|
||||
if ok {
|
||||
entry.Data["fields.message"] = v
|
||||
}
|
||||
entry.Data["message"] = entry.Message
|
||||
|
||||
// set level field
|
||||
v, ok = entry.Data["level"]
|
||||
if ok {
|
||||
entry.Data["fields.level"] = v
|
||||
}
|
||||
entry.Data["level"] = entry.Level.String()
|
||||
|
||||
// set type field
|
||||
if f.Type != "" {
|
||||
v, ok = entry.Data["type"]
|
||||
if ok {
|
||||
entry.Data["fields.type"] = v
|
||||
}
|
||||
entry.Data["type"] = f.Type
|
||||
}
|
||||
|
||||
serialized, err := json.Marshal(entry.Data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
|
||||
}
|
||||
return append(serialized, '\n'), nil
|
||||
}
|
||||
52
Godeps/_workspace/src/github.com/Sirupsen/logrus/formatters/logstash/logstash_test.go
generated
vendored
52
Godeps/_workspace/src/github.com/Sirupsen/logrus/formatters/logstash/logstash_test.go
generated
vendored
@ -1,52 +0,0 @@
|
||||
package logstash
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/Sirupsen/logrus"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLogstashFormatter(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
lf := LogstashFormatter{Type: "abc"}
|
||||
|
||||
fields := logrus.Fields{
|
||||
"message": "def",
|
||||
"level": "ijk",
|
||||
"type": "lmn",
|
||||
"one": 1,
|
||||
"pi": 3.14,
|
||||
"bool": true,
|
||||
}
|
||||
|
||||
entry := logrus.WithFields(fields)
|
||||
entry.Message = "msg"
|
||||
entry.Level = logrus.InfoLevel
|
||||
|
||||
b, _ := lf.Format(entry)
|
||||
|
||||
var data map[string]interface{}
|
||||
dec := json.NewDecoder(bytes.NewReader(b))
|
||||
dec.UseNumber()
|
||||
dec.Decode(&data)
|
||||
|
||||
// base fields
|
||||
assert.Equal(json.Number("1"), data["@version"])
|
||||
assert.NotEmpty(data["@timestamp"])
|
||||
assert.Equal("abc", data["type"])
|
||||
assert.Equal("msg", data["message"])
|
||||
assert.Equal("info", data["level"])
|
||||
|
||||
// substituted fields
|
||||
assert.Equal("def", data["fields.message"])
|
||||
assert.Equal("ijk", data["fields.level"])
|
||||
assert.Equal("lmn", data["fields.type"])
|
||||
|
||||
// formats
|
||||
assert.Equal(json.Number("1"), data["one"])
|
||||
assert.Equal(json.Number("3.14"), data["pi"])
|
||||
assert.Equal(true, data["bool"])
|
||||
}
|
||||
122
Godeps/_workspace/src/github.com/Sirupsen/logrus/hook_test.go
generated
vendored
122
Godeps/_workspace/src/github.com/Sirupsen/logrus/hook_test.go
generated
vendored
@ -1,122 +0,0 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type TestHook struct {
|
||||
Fired bool
|
||||
}
|
||||
|
||||
func (hook *TestHook) Fire(entry *Entry) error {
|
||||
hook.Fired = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (hook *TestHook) Levels() []Level {
|
||||
return []Level{
|
||||
DebugLevel,
|
||||
InfoLevel,
|
||||
WarnLevel,
|
||||
ErrorLevel,
|
||||
FatalLevel,
|
||||
PanicLevel,
|
||||
}
|
||||
}
|
||||
|
||||
func TestHookFires(t *testing.T) {
|
||||
hook := new(TestHook)
|
||||
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Hooks.Add(hook)
|
||||
assert.Equal(t, hook.Fired, false)
|
||||
|
||||
log.Print("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, hook.Fired, true)
|
||||
})
|
||||
}
|
||||
|
||||
type ModifyHook struct {
|
||||
}
|
||||
|
||||
func (hook *ModifyHook) Fire(entry *Entry) error {
|
||||
entry.Data["wow"] = "whale"
|
||||
return nil
|
||||
}
|
||||
|
||||
func (hook *ModifyHook) Levels() []Level {
|
||||
return []Level{
|
||||
DebugLevel,
|
||||
InfoLevel,
|
||||
WarnLevel,
|
||||
ErrorLevel,
|
||||
FatalLevel,
|
||||
PanicLevel,
|
||||
}
|
||||
}
|
||||
|
||||
func TestHookCanModifyEntry(t *testing.T) {
|
||||
hook := new(ModifyHook)
|
||||
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Hooks.Add(hook)
|
||||
log.WithField("wow", "elephant").Print("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["wow"], "whale")
|
||||
})
|
||||
}
|
||||
|
||||
func TestCanFireMultipleHooks(t *testing.T) {
|
||||
hook1 := new(ModifyHook)
|
||||
hook2 := new(TestHook)
|
||||
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Hooks.Add(hook1)
|
||||
log.Hooks.Add(hook2)
|
||||
|
||||
log.WithField("wow", "elephant").Print("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["wow"], "whale")
|
||||
assert.Equal(t, hook2.Fired, true)
|
||||
})
|
||||
}
|
||||
|
||||
type ErrorHook struct {
|
||||
Fired bool
|
||||
}
|
||||
|
||||
func (hook *ErrorHook) Fire(entry *Entry) error {
|
||||
hook.Fired = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (hook *ErrorHook) Levels() []Level {
|
||||
return []Level{
|
||||
ErrorLevel,
|
||||
}
|
||||
}
|
||||
|
||||
func TestErrorHookShouldntFireOnInfo(t *testing.T) {
|
||||
hook := new(ErrorHook)
|
||||
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Hooks.Add(hook)
|
||||
log.Info("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, hook.Fired, false)
|
||||
})
|
||||
}
|
||||
|
||||
func TestErrorHookShouldFireOnError(t *testing.T) {
|
||||
hook := new(ErrorHook)
|
||||
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Hooks.Add(hook)
|
||||
log.Error("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, hook.Fired, true)
|
||||
})
|
||||
}
|
||||
34
Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks.go
generated
vendored
34
Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks.go
generated
vendored
@ -1,34 +0,0 @@
|
||||
package logrus
|
||||
|
||||
// A hook to be fired when logging on the logging levels returned from
|
||||
// `Levels()` on your implementation of the interface. Note that this is not
|
||||
// fired in a goroutine or a channel with workers, you should handle such
|
||||
// functionality yourself if your call is non-blocking and you don't wish for
|
||||
// the logging calls for levels returned from `Levels()` to block.
|
||||
type Hook interface {
|
||||
Levels() []Level
|
||||
Fire(*Entry) error
|
||||
}
|
||||
|
||||
// Internal type for storing the hooks on a logger instance.
|
||||
type levelHooks map[Level][]Hook
|
||||
|
||||
// Add a hook to an instance of logger. This is called with
|
||||
// `log.Hooks.Add(new(MyHook))` where `MyHook` implements the `Hook` interface.
|
||||
func (hooks levelHooks) Add(hook Hook) {
|
||||
for _, level := range hook.Levels() {
|
||||
hooks[level] = append(hooks[level], hook)
|
||||
}
|
||||
}
|
||||
|
||||
// Fire all the hooks for the passed level. Used by `entry.log` to fire
|
||||
// appropriate hooks for a log entry.
|
||||
func (hooks levelHooks) Fire(level Level, entry *Entry) error {
|
||||
for _, hook := range hooks[level] {
|
||||
if err := hook.Fire(entry); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
54
Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/airbrake/airbrake.go
generated
vendored
54
Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/airbrake/airbrake.go
generated
vendored
@ -1,54 +0,0 @@
|
||||
package airbrake
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/Sirupsen/logrus"
|
||||
"github.com/tobi/airbrake-go"
|
||||
)
|
||||
|
||||
// AirbrakeHook to send exceptions to an exception-tracking service compatible
|
||||
// with the Airbrake API.
|
||||
type airbrakeHook struct {
|
||||
APIKey string
|
||||
Endpoint string
|
||||
Environment string
|
||||
}
|
||||
|
||||
func NewHook(endpoint, apiKey, env string) *airbrakeHook {
|
||||
return &airbrakeHook{
|
||||
APIKey: apiKey,
|
||||
Endpoint: endpoint,
|
||||
Environment: env,
|
||||
}
|
||||
}
|
||||
|
||||
func (hook *airbrakeHook) Fire(entry *logrus.Entry) error {
|
||||
airbrake.ApiKey = hook.APIKey
|
||||
airbrake.Endpoint = hook.Endpoint
|
||||
airbrake.Environment = hook.Environment
|
||||
|
||||
var notifyErr error
|
||||
err, ok := entry.Data["error"].(error)
|
||||
if ok {
|
||||
notifyErr = err
|
||||
} else {
|
||||
notifyErr = errors.New(entry.Message)
|
||||
}
|
||||
|
||||
airErr := airbrake.Notify(notifyErr)
|
||||
if airErr != nil {
|
||||
return fmt.Errorf("Failed to send error to Airbrake: %s", airErr)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (hook *airbrakeHook) Levels() []logrus.Level {
|
||||
return []logrus.Level{
|
||||
logrus.ErrorLevel,
|
||||
logrus.FatalLevel,
|
||||
logrus.PanicLevel,
|
||||
}
|
||||
}
|
||||
133
Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/airbrake/airbrake_test.go
generated
vendored
133
Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/airbrake/airbrake_test.go
generated
vendored
@ -1,133 +0,0 @@
|
||||
package airbrake
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
type notice struct {
|
||||
Error NoticeError `xml:"error"`
|
||||
}
|
||||
type NoticeError struct {
|
||||
Class string `xml:"class"`
|
||||
Message string `xml:"message"`
|
||||
}
|
||||
|
||||
type customErr struct {
|
||||
msg string
|
||||
}
|
||||
|
||||
func (e *customErr) Error() string {
|
||||
return e.msg
|
||||
}
|
||||
|
||||
const (
|
||||
testAPIKey = "abcxyz"
|
||||
testEnv = "development"
|
||||
expectedClass = "*airbrake.customErr"
|
||||
expectedMsg = "foo"
|
||||
unintendedMsg = "Airbrake will not see this string"
|
||||
)
|
||||
|
||||
var (
|
||||
noticeError = make(chan NoticeError, 1)
|
||||
)
|
||||
|
||||
// TestLogEntryMessageReceived checks if invoking Logrus' log.Error
|
||||
// method causes an XML payload containing the log entry message is received
|
||||
// by a HTTP server emulating an Airbrake-compatible endpoint.
|
||||
func TestLogEntryMessageReceived(t *testing.T) {
|
||||
log := logrus.New()
|
||||
ts := startAirbrakeServer(t)
|
||||
defer ts.Close()
|
||||
|
||||
hook := NewHook(ts.URL, testAPIKey, "production")
|
||||
log.Hooks.Add(hook)
|
||||
|
||||
log.Error(expectedMsg)
|
||||
|
||||
select {
|
||||
case received := <-noticeError:
|
||||
if received.Message != expectedMsg {
|
||||
t.Errorf("Unexpected message received: %s", received.Message)
|
||||
}
|
||||
case <-time.After(time.Second):
|
||||
t.Error("Timed out; no notice received by Airbrake API")
|
||||
}
|
||||
}
|
||||
|
||||
// TestLogEntryMessageReceived confirms that, when passing an error type using
|
||||
// logrus.Fields, a HTTP server emulating an Airbrake endpoint receives the
|
||||
// error message returned by the Error() method on the error interface
|
||||
// rather than the logrus.Entry.Message string.
|
||||
func TestLogEntryWithErrorReceived(t *testing.T) {
|
||||
log := logrus.New()
|
||||
ts := startAirbrakeServer(t)
|
||||
defer ts.Close()
|
||||
|
||||
hook := NewHook(ts.URL, testAPIKey, "production")
|
||||
log.Hooks.Add(hook)
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"error": &customErr{expectedMsg},
|
||||
}).Error(unintendedMsg)
|
||||
|
||||
select {
|
||||
case received := <-noticeError:
|
||||
if received.Message != expectedMsg {
|
||||
t.Errorf("Unexpected message received: %s", received.Message)
|
||||
}
|
||||
if received.Class != expectedClass {
|
||||
t.Errorf("Unexpected error class: %s", received.Class)
|
||||
}
|
||||
case <-time.After(time.Second):
|
||||
t.Error("Timed out; no notice received by Airbrake API")
|
||||
}
|
||||
}
|
||||
|
||||
// TestLogEntryWithNonErrorTypeNotReceived confirms that, when passing a
|
||||
// non-error type using logrus.Fields, a HTTP server emulating an Airbrake
|
||||
// endpoint receives the logrus.Entry.Message string.
|
||||
//
|
||||
// Only error types are supported when setting the 'error' field using
|
||||
// logrus.WithFields().
|
||||
func TestLogEntryWithNonErrorTypeNotReceived(t *testing.T) {
|
||||
log := logrus.New()
|
||||
ts := startAirbrakeServer(t)
|
||||
defer ts.Close()
|
||||
|
||||
hook := NewHook(ts.URL, testAPIKey, "production")
|
||||
log.Hooks.Add(hook)
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"error": expectedMsg,
|
||||
}).Error(unintendedMsg)
|
||||
|
||||
select {
|
||||
case received := <-noticeError:
|
||||
if received.Message != unintendedMsg {
|
||||
t.Errorf("Unexpected message received: %s", received.Message)
|
||||
}
|
||||
case <-time.After(time.Second):
|
||||
t.Error("Timed out; no notice received by Airbrake API")
|
||||
}
|
||||
}
|
||||
|
||||
func startAirbrakeServer(t *testing.T) *httptest.Server {
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
var notice notice
|
||||
if err := xml.NewDecoder(r.Body).Decode(¬ice); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
r.Body.Close()
|
||||
|
||||
noticeError <- notice.Error
|
||||
}))
|
||||
|
||||
return ts
|
||||
}
|
||||
68
Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/bugsnag/bugsnag.go
generated
vendored
68
Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/bugsnag/bugsnag.go
generated
vendored
@ -1,68 +0,0 @@
|
||||
package logrus_bugsnag
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/bugsnag/bugsnag-go"
|
||||
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
type bugsnagHook struct{}
|
||||
|
||||
// ErrBugsnagUnconfigured is returned if NewBugsnagHook is called before
|
||||
// bugsnag.Configure. Bugsnag must be configured before the hook.
|
||||
var ErrBugsnagUnconfigured = errors.New("bugsnag must be configured before installing this logrus hook")
|
||||
|
||||
// ErrBugsnagSendFailed indicates that the hook failed to submit an error to
|
||||
// bugsnag. The error was successfully generated, but `bugsnag.Notify()`
|
||||
// failed.
|
||||
type ErrBugsnagSendFailed struct {
|
||||
err error
|
||||
}
|
||||
|
||||
func (e ErrBugsnagSendFailed) Error() string {
|
||||
return "failed to send error to Bugsnag: " + e.err.Error()
|
||||
}
|
||||
|
||||
// NewBugsnagHook initializes a logrus hook which sends exceptions to an
|
||||
// exception-tracking service compatible with the Bugsnag API. Before using
|
||||
// this hook, you must call bugsnag.Configure(). The returned object should be
|
||||
// registered with a log via `AddHook()`
|
||||
//
|
||||
// Entries that trigger an Error, Fatal or Panic should now include an "error"
|
||||
// field to send to Bugsnag.
|
||||
func NewBugsnagHook() (*bugsnagHook, error) {
|
||||
if bugsnag.Config.APIKey == "" {
|
||||
return nil, ErrBugsnagUnconfigured
|
||||
}
|
||||
return &bugsnagHook{}, nil
|
||||
}
|
||||
|
||||
// Fire forwards an error to Bugsnag. Given a logrus.Entry, it extracts the
|
||||
// "error" field (or the Message if the error isn't present) and sends it off.
|
||||
func (hook *bugsnagHook) Fire(entry *logrus.Entry) error {
|
||||
var notifyErr error
|
||||
err, ok := entry.Data["error"].(error)
|
||||
if ok {
|
||||
notifyErr = err
|
||||
} else {
|
||||
notifyErr = errors.New(entry.Message)
|
||||
}
|
||||
|
||||
bugsnagErr := bugsnag.Notify(notifyErr)
|
||||
if bugsnagErr != nil {
|
||||
return ErrBugsnagSendFailed{bugsnagErr}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Levels enumerates the log levels on which the error should be forwarded to
|
||||
// bugsnag: everything at or above the "Error" level.
|
||||
func (hook *bugsnagHook) Levels() []logrus.Level {
|
||||
return []logrus.Level{
|
||||
logrus.ErrorLevel,
|
||||
logrus.FatalLevel,
|
||||
logrus.PanicLevel,
|
||||
}
|
||||
}
|
||||
64
Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/bugsnag/bugsnag_test.go
generated
vendored
64
Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/bugsnag/bugsnag_test.go
generated
vendored
@ -1,64 +0,0 @@
|
||||
package logrus_bugsnag
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/bugsnag/bugsnag-go"
|
||||
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
type notice struct {
|
||||
Events []struct {
|
||||
Exceptions []struct {
|
||||
Message string `json:"message"`
|
||||
} `json:"exceptions"`
|
||||
} `json:"events"`
|
||||
}
|
||||
|
||||
func TestNoticeReceived(t *testing.T) {
|
||||
msg := make(chan string, 1)
|
||||
expectedMsg := "foo"
|
||||
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
var notice notice
|
||||
data, _ := ioutil.ReadAll(r.Body)
|
||||
if err := json.Unmarshal(data, ¬ice); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
_ = r.Body.Close()
|
||||
|
||||
msg <- notice.Events[0].Exceptions[0].Message
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
hook := &bugsnagHook{}
|
||||
|
||||
bugsnag.Configure(bugsnag.Configuration{
|
||||
Endpoint: ts.URL,
|
||||
ReleaseStage: "production",
|
||||
APIKey: "12345678901234567890123456789012",
|
||||
Synchronous: true,
|
||||
})
|
||||
|
||||
log := logrus.New()
|
||||
log.Hooks.Add(hook)
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"error": errors.New(expectedMsg),
|
||||
}).Error("Bugsnag will not see this string")
|
||||
|
||||
select {
|
||||
case received := <-msg:
|
||||
if received != expectedMsg {
|
||||
t.Errorf("Unexpected message received: %s", received)
|
||||
}
|
||||
case <-time.After(time.Second):
|
||||
t.Error("Timed out; no notice received by Bugsnag API")
|
||||
}
|
||||
}
|
||||
28
Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/papertrail/README.md
generated
vendored
28
Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/papertrail/README.md
generated
vendored
@ -1,28 +0,0 @@
|
||||
# Papertrail Hook for Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:" />
|
||||
|
||||
[Papertrail](https://papertrailapp.com) provides hosted log management. Once stored in Papertrail, you can [group](http://help.papertrailapp.com/kb/how-it-works/groups/) your logs on various dimensions, [search](http://help.papertrailapp.com/kb/how-it-works/search-syntax) them, and trigger [alerts](http://help.papertrailapp.com/kb/how-it-works/alerts).
|
||||
|
||||
In most deployments, you'll want to send logs to Papertrail via their [remote_syslog](http://help.papertrailapp.com/kb/configuration/configuring-centralized-logging-from-text-log-files-in-unix/) daemon, which requires no application-specific configuration. This hook is intended for relatively low-volume logging, likely in managed cloud hosting deployments where installing `remote_syslog` is not possible.
|
||||
|
||||
## Usage
|
||||
|
||||
You can find your Papertrail UDP port on your [Papertrail account page](https://papertrailapp.com/account/destinations). Substitute it below for `YOUR_PAPERTRAIL_UDP_PORT`.
|
||||
|
||||
For `YOUR_APP_NAME`, substitute a short string that will readily identify your application or service in the logs.
|
||||
|
||||
```go
|
||||
import (
|
||||
"log/syslog"
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/Sirupsen/logrus/hooks/papertrail"
|
||||
)
|
||||
|
||||
func main() {
|
||||
log := logrus.New()
|
||||
hook, err := logrus_papertrail.NewPapertrailHook("logs.papertrailapp.com", YOUR_PAPERTRAIL_UDP_PORT, YOUR_APP_NAME)
|
||||
|
||||
if err == nil {
|
||||
log.Hooks.Add(hook)
|
||||
}
|
||||
}
|
||||
```
|
||||
55
Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/papertrail/papertrail.go
generated
vendored
55
Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/papertrail/papertrail.go
generated
vendored
@ -1,55 +0,0 @@
|
||||
package logrus_papertrail
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
format = "Jan 2 15:04:05"
|
||||
)
|
||||
|
||||
// PapertrailHook to send logs to a logging service compatible with the Papertrail API.
|
||||
type PapertrailHook struct {
|
||||
Host string
|
||||
Port int
|
||||
AppName string
|
||||
UDPConn net.Conn
|
||||
}
|
||||
|
||||
// NewPapertrailHook creates a hook to be added to an instance of logger.
|
||||
func NewPapertrailHook(host string, port int, appName string) (*PapertrailHook, error) {
|
||||
conn, err := net.Dial("udp", fmt.Sprintf("%s:%d", host, port))
|
||||
return &PapertrailHook{host, port, appName, conn}, err
|
||||
}
|
||||
|
||||
// Fire is called when a log event is fired.
|
||||
func (hook *PapertrailHook) Fire(entry *logrus.Entry) error {
|
||||
date := time.Now().Format(format)
|
||||
msg, _ := entry.String()
|
||||
payload := fmt.Sprintf("<22> %s %s: %s", date, hook.AppName, msg)
|
||||
|
||||
bytesWritten, err := hook.UDPConn.Write([]byte(payload))
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Unable to send log line to Papertrail via UDP. Wrote %d bytes before error: %v", bytesWritten, err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Levels returns the available logging levels.
|
||||
func (hook *PapertrailHook) Levels() []logrus.Level {
|
||||
return []logrus.Level{
|
||||
logrus.PanicLevel,
|
||||
logrus.FatalLevel,
|
||||
logrus.ErrorLevel,
|
||||
logrus.WarnLevel,
|
||||
logrus.InfoLevel,
|
||||
logrus.DebugLevel,
|
||||
}
|
||||
}
|
||||
26
Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/papertrail/papertrail_test.go
generated
vendored
26
Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/papertrail/papertrail_test.go
generated
vendored
@ -1,26 +0,0 @@
|
||||
package logrus_papertrail
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/Sirupsen/logrus"
|
||||
"github.com/stvp/go-udp-testing"
|
||||
)
|
||||
|
||||
func TestWritingToUDP(t *testing.T) {
|
||||
port := 16661
|
||||
udp.SetAddr(fmt.Sprintf(":%d", port))
|
||||
|
||||
hook, err := NewPapertrailHook("localhost", port, "test")
|
||||
if err != nil {
|
||||
t.Errorf("Unable to connect to local UDP server.")
|
||||
}
|
||||
|
||||
log := logrus.New()
|
||||
log.Hooks.Add(hook)
|
||||
|
||||
udp.ShouldReceive(t, "foo", func() {
|
||||
log.Info("foo")
|
||||
})
|
||||
}
|
||||
61
Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/sentry/README.md
generated
vendored
61
Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/sentry/README.md
generated
vendored
@ -1,61 +0,0 @@
|
||||
# Sentry Hook for Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:" />
|
||||
|
||||
[Sentry](https://getsentry.com) provides both self-hosted and hosted
|
||||
solutions for exception tracking.
|
||||
Both client and server are
|
||||
[open source](https://github.com/getsentry/sentry).
|
||||
|
||||
## Usage
|
||||
|
||||
Every sentry application defined on the server gets a different
|
||||
[DSN](https://www.getsentry.com/docs/). In the example below replace
|
||||
`YOUR_DSN` with the one created for your application.
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/Sirupsen/logrus/hooks/sentry"
|
||||
)
|
||||
|
||||
func main() {
|
||||
log := logrus.New()
|
||||
hook, err := logrus_sentry.NewSentryHook(YOUR_DSN, []logrus.Level{
|
||||
logrus.PanicLevel,
|
||||
logrus.FatalLevel,
|
||||
logrus.ErrorLevel,
|
||||
})
|
||||
|
||||
if err == nil {
|
||||
log.Hooks.Add(hook)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Special fields
|
||||
|
||||
Some logrus fields have a special meaning in this hook,
|
||||
these are server_name and logger.
|
||||
When logs are sent to sentry these fields are treated differently.
|
||||
- server_name (also known as hostname) is the name of the server which
|
||||
is logging the event (hostname.example.com)
|
||||
- logger is the part of the application which is logging the event.
|
||||
In go this usually means setting it to the name of the package.
|
||||
|
||||
## Timeout
|
||||
|
||||
`Timeout` is the time the sentry hook will wait for a response
|
||||
from the sentry server.
|
||||
|
||||
If this time elapses with no response from
|
||||
the server an error will be returned.
|
||||
|
||||
If `Timeout` is set to 0 the SentryHook will not wait for a reply
|
||||
and will assume a correct delivery.
|
||||
|
||||
The SentryHook has a default timeout of `100 milliseconds` when created
|
||||
with a call to `NewSentryHook`. This can be changed by assigning a value to the `Timeout` field:
|
||||
|
||||
```go
|
||||
hook, _ := logrus_sentry.NewSentryHook(...)
|
||||
hook.Timeout = 20*time.Second
|
||||
```
|
||||
100
Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/sentry/sentry.go
generated
vendored
100
Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/sentry/sentry.go
generated
vendored
@ -1,100 +0,0 @@
|
||||
package logrus_sentry
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/getsentry/raven-go"
|
||||
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
var (
|
||||
severityMap = map[logrus.Level]raven.Severity{
|
||||
logrus.DebugLevel: raven.DEBUG,
|
||||
logrus.InfoLevel: raven.INFO,
|
||||
logrus.WarnLevel: raven.WARNING,
|
||||
logrus.ErrorLevel: raven.ERROR,
|
||||
logrus.FatalLevel: raven.FATAL,
|
||||
logrus.PanicLevel: raven.FATAL,
|
||||
}
|
||||
)
|
||||
|
||||
func getAndDel(d logrus.Fields, key string) (string, bool) {
|
||||
var (
|
||||
ok bool
|
||||
v interface{}
|
||||
val string
|
||||
)
|
||||
if v, ok = d[key]; !ok {
|
||||
return "", false
|
||||
}
|
||||
|
||||
if val, ok = v.(string); !ok {
|
||||
return "", false
|
||||
}
|
||||
delete(d, key)
|
||||
return val, true
|
||||
}
|
||||
|
||||
// SentryHook delivers logs to a sentry server.
|
||||
type SentryHook struct {
|
||||
// Timeout sets the time to wait for a delivery error from the sentry server.
|
||||
// If this is set to zero the server will not wait for any response and will
|
||||
// consider the message correctly sent
|
||||
Timeout time.Duration
|
||||
|
||||
client *raven.Client
|
||||
levels []logrus.Level
|
||||
}
|
||||
|
||||
// NewSentryHook creates a hook to be added to an instance of logger
|
||||
// and initializes the raven client.
|
||||
// This method sets the timeout to 100 milliseconds.
|
||||
func NewSentryHook(DSN string, levels []logrus.Level) (*SentryHook, error) {
|
||||
client, err := raven.NewClient(DSN, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &SentryHook{100 * time.Millisecond, client, levels}, nil
|
||||
}
|
||||
|
||||
// Called when an event should be sent to sentry
|
||||
// Special fields that sentry uses to give more information to the server
|
||||
// are extracted from entry.Data (if they are found)
|
||||
// These fields are: logger and server_name
|
||||
func (hook *SentryHook) Fire(entry *logrus.Entry) error {
|
||||
packet := &raven.Packet{
|
||||
Message: entry.Message,
|
||||
Timestamp: raven.Timestamp(entry.Time),
|
||||
Level: severityMap[entry.Level],
|
||||
Platform: "go",
|
||||
}
|
||||
|
||||
d := entry.Data
|
||||
|
||||
if logger, ok := getAndDel(d, "logger"); ok {
|
||||
packet.Logger = logger
|
||||
}
|
||||
if serverName, ok := getAndDel(d, "server_name"); ok {
|
||||
packet.ServerName = serverName
|
||||
}
|
||||
packet.Extra = map[string]interface{}(d)
|
||||
|
||||
_, errCh := hook.client.Capture(packet, nil)
|
||||
timeout := hook.Timeout
|
||||
if timeout != 0 {
|
||||
timeoutCh := time.After(timeout)
|
||||
select {
|
||||
case err := <-errCh:
|
||||
return err
|
||||
case <-timeoutCh:
|
||||
return fmt.Errorf("no response from sentry server in %s", timeout)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Levels returns the available logging levels.
|
||||
func (hook *SentryHook) Levels() []logrus.Level {
|
||||
return hook.levels
|
||||
}
|
||||
97
Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/sentry/sentry_test.go
generated
vendored
97
Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/sentry/sentry_test.go
generated
vendored
@ -1,97 +0,0 @@
|
||||
package logrus_sentry
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/getsentry/raven-go"
|
||||
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
message = "error message"
|
||||
server_name = "testserver.internal"
|
||||
logger_name = "test.logger"
|
||||
)
|
||||
|
||||
func getTestLogger() *logrus.Logger {
|
||||
l := logrus.New()
|
||||
l.Out = ioutil.Discard
|
||||
return l
|
||||
}
|
||||
|
||||
func WithTestDSN(t *testing.T, tf func(string, <-chan *raven.Packet)) {
|
||||
pch := make(chan *raven.Packet, 1)
|
||||
s := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
defer req.Body.Close()
|
||||
d := json.NewDecoder(req.Body)
|
||||
p := &raven.Packet{}
|
||||
err := d.Decode(p)
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
pch <- p
|
||||
}))
|
||||
defer s.Close()
|
||||
|
||||
fragments := strings.SplitN(s.URL, "://", 2)
|
||||
dsn := fmt.Sprintf(
|
||||
"%s://public:secret@%s/sentry/project-id",
|
||||
fragments[0],
|
||||
fragments[1],
|
||||
)
|
||||
tf(dsn, pch)
|
||||
}
|
||||
|
||||
func TestSpecialFields(t *testing.T) {
|
||||
WithTestDSN(t, func(dsn string, pch <-chan *raven.Packet) {
|
||||
logger := getTestLogger()
|
||||
|
||||
hook, err := NewSentryHook(dsn, []logrus.Level{
|
||||
logrus.ErrorLevel,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
logger.Hooks.Add(hook)
|
||||
logger.WithFields(logrus.Fields{
|
||||
"server_name": server_name,
|
||||
"logger": logger_name,
|
||||
}).Error(message)
|
||||
|
||||
packet := <-pch
|
||||
if packet.Logger != logger_name {
|
||||
t.Errorf("logger should have been %s, was %s", logger_name, packet.Logger)
|
||||
}
|
||||
|
||||
if packet.ServerName != server_name {
|
||||
t.Errorf("server_name should have been %s, was %s", server_name, packet.ServerName)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestSentryHandler(t *testing.T) {
|
||||
WithTestDSN(t, func(dsn string, pch <-chan *raven.Packet) {
|
||||
logger := getTestLogger()
|
||||
hook, err := NewSentryHook(dsn, []logrus.Level{
|
||||
logrus.ErrorLevel,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
logger.Hooks.Add(hook)
|
||||
|
||||
logger.Error(message)
|
||||
packet := <-pch
|
||||
if packet.Message != message {
|
||||
t.Errorf("message should have been %s, was %s", message, packet.Message)
|
||||
}
|
||||
})
|
||||
}
|
||||
20
Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/syslog/README.md
generated
vendored
20
Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/syslog/README.md
generated
vendored
@ -1,20 +0,0 @@
|
||||
# Syslog Hooks for Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:"/>
|
||||
|
||||
## Usage
|
||||
|
||||
```go
|
||||
import (
|
||||
"log/syslog"
|
||||
"github.com/Sirupsen/logrus"
|
||||
logrus_syslog "github.com/Sirupsen/logrus/hooks/syslog"
|
||||
)
|
||||
|
||||
func main() {
|
||||
log := logrus.New()
|
||||
hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
|
||||
|
||||
if err == nil {
|
||||
log.Hooks.Add(hook)
|
||||
}
|
||||
}
|
||||
```
|
||||
59
Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/syslog/syslog.go
generated
vendored
59
Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/syslog/syslog.go
generated
vendored
@ -1,59 +0,0 @@
|
||||
package logrus_syslog
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/Sirupsen/logrus"
|
||||
"log/syslog"
|
||||
"os"
|
||||
)
|
||||
|
||||
// SyslogHook to send logs via syslog.
|
||||
type SyslogHook struct {
|
||||
Writer *syslog.Writer
|
||||
SyslogNetwork string
|
||||
SyslogRaddr string
|
||||
}
|
||||
|
||||
// Creates a hook to be added to an instance of logger. This is called with
|
||||
// `hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_DEBUG, "")`
|
||||
// `if err == nil { log.Hooks.Add(hook) }`
|
||||
func NewSyslogHook(network, raddr string, priority syslog.Priority, tag string) (*SyslogHook, error) {
|
||||
w, err := syslog.Dial(network, raddr, priority, tag)
|
||||
return &SyslogHook{w, network, raddr}, err
|
||||
}
|
||||
|
||||
func (hook *SyslogHook) Fire(entry *logrus.Entry) error {
|
||||
line, err := entry.String()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Unable to read entry, %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
switch entry.Level {
|
||||
case logrus.PanicLevel:
|
||||
return hook.Writer.Crit(line)
|
||||
case logrus.FatalLevel:
|
||||
return hook.Writer.Crit(line)
|
||||
case logrus.ErrorLevel:
|
||||
return hook.Writer.Err(line)
|
||||
case logrus.WarnLevel:
|
||||
return hook.Writer.Warning(line)
|
||||
case logrus.InfoLevel:
|
||||
return hook.Writer.Info(line)
|
||||
case logrus.DebugLevel:
|
||||
return hook.Writer.Debug(line)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (hook *SyslogHook) Levels() []logrus.Level {
|
||||
return []logrus.Level{
|
||||
logrus.PanicLevel,
|
||||
logrus.FatalLevel,
|
||||
logrus.ErrorLevel,
|
||||
logrus.WarnLevel,
|
||||
logrus.InfoLevel,
|
||||
logrus.DebugLevel,
|
||||
}
|
||||
}
|
||||
26
Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/syslog/syslog_test.go
generated
vendored
26
Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/syslog/syslog_test.go
generated
vendored
@ -1,26 +0,0 @@
|
||||
package logrus_syslog
|
||||
|
||||
import (
|
||||
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/Sirupsen/logrus"
|
||||
"log/syslog"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLocalhostAddAndPrint(t *testing.T) {
|
||||
log := logrus.New()
|
||||
hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Unable to connect to local syslog.")
|
||||
}
|
||||
|
||||
log.Hooks.Add(hook)
|
||||
|
||||
for _, level := range hook.Levels() {
|
||||
if len(log.Hooks[level]) != 1 {
|
||||
t.Errorf("SyslogHook was not added. The length of log.Hooks[%v]: %v", level, len(log.Hooks[level]))
|
||||
}
|
||||
}
|
||||
|
||||
log.Info("Congratulations!")
|
||||
}
|
||||
40
Godeps/_workspace/src/github.com/Sirupsen/logrus/json_formatter.go
generated
vendored
40
Godeps/_workspace/src/github.com/Sirupsen/logrus/json_formatter.go
generated
vendored
@ -1,40 +0,0 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type JSONFormatter struct {
|
||||
// TimestampFormat sets the format used for marshaling timestamps.
|
||||
TimestampFormat string
|
||||
}
|
||||
|
||||
func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
||||
data := make(Fields, len(entry.Data)+3)
|
||||
for k, v := range entry.Data {
|
||||
switch v := v.(type) {
|
||||
case error:
|
||||
// Otherwise errors are ignored by `encoding/json`
|
||||
// https://github.com/Sirupsen/logrus/issues/137
|
||||
data[k] = v.Error()
|
||||
default:
|
||||
data[k] = v
|
||||
}
|
||||
}
|
||||
prefixFieldClashes(data)
|
||||
|
||||
if f.TimestampFormat == "" {
|
||||
f.TimestampFormat = DefaultTimestampFormat
|
||||
}
|
||||
|
||||
data["time"] = entry.Time.Format(f.TimestampFormat)
|
||||
data["msg"] = entry.Message
|
||||
data["level"] = entry.Level.String()
|
||||
|
||||
serialized, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
|
||||
}
|
||||
return append(serialized, '\n'), nil
|
||||
}
|
||||
120
Godeps/_workspace/src/github.com/Sirupsen/logrus/json_formatter_test.go
generated
vendored
120
Godeps/_workspace/src/github.com/Sirupsen/logrus/json_formatter_test.go
generated
vendored
@ -1,120 +0,0 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestErrorNotLost(t *testing.T) {
|
||||
formatter := &JSONFormatter{}
|
||||
|
||||
b, err := formatter.Format(WithField("error", errors.New("wild walrus")))
|
||||
if err != nil {
|
||||
t.Fatal("Unable to format entry: ", err)
|
||||
}
|
||||
|
||||
entry := make(map[string]interface{})
|
||||
err = json.Unmarshal(b, &entry)
|
||||
if err != nil {
|
||||
t.Fatal("Unable to unmarshal formatted entry: ", err)
|
||||
}
|
||||
|
||||
if entry["error"] != "wild walrus" {
|
||||
t.Fatal("Error field not set")
|
||||
}
|
||||
}
|
||||
|
||||
func TestErrorNotLostOnFieldNotNamedError(t *testing.T) {
|
||||
formatter := &JSONFormatter{}
|
||||
|
||||
b, err := formatter.Format(WithField("omg", errors.New("wild walrus")))
|
||||
if err != nil {
|
||||
t.Fatal("Unable to format entry: ", err)
|
||||
}
|
||||
|
||||
entry := make(map[string]interface{})
|
||||
err = json.Unmarshal(b, &entry)
|
||||
if err != nil {
|
||||
t.Fatal("Unable to unmarshal formatted entry: ", err)
|
||||
}
|
||||
|
||||
if entry["omg"] != "wild walrus" {
|
||||
t.Fatal("Error field not set")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFieldClashWithTime(t *testing.T) {
|
||||
formatter := &JSONFormatter{}
|
||||
|
||||
b, err := formatter.Format(WithField("time", "right now!"))
|
||||
if err != nil {
|
||||
t.Fatal("Unable to format entry: ", err)
|
||||
}
|
||||
|
||||
entry := make(map[string]interface{})
|
||||
err = json.Unmarshal(b, &entry)
|
||||
if err != nil {
|
||||
t.Fatal("Unable to unmarshal formatted entry: ", err)
|
||||
}
|
||||
|
||||
if entry["fields.time"] != "right now!" {
|
||||
t.Fatal("fields.time not set to original time field")
|
||||
}
|
||||
|
||||
if entry["time"] != "0001-01-01T00:00:00Z" {
|
||||
t.Fatal("time field not set to current time, was: ", entry["time"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestFieldClashWithMsg(t *testing.T) {
|
||||
formatter := &JSONFormatter{}
|
||||
|
||||
b, err := formatter.Format(WithField("msg", "something"))
|
||||
if err != nil {
|
||||
t.Fatal("Unable to format entry: ", err)
|
||||
}
|
||||
|
||||
entry := make(map[string]interface{})
|
||||
err = json.Unmarshal(b, &entry)
|
||||
if err != nil {
|
||||
t.Fatal("Unable to unmarshal formatted entry: ", err)
|
||||
}
|
||||
|
||||
if entry["fields.msg"] != "something" {
|
||||
t.Fatal("fields.msg not set to original msg field")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFieldClashWithLevel(t *testing.T) {
|
||||
formatter := &JSONFormatter{}
|
||||
|
||||
b, err := formatter.Format(WithField("level", "something"))
|
||||
if err != nil {
|
||||
t.Fatal("Unable to format entry: ", err)
|
||||
}
|
||||
|
||||
entry := make(map[string]interface{})
|
||||
err = json.Unmarshal(b, &entry)
|
||||
if err != nil {
|
||||
t.Fatal("Unable to unmarshal formatted entry: ", err)
|
||||
}
|
||||
|
||||
if entry["fields.level"] != "something" {
|
||||
t.Fatal("fields.level not set to original level field")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJSONEntryEndsWithNewline(t *testing.T) {
|
||||
formatter := &JSONFormatter{}
|
||||
|
||||
b, err := formatter.Format(WithField("level", "something"))
|
||||
if err != nil {
|
||||
t.Fatal("Unable to format entry: ", err)
|
||||
}
|
||||
|
||||
if b[len(b)-1] != '\n' {
|
||||
t.Fatal("Expected JSON log entry to end with a newline")
|
||||
}
|
||||
}
|
||||
203
Godeps/_workspace/src/github.com/Sirupsen/logrus/logger.go
generated
vendored
203
Godeps/_workspace/src/github.com/Sirupsen/logrus/logger.go
generated
vendored
@ -1,203 +0,0 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Logger struct {
|
||||
// The logs are `io.Copy`'d to this in a mutex. It's common to set this to a
|
||||
// file, or leave it default which is `os.Stdout`. You can also set this to
|
||||
// something more adventorous, such as logging to Kafka.
|
||||
Out io.Writer
|
||||
// Hooks for the logger instance. These allow firing events based on logging
|
||||
// levels and log entries. For example, to send errors to an error tracking
|
||||
// service, log to StatsD or dump the core on fatal errors.
|
||||
Hooks levelHooks
|
||||
// All log entries pass through the formatter before logged to Out. The
|
||||
// included formatters are `TextFormatter` and `JSONFormatter` for which
|
||||
// TextFormatter is the default. In development (when a TTY is attached) it
|
||||
// logs with colors, but to a file it wouldn't. You can easily implement your
|
||||
// own that implements the `Formatter` interface, see the `README` or included
|
||||
// formatters for examples.
|
||||
Formatter Formatter
|
||||
// The logging level the logger should log at. This is typically (and defaults
|
||||
// to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be
|
||||
// logged. `logrus.Debug` is useful in
|
||||
Level Level
|
||||
// Used to sync writing to the log.
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
// Creates a new logger. Configuration should be set by changing `Formatter`,
|
||||
// `Out` and `Hooks` directly on the default logger instance. You can also just
|
||||
// instantiate your own:
|
||||
//
|
||||
// var log = &Logger{
|
||||
// Out: os.Stderr,
|
||||
// Formatter: new(JSONFormatter),
|
||||
// Hooks: make(levelHooks),
|
||||
// Level: logrus.DebugLevel,
|
||||
// }
|
||||
//
|
||||
// It's recommended to make this a global instance called `log`.
|
||||
func New() *Logger {
|
||||
return &Logger{
|
||||
Out: os.Stdout,
|
||||
Formatter: new(TextFormatter),
|
||||
Hooks: make(levelHooks),
|
||||
Level: InfoLevel,
|
||||
}
|
||||
}
|
||||
|
||||
// Adds a field to the log entry, note that you it doesn't log until you call
|
||||
// Debug, Print, Info, Warn, Fatal or Panic. It only creates a log entry.
|
||||
// Ff you want multiple fields, use `WithFields`.
|
||||
func (logger *Logger) WithField(key string, value interface{}) *Entry {
|
||||
return NewEntry(logger).WithField(key, value)
|
||||
}
|
||||
|
||||
// Adds a struct of fields to the log entry. All it does is call `WithField` for
|
||||
// each `Field`.
|
||||
func (logger *Logger) WithFields(fields Fields) *Entry {
|
||||
return NewEntry(logger).WithFields(fields)
|
||||
}
|
||||
|
||||
func (logger *Logger) Debugf(format string, args ...interface{}) {
|
||||
if logger.Level >= DebugLevel {
|
||||
NewEntry(logger).Debugf(format, args...)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Infof(format string, args ...interface{}) {
|
||||
if logger.Level >= InfoLevel {
|
||||
NewEntry(logger).Infof(format, args...)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Printf(format string, args ...interface{}) {
|
||||
NewEntry(logger).Printf(format, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Warnf(format string, args ...interface{}) {
|
||||
if logger.Level >= WarnLevel {
|
||||
NewEntry(logger).Warnf(format, args...)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Warningf(format string, args ...interface{}) {
|
||||
if logger.Level >= WarnLevel {
|
||||
NewEntry(logger).Warnf(format, args...)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Errorf(format string, args ...interface{}) {
|
||||
if logger.Level >= ErrorLevel {
|
||||
NewEntry(logger).Errorf(format, args...)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Fatalf(format string, args ...interface{}) {
|
||||
if logger.Level >= FatalLevel {
|
||||
NewEntry(logger).Fatalf(format, args...)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Panicf(format string, args ...interface{}) {
|
||||
if logger.Level >= PanicLevel {
|
||||
NewEntry(logger).Panicf(format, args...)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Debug(args ...interface{}) {
|
||||
if logger.Level >= DebugLevel {
|
||||
NewEntry(logger).Debug(args...)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Info(args ...interface{}) {
|
||||
if logger.Level >= InfoLevel {
|
||||
NewEntry(logger).Info(args...)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Print(args ...interface{}) {
|
||||
NewEntry(logger).Info(args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Warn(args ...interface{}) {
|
||||
if logger.Level >= WarnLevel {
|
||||
NewEntry(logger).Warn(args...)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Warning(args ...interface{}) {
|
||||
if logger.Level >= WarnLevel {
|
||||
NewEntry(logger).Warn(args...)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Error(args ...interface{}) {
|
||||
if logger.Level >= ErrorLevel {
|
||||
NewEntry(logger).Error(args...)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Fatal(args ...interface{}) {
|
||||
if logger.Level >= FatalLevel {
|
||||
NewEntry(logger).Fatal(args...)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Panic(args ...interface{}) {
|
||||
if logger.Level >= PanicLevel {
|
||||
NewEntry(logger).Panic(args...)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Debugln(args ...interface{}) {
|
||||
if logger.Level >= DebugLevel {
|
||||
NewEntry(logger).Debugln(args...)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Infoln(args ...interface{}) {
|
||||
if logger.Level >= InfoLevel {
|
||||
NewEntry(logger).Infoln(args...)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Println(args ...interface{}) {
|
||||
NewEntry(logger).Println(args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Warnln(args ...interface{}) {
|
||||
if logger.Level >= WarnLevel {
|
||||
NewEntry(logger).Warnln(args...)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Warningln(args ...interface{}) {
|
||||
if logger.Level >= WarnLevel {
|
||||
NewEntry(logger).Warnln(args...)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Errorln(args ...interface{}) {
|
||||
if logger.Level >= ErrorLevel {
|
||||
NewEntry(logger).Errorln(args...)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Fatalln(args ...interface{}) {
|
||||
if logger.Level >= FatalLevel {
|
||||
NewEntry(logger).Fatalln(args...)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Panicln(args ...interface{}) {
|
||||
if logger.Level >= PanicLevel {
|
||||
NewEntry(logger).Panicln(args...)
|
||||
}
|
||||
}
|
||||
94
Godeps/_workspace/src/github.com/Sirupsen/logrus/logrus.go
generated
vendored
94
Godeps/_workspace/src/github.com/Sirupsen/logrus/logrus.go
generated
vendored
@ -1,94 +0,0 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
)
|
||||
|
||||
// Fields type, used to pass to `WithFields`.
|
||||
type Fields map[string]interface{}
|
||||
|
||||
// Level type
|
||||
type Level uint8
|
||||
|
||||
// Convert the Level to a string. E.g. PanicLevel becomes "panic".
|
||||
func (level Level) String() string {
|
||||
switch level {
|
||||
case DebugLevel:
|
||||
return "debug"
|
||||
case InfoLevel:
|
||||
return "info"
|
||||
case WarnLevel:
|
||||
return "warning"
|
||||
case ErrorLevel:
|
||||
return "error"
|
||||
case FatalLevel:
|
||||
return "fatal"
|
||||
case PanicLevel:
|
||||
return "panic"
|
||||
}
|
||||
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
// ParseLevel takes a string level and returns the Logrus log level constant.
|
||||
func ParseLevel(lvl string) (Level, error) {
|
||||
switch lvl {
|
||||
case "panic":
|
||||
return PanicLevel, nil
|
||||
case "fatal":
|
||||
return FatalLevel, nil
|
||||
case "error":
|
||||
return ErrorLevel, nil
|
||||
case "warn", "warning":
|
||||
return WarnLevel, nil
|
||||
case "info":
|
||||
return InfoLevel, nil
|
||||
case "debug":
|
||||
return DebugLevel, nil
|
||||
}
|
||||
|
||||
var l Level
|
||||
return l, fmt.Errorf("not a valid logrus Level: %q", lvl)
|
||||
}
|
||||
|
||||
// These are the different logging levels. You can set the logging level to log
|
||||
// on your instance of logger, obtained with `logrus.New()`.
|
||||
const (
|
||||
// PanicLevel level, highest level of severity. Logs and then calls panic with the
|
||||
// message passed to Debug, Info, ...
|
||||
PanicLevel Level = iota
|
||||
// FatalLevel level. Logs and then calls `os.Exit(1)`. It will exit even if the
|
||||
// logging level is set to Panic.
|
||||
FatalLevel
|
||||
// ErrorLevel level. Logs. Used for errors that should definitely be noted.
|
||||
// Commonly used for hooks to send errors to an error tracking service.
|
||||
ErrorLevel
|
||||
// WarnLevel level. Non-critical entries that deserve eyes.
|
||||
WarnLevel
|
||||
// InfoLevel level. General operational entries about what's going on inside the
|
||||
// application.
|
||||
InfoLevel
|
||||
// DebugLevel level. Usually only enabled when debugging. Very verbose logging.
|
||||
DebugLevel
|
||||
)
|
||||
|
||||
// Won't compile if StdLogger can't be realized by a log.Logger
|
||||
var _ StdLogger = &log.Logger{}
|
||||
|
||||
// StdLogger is what your logrus-enabled library should take, that way
|
||||
// it'll accept a stdlib logger and a logrus logger. There's no standard
|
||||
// interface, this is the closest we get, unfortunately.
|
||||
type StdLogger interface {
|
||||
Print(...interface{})
|
||||
Printf(string, ...interface{})
|
||||
Println(...interface{})
|
||||
|
||||
Fatal(...interface{})
|
||||
Fatalf(string, ...interface{})
|
||||
Fatalln(...interface{})
|
||||
|
||||
Panic(...interface{})
|
||||
Panicf(string, ...interface{})
|
||||
Panicln(...interface{})
|
||||
}
|
||||
301
Godeps/_workspace/src/github.com/Sirupsen/logrus/logrus_test.go
generated
vendored
301
Godeps/_workspace/src/github.com/Sirupsen/logrus/logrus_test.go
generated
vendored
@ -1,301 +0,0 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func LogAndAssertJSON(t *testing.T, log func(*Logger), assertions func(fields Fields)) {
|
||||
var buffer bytes.Buffer
|
||||
var fields Fields
|
||||
|
||||
logger := New()
|
||||
logger.Out = &buffer
|
||||
logger.Formatter = new(JSONFormatter)
|
||||
|
||||
log(logger)
|
||||
|
||||
err := json.Unmarshal(buffer.Bytes(), &fields)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assertions(fields)
|
||||
}
|
||||
|
||||
func LogAndAssertText(t *testing.T, log func(*Logger), assertions func(fields map[string]string)) {
|
||||
var buffer bytes.Buffer
|
||||
|
||||
logger := New()
|
||||
logger.Out = &buffer
|
||||
logger.Formatter = &TextFormatter{
|
||||
DisableColors: true,
|
||||
}
|
||||
|
||||
log(logger)
|
||||
|
||||
fields := make(map[string]string)
|
||||
for _, kv := range strings.Split(buffer.String(), " ") {
|
||||
if !strings.Contains(kv, "=") {
|
||||
continue
|
||||
}
|
||||
kvArr := strings.Split(kv, "=")
|
||||
key := strings.TrimSpace(kvArr[0])
|
||||
val := kvArr[1]
|
||||
if kvArr[1][0] == '"' {
|
||||
var err error
|
||||
val, err = strconv.Unquote(val)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
fields[key] = val
|
||||
}
|
||||
assertions(fields)
|
||||
}
|
||||
|
||||
func TestPrint(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Print("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["msg"], "test")
|
||||
assert.Equal(t, fields["level"], "info")
|
||||
})
|
||||
}
|
||||
|
||||
func TestInfo(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Info("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["msg"], "test")
|
||||
assert.Equal(t, fields["level"], "info")
|
||||
})
|
||||
}
|
||||
|
||||
func TestWarn(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Warn("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["msg"], "test")
|
||||
assert.Equal(t, fields["level"], "warning")
|
||||
})
|
||||
}
|
||||
|
||||
func TestInfolnShouldAddSpacesBetweenStrings(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Infoln("test", "test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["msg"], "test test")
|
||||
})
|
||||
}
|
||||
|
||||
func TestInfolnShouldAddSpacesBetweenStringAndNonstring(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Infoln("test", 10)
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["msg"], "test 10")
|
||||
})
|
||||
}
|
||||
|
||||
func TestInfolnShouldAddSpacesBetweenTwoNonStrings(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Infoln(10, 10)
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["msg"], "10 10")
|
||||
})
|
||||
}
|
||||
|
||||
func TestInfoShouldAddSpacesBetweenTwoNonStrings(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Infoln(10, 10)
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["msg"], "10 10")
|
||||
})
|
||||
}
|
||||
|
||||
func TestInfoShouldNotAddSpacesBetweenStringAndNonstring(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Info("test", 10)
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["msg"], "test10")
|
||||
})
|
||||
}
|
||||
|
||||
func TestInfoShouldNotAddSpacesBetweenStrings(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.Info("test", "test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["msg"], "testtest")
|
||||
})
|
||||
}
|
||||
|
||||
func TestWithFieldsShouldAllowAssignments(t *testing.T) {
|
||||
var buffer bytes.Buffer
|
||||
var fields Fields
|
||||
|
||||
logger := New()
|
||||
logger.Out = &buffer
|
||||
logger.Formatter = new(JSONFormatter)
|
||||
|
||||
localLog := logger.WithFields(Fields{
|
||||
"key1": "value1",
|
||||
})
|
||||
|
||||
localLog.WithField("key2", "value2").Info("test")
|
||||
err := json.Unmarshal(buffer.Bytes(), &fields)
|
||||
assert.Nil(t, err)
|
||||
|
||||
assert.Equal(t, "value2", fields["key2"])
|
||||
assert.Equal(t, "value1", fields["key1"])
|
||||
|
||||
buffer = bytes.Buffer{}
|
||||
fields = Fields{}
|
||||
localLog.Info("test")
|
||||
err = json.Unmarshal(buffer.Bytes(), &fields)
|
||||
assert.Nil(t, err)
|
||||
|
||||
_, ok := fields["key2"]
|
||||
assert.Equal(t, false, ok)
|
||||
assert.Equal(t, "value1", fields["key1"])
|
||||
}
|
||||
|
||||
func TestUserSuppliedFieldDoesNotOverwriteDefaults(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.WithField("msg", "hello").Info("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["msg"], "test")
|
||||
})
|
||||
}
|
||||
|
||||
func TestUserSuppliedMsgFieldHasPrefix(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.WithField("msg", "hello").Info("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["msg"], "test")
|
||||
assert.Equal(t, fields["fields.msg"], "hello")
|
||||
})
|
||||
}
|
||||
|
||||
func TestUserSuppliedTimeFieldHasPrefix(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.WithField("time", "hello").Info("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["fields.time"], "hello")
|
||||
})
|
||||
}
|
||||
|
||||
func TestUserSuppliedLevelFieldHasPrefix(t *testing.T) {
|
||||
LogAndAssertJSON(t, func(log *Logger) {
|
||||
log.WithField("level", 1).Info("test")
|
||||
}, func(fields Fields) {
|
||||
assert.Equal(t, fields["level"], "info")
|
||||
assert.Equal(t, fields["fields.level"], 1.0) // JSON has floats only
|
||||
})
|
||||
}
|
||||
|
||||
func TestDefaultFieldsAreNotPrefixed(t *testing.T) {
|
||||
LogAndAssertText(t, func(log *Logger) {
|
||||
ll := log.WithField("herp", "derp")
|
||||
ll.Info("hello")
|
||||
ll.Info("bye")
|
||||
}, func(fields map[string]string) {
|
||||
for _, fieldName := range []string{"fields.level", "fields.time", "fields.msg"} {
|
||||
if _, ok := fields[fieldName]; ok {
|
||||
t.Fatalf("should not have prefixed %q: %v", fieldName, fields)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestDoubleLoggingDoesntPrefixPreviousFields(t *testing.T) {
|
||||
|
||||
var buffer bytes.Buffer
|
||||
var fields Fields
|
||||
|
||||
logger := New()
|
||||
logger.Out = &buffer
|
||||
logger.Formatter = new(JSONFormatter)
|
||||
|
||||
llog := logger.WithField("context", "eating raw fish")
|
||||
|
||||
llog.Info("looks delicious")
|
||||
|
||||
err := json.Unmarshal(buffer.Bytes(), &fields)
|
||||
assert.NoError(t, err, "should have decoded first message")
|
||||
assert.Equal(t, len(fields), 4, "should only have msg/time/level/context fields")
|
||||
assert.Equal(t, fields["msg"], "looks delicious")
|
||||
assert.Equal(t, fields["context"], "eating raw fish")
|
||||
|
||||
buffer.Reset()
|
||||
|
||||
llog.Warn("omg it is!")
|
||||
|
||||
err = json.Unmarshal(buffer.Bytes(), &fields)
|
||||
assert.NoError(t, err, "should have decoded second message")
|
||||
assert.Equal(t, len(fields), 4, "should only have msg/time/level/context fields")
|
||||
assert.Equal(t, fields["msg"], "omg it is!")
|
||||
assert.Equal(t, fields["context"], "eating raw fish")
|
||||
assert.Nil(t, fields["fields.msg"], "should not have prefixed previous `msg` entry")
|
||||
|
||||
}
|
||||
|
||||
func TestConvertLevelToString(t *testing.T) {
|
||||
assert.Equal(t, "debug", DebugLevel.String())
|
||||
assert.Equal(t, "info", InfoLevel.String())
|
||||
assert.Equal(t, "warning", WarnLevel.String())
|
||||
assert.Equal(t, "error", ErrorLevel.String())
|
||||
assert.Equal(t, "fatal", FatalLevel.String())
|
||||
assert.Equal(t, "panic", PanicLevel.String())
|
||||
}
|
||||
|
||||
func TestParseLevel(t *testing.T) {
|
||||
l, err := ParseLevel("panic")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, PanicLevel, l)
|
||||
|
||||
l, err = ParseLevel("fatal")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, FatalLevel, l)
|
||||
|
||||
l, err = ParseLevel("error")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, ErrorLevel, l)
|
||||
|
||||
l, err = ParseLevel("warn")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, WarnLevel, l)
|
||||
|
||||
l, err = ParseLevel("warning")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, WarnLevel, l)
|
||||
|
||||
l, err = ParseLevel("info")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, InfoLevel, l)
|
||||
|
||||
l, err = ParseLevel("debug")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, DebugLevel, l)
|
||||
|
||||
l, err = ParseLevel("invalid")
|
||||
assert.Equal(t, "not a valid logrus Level: \"invalid\"", err.Error())
|
||||
}
|
||||
|
||||
func TestGetSetLevelRace(t *testing.T) {
|
||||
wg := sync.WaitGroup{}
|
||||
for i := 0; i < 100; i++ {
|
||||
wg.Add(1)
|
||||
go func(i int) {
|
||||
defer wg.Done()
|
||||
if i%2 == 0 {
|
||||
SetLevel(InfoLevel)
|
||||
} else {
|
||||
GetLevel()
|
||||
}
|
||||
}(i)
|
||||
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
12
Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_darwin.go
generated
vendored
12
Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_darwin.go
generated
vendored
@ -1,12 +0,0 @@
|
||||
// Based on ssh/terminal:
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package logrus
|
||||
|
||||
import "syscall"
|
||||
|
||||
const ioctlReadTermios = syscall.TIOCGETA
|
||||
|
||||
type Termios syscall.Termios
|
||||
20
Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_freebsd.go
generated
vendored
20
Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_freebsd.go
generated
vendored
@ -1,20 +0,0 @@
|
||||
/*
|
||||
Go 1.2 doesn't include Termios for FreeBSD. This should be added in 1.3 and this could be merged with terminal_darwin.
|
||||
*/
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
const ioctlReadTermios = syscall.TIOCGETA
|
||||
|
||||
type Termios struct {
|
||||
Iflag uint32
|
||||
Oflag uint32
|
||||
Cflag uint32
|
||||
Lflag uint32
|
||||
Cc [20]uint8
|
||||
Ispeed uint32
|
||||
Ospeed uint32
|
||||
}
|
||||
12
Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_linux.go
generated
vendored
12
Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_linux.go
generated
vendored
@ -1,12 +0,0 @@
|
||||
// Based on ssh/terminal:
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package logrus
|
||||
|
||||
import "syscall"
|
||||
|
||||
const ioctlReadTermios = syscall.TCGETS
|
||||
|
||||
type Termios syscall.Termios
|
||||
21
Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_notwindows.go
generated
vendored
21
Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_notwindows.go
generated
vendored
@ -1,21 +0,0 @@
|
||||
// Based on ssh/terminal:
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build linux darwin freebsd openbsd
|
||||
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// IsTerminal returns true if the given file descriptor is a terminal.
|
||||
func IsTerminal() bool {
|
||||
fd := syscall.Stdout
|
||||
var termios Termios
|
||||
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
|
||||
return err == 0
|
||||
}
|
||||
7
Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_openbsd.go
generated
vendored
7
Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_openbsd.go
generated
vendored
@ -1,7 +0,0 @@
|
||||
package logrus
|
||||
|
||||
import "syscall"
|
||||
|
||||
const ioctlReadTermios = syscall.TIOCGETA
|
||||
|
||||
type Termios syscall.Termios
|
||||
27
Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_windows.go
generated
vendored
27
Godeps/_workspace/src/github.com/Sirupsen/logrus/terminal_windows.go
generated
vendored
@ -1,27 +0,0 @@
|
||||
// Based on ssh/terminal:
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows
|
||||
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||
|
||||
var (
|
||||
procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
|
||||
)
|
||||
|
||||
// IsTerminal returns true if the given file descriptor is a terminal.
|
||||
func IsTerminal() bool {
|
||||
fd := syscall.Stdout
|
||||
var st uint32
|
||||
r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0)
|
||||
return r != 0 && e == 0
|
||||
}
|
||||
149
Godeps/_workspace/src/github.com/Sirupsen/logrus/text_formatter.go
generated
vendored
149
Godeps/_workspace/src/github.com/Sirupsen/logrus/text_formatter.go
generated
vendored
@ -1,149 +0,0 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
nocolor = 0
|
||||
red = 31
|
||||
green = 32
|
||||
yellow = 33
|
||||
blue = 34
|
||||
gray = 37
|
||||
)
|
||||
|
||||
var (
|
||||
baseTimestamp time.Time
|
||||
isTerminal bool
|
||||
)
|
||||
|
||||
func init() {
|
||||
baseTimestamp = time.Now()
|
||||
isTerminal = IsTerminal()
|
||||
}
|
||||
|
||||
func miniTS() int {
|
||||
return int(time.Since(baseTimestamp) / time.Second)
|
||||
}
|
||||
|
||||
type TextFormatter struct {
|
||||
// Set to true to bypass checking for a TTY before outputting colors.
|
||||
ForceColors bool
|
||||
|
||||
// Force disabling colors.
|
||||
DisableColors bool
|
||||
|
||||
// Disable timestamp logging. useful when output is redirected to logging
|
||||
// system that already adds timestamps.
|
||||
DisableTimestamp bool
|
||||
|
||||
// Enable logging the full timestamp when a TTY is attached instead of just
|
||||
// the time passed since beginning of execution.
|
||||
FullTimestamp bool
|
||||
|
||||
// TimestampFormat to use for display when a full timestamp is printed
|
||||
TimestampFormat string
|
||||
|
||||
// The fields are sorted by default for a consistent output. For applications
|
||||
// that log extremely frequently and don't use the JSON formatter this may not
|
||||
// be desired.
|
||||
DisableSorting bool
|
||||
}
|
||||
|
||||
func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
||||
var keys []string = make([]string, 0, len(entry.Data))
|
||||
for k := range entry.Data {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
|
||||
if !f.DisableSorting {
|
||||
sort.Strings(keys)
|
||||
}
|
||||
|
||||
b := &bytes.Buffer{}
|
||||
|
||||
prefixFieldClashes(entry.Data)
|
||||
|
||||
isColored := (f.ForceColors || isTerminal) && !f.DisableColors
|
||||
|
||||
if f.TimestampFormat == "" {
|
||||
f.TimestampFormat = DefaultTimestampFormat
|
||||
}
|
||||
if isColored {
|
||||
f.printColored(b, entry, keys)
|
||||
} else {
|
||||
if !f.DisableTimestamp {
|
||||
f.appendKeyValue(b, "time", entry.Time.Format(f.TimestampFormat))
|
||||
}
|
||||
f.appendKeyValue(b, "level", entry.Level.String())
|
||||
f.appendKeyValue(b, "msg", entry.Message)
|
||||
for _, key := range keys {
|
||||
f.appendKeyValue(b, key, entry.Data[key])
|
||||
}
|
||||
}
|
||||
|
||||
b.WriteByte('\n')
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string) {
|
||||
var levelColor int
|
||||
switch entry.Level {
|
||||
case DebugLevel:
|
||||
levelColor = gray
|
||||
case WarnLevel:
|
||||
levelColor = yellow
|
||||
case ErrorLevel, FatalLevel, PanicLevel:
|
||||
levelColor = red
|
||||
default:
|
||||
levelColor = blue
|
||||
}
|
||||
|
||||
levelText := strings.ToUpper(entry.Level.String())[0:4]
|
||||
|
||||
if !f.FullTimestamp {
|
||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, miniTS(), entry.Message)
|
||||
} else {
|
||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %-44s ", levelColor, levelText, entry.Time.Format(f.TimestampFormat), entry.Message)
|
||||
}
|
||||
for _, k := range keys {
|
||||
v := entry.Data[k]
|
||||
fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=%v", levelColor, k, v)
|
||||
}
|
||||
}
|
||||
|
||||
func needsQuoting(text string) bool {
|
||||
for _, ch := range text {
|
||||
if !((ch >= 'a' && ch <= 'z') ||
|
||||
(ch >= 'A' && ch <= 'Z') ||
|
||||
(ch >= '0' && ch <= '9') ||
|
||||
ch == '-' || ch == '.') {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key, value interface{}) {
|
||||
switch value.(type) {
|
||||
case string:
|
||||
if needsQuoting(value.(string)) {
|
||||
fmt.Fprintf(b, "%v=%s ", key, value)
|
||||
} else {
|
||||
fmt.Fprintf(b, "%v=%q ", key, value)
|
||||
}
|
||||
case error:
|
||||
if needsQuoting(value.(error).Error()) {
|
||||
fmt.Fprintf(b, "%v=%s ", key, value)
|
||||
} else {
|
||||
fmt.Fprintf(b, "%v=%q ", key, value)
|
||||
}
|
||||
default:
|
||||
fmt.Fprintf(b, "%v=%v ", key, value)
|
||||
}
|
||||
}
|
||||
61
Godeps/_workspace/src/github.com/Sirupsen/logrus/text_formatter_test.go
generated
vendored
61
Godeps/_workspace/src/github.com/Sirupsen/logrus/text_formatter_test.go
generated
vendored
@ -1,61 +0,0 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestQuoting(t *testing.T) {
|
||||
tf := &TextFormatter{DisableColors: true}
|
||||
|
||||
checkQuoting := func(q bool, value interface{}) {
|
||||
b, _ := tf.Format(WithField("test", value))
|
||||
idx := bytes.Index(b, ([]byte)("test="))
|
||||
cont := bytes.Contains(b[idx+5:], []byte{'"'})
|
||||
if cont != q {
|
||||
if q {
|
||||
t.Errorf("quoting expected for: %#v", value)
|
||||
} else {
|
||||
t.Errorf("quoting not expected for: %#v", value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
checkQuoting(false, "abcd")
|
||||
checkQuoting(false, "v1.0")
|
||||
checkQuoting(false, "1234567890")
|
||||
checkQuoting(true, "/foobar")
|
||||
checkQuoting(true, "x y")
|
||||
checkQuoting(true, "x,y")
|
||||
checkQuoting(false, errors.New("invalid"))
|
||||
checkQuoting(true, errors.New("invalid argument"))
|
||||
}
|
||||
|
||||
func TestTimestampFormat(t *testing.T) {
|
||||
checkTimeStr := func(format string) {
|
||||
customFormatter := &TextFormatter{DisableColors: true, TimestampFormat: format}
|
||||
customStr, _ := customFormatter.Format(WithField("test", "test"))
|
||||
timeStart := bytes.Index(customStr, ([]byte)("time="))
|
||||
timeEnd := bytes.Index(customStr, ([]byte)("level="))
|
||||
timeStr := customStr[timeStart+5 : timeEnd-1]
|
||||
if timeStr[0] == '"' && timeStr[len(timeStr)-1] == '"' {
|
||||
timeStr = timeStr[1 : len(timeStr)-1]
|
||||
}
|
||||
if format == "" {
|
||||
format = time.RFC3339
|
||||
}
|
||||
_, e := time.Parse(format, (string)(timeStr))
|
||||
if e != nil {
|
||||
t.Errorf("time string \"%s\" did not match provided time format \"%s\": %s", timeStr, format, e)
|
||||
}
|
||||
}
|
||||
|
||||
checkTimeStr("2006-01-02T15:04:05.000000000Z07:00")
|
||||
checkTimeStr("Mon Jan _2 15:04:05 2006")
|
||||
checkTimeStr("")
|
||||
}
|
||||
|
||||
// TODO add tests for sorting etc., this requires a parser for the text
|
||||
// formatter output.
|
||||
31
Godeps/_workspace/src/github.com/Sirupsen/logrus/writer.go
generated
vendored
31
Godeps/_workspace/src/github.com/Sirupsen/logrus/writer.go
generated
vendored
@ -1,31 +0,0 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func (logger *Logger) Writer() *io.PipeWriter {
|
||||
reader, writer := io.Pipe()
|
||||
|
||||
go logger.writerScanner(reader)
|
||||
runtime.SetFinalizer(writer, writerFinalizer)
|
||||
|
||||
return writer
|
||||
}
|
||||
|
||||
func (logger *Logger) writerScanner(reader *io.PipeReader) {
|
||||
scanner := bufio.NewScanner(reader)
|
||||
for scanner.Scan() {
|
||||
logger.Print(scanner.Text())
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
logger.Errorf("Error while reading from Writer: %s", err)
|
||||
}
|
||||
reader.Close()
|
||||
}
|
||||
|
||||
func writerFinalizer(writer *io.PipeWriter) {
|
||||
writer.Close()
|
||||
}
|
||||
2
Godeps/_workspace/src/github.com/ipfs/go-log/.gxlastpubver
generated
vendored
2
Godeps/_workspace/src/github.com/ipfs/go-log/.gxlastpubver
generated
vendored
@ -1 +1 @@
|
||||
QmXJkcEXB6C9h6Ytb6rrUTFU56Ro62zxgrbxTT3dgjQGA8
|
||||
QmTBXYb6y2ZcJmoXVKk3pf9rzSEjbCg7tQaJW7RSuH14nv
|
||||
35
Godeps/_workspace/src/github.com/ipfs/go-log/entry.go
generated
vendored
35
Godeps/_workspace/src/github.com/ipfs/go-log/entry.go
generated
vendored
@ -1,42 +1,7 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
type entry struct {
|
||||
loggables []Loggable
|
||||
system string
|
||||
event string
|
||||
}
|
||||
|
||||
// Log logs the event unconditionally (regardless of log level)
|
||||
// TODO add support for leveled-logs once we decide which levels we want
|
||||
// for our structured logs
|
||||
func (e *entry) Log() {
|
||||
e.log()
|
||||
}
|
||||
|
||||
// log is a private method invoked by the public Log, Info, Error methods
|
||||
func (e *entry) log() {
|
||||
// accumulate metadata
|
||||
accum := Metadata{}
|
||||
for _, loggable := range e.loggables {
|
||||
accum = DeepMerge(accum, loggable.Loggable())
|
||||
}
|
||||
|
||||
// apply final attributes to reserved keys
|
||||
// TODO accum["level"] = level
|
||||
accum["event"] = e.event
|
||||
accum["system"] = e.system
|
||||
accum["time"] = FormatRFC3339(time.Now())
|
||||
|
||||
// TODO roll our own event logger
|
||||
logrus.WithFields(map[string]interface{}(accum)).Info(e.event)
|
||||
}
|
||||
|
||||
func FormatRFC3339(t time.Time) string {
|
||||
return t.UTC().Format(time.RFC3339Nano)
|
||||
}
|
||||
|
||||
33
Godeps/_workspace/src/github.com/ipfs/go-log/log.go
generated
vendored
33
Godeps/_workspace/src/github.com/ipfs/go-log/log.go
generated
vendored
@ -1,6 +1,7 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
@ -53,13 +54,12 @@ func Logger(system string) EventLogger {
|
||||
// TODO if we would like to adjust log levels at run-time. Store this event
|
||||
// logger in a map (just like the util.Logger impl)
|
||||
if len(system) == 0 {
|
||||
log.Warnf("Missing name parameter")
|
||||
setuplog := getLogger("setup-logger")
|
||||
setuplog.Warning("Missing name parameter")
|
||||
system = "undefined"
|
||||
}
|
||||
if _, ok := loggers[system]; !ok {
|
||||
loggers[system] = log.WithField("module", system)
|
||||
}
|
||||
logger := loggers[system]
|
||||
|
||||
logger := getLogger(system)
|
||||
|
||||
return &eventLogger{system: system, StandardLogger: logger}
|
||||
}
|
||||
@ -116,7 +116,24 @@ func (el *eventLogger) Event(ctx context.Context, event string, metadata ...Logg
|
||||
event: event,
|
||||
}
|
||||
|
||||
e.Log() // TODO replace this when leveled-logs have been implemented
|
||||
accum := Metadata{}
|
||||
for _, loggable := range e.loggables {
|
||||
accum = DeepMerge(accum, loggable.Loggable())
|
||||
}
|
||||
|
||||
// apply final attributes to reserved keys
|
||||
// TODO accum["level"] = level
|
||||
accum["event"] = e.event
|
||||
accum["system"] = e.system
|
||||
accum["time"] = FormatRFC3339(time.Now())
|
||||
|
||||
out, err := json.Marshal(accum)
|
||||
if err != nil {
|
||||
el.Errorf("ERROR FORMATTING EVENT ENTRY: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
WriterGroup.Write(append(out, '\n'))
|
||||
}
|
||||
|
||||
type EventInProgress struct {
|
||||
@ -147,3 +164,7 @@ func (eip *EventInProgress) Close() error {
|
||||
eip.Done()
|
||||
return nil
|
||||
}
|
||||
|
||||
func FormatRFC3339(t time.Time) string {
|
||||
return t.UTC().Format(time.RFC3339Nano)
|
||||
}
|
||||
|
||||
61
Godeps/_workspace/src/github.com/ipfs/go-log/oldlog.go
generated
vendored
61
Godeps/_workspace/src/github.com/ipfs/go-log/oldlog.go
generated
vendored
@ -4,22 +4,22 @@ import (
|
||||
"errors"
|
||||
"os"
|
||||
|
||||
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/Sirupsen/logrus"
|
||||
logging "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/whyrusleeping/go-logging"
|
||||
)
|
||||
|
||||
func init() {
|
||||
SetupLogging()
|
||||
}
|
||||
|
||||
var log = logrus.New()
|
||||
var ansiGray = "\033[0;37m"
|
||||
var ansiBlue = "\033[0;34m"
|
||||
|
||||
// LogFormats is a map of formats used for our logger, keyed by name.
|
||||
// TODO: write custom TextFormatter (don't print module=name explicitly) and
|
||||
// fork logrus to add shortfile
|
||||
var LogFormats = map[string]*logrus.TextFormatter{
|
||||
"nocolor": {DisableColors: true, FullTimestamp: true, TimestampFormat: "2006-01-02 15:04:05.000000", DisableSorting: true},
|
||||
"color": {DisableColors: false, FullTimestamp: true, TimestampFormat: "15:04:05:000", DisableSorting: true},
|
||||
var LogFormats = map[string]string{
|
||||
"nocolor": "%{time:2006-01-02 15:04:05.000000} %{level} %{module} %{shortfile}: %{message}",
|
||||
"color": ansiGray + "%{time:15:04:05.000} %{color}%{level:5.5s} " + ansiBlue +
|
||||
"%{module:10.10s}: %{color:reset}%{message} " + ansiGray + "%{shortfile}%{color:reset}",
|
||||
}
|
||||
|
||||
var defaultLogFormat = "color"
|
||||
|
||||
// Logging environment variables
|
||||
@ -32,50 +32,50 @@ const (
|
||||
var ErrNoSuchLogger = errors.New("Error: No such logger")
|
||||
|
||||
// loggers is the set of loggers in the system
|
||||
var loggers = map[string]*logrus.Entry{}
|
||||
var loggers = map[string]*logging.Logger{}
|
||||
|
||||
// SetupLogging will initialize the logger backend and set the flags.
|
||||
func SetupLogging() {
|
||||
|
||||
format, ok := LogFormats[os.Getenv(envLoggingFmt)]
|
||||
if !ok {
|
||||
format = LogFormats[defaultLogFormat]
|
||||
fmt := LogFormats[os.Getenv(envLoggingFmt)]
|
||||
if fmt == "" {
|
||||
fmt = LogFormats[defaultLogFormat]
|
||||
}
|
||||
|
||||
log.Out = os.Stderr
|
||||
log.Formatter = format
|
||||
backend := logging.NewLogBackend(os.Stderr, "", 0)
|
||||
logging.SetBackend(backend)
|
||||
logging.SetFormatter(logging.MustStringFormatter(fmt))
|
||||
|
||||
lvl := logrus.ErrorLevel
|
||||
lvl := logging.ERROR
|
||||
|
||||
if logenv := os.Getenv(envLogging); logenv != "" {
|
||||
var err error
|
||||
lvl, err = logrus.ParseLevel(logenv)
|
||||
lvl, err = logging.LogLevel(logenv)
|
||||
if err != nil {
|
||||
log.Debugf("logrus.ParseLevel() Error: %q", err)
|
||||
lvl = logrus.ErrorLevel // reset to ERROR, could be undefined now(?)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
SetAllLoggers(lvl)
|
||||
}
|
||||
|
||||
// SetDebugLogging calls SetAllLoggers with logrus.DebugLevel
|
||||
// SetDebugLogging calls SetAllLoggers with logging.DEBUG
|
||||
func SetDebugLogging() {
|
||||
SetAllLoggers(logrus.DebugLevel)
|
||||
SetAllLoggers(logging.DEBUG)
|
||||
}
|
||||
|
||||
// SetAllLoggers changes the logrus.Level of all loggers to lvl
|
||||
func SetAllLoggers(lvl logrus.Level) {
|
||||
log.Level = lvl
|
||||
for _, logger := range loggers {
|
||||
logger.Level = lvl
|
||||
// SetAllLoggers changes the logging.Level of all loggers to lvl
|
||||
func SetAllLoggers(lvl logging.Level) {
|
||||
logging.SetLevel(lvl, "")
|
||||
for n := range loggers {
|
||||
logging.SetLevel(lvl, n)
|
||||
}
|
||||
}
|
||||
|
||||
// SetLogLevel changes the log level of a specific subsystem
|
||||
// name=="*" changes all subsystems
|
||||
func SetLogLevel(name, level string) error {
|
||||
lvl, err := logrus.ParseLevel(level)
|
||||
lvl, err := logging.LogLevel(level)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -91,7 +91,14 @@ func SetLogLevel(name, level string) error {
|
||||
return ErrNoSuchLogger
|
||||
}
|
||||
|
||||
loggers[name].Level = lvl
|
||||
logging.SetLevel(lvl, name)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getLogger(name string) *logging.Logger {
|
||||
log := logging.MustGetLogger(name)
|
||||
log.ExtraCalldepth = 1
|
||||
loggers[name] = log
|
||||
return log
|
||||
}
|
||||
|
||||
19
Godeps/_workspace/src/github.com/ipfs/go-log/option.go
generated
vendored
19
Godeps/_workspace/src/github.com/ipfs/go-log/option.go
generated
vendored
@ -4,7 +4,7 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/Sirupsen/logrus"
|
||||
logging "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/whyrusleeping/go-logging"
|
||||
)
|
||||
|
||||
// init sets up sane defaults
|
||||
@ -30,32 +30,33 @@ func Configure(options ...Option) {
|
||||
|
||||
// LdJSONFormatter Option formats the event log as line-delimited JSON
|
||||
var LdJSONFormatter = func() {
|
||||
logrus.SetFormatter(&PoliteJSONFormatter{})
|
||||
logging.SetFormatter(&PoliteJSONFormatter{})
|
||||
}
|
||||
|
||||
// TextFormatter Option formats the event log as human-readable plain-text
|
||||
var TextFormatter = func() {
|
||||
logrus.SetFormatter(&logrus.TextFormatter{})
|
||||
logging.SetFormatter(logging.DefaultFormatter)
|
||||
}
|
||||
|
||||
func Output(w io.Writer) Option {
|
||||
return func() {
|
||||
logrus.SetOutput(w)
|
||||
backend := logging.NewLogBackend(w, "", 0)
|
||||
logging.SetBackend(backend)
|
||||
// TODO return previous Output option
|
||||
}
|
||||
}
|
||||
|
||||
// LevelDebug Option sets the log level to debug
|
||||
var LevelDebug = func() {
|
||||
logrus.SetLevel(logrus.DebugLevel)
|
||||
logging.SetLevel(logging.DEBUG, "")
|
||||
}
|
||||
|
||||
// LevelDebug Option sets the log level to error
|
||||
// LevelError Option sets the log level to error
|
||||
var LevelError = func() {
|
||||
logrus.SetLevel(logrus.ErrorLevel)
|
||||
logging.SetLevel(logging.ERROR, "")
|
||||
}
|
||||
|
||||
// LevelDebug Option sets the log level to info
|
||||
// LevelInfo Option sets the log level to info
|
||||
var LevelInfo = func() {
|
||||
logrus.SetLevel(logrus.InfoLevel)
|
||||
logging.SetLevel(logging.INFO, "")
|
||||
}
|
||||
|
||||
20
Godeps/_workspace/src/github.com/ipfs/go-log/polite_json_formatter.go
generated
vendored
20
Godeps/_workspace/src/github.com/ipfs/go-log/polite_json_formatter.go
generated
vendored
@ -2,19 +2,27 @@ package log
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/Sirupsen/logrus"
|
||||
logging "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/whyrusleeping/go-logging"
|
||||
)
|
||||
|
||||
// PoliteJSONFormatter marshals entries into JSON encoded slices (without
|
||||
// overwriting user-provided keys). How polite of it!
|
||||
type PoliteJSONFormatter struct{}
|
||||
|
||||
func (f *PoliteJSONFormatter) Format(entry *logrus.Entry) ([]byte, error) {
|
||||
serialized, err := json.Marshal(entry.Data)
|
||||
func (f *PoliteJSONFormatter) Format(calldepth int, r *logging.Record, w io.Writer) error {
|
||||
entry := make(map[string]interface{})
|
||||
entry["id"] = r.Id
|
||||
entry["level"] = r.Level
|
||||
entry["time"] = r.Time
|
||||
entry["module"] = r.Module
|
||||
entry["message"] = r.Message()
|
||||
err := json.NewEncoder(w).Encode(entry)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
|
||||
return err
|
||||
}
|
||||
return append(serialized, '\n'), nil
|
||||
|
||||
w.Write([]byte{'\n'})
|
||||
return nil
|
||||
}
|
||||
|
||||
19
Godeps/_workspace/src/github.com/ipfs/go-log/writer.go
generated
vendored
19
Godeps/_workspace/src/github.com/ipfs/go-log/writer.go
generated
vendored
@ -13,27 +13,24 @@ type MirrorWriter struct {
|
||||
func (mw *MirrorWriter) Write(b []byte) (int, error) {
|
||||
mw.lk.Lock()
|
||||
// write to all writers, and nil out the broken ones.
|
||||
var dropped bool
|
||||
for i, w := range mw.writers {
|
||||
_, err := w.Write(b)
|
||||
if err != nil {
|
||||
mw.writers[i] = nil
|
||||
dropped = true
|
||||
}
|
||||
}
|
||||
|
||||
// consolidate the slice
|
||||
for i := 0; i < len(mw.writers); i++ {
|
||||
if mw.writers[i] != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
j := len(mw.writers) - 1
|
||||
for ; j > i; j-- {
|
||||
if mw.writers[j] != nil {
|
||||
mw.writers[i], mw.writers[j] = mw.writers[j], nil // swap
|
||||
break
|
||||
if dropped {
|
||||
writers := mw.writers
|
||||
mw.writers = nil
|
||||
for _, w := range writers {
|
||||
if w != nil {
|
||||
mw.writers = append(mw.writers, w)
|
||||
}
|
||||
}
|
||||
mw.writers = mw.writers[:j]
|
||||
}
|
||||
mw.lk.Unlock()
|
||||
return len(b), nil
|
||||
|
||||
6
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/.travis.yml
generated
vendored
Normal file
6
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.0
|
||||
- 1.1
|
||||
- tip
|
||||
5
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/CONTRIBUTORS
generated
vendored
Normal file
5
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/CONTRIBUTORS
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
Alec Thomas <alec@swapoff.org>
|
||||
Guilhem Lettron <guilhem.lettron@optiflows.com>
|
||||
Ivan Daniluk <ivan.daniluk@gmail.com>
|
||||
Nimi Wariboko Jr <nimi@channelmeter.com>
|
||||
Róbert Selvek <robert.selvek@gmail.com>
|
||||
27
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/LICENSE
generated
vendored
Normal file
27
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/LICENSE
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
Copyright (c) 2013 Örjan Persson. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
89
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/README.md
generated
vendored
Normal file
89
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/README.md
generated
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
## Golang logging library
|
||||
|
||||
[](https://godoc.org/github.com/op/go-logging) [](https://travis-ci.org/op/go-logging)
|
||||
|
||||
Package logging implements a logging infrastructure for Go. Its output format
|
||||
is customizable and supports different logging backends like syslog, file and
|
||||
memory. Multiple backends can be utilized with different log levels per backend
|
||||
and logger.
|
||||
|
||||
## Example
|
||||
|
||||
Let's have a look at an [example](examples/example.go) which demonstrates most
|
||||
of the features found in this library.
|
||||
|
||||
[](examples/example.go)
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/op/go-logging"
|
||||
)
|
||||
|
||||
var log = logging.MustGetLogger("example")
|
||||
|
||||
// Example format string. Everything except the message has a custom color
|
||||
// which is dependent on the log level. Many fields have a custom output
|
||||
// formatting too, eg. the time returns the hour down to the milli second.
|
||||
var format = logging.MustStringFormatter(
|
||||
"%{color}%{time:15:04:05.000} %{shortfunc} ▶ %{level:.4s} %{id:03x}%{color:reset} %{message}",
|
||||
)
|
||||
|
||||
// Password is just an example type implementing the Redactor interface. Any
|
||||
// time this is logged, the Redacted() function will be called.
|
||||
type Password string
|
||||
|
||||
func (p Password) Redacted() interface{} {
|
||||
return logging.Redact(string(p))
|
||||
}
|
||||
|
||||
func main() {
|
||||
// For demo purposes, create two backend for os.Stderr.
|
||||
backend1 := logging.NewLogBackend(os.Stderr, "", 0)
|
||||
backend2 := logging.NewLogBackend(os.Stderr, "", 0)
|
||||
|
||||
// For messages written to backend2 we want to add some additional
|
||||
// information to the output, including the used log level and the name of
|
||||
// the function.
|
||||
backend2Formatter := logging.NewBackendFormatter(backend2, format)
|
||||
|
||||
// Only errors and more severe messages should be sent to backend1
|
||||
backend1Leveled := logging.AddModuleLevel(backend1)
|
||||
backend1Leveled.SetLevel(logging.ERROR, "")
|
||||
|
||||
// Set the backends to be used.
|
||||
logging.SetBackend(backend1Leveled, backend2Formatter)
|
||||
|
||||
log.Debug("debug %s", Password("secret"))
|
||||
log.Info("info")
|
||||
log.Notice("notice")
|
||||
log.Warning("warning")
|
||||
log.Error("err")
|
||||
log.Critical("crit")
|
||||
}
|
||||
```
|
||||
|
||||
## Installing
|
||||
|
||||
### Using *go get*
|
||||
|
||||
$ go get github.com/op/go-logging
|
||||
|
||||
After this command *go-logging* is ready to use. Its source will be in:
|
||||
|
||||
$GOROOT/src/pkg/github.com/op/go-logging
|
||||
|
||||
You can use `go get -u` to update the package.
|
||||
|
||||
## Documentation
|
||||
|
||||
For docs, see http://godoc.org/github.com/op/go-logging or run:
|
||||
|
||||
$ godoc github.com/op/go-logging
|
||||
|
||||
## Additional resources
|
||||
|
||||
* [wslog](https://godoc.org/github.com/cryptix/go/logging/wslog) -- exposes log messages through a WebSocket.
|
||||
39
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/backend.go
generated
vendored
Normal file
39
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/backend.go
generated
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
// Copyright 2013, Örjan Persson. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package logging
|
||||
|
||||
// defaultBackend is the backend used for all logging calls.
|
||||
var defaultBackend LeveledBackend
|
||||
|
||||
// Backend is the interface which a log backend need to implement to be able to
|
||||
// be used as a logging backend.
|
||||
type Backend interface {
|
||||
Log(Level, int, *Record) error
|
||||
}
|
||||
|
||||
// Set backend replaces the backend currently set with the given new logging
|
||||
// backend.
|
||||
func SetBackend(backends ...Backend) LeveledBackend {
|
||||
var backend Backend
|
||||
if len(backends) == 1 {
|
||||
backend = backends[0]
|
||||
} else {
|
||||
backend = MultiLogger(backends...)
|
||||
}
|
||||
|
||||
defaultBackend = AddModuleLevel(backend)
|
||||
return defaultBackend
|
||||
}
|
||||
|
||||
// SetLevel sets the logging level for the specified module. The module
|
||||
// corresponds to the string specified in GetLogger.
|
||||
func SetLevel(level Level, module string) {
|
||||
defaultBackend.SetLevel(level, module)
|
||||
}
|
||||
|
||||
// GetLevel returns the logging level for the specified module.
|
||||
func GetLevel(module string) Level {
|
||||
return defaultBackend.GetLevel(module)
|
||||
}
|
||||
40
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/example_test.go
generated
vendored
Normal file
40
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/example_test.go
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
package logging
|
||||
|
||||
import "os"
|
||||
|
||||
func Example() {
|
||||
// This call is for testing purposes and will set the time to unix epoch.
|
||||
InitForTesting(DEBUG)
|
||||
|
||||
var log = MustGetLogger("example")
|
||||
|
||||
// For demo purposes, create two backend for os.Stdout.
|
||||
//
|
||||
// os.Stderr should most likely be used in the real world but then the
|
||||
// "Output:" check in this example would not work.
|
||||
backend1 := NewLogBackend(os.Stdout, "", 0)
|
||||
backend2 := NewLogBackend(os.Stdout, "", 0)
|
||||
|
||||
// For messages written to backend2 we want to add some additional
|
||||
// information to the output, including the used log level and the name of
|
||||
// the function.
|
||||
var format = MustStringFormatter(
|
||||
"%{time:15:04:05.000} %{shortfunc} %{level:.1s} %{message}",
|
||||
)
|
||||
backend2Formatter := NewBackendFormatter(backend2, format)
|
||||
|
||||
// Only errors and more severe messages should be sent to backend2
|
||||
backend2Leveled := AddModuleLevel(backend2Formatter)
|
||||
backend2Leveled.SetLevel(ERROR, "")
|
||||
|
||||
// Set the backends to be used and the default level.
|
||||
SetBackend(backend1, backend2Leveled)
|
||||
|
||||
log.Debug("debug %s", "arg")
|
||||
log.Error("error")
|
||||
|
||||
// Output:
|
||||
// debug arg
|
||||
// error
|
||||
// 00:00:00.000 Example E error
|
||||
}
|
||||
49
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/examples/example.go
generated
vendored
Normal file
49
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/examples/example.go
generated
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/whyrusleeping/go-logging"
|
||||
)
|
||||
|
||||
var log = logging.MustGetLogger("example")
|
||||
|
||||
// Example format string. Everything except the message has a custom color
|
||||
// which is dependent on the log level. Many fields have a custom output
|
||||
// formatting too, eg. the time returns the hour down to the milli second.
|
||||
var format = logging.MustStringFormatter(
|
||||
"%{color}%{time:15:04:05.000} %{shortfunc} ▶ %{level:.4s} %{id:03x}%{color:reset} %{message}",
|
||||
)
|
||||
|
||||
// Password is just an example type implementing the Redactor interface. Any
|
||||
// time this is logged, the Redacted() function will be called.
|
||||
type Password string
|
||||
|
||||
func (p Password) Redacted() interface{} {
|
||||
return logging.Redact(string(p))
|
||||
}
|
||||
|
||||
func main() {
|
||||
// For demo purposes, create two backend for os.Stderr.
|
||||
backend1 := logging.NewLogBackend(os.Stderr, "", 0)
|
||||
backend2 := logging.NewLogBackend(os.Stderr, "", 0)
|
||||
|
||||
// For messages written to backend2 we want to add some additional
|
||||
// information to the output, including the used log level and the name of
|
||||
// the function.
|
||||
backend2Formatter := logging.NewBackendFormatter(backend2, format)
|
||||
|
||||
// Only errors and more severe messages should be sent to backend1
|
||||
backend1Leveled := logging.AddModuleLevel(backend1)
|
||||
backend1Leveled.SetLevel(logging.ERROR, "")
|
||||
|
||||
// Set the backends to be used.
|
||||
logging.SetBackend(backend1Leveled, backend2Formatter)
|
||||
|
||||
log.Debug("debug %s", Password("secret"))
|
||||
log.Info("info")
|
||||
log.Notice("notice")
|
||||
log.Warning("warning")
|
||||
log.Error("err")
|
||||
log.Critical("crit")
|
||||
}
|
||||
BIN
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/examples/example.png
generated
vendored
Normal file
BIN
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/examples/example.png
generated
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
368
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/format.go
generated
vendored
Normal file
368
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/format.go
generated
vendored
Normal file
@ -0,0 +1,368 @@
|
||||
// Copyright 2013, Örjan Persson. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package logging
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// TODO see Formatter interface in fmt/print.go
|
||||
// TODO try text/template, maybe it have enough performance
|
||||
// TODO other template systems?
|
||||
// TODO make it possible to specify formats per backend?
|
||||
type fmtVerb int
|
||||
|
||||
const (
|
||||
fmtVerbTime fmtVerb = iota
|
||||
fmtVerbLevel
|
||||
fmtVerbId
|
||||
fmtVerbPid
|
||||
fmtVerbProgram
|
||||
fmtVerbModule
|
||||
fmtVerbMessage
|
||||
fmtVerbLongfile
|
||||
fmtVerbShortfile
|
||||
fmtVerbLongpkg
|
||||
fmtVerbShortpkg
|
||||
fmtVerbLongfunc
|
||||
fmtVerbShortfunc
|
||||
fmtVerbLevelColor
|
||||
|
||||
// Keep last, there are no match for these below.
|
||||
fmtVerbUnknown
|
||||
fmtVerbStatic
|
||||
)
|
||||
|
||||
var fmtVerbs = []string{
|
||||
"time",
|
||||
"level",
|
||||
"id",
|
||||
"pid",
|
||||
"program",
|
||||
"module",
|
||||
"message",
|
||||
"longfile",
|
||||
"shortfile",
|
||||
"longpkg",
|
||||
"shortpkg",
|
||||
"longfunc",
|
||||
"shortfunc",
|
||||
"color",
|
||||
}
|
||||
|
||||
const rfc3339Milli = "2006-01-02T15:04:05.999Z07:00"
|
||||
|
||||
var defaultVerbsLayout = []string{
|
||||
rfc3339Milli,
|
||||
"s",
|
||||
"d",
|
||||
"d",
|
||||
"s",
|
||||
"s",
|
||||
"s",
|
||||
"s",
|
||||
"s",
|
||||
"s",
|
||||
"s",
|
||||
"s",
|
||||
"s",
|
||||
"",
|
||||
}
|
||||
|
||||
var (
|
||||
pid = os.Getpid()
|
||||
program = filepath.Base(os.Args[0])
|
||||
)
|
||||
|
||||
func getFmtVerbByName(name string) fmtVerb {
|
||||
for i, verb := range fmtVerbs {
|
||||
if name == verb {
|
||||
return fmtVerb(i)
|
||||
}
|
||||
}
|
||||
return fmtVerbUnknown
|
||||
}
|
||||
|
||||
// Formatter is the required interface for a custom log record formatter.
|
||||
type Formatter interface {
|
||||
Format(calldepth int, r *Record, w io.Writer) error
|
||||
}
|
||||
|
||||
// formatter is used by all backends unless otherwise overriden.
|
||||
var formatter struct {
|
||||
sync.RWMutex
|
||||
def Formatter
|
||||
}
|
||||
|
||||
func getFormatter() Formatter {
|
||||
formatter.RLock()
|
||||
defer formatter.RUnlock()
|
||||
return formatter.def
|
||||
}
|
||||
|
||||
var (
|
||||
// DefaultFormatter is the default formatter used and is only the message.
|
||||
DefaultFormatter Formatter = MustStringFormatter("%{message}")
|
||||
|
||||
// Glog format
|
||||
GlogFormatter Formatter = MustStringFormatter("%{level:.1s}%{time:0102 15:04:05.999999} %{pid} %{shortfile}] %{message}")
|
||||
)
|
||||
|
||||
// SetFormatter sets the default formatter for all new backends. A backend will
|
||||
// fetch this value once it is needed to format a record. Note that backends
|
||||
// will cache the formatter after the first point. For now, make sure to set
|
||||
// the formatter before logging.
|
||||
func SetFormatter(f Formatter) {
|
||||
formatter.Lock()
|
||||
defer formatter.Unlock()
|
||||
formatter.def = f
|
||||
}
|
||||
|
||||
var formatRe *regexp.Regexp = regexp.MustCompile(`%{([a-z]+)(?::(.*?[^\\]))?}`)
|
||||
|
||||
type part struct {
|
||||
verb fmtVerb
|
||||
layout string
|
||||
}
|
||||
|
||||
// stringFormatter contains a list of parts which explains how to build the
|
||||
// formatted string passed on to the logging backend.
|
||||
type stringFormatter struct {
|
||||
parts []part
|
||||
}
|
||||
|
||||
// NewStringFormatter returns a new Formatter which outputs the log record as a
|
||||
// string based on the 'verbs' specified in the format string.
|
||||
//
|
||||
// The verbs:
|
||||
//
|
||||
// General:
|
||||
// %{id} Sequence number for log message (uint64).
|
||||
// %{pid} Process id (int)
|
||||
// %{time} Time when log occurred (time.Time)
|
||||
// %{level} Log level (Level)
|
||||
// %{module} Module (string)
|
||||
// %{program} Basename of os.Args[0] (string)
|
||||
// %{message} Message (string)
|
||||
// %{longfile} Full file name and line number: /a/b/c/d.go:23
|
||||
// %{shortfile} Final file name element and line number: d.go:23
|
||||
// %{color} ANSI color based on log level
|
||||
//
|
||||
// For normal types, the output can be customized by using the 'verbs' defined
|
||||
// in the fmt package, eg. '%{id:04d}' to make the id output be '%04d' as the
|
||||
// format string.
|
||||
//
|
||||
// For time.Time, use the same layout as time.Format to change the time format
|
||||
// when output, eg "2006-01-02T15:04:05.999Z-07:00".
|
||||
//
|
||||
// For the 'color' verb, the output can be adjusted to either use bold colors,
|
||||
// i.e., '%{color:bold}' or to reset the ANSI attributes, i.e.,
|
||||
// '%{color:reset}' Note that if you use the color verb explicitly, be sure to
|
||||
// reset it or else the color state will persist past your log message. e.g.,
|
||||
// "%{color:bold}%{time:15:04:05} %{level:-8s}%{color:reset} %{message}" will
|
||||
// just colorize the time and level, leaving the message uncolored.
|
||||
//
|
||||
// There's also a couple of experimental 'verbs'. These are exposed to get
|
||||
// feedback and needs a bit of tinkering. Hence, they might change in the
|
||||
// future.
|
||||
//
|
||||
// Experimental:
|
||||
// %{longpkg} Full package path, eg. github.com/go-logging
|
||||
// %{shortpkg} Base package path, eg. go-logging
|
||||
// %{longfunc} Full function name, eg. littleEndian.PutUint32
|
||||
// %{shortfunc} Base function name, eg. PutUint32
|
||||
func NewStringFormatter(format string) (*stringFormatter, error) {
|
||||
var fmter = &stringFormatter{}
|
||||
|
||||
// Find the boundaries of all %{vars}
|
||||
matches := formatRe.FindAllStringSubmatchIndex(format, -1)
|
||||
if matches == nil {
|
||||
return nil, errors.New("logger: invalid log format: " + format)
|
||||
}
|
||||
|
||||
// Collect all variables and static text for the format
|
||||
prev := 0
|
||||
for _, m := range matches {
|
||||
start, end := m[0], m[1]
|
||||
if start > prev {
|
||||
fmter.add(fmtVerbStatic, format[prev:start])
|
||||
}
|
||||
|
||||
name := format[m[2]:m[3]]
|
||||
verb := getFmtVerbByName(name)
|
||||
if verb == fmtVerbUnknown {
|
||||
return nil, errors.New("logger: unknown variable: " + name)
|
||||
}
|
||||
|
||||
// Handle layout customizations or use the default. If this is not for the
|
||||
// time or color formatting, we need to prefix with %.
|
||||
layout := defaultVerbsLayout[verb]
|
||||
if m[4] != -1 {
|
||||
layout = format[m[4]:m[5]]
|
||||
}
|
||||
if verb != fmtVerbTime && verb != fmtVerbLevelColor {
|
||||
layout = "%" + layout
|
||||
}
|
||||
|
||||
fmter.add(verb, layout)
|
||||
prev = end
|
||||
}
|
||||
end := format[prev:]
|
||||
if end != "" {
|
||||
fmter.add(fmtVerbStatic, end)
|
||||
}
|
||||
|
||||
// Make a test run to make sure we can format it correctly.
|
||||
t, err := time.Parse(time.RFC3339, "2010-02-04T21:00:57-08:00")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
r := &Record{
|
||||
Id: 12345,
|
||||
Time: t,
|
||||
Module: "logger",
|
||||
fmt: "hello %s",
|
||||
args: []interface{}{"go"},
|
||||
}
|
||||
if err := fmter.Format(0, r, &bytes.Buffer{}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return fmter, nil
|
||||
}
|
||||
|
||||
// MustStringFormatter is equivalent to NewStringFormatter with a call to panic
|
||||
// on error.
|
||||
func MustStringFormatter(format string) *stringFormatter {
|
||||
f, err := NewStringFormatter(format)
|
||||
if err != nil {
|
||||
panic("Failed to initialized string formatter: " + err.Error())
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
func (f *stringFormatter) add(verb fmtVerb, layout string) {
|
||||
f.parts = append(f.parts, part{verb, layout})
|
||||
}
|
||||
|
||||
func (f *stringFormatter) Format(calldepth int, r *Record, output io.Writer) error {
|
||||
for _, part := range f.parts {
|
||||
if part.verb == fmtVerbStatic {
|
||||
output.Write([]byte(part.layout))
|
||||
} else if part.verb == fmtVerbTime {
|
||||
output.Write([]byte(r.Time.Format(part.layout)))
|
||||
} else if part.verb == fmtVerbLevelColor {
|
||||
if part.layout == "bold" {
|
||||
output.Write([]byte(boldcolors[r.Level]))
|
||||
} else if part.layout == "reset" {
|
||||
output.Write([]byte("\033[0m"))
|
||||
} else {
|
||||
output.Write([]byte(colors[r.Level]))
|
||||
}
|
||||
} else {
|
||||
var v interface{}
|
||||
switch part.verb {
|
||||
case fmtVerbLevel:
|
||||
v = r.Level
|
||||
break
|
||||
case fmtVerbId:
|
||||
v = r.Id
|
||||
break
|
||||
case fmtVerbPid:
|
||||
v = pid
|
||||
break
|
||||
case fmtVerbProgram:
|
||||
v = program
|
||||
break
|
||||
case fmtVerbModule:
|
||||
v = r.Module
|
||||
break
|
||||
case fmtVerbMessage:
|
||||
v = r.Message()
|
||||
break
|
||||
case fmtVerbLongfile, fmtVerbShortfile:
|
||||
_, file, line, ok := runtime.Caller(calldepth + 1)
|
||||
if !ok {
|
||||
file = "???"
|
||||
line = 0
|
||||
} else if part.verb == fmtVerbShortfile {
|
||||
file = filepath.Base(file)
|
||||
}
|
||||
v = fmt.Sprintf("%s:%d", file, line)
|
||||
case fmtVerbLongfunc, fmtVerbShortfunc,
|
||||
fmtVerbLongpkg, fmtVerbShortpkg:
|
||||
// TODO cache pc
|
||||
v = "???"
|
||||
if pc, _, _, ok := runtime.Caller(calldepth + 1); ok {
|
||||
if f := runtime.FuncForPC(pc); f != nil {
|
||||
v = formatFuncName(part.verb, f.Name())
|
||||
}
|
||||
}
|
||||
default:
|
||||
panic("unhandled format part")
|
||||
}
|
||||
fmt.Fprintf(output, part.layout, v)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// formatFuncName tries to extract certain part of the runtime formatted
|
||||
// function name to some pre-defined variation.
|
||||
//
|
||||
// This function is known to not work properly if the package path or name
|
||||
// contains a dot.
|
||||
func formatFuncName(v fmtVerb, f string) string {
|
||||
i := strings.LastIndex(f, "/")
|
||||
j := strings.Index(f[i+1:], ".")
|
||||
if j < 1 {
|
||||
return "???"
|
||||
}
|
||||
pkg, fun := f[:i+j+1], f[i+j+2:]
|
||||
switch v {
|
||||
case fmtVerbLongpkg:
|
||||
return pkg
|
||||
case fmtVerbShortpkg:
|
||||
return path.Base(pkg)
|
||||
case fmtVerbLongfunc:
|
||||
return fun
|
||||
case fmtVerbShortfunc:
|
||||
i = strings.LastIndex(fun, ".")
|
||||
return fun[i+1:]
|
||||
}
|
||||
panic("unexpected func formatter")
|
||||
}
|
||||
|
||||
// backendFormatter combines a backend with a specific formatter making it
|
||||
// possible to have different log formats for different backends.
|
||||
type backendFormatter struct {
|
||||
b Backend
|
||||
f Formatter
|
||||
}
|
||||
|
||||
// NewBackendFormatter creates a new backend which makes all records that
|
||||
// passes through it beeing formatted by the specific formatter.
|
||||
func NewBackendFormatter(b Backend, f Formatter) *backendFormatter {
|
||||
return &backendFormatter{b, f}
|
||||
}
|
||||
|
||||
// Log implements the Log function required by the Backend interface.
|
||||
func (bf *backendFormatter) Log(level Level, calldepth int, r *Record) error {
|
||||
// Make a shallow copy of the record and replace any formatter
|
||||
r2 := *r
|
||||
r2.formatter = bf.f
|
||||
return bf.b.Log(level, calldepth+1, &r2)
|
||||
}
|
||||
184
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/format_test.go
generated
vendored
Normal file
184
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/format_test.go
generated
vendored
Normal file
@ -0,0 +1,184 @@
|
||||
// Copyright 2013, Örjan Persson. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package logging
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFormat(t *testing.T) {
|
||||
backend := InitForTesting(DEBUG)
|
||||
|
||||
f, err := NewStringFormatter("%{shortfile} %{time:2006-01-02T15:04:05} %{level:.1s} %{id:04d} %{module} %{message}")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to set format: %s", err)
|
||||
}
|
||||
SetFormatter(f)
|
||||
|
||||
log := MustGetLogger("module")
|
||||
log.Debug("hello")
|
||||
|
||||
line := MemoryRecordN(backend, 0).Formatted(0)
|
||||
if "format_test.go:24 1970-01-01T00:00:00 D 0001 module hello" != line {
|
||||
t.Errorf("Unexpected format: %s", line)
|
||||
}
|
||||
}
|
||||
|
||||
func logAndGetLine(backend *MemoryBackend) string {
|
||||
MustGetLogger("foo").Debug("hello")
|
||||
return MemoryRecordN(backend, 0).Formatted(1)
|
||||
}
|
||||
|
||||
func getLastLine(backend *MemoryBackend) string {
|
||||
return MemoryRecordN(backend, 0).Formatted(1)
|
||||
}
|
||||
|
||||
func realFunc(backend *MemoryBackend) string {
|
||||
return logAndGetLine(backend)
|
||||
}
|
||||
|
||||
type structFunc struct{}
|
||||
|
||||
func (structFunc) Log(backend *MemoryBackend) string {
|
||||
return logAndGetLine(backend)
|
||||
}
|
||||
|
||||
func TestRealFuncFormat(t *testing.T) {
|
||||
backend := InitForTesting(DEBUG)
|
||||
SetFormatter(MustStringFormatter("%{shortfunc}"))
|
||||
|
||||
line := realFunc(backend)
|
||||
if "realFunc" != line {
|
||||
t.Errorf("Unexpected format: %s", line)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStructFuncFormat(t *testing.T) {
|
||||
backend := InitForTesting(DEBUG)
|
||||
SetFormatter(MustStringFormatter("%{longfunc}"))
|
||||
|
||||
var x structFunc
|
||||
line := x.Log(backend)
|
||||
if "structFunc.Log" != line {
|
||||
t.Errorf("Unexpected format: %s", line)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVarFuncFormat(t *testing.T) {
|
||||
backend := InitForTesting(DEBUG)
|
||||
SetFormatter(MustStringFormatter("%{shortfunc}"))
|
||||
|
||||
var varFunc = func() string {
|
||||
return logAndGetLine(backend)
|
||||
}
|
||||
|
||||
line := varFunc()
|
||||
if "???" == line || "TestVarFuncFormat" == line || "varFunc" == line {
|
||||
t.Errorf("Unexpected format: %s", line)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormatFuncName(t *testing.T) {
|
||||
var tests = []struct {
|
||||
filename string
|
||||
longpkg string
|
||||
shortpkg string
|
||||
longfunc string
|
||||
shortfunc string
|
||||
}{
|
||||
{"",
|
||||
"???",
|
||||
"???",
|
||||
"???",
|
||||
"???"},
|
||||
{"main",
|
||||
"???",
|
||||
"???",
|
||||
"???",
|
||||
"???"},
|
||||
{"main.",
|
||||
"main",
|
||||
"main",
|
||||
"",
|
||||
""},
|
||||
{"main.main",
|
||||
"main",
|
||||
"main",
|
||||
"main",
|
||||
"main"},
|
||||
{"github.com/op/go-logging.func·001",
|
||||
"github.com/op/go-logging",
|
||||
"go-logging",
|
||||
"func·001",
|
||||
"func·001"},
|
||||
{"github.com/op/go-logging.stringFormatter.Format",
|
||||
"github.com/op/go-logging",
|
||||
"go-logging",
|
||||
"stringFormatter.Format",
|
||||
"Format"},
|
||||
}
|
||||
|
||||
var v string
|
||||
for _, test := range tests {
|
||||
v = formatFuncName(fmtVerbLongpkg, test.filename)
|
||||
if test.longpkg != v {
|
||||
t.Errorf("%s != %s", test.longpkg, v)
|
||||
}
|
||||
v = formatFuncName(fmtVerbShortpkg, test.filename)
|
||||
if test.shortpkg != v {
|
||||
t.Errorf("%s != %s", test.shortpkg, v)
|
||||
}
|
||||
v = formatFuncName(fmtVerbLongfunc, test.filename)
|
||||
if test.longfunc != v {
|
||||
t.Errorf("%s != %s", test.longfunc, v)
|
||||
}
|
||||
v = formatFuncName(fmtVerbShortfunc, test.filename)
|
||||
if test.shortfunc != v {
|
||||
t.Errorf("%s != %s", test.shortfunc, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestBackendFormatter(t *testing.T) {
|
||||
InitForTesting(DEBUG)
|
||||
|
||||
// Create two backends and wrap one of the with a backend formatter
|
||||
b1 := NewMemoryBackend(1)
|
||||
b2 := NewMemoryBackend(1)
|
||||
|
||||
f := MustStringFormatter("%{level} %{message}")
|
||||
bf := NewBackendFormatter(b2, f)
|
||||
|
||||
SetBackend(b1, bf)
|
||||
|
||||
log := MustGetLogger("module")
|
||||
log.Info("foo")
|
||||
if "foo" != getLastLine(b1) {
|
||||
t.Errorf("Unexpected line: %s", getLastLine(b1))
|
||||
}
|
||||
if "INFO foo" != getLastLine(b2) {
|
||||
t.Errorf("Unexpected line: %s", getLastLine(b2))
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkStringFormatter(b *testing.B) {
|
||||
fmt := "%{time:2006-01-02T15:04:05} %{level:.1s} %{id:04d} %{module} %{message}"
|
||||
f := MustStringFormatter(fmt)
|
||||
|
||||
backend := InitForTesting(DEBUG)
|
||||
buf := &bytes.Buffer{}
|
||||
log := MustGetLogger("module")
|
||||
log.Debug("")
|
||||
record := MemoryRecordN(backend, 0)
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
if err := f.Format(1, record, buf); err != nil {
|
||||
b.Fatal(err)
|
||||
buf.Truncate(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
124
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/level.go
generated
vendored
Normal file
124
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/level.go
generated
vendored
Normal file
@ -0,0 +1,124 @@
|
||||
// Copyright 2013, Örjan Persson. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package logging
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var ErrInvalidLogLevel = errors.New("logger: invalid log level")
|
||||
|
||||
// Level defines all available log levels for log messages.
|
||||
type Level int
|
||||
|
||||
const (
|
||||
CRITICAL Level = iota
|
||||
ERROR
|
||||
WARNING
|
||||
NOTICE
|
||||
INFO
|
||||
DEBUG
|
||||
)
|
||||
|
||||
var levelNames = []string{
|
||||
"CRITICAL",
|
||||
"ERROR",
|
||||
"WARNING",
|
||||
"NOTICE",
|
||||
"INFO",
|
||||
"DEBUG",
|
||||
}
|
||||
|
||||
// String returns the string representation of a logging level.
|
||||
func (p Level) String() string {
|
||||
return levelNames[p]
|
||||
}
|
||||
|
||||
// LogLevel returns the log level from a string representation.
|
||||
func LogLevel(level string) (Level, error) {
|
||||
for i, name := range levelNames {
|
||||
if strings.EqualFold(name, level) {
|
||||
return Level(i), nil
|
||||
}
|
||||
}
|
||||
return ERROR, ErrInvalidLogLevel
|
||||
}
|
||||
|
||||
type Leveled interface {
|
||||
GetLevel(string) Level
|
||||
SetLevel(Level, string)
|
||||
IsEnabledFor(Level, string) bool
|
||||
}
|
||||
|
||||
// LeveledBackend is a log backend with additional knobs for setting levels on
|
||||
// individual modules to different levels.
|
||||
type LeveledBackend interface {
|
||||
Backend
|
||||
Leveled
|
||||
}
|
||||
|
||||
type moduleLeveled struct {
|
||||
levels map[string]Level
|
||||
backend Backend
|
||||
formatter Formatter
|
||||
once sync.Once
|
||||
}
|
||||
|
||||
// AddModuleLevel wraps a log backend with knobs to have different log levels
|
||||
// for different modules.
|
||||
func AddModuleLevel(backend Backend) LeveledBackend {
|
||||
var leveled LeveledBackend
|
||||
var ok bool
|
||||
if leveled, ok = backend.(LeveledBackend); !ok {
|
||||
leveled = &moduleLeveled{
|
||||
levels: make(map[string]Level),
|
||||
backend: backend,
|
||||
}
|
||||
}
|
||||
return leveled
|
||||
}
|
||||
|
||||
// GetLevel returns the log level for the given module.
|
||||
func (l *moduleLeveled) GetLevel(module string) Level {
|
||||
level, exists := l.levels[module]
|
||||
if exists == false {
|
||||
level, exists = l.levels[""]
|
||||
// no configuration exists, default to debug
|
||||
if exists == false {
|
||||
level = DEBUG
|
||||
}
|
||||
}
|
||||
return level
|
||||
}
|
||||
|
||||
// SetLevel sets the log level for the given module.
|
||||
func (l *moduleLeveled) SetLevel(level Level, module string) {
|
||||
l.levels[module] = level
|
||||
}
|
||||
|
||||
// IsEnabledFor will return true if logging is enabled for the given module.
|
||||
func (l *moduleLeveled) IsEnabledFor(level Level, module string) bool {
|
||||
return level <= l.GetLevel(module)
|
||||
}
|
||||
|
||||
func (l *moduleLeveled) Log(level Level, calldepth int, rec *Record) (err error) {
|
||||
if l.IsEnabledFor(level, rec.Module) {
|
||||
// TODO get rid of traces of formatter here. BackendFormatter should be used.
|
||||
rec.formatter = l.getFormatterAndCacheCurrent()
|
||||
err = l.backend.Log(level, calldepth+1, rec)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (l *moduleLeveled) getFormatterAndCacheCurrent() Formatter {
|
||||
l.once.Do(func() {
|
||||
if l.formatter == nil {
|
||||
l.formatter = getFormatter()
|
||||
}
|
||||
})
|
||||
return l.formatter
|
||||
}
|
||||
76
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/level_test.go
generated
vendored
Normal file
76
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/level_test.go
generated
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
// Copyright 2013, Örjan Persson. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package logging
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestLevelString(t *testing.T) {
|
||||
// Make sure all levels can be converted from string -> constant -> string
|
||||
for _, name := range levelNames {
|
||||
level, err := LogLevel(name)
|
||||
if err != nil {
|
||||
t.Errorf("failed to get level: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
if level.String() != name {
|
||||
t.Errorf("invalid level conversion: %v != %v", level, name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLevelLogLevel(t *testing.T) {
|
||||
tests := []struct {
|
||||
expected Level
|
||||
level string
|
||||
}{
|
||||
{-1, "bla"},
|
||||
{INFO, "iNfO"},
|
||||
{ERROR, "error"},
|
||||
{WARNING, "warninG"},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
level, err := LogLevel(test.level)
|
||||
if err != nil {
|
||||
if test.expected == -1 {
|
||||
continue
|
||||
} else {
|
||||
t.Errorf("failed to convert %s: %s", test.level, err)
|
||||
}
|
||||
}
|
||||
if test.expected != level {
|
||||
t.Errorf("failed to convert %s to level: %s != %s", test.level, test.expected, level)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLevelModuleLevel(t *testing.T) {
|
||||
backend := NewMemoryBackend(128)
|
||||
|
||||
leveled := AddModuleLevel(backend)
|
||||
leveled.SetLevel(NOTICE, "")
|
||||
leveled.SetLevel(ERROR, "foo")
|
||||
leveled.SetLevel(INFO, "foo.bar")
|
||||
leveled.SetLevel(WARNING, "bar")
|
||||
|
||||
expected := []struct {
|
||||
level Level
|
||||
module string
|
||||
}{
|
||||
{NOTICE, ""},
|
||||
{NOTICE, "something"},
|
||||
{ERROR, "foo"},
|
||||
{INFO, "foo.bar"},
|
||||
{WARNING, "bar"},
|
||||
}
|
||||
|
||||
for _, e := range expected {
|
||||
actual := leveled.GetLevel(e.module)
|
||||
if e.level != actual {
|
||||
t.Errorf("unexpected level in %s: %s != %s", e.module, e.level, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
80
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/log.go
generated
vendored
Normal file
80
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/log.go
generated
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
// Copyright 2013, Örjan Persson. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package logging
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
)
|
||||
|
||||
// TODO initialize here
|
||||
var colors []string
|
||||
var boldcolors []string
|
||||
|
||||
type color int
|
||||
|
||||
const (
|
||||
colorBlack = (iota + 30)
|
||||
colorRed
|
||||
colorGreen
|
||||
colorYellow
|
||||
colorBlue
|
||||
colorMagenta
|
||||
colorCyan
|
||||
colorWhite
|
||||
)
|
||||
|
||||
// LogBackend utilizes the standard log module.
|
||||
type LogBackend struct {
|
||||
Logger *log.Logger
|
||||
Color bool
|
||||
}
|
||||
|
||||
// NewLogBackend creates a new LogBackend.
|
||||
func NewLogBackend(out io.Writer, prefix string, flag int) *LogBackend {
|
||||
return &LogBackend{Logger: log.New(out, prefix, flag)}
|
||||
}
|
||||
|
||||
func (b *LogBackend) Log(level Level, calldepth int, rec *Record) error {
|
||||
if b.Color {
|
||||
buf := &bytes.Buffer{}
|
||||
buf.Write([]byte(colors[level]))
|
||||
buf.Write([]byte(rec.Formatted(calldepth + 1)))
|
||||
buf.Write([]byte("\033[0m"))
|
||||
// For some reason, the Go logger arbitrarily decided "2" was the correct
|
||||
// call depth...
|
||||
return b.Logger.Output(calldepth+2, buf.String())
|
||||
} else {
|
||||
return b.Logger.Output(calldepth+2, rec.Formatted(calldepth+1))
|
||||
}
|
||||
panic("should not be reached")
|
||||
}
|
||||
|
||||
func colorSeq(color color) string {
|
||||
return fmt.Sprintf("\033[%dm", int(color))
|
||||
}
|
||||
|
||||
func colorSeqBold(color color) string {
|
||||
return fmt.Sprintf("\033[%d;1m", int(color))
|
||||
}
|
||||
|
||||
func init() {
|
||||
colors = []string{
|
||||
CRITICAL: colorSeq(colorMagenta),
|
||||
ERROR: colorSeq(colorRed),
|
||||
WARNING: colorSeq(colorYellow),
|
||||
NOTICE: colorSeq(colorGreen),
|
||||
DEBUG: colorSeq(colorCyan),
|
||||
}
|
||||
boldcolors = []string{
|
||||
CRITICAL: colorSeqBold(colorMagenta),
|
||||
ERROR: colorSeqBold(colorRed),
|
||||
WARNING: colorSeqBold(colorYellow),
|
||||
NOTICE: colorSeqBold(colorGreen),
|
||||
DEBUG: colorSeqBold(colorCyan),
|
||||
}
|
||||
}
|
||||
118
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/log_test.go
generated
vendored
Normal file
118
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/log_test.go
generated
vendored
Normal file
@ -0,0 +1,118 @@
|
||||
// Copyright 2013, Örjan Persson. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package logging
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLogCalldepth(t *testing.T) {
|
||||
buf := &bytes.Buffer{}
|
||||
SetBackend(NewLogBackend(buf, "", log.Lshortfile))
|
||||
SetFormatter(MustStringFormatter("%{shortfile} %{level} %{message}"))
|
||||
|
||||
log := MustGetLogger("test")
|
||||
log.Info("test filename")
|
||||
|
||||
parts := strings.SplitN(buf.String(), " ", 2)
|
||||
|
||||
// Verify that the correct filename is registered by the stdlib logger
|
||||
if !strings.HasPrefix(parts[0], "log_test.go:") {
|
||||
t.Errorf("incorrect filename: %s", parts[0])
|
||||
}
|
||||
// Verify that the correct filename is registered by go-logging
|
||||
if !strings.HasPrefix(parts[1], "log_test.go:") {
|
||||
t.Errorf("incorrect filename: %s", parts[1])
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkLogMemoryBackendIgnored(b *testing.B) {
|
||||
backend := SetBackend(NewMemoryBackend(1024))
|
||||
backend.SetLevel(INFO, "")
|
||||
RunLogBenchmark(b)
|
||||
}
|
||||
|
||||
func BenchmarkLogMemoryBackend(b *testing.B) {
|
||||
backend := SetBackend(NewMemoryBackend(1024))
|
||||
backend.SetLevel(DEBUG, "")
|
||||
RunLogBenchmark(b)
|
||||
}
|
||||
|
||||
func BenchmarkLogChannelMemoryBackend(b *testing.B) {
|
||||
channelBackend := NewChannelMemoryBackend(1024)
|
||||
backend := SetBackend(channelBackend)
|
||||
backend.SetLevel(DEBUG, "")
|
||||
RunLogBenchmark(b)
|
||||
channelBackend.Flush()
|
||||
}
|
||||
|
||||
func BenchmarkLogLeveled(b *testing.B) {
|
||||
backend := SetBackend(NewLogBackend(ioutil.Discard, "", 0))
|
||||
backend.SetLevel(INFO, "")
|
||||
|
||||
RunLogBenchmark(b)
|
||||
}
|
||||
|
||||
func BenchmarkLogLogBackend(b *testing.B) {
|
||||
backend := SetBackend(NewLogBackend(ioutil.Discard, "", 0))
|
||||
backend.SetLevel(DEBUG, "")
|
||||
RunLogBenchmark(b)
|
||||
}
|
||||
|
||||
func BenchmarkLogLogBackendColor(b *testing.B) {
|
||||
colorizer := NewLogBackend(ioutil.Discard, "", 0)
|
||||
colorizer.Color = true
|
||||
backend := SetBackend(colorizer)
|
||||
backend.SetLevel(DEBUG, "")
|
||||
RunLogBenchmark(b)
|
||||
}
|
||||
|
||||
func BenchmarkLogLogBackendStdFlags(b *testing.B) {
|
||||
backend := SetBackend(NewLogBackend(ioutil.Discard, "", log.LstdFlags))
|
||||
backend.SetLevel(DEBUG, "")
|
||||
RunLogBenchmark(b)
|
||||
}
|
||||
|
||||
func BenchmarkLogLogBackendLongFileFlag(b *testing.B) {
|
||||
backend := SetBackend(NewLogBackend(ioutil.Discard, "", log.Llongfile))
|
||||
backend.SetLevel(DEBUG, "")
|
||||
RunLogBenchmark(b)
|
||||
}
|
||||
|
||||
func RunLogBenchmark(b *testing.B) {
|
||||
password := Password("foo")
|
||||
log := MustGetLogger("test")
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
log.Debug("log line for %d and this is rectified: %s", i, password)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkLogFixed(b *testing.B) {
|
||||
backend := SetBackend(NewLogBackend(ioutil.Discard, "", 0))
|
||||
backend.SetLevel(DEBUG, "")
|
||||
|
||||
RunLogBenchmarkFixedString(b)
|
||||
}
|
||||
|
||||
func BenchmarkLogFixedIgnored(b *testing.B) {
|
||||
backend := SetBackend(NewLogBackend(ioutil.Discard, "", 0))
|
||||
backend.SetLevel(INFO, "")
|
||||
RunLogBenchmarkFixedString(b)
|
||||
}
|
||||
|
||||
func RunLogBenchmarkFixedString(b *testing.B) {
|
||||
log := MustGetLogger("test")
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
log.Debug("some random fixed text")
|
||||
}
|
||||
}
|
||||
277
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/logger.go
generated
vendored
Normal file
277
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/logger.go
generated
vendored
Normal file
@ -0,0 +1,277 @@
|
||||
// Copyright 2013, Örjan Persson. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package logging implements a logging infrastructure for Go. It supports
|
||||
// different logging backends like syslog, file and memory. Multiple backends
|
||||
// can be utilized with different log levels per backend and logger.
|
||||
package logging
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Redactor is an interface for types that may contain sensitive information
|
||||
// (like passwords), which shouldn't be printed to the log. The idea was found
|
||||
// in relog as part of the vitness project.
|
||||
type Redactor interface {
|
||||
Redacted() interface{}
|
||||
}
|
||||
|
||||
// Redact returns a string of * having the same length as s.
|
||||
func Redact(s string) string {
|
||||
return strings.Repeat("*", len(s))
|
||||
}
|
||||
|
||||
var (
|
||||
// Sequence number is incremented and utilized for all log records created.
|
||||
sequenceNo uint64
|
||||
|
||||
// timeNow is a customizable for testing purposes.
|
||||
timeNow = time.Now
|
||||
)
|
||||
|
||||
// Record represents a log record and contains the timestamp when the record
|
||||
// was created, an increasing id, filename and line and finally the actual
|
||||
// formatted log line.
|
||||
type Record struct {
|
||||
Id uint64
|
||||
Time time.Time
|
||||
Module string
|
||||
Level Level
|
||||
|
||||
// message is kept as a pointer to have shallow copies update this once
|
||||
// needed.
|
||||
message *string
|
||||
args []interface{}
|
||||
fmt string
|
||||
formatter Formatter
|
||||
formatted string
|
||||
}
|
||||
|
||||
// Formatted returns the string-formatted version of a record.
|
||||
func (r *Record) Formatted(calldepth int) string {
|
||||
if r.formatted == "" {
|
||||
var buf bytes.Buffer
|
||||
r.formatter.Format(calldepth+1, r, &buf)
|
||||
r.formatted = buf.String()
|
||||
}
|
||||
return r.formatted
|
||||
}
|
||||
|
||||
// Message returns a string message for outputting. Redacts any record args
|
||||
// that implement the Redactor interface
|
||||
func (r *Record) Message() string {
|
||||
if r.message == nil {
|
||||
// Redact the arguments that implements the Redactor interface
|
||||
for i, arg := range r.args {
|
||||
if redactor, ok := arg.(Redactor); ok == true {
|
||||
r.args[i] = redactor.Redacted()
|
||||
}
|
||||
}
|
||||
msg := fmt.Sprintf(r.fmt, r.args...)
|
||||
r.message = &msg
|
||||
}
|
||||
return *r.message
|
||||
}
|
||||
|
||||
// Logger is a logging unit. It controls the flow of messages to a given
|
||||
// (swappable) backend.
|
||||
type Logger struct {
|
||||
Module string
|
||||
backend LeveledBackend
|
||||
haveBackend bool
|
||||
|
||||
// ExtraCallDepth can be used to add additional call depth when getting the
|
||||
// calling function. This is normally used when wrapping a logger.
|
||||
ExtraCalldepth int
|
||||
}
|
||||
|
||||
// SetBackend changes the backend of the logger.
|
||||
func (l *Logger) SetBackend(backend LeveledBackend) {
|
||||
l.backend = backend
|
||||
l.haveBackend = true
|
||||
}
|
||||
|
||||
// GetLogger creates and returns a Logger object based on the module name.
|
||||
// TODO call NewLogger and remove MustGetLogger?
|
||||
func GetLogger(module string) (*Logger, error) {
|
||||
return &Logger{Module: module}, nil
|
||||
}
|
||||
|
||||
// MustGetLogger is like GetLogger but panics if the logger can't be created.
|
||||
// It simplifies safe initialization of a global logger for eg. a package.
|
||||
func MustGetLogger(module string) *Logger {
|
||||
logger, err := GetLogger(module)
|
||||
if err != nil {
|
||||
panic("logger: " + module + ": " + err.Error())
|
||||
}
|
||||
return logger
|
||||
}
|
||||
|
||||
// Reset restores the internal state of the logging library.
|
||||
func Reset() {
|
||||
// TODO make a global Init() method to be less magic? or make it such that
|
||||
// if there's no backends at all configured, we could use some tricks to
|
||||
// automatically setup backends based if we have a TTY or not.
|
||||
sequenceNo = 0
|
||||
b := SetBackend(NewLogBackend(os.Stderr, "", log.LstdFlags))
|
||||
b.SetLevel(DEBUG, "")
|
||||
SetFormatter(DefaultFormatter)
|
||||
timeNow = time.Now
|
||||
}
|
||||
|
||||
// InitForTesting is a convenient method when using logging in a test. Once
|
||||
// called, the time will be frozen to January 1, 1970 UTC.
|
||||
func InitForTesting(level Level) *MemoryBackend {
|
||||
Reset()
|
||||
|
||||
memoryBackend := NewMemoryBackend(10240)
|
||||
|
||||
leveledBackend := AddModuleLevel(memoryBackend)
|
||||
leveledBackend.SetLevel(level, "")
|
||||
SetBackend(leveledBackend)
|
||||
|
||||
timeNow = func() time.Time {
|
||||
return time.Unix(0, 0).UTC()
|
||||
}
|
||||
return memoryBackend
|
||||
}
|
||||
|
||||
// IsEnabledFor returns true if the logger is enabled for the given level.
|
||||
func (l *Logger) IsEnabledFor(level Level) bool {
|
||||
return defaultBackend.IsEnabledFor(level, l.Module)
|
||||
}
|
||||
|
||||
func (l *Logger) log(lvl Level, format string, args ...interface{}) {
|
||||
if !l.IsEnabledFor(lvl) {
|
||||
return
|
||||
}
|
||||
|
||||
// Create the logging record and pass it in to the backend
|
||||
record := &Record{
|
||||
Id: atomic.AddUint64(&sequenceNo, 1),
|
||||
Time: timeNow(),
|
||||
Module: l.Module,
|
||||
Level: lvl,
|
||||
fmt: format,
|
||||
args: args,
|
||||
}
|
||||
|
||||
// TODO use channels to fan out the records to all backends?
|
||||
// TODO in case of errors, do something (tricky)
|
||||
|
||||
// calldepth=2 brings the stack up to the caller of the level
|
||||
// methods, Info(), Fatal(), etc.
|
||||
// ExtraCallDepth allows this to be extended further up the stack in case we
|
||||
// are wrapping these methods, eg. to expose them package level
|
||||
if l.haveBackend {
|
||||
l.backend.Log(lvl, 2+l.ExtraCalldepth, record)
|
||||
return
|
||||
}
|
||||
|
||||
defaultBackend.Log(lvl, 2+l.ExtraCalldepth, record)
|
||||
}
|
||||
|
||||
// Fatal is equivalent to l.Critical(fmt.Sprint()) followed by a call to os.Exit(1).
|
||||
func (l *Logger) Fatal(args ...interface{}) {
|
||||
s := fmt.Sprint(args...)
|
||||
l.log(CRITICAL, "%s", s)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Fatalf is equivalent to l.Critical followed by a call to os.Exit(1).
|
||||
func (l *Logger) Fatalf(format string, args ...interface{}) {
|
||||
l.log(CRITICAL, format, args...)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Panic is equivalent to l.Critical(fmt.Sprint()) followed by a call to panic().
|
||||
func (l *Logger) Panic(args ...interface{}) {
|
||||
s := fmt.Sprint(args...)
|
||||
l.log(CRITICAL, "%s", s)
|
||||
panic(s)
|
||||
}
|
||||
|
||||
// Panicf is equivalent to l.Critical followed by a call to panic().
|
||||
func (l *Logger) Panicf(format string, args ...interface{}) {
|
||||
s := fmt.Sprintf(format, args...)
|
||||
l.log(CRITICAL, "%s", s)
|
||||
panic(s)
|
||||
}
|
||||
|
||||
// Critical logs a message using CRITICAL as log level. (fmt.Sprint())
|
||||
func (l *Logger) Critical(args ...interface{}) {
|
||||
s := fmt.Sprint(args...)
|
||||
l.log(CRITICAL, "%s", s)
|
||||
}
|
||||
|
||||
// Criticalf logs a message using CRITICAL as log level.
|
||||
func (l *Logger) Criticalf(format string, args ...interface{}) {
|
||||
l.log(CRITICAL, format, args...)
|
||||
}
|
||||
|
||||
// Error logs a message using ERROR as log level. (fmt.Sprint())
|
||||
func (l *Logger) Error(args ...interface{}) {
|
||||
s := fmt.Sprint(args...)
|
||||
l.log(ERROR, "%s", s)
|
||||
}
|
||||
|
||||
// Errorf logs a message using ERROR as log level.
|
||||
func (l *Logger) Errorf(format string, args ...interface{}) {
|
||||
l.log(ERROR, format, args...)
|
||||
}
|
||||
|
||||
// Warning logs a message using WARNING as log level.
|
||||
func (l *Logger) Warning(args ...interface{}) {
|
||||
s := fmt.Sprint(args...)
|
||||
l.log(WARNING, "%s", s)
|
||||
}
|
||||
|
||||
// Warningf logs a message using WARNING as log level.
|
||||
func (l *Logger) Warningf(format string, args ...interface{}) {
|
||||
l.log(WARNING, format, args...)
|
||||
}
|
||||
|
||||
// Notice logs a message using NOTICE as log level.
|
||||
func (l *Logger) Notice(args ...interface{}) {
|
||||
s := fmt.Sprint(args...)
|
||||
l.log(NOTICE, "%s", s)
|
||||
}
|
||||
|
||||
// Noticef logs a message using NOTICE as log level.
|
||||
func (l *Logger) Noticef(format string, args ...interface{}) {
|
||||
l.log(NOTICE, format, args...)
|
||||
}
|
||||
|
||||
// Info logs a message using INFO as log level.
|
||||
func (l *Logger) Info(args ...interface{}) {
|
||||
s := fmt.Sprint(args...)
|
||||
l.log(INFO, "%s", s)
|
||||
}
|
||||
|
||||
// Infof logs a message using INFO as log level.
|
||||
func (l *Logger) Infof(format string, args ...interface{}) {
|
||||
l.log(INFO, format, args...)
|
||||
}
|
||||
|
||||
// Debug logs a message using DEBUG as log level.
|
||||
func (l *Logger) Debug(args ...interface{}) {
|
||||
s := fmt.Sprint(args...)
|
||||
l.log(DEBUG, "%s", s)
|
||||
}
|
||||
|
||||
// Debugf logs a message using DEBUG as log level.
|
||||
func (l *Logger) Debugf(format string, args ...interface{}) {
|
||||
l.log(DEBUG, format, args...)
|
||||
}
|
||||
|
||||
func init() {
|
||||
Reset()
|
||||
}
|
||||
53
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/logger_test.go
generated
vendored
Normal file
53
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/logger_test.go
generated
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
// Copyright 2013, Örjan Persson. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package logging
|
||||
|
||||
import "testing"
|
||||
|
||||
type Password string
|
||||
|
||||
func (p Password) Redacted() interface{} {
|
||||
return Redact(string(p))
|
||||
}
|
||||
|
||||
func TestSequenceNoOverflow(t *testing.T) {
|
||||
// Forcefully set the next sequence number to the maximum
|
||||
backend := InitForTesting(DEBUG)
|
||||
sequenceNo = ^uint64(0)
|
||||
|
||||
log := MustGetLogger("test")
|
||||
log.Debug("test")
|
||||
|
||||
if MemoryRecordN(backend, 0).Id != 0 {
|
||||
t.Errorf("Unexpected sequence no: %v", MemoryRecordN(backend, 0).Id)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRedact(t *testing.T) {
|
||||
backend := InitForTesting(DEBUG)
|
||||
password := Password("123456")
|
||||
log := MustGetLogger("test")
|
||||
log.Debugf("foo %s", password)
|
||||
if "foo ******" != MemoryRecordN(backend, 0).Formatted(0) {
|
||||
t.Errorf("redacted line: %v", MemoryRecordN(backend, 0))
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrivateBackend(t *testing.T) {
|
||||
stdBackend := InitForTesting(DEBUG)
|
||||
log := MustGetLogger("test")
|
||||
privateBackend := NewMemoryBackend(10240)
|
||||
lvlBackend := AddModuleLevel(privateBackend)
|
||||
lvlBackend.SetLevel(DEBUG, "")
|
||||
log.SetBackend(lvlBackend)
|
||||
log.Debug("to private backend")
|
||||
if stdBackend.size > 0 {
|
||||
t.Errorf("something in stdBackend, size of backend: %d", stdBackend.size)
|
||||
}
|
||||
if "to private baсkend" == MemoryRecordN(privateBackend, 0).Formatted(0) {
|
||||
t.Errorf("logged to defaultBackend: %s", MemoryRecordN(privateBackend, 0))
|
||||
}
|
||||
|
||||
}
|
||||
217
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/memory.go
generated
vendored
Normal file
217
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/memory.go
generated
vendored
Normal file
@ -0,0 +1,217 @@
|
||||
// Copyright 2013, Örjan Persson. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package logging
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// TODO pick one of the memory backends and stick with it or share interface.
|
||||
|
||||
// Node is a record node pointing to an optional next node.
|
||||
type node struct {
|
||||
next *node
|
||||
Record *Record
|
||||
}
|
||||
|
||||
// Next returns the next record node. If there's no node available, it will
|
||||
// return nil.
|
||||
func (n *node) Next() *node {
|
||||
return n.next
|
||||
}
|
||||
|
||||
// MemoryBackend is a simple memory based logging backend that will not produce
|
||||
// any output but merly keep records, up to the given size, in memory.
|
||||
type MemoryBackend struct {
|
||||
size int32
|
||||
maxSize int32
|
||||
head, tail unsafe.Pointer
|
||||
}
|
||||
|
||||
// NewMemoryBackend creates a simple in-memory logging backend.
|
||||
func NewMemoryBackend(size int) *MemoryBackend {
|
||||
return &MemoryBackend{maxSize: int32(size)}
|
||||
}
|
||||
|
||||
// Log implements the Log method required by Backend.
|
||||
func (b *MemoryBackend) Log(level Level, calldepth int, rec *Record) error {
|
||||
var size int32
|
||||
|
||||
n := &node{Record: rec}
|
||||
np := unsafe.Pointer(n)
|
||||
|
||||
// Add the record to the tail. If there's no records available, tail and
|
||||
// head will both be nil. When we successfully set the tail and the previous
|
||||
// value was nil, it's safe to set the head to the current value too.
|
||||
for {
|
||||
tailp := b.tail
|
||||
swapped := atomic.CompareAndSwapPointer(
|
||||
&b.tail,
|
||||
tailp,
|
||||
np,
|
||||
)
|
||||
if swapped == true {
|
||||
if tailp == nil {
|
||||
b.head = np
|
||||
} else {
|
||||
(*node)(tailp).next = n
|
||||
}
|
||||
size = atomic.AddInt32(&b.size, 1)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Since one record was added, we might have overflowed the list. Remove
|
||||
// a record if that is the case. The size will fluctate a bit, but
|
||||
// eventual consistent.
|
||||
if b.maxSize > 0 && size > b.maxSize {
|
||||
for {
|
||||
headp := b.head
|
||||
head := (*node)(b.head)
|
||||
if head.next == nil {
|
||||
break
|
||||
}
|
||||
swapped := atomic.CompareAndSwapPointer(
|
||||
&b.head,
|
||||
headp,
|
||||
unsafe.Pointer(head.next),
|
||||
)
|
||||
if swapped == true {
|
||||
atomic.AddInt32(&b.size, -1)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Head returns the oldest record node kept in memory. It can be used to
|
||||
// iterate over records, one by one, up to the last record.
|
||||
//
|
||||
// Note: new records can get added while iterating. Hence the number of records
|
||||
// iterated over might be larger than the maximum size.
|
||||
func (b *MemoryBackend) Head() *node {
|
||||
return (*node)(b.head)
|
||||
}
|
||||
|
||||
type event int
|
||||
|
||||
const (
|
||||
eventFlush event = iota
|
||||
eventStop
|
||||
)
|
||||
|
||||
// ChannelMemoryBackend is very similar to the MemoryBackend, except that it
|
||||
// internally utilizes a channel.
|
||||
type ChannelMemoryBackend struct {
|
||||
maxSize int
|
||||
size int
|
||||
incoming chan *Record
|
||||
events chan event
|
||||
mu sync.Mutex
|
||||
running bool
|
||||
flushWg sync.WaitGroup
|
||||
stopWg sync.WaitGroup
|
||||
head, tail *node
|
||||
}
|
||||
|
||||
// NewChannelMemoryBackend creates a simple in-memory logging backend which
|
||||
// utilizes a go channel for communication.
|
||||
//
|
||||
// Start will automatically be called by this function.
|
||||
func NewChannelMemoryBackend(size int) *ChannelMemoryBackend {
|
||||
backend := &ChannelMemoryBackend{
|
||||
maxSize: size,
|
||||
incoming: make(chan *Record, 1024),
|
||||
events: make(chan event),
|
||||
}
|
||||
backend.Start()
|
||||
return backend
|
||||
}
|
||||
|
||||
// Start launches the internal goroutine which starts processing data from the
|
||||
// input channel.
|
||||
func (b *ChannelMemoryBackend) Start() {
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
|
||||
// Launch the goroutine unless it's already running.
|
||||
if b.running != true {
|
||||
b.running = true
|
||||
b.stopWg.Add(1)
|
||||
go b.process()
|
||||
}
|
||||
}
|
||||
|
||||
func (b *ChannelMemoryBackend) process() {
|
||||
defer b.stopWg.Done()
|
||||
for {
|
||||
select {
|
||||
case rec := <-b.incoming:
|
||||
b.insertRecord(rec)
|
||||
case e := <-b.events:
|
||||
switch e {
|
||||
case eventStop:
|
||||
return
|
||||
case eventFlush:
|
||||
for len(b.incoming) > 0 {
|
||||
b.insertRecord(<-b.incoming)
|
||||
}
|
||||
b.flushWg.Done()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (b *ChannelMemoryBackend) insertRecord(rec *Record) {
|
||||
prev := b.tail
|
||||
b.tail = &node{Record: rec}
|
||||
if prev == nil {
|
||||
b.head = b.tail
|
||||
} else {
|
||||
prev.next = b.tail
|
||||
}
|
||||
|
||||
if b.maxSize > 0 && b.size >= b.maxSize {
|
||||
b.head = b.head.next
|
||||
} else {
|
||||
b.size += 1
|
||||
}
|
||||
}
|
||||
|
||||
// Flush waits until all records in the buffered channel have been processed.
|
||||
func (b *ChannelMemoryBackend) Flush() {
|
||||
b.flushWg.Add(1)
|
||||
b.events <- eventFlush
|
||||
b.flushWg.Wait()
|
||||
}
|
||||
|
||||
// Stop signals the internal goroutine to exit and waits until it have.
|
||||
func (b *ChannelMemoryBackend) Stop() {
|
||||
b.mu.Lock()
|
||||
if b.running == true {
|
||||
b.running = false
|
||||
b.events <- eventStop
|
||||
}
|
||||
b.mu.Unlock()
|
||||
b.stopWg.Wait()
|
||||
}
|
||||
|
||||
// Log implements the Log method required by Backend.
|
||||
func (b *ChannelMemoryBackend) Log(level Level, calldepth int, rec *Record) error {
|
||||
b.incoming <- rec
|
||||
return nil
|
||||
}
|
||||
|
||||
// Head returns the oldest record node kept in memory. It can be used to
|
||||
// iterate over records, one by one, up to the last record.
|
||||
//
|
||||
// Note: new records can get added while iterating. Hence the number of records
|
||||
// iterated over might be larger than the maximum size.
|
||||
func (b *ChannelMemoryBackend) Head() *node {
|
||||
return b.head
|
||||
}
|
||||
117
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/memory_test.go
generated
vendored
Normal file
117
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/memory_test.go
generated
vendored
Normal file
@ -0,0 +1,117 @@
|
||||
// Copyright 2013, Örjan Persson. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package logging
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TODO share more code between these tests
|
||||
func MemoryRecordN(b *MemoryBackend, n int) *Record {
|
||||
node := b.Head()
|
||||
for i := 0; i < n; i++ {
|
||||
if node == nil {
|
||||
break
|
||||
}
|
||||
node = node.Next()
|
||||
}
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
return node.Record
|
||||
}
|
||||
|
||||
func ChannelMemoryRecordN(b *ChannelMemoryBackend, n int) *Record {
|
||||
b.Flush()
|
||||
node := b.Head()
|
||||
for i := 0; i < n; i++ {
|
||||
if node == nil {
|
||||
break
|
||||
}
|
||||
node = node.Next()
|
||||
}
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
return node.Record
|
||||
}
|
||||
|
||||
func TestMemoryBackend(t *testing.T) {
|
||||
backend := NewMemoryBackend(8)
|
||||
SetBackend(backend)
|
||||
|
||||
log := MustGetLogger("test")
|
||||
|
||||
if nil != MemoryRecordN(backend, 0) || 0 != backend.size {
|
||||
t.Errorf("memory level: %d", backend.size)
|
||||
}
|
||||
|
||||
// Run 13 times, the resulting vector should be [5..12]
|
||||
for i := 0; i < 13; i++ {
|
||||
log.Infof("%d", i)
|
||||
}
|
||||
|
||||
if 8 != backend.size {
|
||||
t.Errorf("record length: %d", backend.size)
|
||||
}
|
||||
record := MemoryRecordN(backend, 0)
|
||||
if "5" != record.Formatted(0) {
|
||||
t.Errorf("unexpected start: %s", record.Formatted(0))
|
||||
}
|
||||
for i := 0; i < 8; i++ {
|
||||
record = MemoryRecordN(backend, i)
|
||||
if strconv.Itoa(i+5) != record.Formatted(0) {
|
||||
t.Errorf("unexpected record: %v", record.Formatted(0))
|
||||
}
|
||||
}
|
||||
record = MemoryRecordN(backend, 7)
|
||||
if "12" != record.Formatted(0) {
|
||||
t.Errorf("unexpected end: %s", record.Formatted(0))
|
||||
}
|
||||
record = MemoryRecordN(backend, 8)
|
||||
if nil != record {
|
||||
t.Errorf("unexpected eof: %s", record.Formatted(0))
|
||||
}
|
||||
}
|
||||
|
||||
func TestChannelMemoryBackend(t *testing.T) {
|
||||
backend := NewChannelMemoryBackend(8)
|
||||
SetBackend(backend)
|
||||
|
||||
log := MustGetLogger("test")
|
||||
|
||||
if nil != ChannelMemoryRecordN(backend, 0) || 0 != backend.size {
|
||||
t.Errorf("memory level: %d", backend.size)
|
||||
}
|
||||
|
||||
// Run 13 times, the resulting vector should be [5..12]
|
||||
for i := 0; i < 13; i++ {
|
||||
log.Infof("%d", i)
|
||||
}
|
||||
backend.Flush()
|
||||
|
||||
if 8 != backend.size {
|
||||
t.Errorf("record length: %d", backend.size)
|
||||
}
|
||||
record := ChannelMemoryRecordN(backend, 0)
|
||||
if "5" != record.Formatted(0) {
|
||||
t.Errorf("unexpected start: %s", record.Formatted(0))
|
||||
}
|
||||
for i := 0; i < 8; i++ {
|
||||
record = ChannelMemoryRecordN(backend, i)
|
||||
if strconv.Itoa(i+5) != record.Formatted(0) {
|
||||
t.Errorf("unexpected record: %v", record.Formatted(0))
|
||||
}
|
||||
}
|
||||
record = ChannelMemoryRecordN(backend, 7)
|
||||
if "12" != record.Formatted(0) {
|
||||
t.Errorf("unexpected end: %s", record.Formatted(0))
|
||||
}
|
||||
record = ChannelMemoryRecordN(backend, 8)
|
||||
if nil != record {
|
||||
t.Errorf("unexpected eof: %s", record.Formatted(0))
|
||||
}
|
||||
}
|
||||
65
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/multi.go
generated
vendored
Normal file
65
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/multi.go
generated
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
// Copyright 2013, Örjan Persson. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package logging
|
||||
|
||||
// TODO remove Level stuff from the multi logger. Do one thing.
|
||||
|
||||
// multiLogger is a log multiplexer which can be used to utilize multiple log
|
||||
// backends at once.
|
||||
type multiLogger struct {
|
||||
backends []LeveledBackend
|
||||
}
|
||||
|
||||
// MultiLogger creates a logger which contain multiple loggers.
|
||||
func MultiLogger(backends ...Backend) LeveledBackend {
|
||||
var leveledBackends []LeveledBackend
|
||||
for _, backend := range backends {
|
||||
leveledBackends = append(leveledBackends, AddModuleLevel(backend))
|
||||
}
|
||||
return &multiLogger{leveledBackends}
|
||||
}
|
||||
|
||||
// Log passes the log record to all backends.
|
||||
func (b *multiLogger) Log(level Level, calldepth int, rec *Record) (err error) {
|
||||
for _, backend := range b.backends {
|
||||
if backend.IsEnabledFor(level, rec.Module) {
|
||||
// Shallow copy of the record for the formatted cache on Record and get the
|
||||
// record formatter from the backend.
|
||||
r2 := *rec
|
||||
if e := backend.Log(level, calldepth+1, &r2); e != nil {
|
||||
err = e
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// GetLevel returns the highest level enabled by all backends.
|
||||
func (b *multiLogger) GetLevel(module string) Level {
|
||||
var level Level
|
||||
for _, backend := range b.backends {
|
||||
if backendLevel := backend.GetLevel(module); backendLevel > level {
|
||||
level = backendLevel
|
||||
}
|
||||
}
|
||||
return level
|
||||
}
|
||||
|
||||
// SetLevel propagates the same level to all backends.
|
||||
func (b *multiLogger) SetLevel(level Level, module string) {
|
||||
for _, backend := range b.backends {
|
||||
backend.SetLevel(level, module)
|
||||
}
|
||||
}
|
||||
|
||||
// IsEnabledFor returns true if any of the backends are enabled for it.
|
||||
func (b *multiLogger) IsEnabledFor(level Level, module string) bool {
|
||||
for _, backend := range b.backends {
|
||||
if backend.IsEnabledFor(level, module) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
51
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/multi_test.go
generated
vendored
Normal file
51
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/multi_test.go
generated
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
// Copyright 2013, Örjan Persson. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package logging
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestMultiLogger(t *testing.T) {
|
||||
log1 := NewMemoryBackend(8)
|
||||
log2 := NewMemoryBackend(8)
|
||||
SetBackend(MultiLogger(log1, log2))
|
||||
|
||||
log := MustGetLogger("test")
|
||||
log.Debug("log")
|
||||
|
||||
if "log" != MemoryRecordN(log1, 0).Formatted(0) {
|
||||
t.Errorf("log1: %v", MemoryRecordN(log1, 0).Formatted(0))
|
||||
}
|
||||
if "log" != MemoryRecordN(log2, 0).Formatted(0) {
|
||||
t.Errorf("log2: %v", MemoryRecordN(log2, 0).Formatted(0))
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultiLoggerLevel(t *testing.T) {
|
||||
log1 := NewMemoryBackend(8)
|
||||
log2 := NewMemoryBackend(8)
|
||||
|
||||
leveled1 := AddModuleLevel(log1)
|
||||
leveled2 := AddModuleLevel(log2)
|
||||
|
||||
multi := MultiLogger(leveled1, leveled2)
|
||||
multi.SetLevel(ERROR, "test")
|
||||
SetBackend(multi)
|
||||
|
||||
log := MustGetLogger("test")
|
||||
log.Notice("log")
|
||||
|
||||
if nil != MemoryRecordN(log1, 0) || nil != MemoryRecordN(log2, 0) {
|
||||
t.Errorf("unexpected log record")
|
||||
}
|
||||
|
||||
leveled1.SetLevel(DEBUG, "test")
|
||||
log.Notice("log")
|
||||
if "log" != MemoryRecordN(log1, 0).Formatted(0) {
|
||||
t.Errorf("log1 not received")
|
||||
}
|
||||
if nil != MemoryRecordN(log2, 0) {
|
||||
t.Errorf("log2 received")
|
||||
}
|
||||
}
|
||||
52
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/syslog.go
generated
vendored
Normal file
52
Godeps/_workspace/src/github.com/whyrusleeping/go-logging/syslog.go
generated
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
// Copyright 2013, Örjan Persson. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//+build !windows,!plan9
|
||||
|
||||
package logging
|
||||
|
||||
import "log/syslog"
|
||||
|
||||
// SyslogBackend is a simple logger to syslog backend. It automatically maps
|
||||
// the internal log levels to appropriate syslog log levels.
|
||||
type SyslogBackend struct {
|
||||
Writer *syslog.Writer
|
||||
}
|
||||
|
||||
// NewSyslogBackend connects to the syslog daemon using UNIX sockets with the
|
||||
// given prefix. If prefix is not given, the prefix will be derived from the
|
||||
// launched command.
|
||||
func NewSyslogBackend(prefix string) (b *SyslogBackend, err error) {
|
||||
var w *syslog.Writer
|
||||
w, err = syslog.New(syslog.LOG_CRIT, prefix)
|
||||
return &SyslogBackend{w}, err
|
||||
}
|
||||
|
||||
// NewSyslogBackendPriority is the same as NewSyslogBackend, but with custom
|
||||
// syslog priority, like syslog.LOG_LOCAL3|syslog.LOG_DEBUG etc.
|
||||
func NewSyslogBackendPriority(prefix string, priority syslog.Priority) (b *SyslogBackend, err error) {
|
||||
var w *syslog.Writer
|
||||
w, err = syslog.New(priority, prefix)
|
||||
return &SyslogBackend{w}, err
|
||||
}
|
||||
|
||||
func (b *SyslogBackend) Log(level Level, calldepth int, rec *Record) error {
|
||||
line := rec.Formatted(calldepth + 1)
|
||||
switch level {
|
||||
case CRITICAL:
|
||||
return b.Writer.Crit(line)
|
||||
case ERROR:
|
||||
return b.Writer.Err(line)
|
||||
case WARNING:
|
||||
return b.Writer.Warning(line)
|
||||
case NOTICE:
|
||||
return b.Writer.Notice(line)
|
||||
case INFO:
|
||||
return b.Writer.Info(line)
|
||||
case DEBUG:
|
||||
return b.Writer.Debug(line)
|
||||
default:
|
||||
}
|
||||
panic("unhandled log level")
|
||||
}
|
||||
@ -12,7 +12,7 @@ import (
|
||||
context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
|
||||
blocks "github.com/ipfs/go-ipfs/blocks"
|
||||
key "github.com/ipfs/go-ipfs/blocks/key"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmXJkcEXB6C9h6Ytb6rrUTFU56Ro62zxgrbxTT3dgjQGA8/go-log"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmTBXYb6y2ZcJmoXVKk3pf9rzSEjbCg7tQaJW7RSuH14nv/go-log"
|
||||
)
|
||||
|
||||
var log = logging.Logger("blockstore")
|
||||
|
||||
@ -4,7 +4,7 @@ package set
|
||||
import (
|
||||
"github.com/ipfs/go-ipfs/blocks/bloom"
|
||||
key "github.com/ipfs/go-ipfs/blocks/key"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmXJkcEXB6C9h6Ytb6rrUTFU56Ro62zxgrbxTT3dgjQGA8/go-log"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmTBXYb6y2ZcJmoXVKk3pf9rzSEjbCg7tQaJW7RSuH14nv/go-log"
|
||||
)
|
||||
|
||||
var log = logging.Logger("blockset")
|
||||
|
||||
@ -11,7 +11,7 @@ import (
|
||||
"github.com/ipfs/go-ipfs/blocks/blockstore"
|
||||
key "github.com/ipfs/go-ipfs/blocks/key"
|
||||
exchange "github.com/ipfs/go-ipfs/exchange"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmXJkcEXB6C9h6Ytb6rrUTFU56Ro62zxgrbxTT3dgjQGA8/go-log"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmTBXYb6y2ZcJmoXVKk3pf9rzSEjbCg7tQaJW7RSuH14nv/go-log"
|
||||
)
|
||||
|
||||
var log = logging.Logger("blockservice")
|
||||
|
||||
@ -28,7 +28,7 @@ import (
|
||||
config "github.com/ipfs/go-ipfs/repo/config"
|
||||
fsrepo "github.com/ipfs/go-ipfs/repo/fsrepo"
|
||||
u "github.com/ipfs/go-ipfs/util"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmXJkcEXB6C9h6Ytb6rrUTFU56Ro62zxgrbxTT3dgjQGA8/go-log"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmTBXYb6y2ZcJmoXVKk3pf9rzSEjbCg7tQaJW7RSuH14nv/go-log"
|
||||
)
|
||||
|
||||
// log is the command logger
|
||||
|
||||
@ -21,7 +21,7 @@ import (
|
||||
ci "github.com/ipfs/go-ipfs/p2p/crypto"
|
||||
secio "github.com/ipfs/go-ipfs/p2p/crypto/secio"
|
||||
peer "github.com/ipfs/go-ipfs/p2p/peer"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmXJkcEXB6C9h6Ytb6rrUTFU56Ro62zxgrbxTT3dgjQGA8/go-log"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmTBXYb6y2ZcJmoXVKk3pf9rzSEjbCg7tQaJW7RSuH14nv/go-log"
|
||||
)
|
||||
|
||||
var verbose = false
|
||||
|
||||
@ -5,7 +5,7 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmXJkcEXB6C9h6Ytb6rrUTFU56Ro62zxgrbxTT3dgjQGA8/go-log"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmTBXYb6y2ZcJmoXVKk3pf9rzSEjbCg7tQaJW7RSuH14nv/go-log"
|
||||
)
|
||||
|
||||
var log = logging.Logger("seccat")
|
||||
|
||||
@ -15,7 +15,7 @@ import (
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmXJkcEXB6C9h6Ytb6rrUTFU56Ro62zxgrbxTT3dgjQGA8/go-log"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmTBXYb6y2ZcJmoXVKk3pf9rzSEjbCg7tQaJW7RSuH14nv/go-log"
|
||||
)
|
||||
|
||||
var log = logging.Logger("command")
|
||||
|
||||
@ -16,7 +16,7 @@ import (
|
||||
context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
|
||||
|
||||
cmds "github.com/ipfs/go-ipfs/commands"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmXJkcEXB6C9h6Ytb6rrUTFU56Ro62zxgrbxTT3dgjQGA8/go-log"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmTBXYb6y2ZcJmoXVKk3pf9rzSEjbCg7tQaJW7RSuH14nv/go-log"
|
||||
)
|
||||
|
||||
var log = logging.Logger("commands/http")
|
||||
|
||||
@ -5,7 +5,7 @@ import (
|
||||
"io"
|
||||
|
||||
cmds "github.com/ipfs/go-ipfs/commands"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmXJkcEXB6C9h6Ytb6rrUTFU56Ro62zxgrbxTT3dgjQGA8/go-log"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmTBXYb6y2ZcJmoXVKk3pf9rzSEjbCg7tQaJW7RSuH14nv/go-log"
|
||||
)
|
||||
|
||||
// Golang os.Args overrides * and replaces the character argument with
|
||||
|
||||
@ -6,7 +6,7 @@ import (
|
||||
|
||||
cmds "github.com/ipfs/go-ipfs/commands"
|
||||
unixfs "github.com/ipfs/go-ipfs/core/commands/unixfs"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmXJkcEXB6C9h6Ytb6rrUTFU56Ro62zxgrbxTT3dgjQGA8/go-log"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmTBXYb6y2ZcJmoXVKk3pf9rzSEjbCg7tQaJW7RSuH14nv/go-log"
|
||||
)
|
||||
|
||||
var log = logging.Logger("core/commands")
|
||||
|
||||
@ -33,7 +33,7 @@ import (
|
||||
addrutil "github.com/ipfs/go-ipfs/p2p/net/swarm/addr"
|
||||
peer "github.com/ipfs/go-ipfs/p2p/peer"
|
||||
ping "github.com/ipfs/go-ipfs/p2p/protocol/ping"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmXJkcEXB6C9h6Ytb6rrUTFU56Ro62zxgrbxTT3dgjQGA8/go-log"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmTBXYb6y2ZcJmoXVKk3pf9rzSEjbCg7tQaJW7RSuH14nv/go-log"
|
||||
|
||||
routing "github.com/ipfs/go-ipfs/routing"
|
||||
dht "github.com/ipfs/go-ipfs/routing/dht"
|
||||
|
||||
@ -14,7 +14,7 @@ import (
|
||||
manet "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net"
|
||||
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/goprocess"
|
||||
core "github.com/ipfs/go-ipfs/core"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmXJkcEXB6C9h6Ytb6rrUTFU56Ro62zxgrbxTT3dgjQGA8/go-log"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmTBXYb6y2ZcJmoXVKk3pf9rzSEjbCg7tQaJW7RSuH14nv/go-log"
|
||||
)
|
||||
|
||||
var log = logging.Logger("core/server")
|
||||
|
||||
@ -6,7 +6,7 @@ import (
|
||||
"net/http"
|
||||
|
||||
core "github.com/ipfs/go-ipfs/core"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmXJkcEXB6C9h6Ytb6rrUTFU56Ro62zxgrbxTT3dgjQGA8/go-log"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmTBXYb6y2ZcJmoXVKk3pf9rzSEjbCg7tQaJW7RSuH14nv/go-log"
|
||||
)
|
||||
|
||||
type writeErrNotifier struct {
|
||||
|
||||
@ -5,7 +5,7 @@ import (
|
||||
key "github.com/ipfs/go-ipfs/blocks/key"
|
||||
"github.com/ipfs/go-ipfs/core"
|
||||
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmXJkcEXB6C9h6Ytb6rrUTFU56Ro62zxgrbxTT3dgjQGA8/go-log"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmTBXYb6y2ZcJmoXVKk3pf9rzSEjbCg7tQaJW7RSuH14nv/go-log"
|
||||
)
|
||||
|
||||
var log = logging.Logger("corerepo")
|
||||
|
||||
@ -14,7 +14,7 @@ import (
|
||||
chunk "github.com/ipfs/go-ipfs/importer/chunk"
|
||||
merkledag "github.com/ipfs/go-ipfs/merkledag"
|
||||
"github.com/ipfs/go-ipfs/pin"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmXJkcEXB6C9h6Ytb6rrUTFU56Ro62zxgrbxTT3dgjQGA8/go-log"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmTBXYb6y2ZcJmoXVKk3pf9rzSEjbCg7tQaJW7RSuH14nv/go-log"
|
||||
unixfs "github.com/ipfs/go-ipfs/unixfs"
|
||||
)
|
||||
|
||||
|
||||
@ -20,7 +20,7 @@ import (
|
||||
inet "github.com/ipfs/go-ipfs/p2p/net"
|
||||
peer "github.com/ipfs/go-ipfs/p2p/peer"
|
||||
protocol "github.com/ipfs/go-ipfs/p2p/protocol"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmXJkcEXB6C9h6Ytb6rrUTFU56Ro62zxgrbxTT3dgjQGA8/go-log"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmTBXYb6y2ZcJmoXVKk3pf9rzSEjbCg7tQaJW7RSuH14nv/go-log"
|
||||
)
|
||||
|
||||
var log = logging.Logger("diagnostics")
|
||||
|
||||
@ -22,7 +22,7 @@ import (
|
||||
wantlist "github.com/ipfs/go-ipfs/exchange/bitswap/wantlist"
|
||||
peer "github.com/ipfs/go-ipfs/p2p/peer"
|
||||
"github.com/ipfs/go-ipfs/thirdparty/delay"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmXJkcEXB6C9h6Ytb6rrUTFU56Ro62zxgrbxTT3dgjQGA8/go-log"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmTBXYb6y2ZcJmoXVKk3pf9rzSEjbCg7tQaJW7RSuH14nv/go-log"
|
||||
)
|
||||
|
||||
var log = logging.Logger("bitswap")
|
||||
|
||||
@ -10,7 +10,7 @@ import (
|
||||
bsmsg "github.com/ipfs/go-ipfs/exchange/bitswap/message"
|
||||
wl "github.com/ipfs/go-ipfs/exchange/bitswap/wantlist"
|
||||
peer "github.com/ipfs/go-ipfs/p2p/peer"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmXJkcEXB6C9h6Ytb6rrUTFU56Ro62zxgrbxTT3dgjQGA8/go-log"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmTBXYb6y2ZcJmoXVKk3pf9rzSEjbCg7tQaJW7RSuH14nv/go-log"
|
||||
)
|
||||
|
||||
// TODO consider taking responsibility for other types of requests. For
|
||||
|
||||
@ -9,7 +9,7 @@ import (
|
||||
inet "github.com/ipfs/go-ipfs/p2p/net"
|
||||
peer "github.com/ipfs/go-ipfs/p2p/peer"
|
||||
routing "github.com/ipfs/go-ipfs/routing"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmXJkcEXB6C9h6Ytb6rrUTFU56Ro62zxgrbxTT3dgjQGA8/go-log"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmTBXYb6y2ZcJmoXVKk3pf9rzSEjbCg7tQaJW7RSuH14nv/go-log"
|
||||
)
|
||||
|
||||
var log = logging.Logger("bitswap_network")
|
||||
|
||||
@ -8,7 +8,7 @@ import (
|
||||
context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
|
||||
|
||||
key "github.com/ipfs/go-ipfs/blocks/key"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmXJkcEXB6C9h6Ytb6rrUTFU56Ro62zxgrbxTT3dgjQGA8/go-log"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmTBXYb6y2ZcJmoXVKk3pf9rzSEjbCg7tQaJW7RSuH14nv/go-log"
|
||||
)
|
||||
|
||||
var TaskWorkerCount = 8
|
||||
|
||||
@ -8,7 +8,7 @@ import (
|
||||
context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
|
||||
blocks "github.com/ipfs/go-ipfs/blocks/blockstore"
|
||||
routing "github.com/ipfs/go-ipfs/routing"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmXJkcEXB6C9h6Ytb6rrUTFU56Ro62zxgrbxTT3dgjQGA8/go-log"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmTBXYb6y2ZcJmoXVKk3pf9rzSEjbCg7tQaJW7RSuH14nv/go-log"
|
||||
)
|
||||
|
||||
var log = logging.Logger("reprovider")
|
||||
|
||||
@ -13,7 +13,7 @@ import (
|
||||
fuse "github.com/ipfs/go-ipfs/Godeps/_workspace/src/bazil.org/fuse"
|
||||
fs "github.com/ipfs/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fs"
|
||||
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmXJkcEXB6C9h6Ytb6rrUTFU56Ro62zxgrbxTT3dgjQGA8/go-log"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmTBXYb6y2ZcJmoXVKk3pf9rzSEjbCg7tQaJW7RSuH14nv/go-log"
|
||||
|
||||
key "github.com/ipfs/go-ipfs/blocks/key"
|
||||
core "github.com/ipfs/go-ipfs/core"
|
||||
|
||||
@ -10,7 +10,7 @@ import (
|
||||
|
||||
goprocess "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/goprocess"
|
||||
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmXJkcEXB6C9h6Ytb6rrUTFU56Ro62zxgrbxTT3dgjQGA8/go-log"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmTBXYb6y2ZcJmoXVKk3pf9rzSEjbCg7tQaJW7RSuH14nv/go-log"
|
||||
)
|
||||
|
||||
var log = logging.Logger("mount")
|
||||
|
||||
@ -16,7 +16,7 @@ import (
|
||||
core "github.com/ipfs/go-ipfs/core"
|
||||
mdag "github.com/ipfs/go-ipfs/merkledag"
|
||||
path "github.com/ipfs/go-ipfs/path"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmXJkcEXB6C9h6Ytb6rrUTFU56Ro62zxgrbxTT3dgjQGA8/go-log"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmTBXYb6y2ZcJmoXVKk3pf9rzSEjbCg7tQaJW7RSuH14nv/go-log"
|
||||
uio "github.com/ipfs/go-ipfs/unixfs/io"
|
||||
ftpb "github.com/ipfs/go-ipfs/unixfs/pb"
|
||||
lgbl "github.com/ipfs/go-ipfs/util/eventlog/loggables"
|
||||
|
||||
@ -4,7 +4,7 @@ package chunk
|
||||
import (
|
||||
"io"
|
||||
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmXJkcEXB6C9h6Ytb6rrUTFU56Ro62zxgrbxTT3dgjQGA8/go-log"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmTBXYb6y2ZcJmoXVKk3pf9rzSEjbCg7tQaJW7RSuH14nv/go-log"
|
||||
)
|
||||
|
||||
var log = logging.Logger("chunk")
|
||||
|
||||
@ -13,7 +13,7 @@ import (
|
||||
trickle "github.com/ipfs/go-ipfs/importer/trickle"
|
||||
dag "github.com/ipfs/go-ipfs/merkledag"
|
||||
"github.com/ipfs/go-ipfs/pin"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmXJkcEXB6C9h6Ytb6rrUTFU56Ro62zxgrbxTT3dgjQGA8/go-log"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmTBXYb6y2ZcJmoXVKk3pf9rzSEjbCg7tQaJW7RSuH14nv/go-log"
|
||||
)
|
||||
|
||||
var log = logging.Logger("importer")
|
||||
|
||||
@ -25,7 +25,7 @@ import (
|
||||
ft "github.com/ipfs/go-ipfs/unixfs"
|
||||
|
||||
context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmXJkcEXB6C9h6Ytb6rrUTFU56Ro62zxgrbxTT3dgjQGA8/go-log"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmTBXYb6y2ZcJmoXVKk3pf9rzSEjbCg7tQaJW7RSuH14nv/go-log"
|
||||
)
|
||||
|
||||
var log = logging.Logger("ipnsfs")
|
||||
|
||||
@ -9,7 +9,7 @@ import (
|
||||
blocks "github.com/ipfs/go-ipfs/blocks"
|
||||
key "github.com/ipfs/go-ipfs/blocks/key"
|
||||
bserv "github.com/ipfs/go-ipfs/blockservice"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmXJkcEXB6C9h6Ytb6rrUTFU56Ro62zxgrbxTT3dgjQGA8/go-log"
|
||||
logging "github.com/ipfs/go-ipfs/vendor/QmTBXYb6y2ZcJmoXVKk3pf9rzSEjbCg7tQaJW7RSuH14nv/go-log"
|
||||
)
|
||||
|
||||
var log = logging.Logger("merkledag")
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user