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