moved Sirupsen to sirupsen on a case sensitive system
Signed-off-by: Igor Morozov <igor@adhoc05-sjc1.prod.uber.internal>master
							parent
							
								
									1e2f10eb65
								
							
						
					
					
						commit
						a97d7c0c15
					
				|  | @ -83,7 +83,7 @@ build: | |||
|     + lint | ||||
|     + build | ||||
|     github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar | ||||
|     github.com/Sirupsen/logrus | ||||
|     github.com/sirupsen/logrus | ||||
|     github.com/docker/libtrust | ||||
|     ... | ||||
|     github.com/yvasiyarov/gorelic | ||||
|  |  | |||
|  | @ -8,7 +8,7 @@ import ( | |||
| 	"strconv" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/Sirupsen/logrus" | ||||
| 	"github.com/sirupsen/logrus" | ||||
| 	"gopkg.in/yaml.v2" | ||||
| ) | ||||
| 
 | ||||
|  |  | |||
|  | @ -8,9 +8,9 @@ import ( | |||
| 	"sync" | ||||
| 	"time" | ||||
| 
 | ||||
| 	log "github.com/Sirupsen/logrus" | ||||
| 	"github.com/docker/distribution/uuid" | ||||
| 	"github.com/gorilla/mux" | ||||
| 	log "github.com/sirupsen/logrus" | ||||
| ) | ||||
| 
 | ||||
| // Common errors used with this package.
 | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ package context | |||
| import ( | ||||
| 	"fmt" | ||||
| 
 | ||||
| 	"github.com/Sirupsen/logrus" | ||||
| 	"github.com/sirupsen/logrus" | ||||
| 	"runtime" | ||||
| ) | ||||
| 
 | ||||
|  |  | |||
|  | @ -9,13 +9,13 @@ import ( | |||
| 	"strings" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/Sirupsen/logrus" | ||||
| 	"github.com/docker/distribution/context" | ||||
| 	"github.com/docker/distribution/registry/api/errcode" | ||||
| 	"github.com/docker/distribution/registry/auth" | ||||
| 	_ "github.com/docker/distribution/registry/auth/htpasswd" | ||||
| 	"github.com/docker/libtrust" | ||||
| 	"github.com/gorilla/mux" | ||||
| 	"github.com/sirupsen/logrus" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
|  |  | |||
|  | @ -3,8 +3,8 @@ package schema1 | |||
| import ( | ||||
| 	"crypto/x509" | ||||
| 
 | ||||
| 	"github.com/Sirupsen/logrus" | ||||
| 	"github.com/docker/libtrust" | ||||
| 	"github.com/sirupsen/logrus" | ||||
| ) | ||||
| 
 | ||||
| // Verify verifies the signature of the signed manifest returning the public
 | ||||
|  |  | |||
|  | @ -6,7 +6,7 @@ import ( | |||
| 	"sync" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/Sirupsen/logrus" | ||||
| 	"github.com/sirupsen/logrus" | ||||
| ) | ||||
| 
 | ||||
| // NOTE(stevvooe): This file contains definitions for several utility sinks.
 | ||||
|  |  | |||
|  | @ -7,7 +7,7 @@ import ( | |||
| 	"sync" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/Sirupsen/logrus" | ||||
| 	"github.com/sirupsen/logrus" | ||||
| 
 | ||||
| 	"testing" | ||||
| ) | ||||
|  |  | |||
|  | @ -10,8 +10,8 @@ import ( | |||
| 	"strings" | ||||
| 	"time" | ||||
| 
 | ||||
| 	log "github.com/Sirupsen/logrus" | ||||
| 	"github.com/docker/libtrust" | ||||
| 	log "github.com/sirupsen/logrus" | ||||
| 
 | ||||
| 	"github.com/docker/distribution/registry/auth" | ||||
| ) | ||||
|  |  | |||
|  | @ -10,10 +10,10 @@ import ( | |||
| 	"sync" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/Sirupsen/logrus" | ||||
| 	"github.com/docker/distribution/registry/client" | ||||
| 	"github.com/docker/distribution/registry/client/auth/challenge" | ||||
| 	"github.com/docker/distribution/registry/client/transport" | ||||
| 	"github.com/sirupsen/logrus" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
|  |  | |||
|  | @ -14,7 +14,6 @@ import ( | |||
| 	"strings" | ||||
| 	"time" | ||||
| 
 | ||||
| 	log "github.com/Sirupsen/logrus" | ||||
| 	"github.com/docker/distribution" | ||||
| 	"github.com/docker/distribution/configuration" | ||||
| 	ctxu "github.com/docker/distribution/context" | ||||
|  | @ -38,6 +37,7 @@ import ( | |||
| 	"github.com/docker/libtrust" | ||||
| 	"github.com/garyburd/redigo/redis" | ||||
| 	"github.com/gorilla/mux" | ||||
| 	log "github.com/sirupsen/logrus" | ||||
| 	"golang.org/x/net/context" | ||||
| ) | ||||
| 
 | ||||
|  |  | |||
|  | @ -7,7 +7,7 @@ import ( | |||
| 	"strings" | ||||
| 	"text/template" | ||||
| 
 | ||||
| 	"github.com/Sirupsen/logrus" | ||||
| 	"github.com/sirupsen/logrus" | ||||
| ) | ||||
| 
 | ||||
| // logHook is for hooking Panic in web application
 | ||||
|  |  | |||
|  | @ -11,7 +11,6 @@ import ( | |||
| 
 | ||||
| 	"rsc.io/letsencrypt" | ||||
| 
 | ||||
| 	log "github.com/Sirupsen/logrus" | ||||
| 	logstash "github.com/bshuster-repo/logrus-logstash-hook" | ||||
| 	"github.com/bugsnag/bugsnag-go" | ||||
| 	"github.com/docker/distribution/configuration" | ||||
|  | @ -22,6 +21,7 @@ import ( | |||
| 	"github.com/docker/distribution/uuid" | ||||
| 	"github.com/docker/distribution/version" | ||||
| 	gorhandlers "github.com/gorilla/handlers" | ||||
| 	log "github.com/sirupsen/logrus" | ||||
| 	"github.com/spf13/cobra" | ||||
| 	"github.com/yvasiyarov/gorelic" | ||||
| ) | ||||
|  |  | |||
|  | @ -7,11 +7,11 @@ import ( | |||
| 	"path" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/Sirupsen/logrus" | ||||
| 	"github.com/docker/distribution" | ||||
| 	"github.com/docker/distribution/context" | ||||
| 	storagedriver "github.com/docker/distribution/registry/storage/driver" | ||||
| 	"github.com/opencontainers/go-digest" | ||||
| 	"github.com/sirupsen/logrus" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
|  |  | |||
|  | @ -7,9 +7,9 @@ import ( | |||
| 	"path" | ||||
| 	"strconv" | ||||
| 
 | ||||
| 	"github.com/Sirupsen/logrus" | ||||
| 	"github.com/docker/distribution/context" | ||||
| 	storagedriver "github.com/docker/distribution/registry/storage/driver" | ||||
| 	"github.com/sirupsen/logrus" | ||||
| 	"github.com/stevvooe/resumable" | ||||
| 
 | ||||
| 	// register resumable hashes with import
 | ||||
|  |  | |||
|  | @ -37,7 +37,7 @@ import ( | |||
| 	"google.golang.org/cloud" | ||||
| 	"google.golang.org/cloud/storage" | ||||
| 
 | ||||
| 	"github.com/Sirupsen/logrus" | ||||
| 	"github.com/sirupsen/logrus" | ||||
| 
 | ||||
| 	ctx "github.com/docker/distribution/context" | ||||
| 	storagedriver "github.com/docker/distribution/registry/storage/driver" | ||||
|  |  | |||
|  | @ -24,11 +24,11 @@ import ( | |||
| 
 | ||||
| 	"github.com/docker/distribution/context" | ||||
| 
 | ||||
| 	"github.com/Sirupsen/logrus" | ||||
| 	"github.com/denverdino/aliyungo/oss" | ||||
| 	storagedriver "github.com/docker/distribution/registry/storage/driver" | ||||
| 	"github.com/docker/distribution/registry/storage/driver/base" | ||||
| 	"github.com/docker/distribution/registry/storage/driver/factory" | ||||
| 	"github.com/sirupsen/logrus" | ||||
| ) | ||||
| 
 | ||||
| const driverName = "oss" | ||||
|  |  | |||
|  | @ -32,11 +32,11 @@ import ( | |||
| 	"strings" | ||||
| 	"time" | ||||
| 
 | ||||
| 	log "github.com/Sirupsen/logrus" | ||||
| 	"github.com/aws/aws-sdk-go/aws/corehandlers" | ||||
| 	"github.com/aws/aws-sdk-go/aws/credentials" | ||||
| 	"github.com/aws/aws-sdk-go/aws/request" | ||||
| 	"github.com/aws/aws-sdk-go/service/s3" | ||||
| 	log "github.com/sirupsen/logrus" | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
|  |  | |||
|  | @ -5,10 +5,10 @@ import ( | |||
| 	"strings" | ||||
| 	"time" | ||||
| 
 | ||||
| 	log "github.com/Sirupsen/logrus" | ||||
| 	"github.com/docker/distribution/context" | ||||
| 	storageDriver "github.com/docker/distribution/registry/storage/driver" | ||||
| 	"github.com/docker/distribution/uuid" | ||||
| 	log "github.com/sirupsen/logrus" | ||||
| ) | ||||
| 
 | ||||
| // uploadData stored the location of temporary files created during a layer upload
 | ||||
|  |  | |||
|  | @ -1,8 +1,8 @@ | |||
| github.com/Azure/azure-sdk-for-go 088007b3b08cc02b27f2eadfdcd870958460ce7e | ||||
| github.com/Azure/go-autorest ec5f4903f77ed9927ac95b19ab8e44ada64c1356 | ||||
| github.com/Sirupsen/logrus d26492970760ca5d33129d2d799e34be5c4782eb | ||||
| github.com/sirupsen/logrus 3d4380f53a34dcdc95f0c1db702615992b38d9a4 | ||||
| github.com/aws/aws-sdk-go c6fc52983ea2375810aa38ddb5370e9cdf611716 | ||||
| github.com/bshuster-repo/logrus-logstash-hook 5f729f2fb50a301153cae84ff5c58981d51c095a | ||||
| github.com/bshuster-repo/logrus-logstash-hook d2c0ecc1836d91814e15e23bb5dc309c3ef51f4a | ||||
| github.com/bugsnag/bugsnag-go b1d153021fcd90ca3f080db36bec96dc690fb274 | ||||
| github.com/bugsnag/osext 0dd3f918b21bec95ace9dc86c7e70266cfc5c702 | ||||
| github.com/bugsnag/panicwrap e2c28503fcd0675329da73bf48b33404db873782 | ||||
|  |  | |||
|  | @ -1,41 +0,0 @@ | |||
| package logrus | ||||
| 
 | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| ) | ||||
| 
 | ||||
| type JSONFormatter struct { | ||||
| 	// TimestampFormat sets the format used for marshaling timestamps.
 | ||||
| 	TimestampFormat string | ||||
| } | ||||
| 
 | ||||
| func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { | ||||
| 	data := make(Fields, len(entry.Data)+3) | ||||
| 	for k, v := range entry.Data { | ||||
| 		switch v := v.(type) { | ||||
| 		case error: | ||||
| 			// Otherwise errors are ignored by `encoding/json`
 | ||||
| 			// https://github.com/Sirupsen/logrus/issues/137
 | ||||
| 			data[k] = v.Error() | ||||
| 		default: | ||||
| 			data[k] = v | ||||
| 		} | ||||
| 	} | ||||
| 	prefixFieldClashes(data) | ||||
| 
 | ||||
| 	timestampFormat := f.TimestampFormat | ||||
| 	if timestampFormat == "" { | ||||
| 		timestampFormat = DefaultTimestampFormat | ||||
| 	} | ||||
| 
 | ||||
| 	data["time"] = entry.Time.Format(timestampFormat) | ||||
| 	data["msg"] = entry.Message | ||||
| 	data["level"] = entry.Level.String() | ||||
| 
 | ||||
| 	serialized, err := json.Marshal(data) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) | ||||
| 	} | ||||
| 	return append(serialized, '\n'), nil | ||||
| } | ||||
|  | @ -1,15 +0,0 @@ | |||
| // +build solaris,!appengine
 | ||||
| 
 | ||||
| package logrus | ||||
| 
 | ||||
| import ( | ||||
| 	"os" | ||||
| 
 | ||||
| 	"golang.org/x/sys/unix" | ||||
| ) | ||||
| 
 | ||||
| // IsTerminal returns true if the given file descriptor is a terminal.
 | ||||
| func IsTerminal() bool { | ||||
| 	_, err := unix.IoctlGetTermios(int(os.Stdout.Fd()), unix.TCGETA) | ||||
| 	return err == nil | ||||
| } | ||||
|  | @ -1,27 +0,0 @@ | |||
| // Based on ssh/terminal:
 | ||||
| // Copyright 2011 The Go Authors. All rights reserved.
 | ||||
| // Use of this source code is governed by a BSD-style
 | ||||
| // license that can be found in the LICENSE file.
 | ||||
| 
 | ||||
| // +build windows,!appengine
 | ||||
| 
 | ||||
| package logrus | ||||
| 
 | ||||
| import ( | ||||
| 	"syscall" | ||||
| 	"unsafe" | ||||
| ) | ||||
| 
 | ||||
| var kernel32 = syscall.NewLazyDLL("kernel32.dll") | ||||
| 
 | ||||
| var ( | ||||
| 	procGetConsoleMode = kernel32.NewProc("GetConsoleMode") | ||||
| ) | ||||
| 
 | ||||
| // IsTerminal returns true if stderr's file descriptor is a terminal.
 | ||||
| func IsTerminal() bool { | ||||
| 	fd := syscall.Stderr | ||||
| 	var st uint32 | ||||
| 	r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) | ||||
| 	return r != 0 && e == 0 | ||||
| } | ||||
|  | @ -7,13 +7,13 @@ Use this hook to send the logs to [Logstash](https://www.elastic.co/products/log | |||
| package main | ||||
| 
 | ||||
| import ( | ||||
|         "github.com/Sirupsen/logrus" | ||||
|         "github.com/sirupsen/logrus" | ||||
|         "github.com/bshuster-repo/logrus-logstash-hook" | ||||
| ) | ||||
| 
 | ||||
| func main() { | ||||
|         log := logrus.New() | ||||
|         hook, err := logrus_logstash.NewHook("tcp", "172.17.0.2:9999", "myappName") | ||||
|         hook, err := logrustash.NewHook("tcp", "172.17.0.2:9999", "myappName") | ||||
| 
 | ||||
|         if err != nil { | ||||
|                 log.Fatal(err) | ||||
|  | @ -47,7 +47,7 @@ This can be done when creating the hook: | |||
| 
 | ||||
| ```go | ||||
| 
 | ||||
| hook, err := logrus_logstash.NewHookWithFields("tcp", "172.17.0.2:9999", "myappName", logrus.Fields{ | ||||
| hook, err := logrustash.NewHookWithFields("tcp", "172.17.0.2:9999", "myappName", logrus.Fields{ | ||||
|         "hostname":    os.Hostname(), | ||||
|         "serviceName": "myServiceName", | ||||
| }) | ||||
|  | @ -83,7 +83,7 @@ For example if you don't want to see the hostname and serviceName on each log li | |||
| ```go | ||||
| 
 | ||||
| 
 | ||||
| hook, err := logrus_logstash.NewHookWithFields("tcp", "172.17.0.2:9999", "myappName", logrus.Fields{ | ||||
| hook, err := logrustash.NewHookWithFields("tcp", "172.17.0.2:9999", "myappName", logrus.Fields{ | ||||
|         "_hostname":    os.Hostname(), | ||||
|         "_serviceName": "myServiceName", | ||||
| }) | ||||
|  | @ -93,3 +93,14 @@ hook.WithPrefix("_") | |||
| 
 | ||||
| There are also constructors available which allow you to specify the prefix from the start. | ||||
| The std-out will not have the '\_hostname' and '\_servicename' fields, and the logstash output will, but the prefix will be dropped from the name. | ||||
| 
 | ||||
| 
 | ||||
| # Authors | ||||
| 
 | ||||
| Name         | Github    | Twitter    | | ||||
| ------------ | --------- | ---------- | | ||||
| Boaz Shuster | ripcurld0 | @ripcurld0 | | ||||
| 
 | ||||
| # License | ||||
| 
 | ||||
| MIT. | ||||
|  |  | |||
|  | @ -1,10 +1,10 @@ | |||
| package logrus_logstash | ||||
| package logrustash | ||||
| 
 | ||||
| import ( | ||||
| 	"net" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/Sirupsen/logrus" | ||||
| 	"github.com/sirupsen/logrus" | ||||
| ) | ||||
| 
 | ||||
| // Hook represents a connection to a Logstash instance
 | ||||
|  | @ -13,6 +13,7 @@ type Hook struct { | |||
| 	appName          string | ||||
| 	alwaysSentFields logrus.Fields | ||||
| 	hookOnlyPrefix   string | ||||
| 	TimeFormat       string | ||||
| } | ||||
| 
 | ||||
| // NewHook creates a new hook to a Logstash instance, which listens on
 | ||||
|  | @ -106,6 +107,9 @@ func (h *Hook) Fire(entry *logrus.Entry) error { | |||
| 	} | ||||
| 
 | ||||
| 	formatter := LogstashFormatter{Type: h.appName} | ||||
| 	if h.TimeFormat != "" { | ||||
| 		formatter.TimestampFormat = h.TimeFormat | ||||
| 	} | ||||
| 
 | ||||
| 	dataBytes, err := formatter.FormatWithPrefix(entry, h.hookOnlyPrefix) | ||||
| 	if err != nil { | ||||
|  |  | |||
|  | @ -1,11 +1,11 @@ | |||
| package logrus_logstash | ||||
| package logrustash | ||||
| 
 | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/Sirupsen/logrus" | ||||
| 	"github.com/sirupsen/logrus" | ||||
| ) | ||||
| 
 | ||||
| // Formatter generates json in logstash format.
 | ||||
|  | @ -44,8 +44,7 @@ func (f *LogstashFormatter) FormatWithPrefix(entry *logrus.Entry, prefix string) | |||
| 	timeStampFormat := f.TimestampFormat | ||||
| 
 | ||||
| 	if timeStampFormat == "" { | ||||
| 		//timeStampFormat = logrus.DefaultTimestampFormat
 | ||||
| 		timeStampFormat = "2006-01-02 15:04:05.000" | ||||
| 		timeStampFormat = logrus.DefaultTimestampFormat | ||||
| 	} | ||||
| 
 | ||||
| 	fields["@timestamp"] = entry.Time.Format(timeStampFormat) | ||||
|  |  | |||
							
								
								
									
										184
									
								
								vendor/github.com/Sirupsen/logrus/README.md → vendor/github.com/sirupsen/logrus/README.md
								
								
									generated
								
								
									vendored
								
								
							
							
						
						
									
										184
									
								
								vendor/github.com/Sirupsen/logrus/README.md → vendor/github.com/sirupsen/logrus/README.md
								
								
									generated
								
								
									vendored
								
								
							|  | @ -1,11 +1,18 @@ | |||
| # 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) [](https://godoc.org/github.com/Sirupsen/logrus) | ||||
| # 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) [](https://godoc.org/github.com/sirupsen/logrus) | ||||
| 
 | ||||
| Logrus is a structured logger for Go (golang), completely API compatible with | ||||
| the standard library logger. [Godoc][godoc]. **Please note the Logrus API is not | ||||
| yet stable (pre 1.0). Logrus itself is completely stable and has been used in | ||||
| many large deployments. The core API is unlikely to change much but please | ||||
| version control your Logrus to make sure you aren't fetching latest `master` on | ||||
| every build.** | ||||
| the standard library logger. [Godoc][godoc]. | ||||
| 
 | ||||
| **Seeing weird case-sensitive problems?** Unfortunately, the author failed to | ||||
| realize the consequences of renaming to lower-case. Due to the Go package | ||||
| environment, this caused issues. Regretfully, there's no turning back now. | ||||
| Everything using `logrus` will need to use the lower-case: | ||||
| `github.com/sirupsen/logrus`. Any package that isn't, should be changed. | ||||
| 
 | ||||
| I am terribly sorry for this inconvenience. Logrus strives hard for backwards | ||||
| compatibility, and the author failed to realize the cascading consequences of | ||||
| such a name-change. To fix Glide, see [these | ||||
| comments](https://github.com/sirupsen/logrus/issues/553#issuecomment-306591437). | ||||
| 
 | ||||
| Nicely color-coded in development (when a TTY is attached, otherwise just | ||||
| plain text): | ||||
|  | @ -46,6 +53,12 @@ time="2015-03-26T01:27:38-04:00" level=fatal msg="The ice breaks!" err=&{0x20822 | |||
| exit status 1 | ||||
| ``` | ||||
| 
 | ||||
| #### Case-sensitivity | ||||
| 
 | ||||
| The organization's name was changed to lower-case--and this will not be changed | ||||
| back. If you are getting import conflicts due to case sensitivity, please use | ||||
| the lower-case import: `github.com/sirupsen/logrus`. | ||||
| 
 | ||||
| #### Example | ||||
| 
 | ||||
| The simplest way to use Logrus is simply the package-level exported logger: | ||||
|  | @ -54,7 +67,7 @@ The simplest way to use Logrus is simply the package-level exported logger: | |||
| package main | ||||
| 
 | ||||
| import ( | ||||
|   log "github.com/Sirupsen/logrus" | ||||
|   log "github.com/sirupsen/logrus" | ||||
| ) | ||||
| 
 | ||||
| func main() { | ||||
|  | @ -65,7 +78,7 @@ func main() { | |||
| ``` | ||||
| 
 | ||||
| Note that it's completely api-compatible with the stdlib logger, so you can | ||||
| replace your `log` imports everywhere with `log "github.com/Sirupsen/logrus"` | ||||
| replace your `log` imports everywhere with `log "github.com/sirupsen/logrus"` | ||||
| and you'll now have the flexibility of Logrus. You can customize it all you | ||||
| want: | ||||
| 
 | ||||
|  | @ -74,15 +87,16 @@ package main | |||
| 
 | ||||
| import ( | ||||
|   "os" | ||||
|   log "github.com/Sirupsen/logrus" | ||||
|   log "github.com/sirupsen/logrus" | ||||
| ) | ||||
| 
 | ||||
| func init() { | ||||
|   // Log as JSON instead of the default ASCII formatter. | ||||
|   log.SetFormatter(&log.JSONFormatter{}) | ||||
| 
 | ||||
|   // Output to stderr instead of stdout, could also be a file. | ||||
|   log.SetOutput(os.Stderr) | ||||
|   // Output to stdout instead of the default stderr | ||||
|   // Can be any io.Writer, see below for File example | ||||
|   log.SetOutput(os.Stdout) | ||||
| 
 | ||||
|   // Only log the warning severity or above. | ||||
|   log.SetLevel(log.WarnLevel) | ||||
|  | @ -123,7 +137,8 @@ application, you can also create an instance of the `logrus` Logger: | |||
| package main | ||||
| 
 | ||||
| import ( | ||||
|   "github.com/Sirupsen/logrus" | ||||
|   "os" | ||||
|   "github.com/sirupsen/logrus" | ||||
| ) | ||||
| 
 | ||||
| // Create a new instance of the logger. You can have any number of instances. | ||||
|  | @ -132,7 +147,15 @@ var log = logrus.New() | |||
| func main() { | ||||
|   // The API for setting attributes is a little different than the package level | ||||
|   // exported logger. See Godoc. | ||||
|   log.Out = os.Stderr | ||||
|   log.Out = os.Stdout | ||||
| 
 | ||||
|   // You could set this to any `io.Writer` such as a file | ||||
|   // file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY, 0666) | ||||
|   // if err == nil { | ||||
|   //  log.Out = file | ||||
|   // } else { | ||||
|   //  log.Info("Failed to log to file, using default stderr") | ||||
|   // } | ||||
| 
 | ||||
|   log.WithFields(logrus.Fields{ | ||||
|     "animal": "walrus", | ||||
|  | @ -143,7 +166,7 @@ func main() { | |||
| 
 | ||||
| #### Fields | ||||
| 
 | ||||
| Logrus encourages careful, structured logging though logging fields instead of | ||||
| Logrus encourages careful, structured logging through logging fields instead of | ||||
| long, unparseable error messages. For example, instead of: `log.Fatalf("Failed | ||||
| to send event %s to topic %s with key %d")`, you should log the much more | ||||
| discoverable: | ||||
|  | @ -165,6 +188,20 @@ In general, with Logrus using any of the `printf`-family functions should be | |||
| seen as a hint you should add a field, however, you can still use the | ||||
| `printf`-family functions with Logrus. | ||||
| 
 | ||||
| #### Default Fields | ||||
| 
 | ||||
| Often it's helpful to have fields _always_ attached to log statements in an | ||||
| application or parts of one. For example, you may want to always log the | ||||
| `request_id` and `user_ip` in the context of a request. Instead of writing | ||||
| `log.WithFields(log.Fields{"request_id": request_id, "user_ip": user_ip})` on | ||||
| every line, you can create a `logrus.Entry` to pass around instead: | ||||
| 
 | ||||
| ```go | ||||
| requestLogger := log.WithFields(log.Fields{"request_id": request_id, "user_ip": user_ip}) | ||||
| requestLogger.Info("something happened on that request") # will log request_id and user_ip | ||||
| requestLogger.Warn("something not great happened") | ||||
| ``` | ||||
| 
 | ||||
| #### Hooks | ||||
| 
 | ||||
| You can add hooks for logging levels. For example to send errors to an exception | ||||
|  | @ -176,9 +213,9 @@ Logrus comes with [built-in hooks](hooks/). Add those, or your custom hook, in | |||
| 
 | ||||
| ```go | ||||
| import ( | ||||
|   log "github.com/Sirupsen/logrus" | ||||
|   log "github.com/sirupsen/logrus" | ||||
|   "gopkg.in/gemnasium/logrus-airbrake-hook.v2" // the package is named "aibrake" | ||||
|   logrus_syslog "github.com/Sirupsen/logrus/hooks/syslog" | ||||
|   logrus_syslog "github.com/sirupsen/logrus/hooks/syslog" | ||||
|   "log/syslog" | ||||
| ) | ||||
| 
 | ||||
|  | @ -200,40 +237,51 @@ Note: Syslog hook also support connecting to local syslog (Ex. "/dev/log" or "/v | |||
| 
 | ||||
| | Hook  | Description | | ||||
| | ----- | ----------- | | ||||
| | [Airbrake](https://github.com/gemnasium/logrus-airbrake-hook) | Send errors to the Airbrake API V3. Uses the official [`gobrake`](https://github.com/airbrake/gobrake) behind the scenes. | | ||||
| | [Airbrake "legacy"](https://github.com/gemnasium/logrus-airbrake-legacy-hook) | Send errors to an exception tracking service compatible with the Airbrake API V2. Uses [`airbrake-go`](https://github.com/tobi/airbrake-go) behind the scenes. | | ||||
| | [Papertrail](https://github.com/polds/logrus-papertrail-hook) | Send errors to the [Papertrail](https://papertrailapp.com) hosted logging service via UDP. | | ||||
| | [Syslog](https://github.com/Sirupsen/logrus/blob/master/hooks/syslog/syslog.go) | Send errors to remote syslog server. Uses standard library `log/syslog` behind the scenes. | | ||||
| | [Bugsnag](https://github.com/Shopify/logrus-bugsnag/blob/master/bugsnag.go) | Send errors to the Bugsnag exception tracking service. | | ||||
| | [Sentry](https://github.com/evalphobia/logrus_sentry) | Send errors to the Sentry error logging and aggregation service. | | ||||
| | [Hiprus](https://github.com/nubo/hiprus) | Send errors to a channel in hipchat. | | ||||
| | [Logrusly](https://github.com/sebest/logrusly) | Send logs to [Loggly](https://www.loggly.com/) | | ||||
| | [Slackrus](https://github.com/johntdyer/slackrus) | Hook for Slack chat. | | ||||
| | [Journalhook](https://github.com/wercker/journalhook) | Hook for logging to `systemd-journald` | | ||||
| | [Graylog](https://github.com/gemnasium/logrus-graylog-hook) | Hook for logging to [Graylog](http://graylog2.org/) | | ||||
| | [Raygun](https://github.com/squirkle/logrus-raygun-hook) | Hook for logging to [Raygun.io](http://raygun.io/) | | ||||
| | [LFShook](https://github.com/rifflock/lfshook) | Hook for logging to the local filesystem | | ||||
| | [Honeybadger](https://github.com/agonzalezro/logrus_honeybadger) | Hook for sending exceptions to Honeybadger | | ||||
| | [Mail](https://github.com/zbindenren/logrus_mail) | Hook for sending exceptions via mail | | ||||
| | [Rollrus](https://github.com/heroku/rollrus) | Hook for sending errors to rollbar | | ||||
| | [Fluentd](https://github.com/evalphobia/logrus_fluent) | Hook for logging to fluentd | | ||||
| | [Mongodb](https://github.com/weekface/mgorus) | Hook for logging to mongodb | | ||||
| | [Influxus] (http://github.com/vlad-doru/influxus) | Hook for concurrently logging to [InfluxDB] (http://influxdata.com/) | | ||||
| | [InfluxDB](https://github.com/Abramovic/logrus_influxdb) | Hook for logging to influxdb | | ||||
| | [Octokit](https://github.com/dorajistyle/logrus-octokit-hook) | Hook for logging to github via octokit | | ||||
| | [DeferPanic](https://github.com/deferpanic/dp-logrus) | Hook for logging to DeferPanic | | ||||
| | [Redis-Hook](https://github.com/rogierlommers/logrus-redis-hook) | Hook for logging to a ELK stack (through Redis) | | ||||
| | [Airbrake](https://github.com/gemnasium/logrus-airbrake-hook) | Send errors to the Airbrake API V3. Uses the official [`gobrake`](https://github.com/airbrake/gobrake) behind the scenes. | | ||||
| | [Amazon Kinesis](https://github.com/evalphobia/logrus_kinesis) | Hook for logging to [Amazon Kinesis](https://aws.amazon.com/kinesis/) | | ||||
| | [Amqp-Hook](https://github.com/vladoatanasov/logrus_amqp) | Hook for logging to Amqp broker (Like RabbitMQ) | | ||||
| | [KafkaLogrus](https://github.com/goibibo/KafkaLogrus) | Hook for logging to kafka | | ||||
| | [Typetalk](https://github.com/dragon3/logrus-typetalk-hook) | Hook for logging to [Typetalk](https://www.typetalk.in/) | | ||||
| | [Bugsnag](https://github.com/Shopify/logrus-bugsnag/blob/master/bugsnag.go) | Send errors to the Bugsnag exception tracking service. | | ||||
| | [DeferPanic](https://github.com/deferpanic/dp-logrus) | Hook for logging to DeferPanic | | ||||
| | [Discordrus](https://github.com/kz/discordrus) | Hook for logging to [Discord](https://discordapp.com/) | | ||||
| | [ElasticSearch](https://github.com/sohlich/elogrus) | Hook for logging to ElasticSearch| | ||||
| | [Sumorus](https://github.com/doublefree/sumorus) | Hook for logging to [SumoLogic](https://www.sumologic.com/)| | ||||
| | [Scribe](https://github.com/sagar8192/logrus-scribe-hook) | Hook for logging to [Scribe](https://github.com/facebookarchive/scribe)| | ||||
| | [Logstash](https://github.com/bshuster-repo/logrus-logstash-hook) | Hook for logging to [Logstash](https://www.elastic.co/products/logstash) | | ||||
| | [logz.io](https://github.com/ripcurld00d/logrus-logzio-hook) | Hook for logging to [logz.io](https://logz.io), a Log as a Service using Logstash | | ||||
| | [Firehose](https://github.com/beaubrewer/logrus_firehose) | Hook for logging to [Amazon Firehose](https://aws.amazon.com/kinesis/firehose/) | ||||
| | [Fluentd](https://github.com/evalphobia/logrus_fluent) | Hook for logging to fluentd | | ||||
| | [Go-Slack](https://github.com/multiplay/go-slack) | Hook for logging to [Slack](https://slack.com) | | ||||
| | [Graylog](https://github.com/gemnasium/logrus-graylog-hook) | Hook for logging to [Graylog](http://graylog2.org/) | | ||||
| | [Hiprus](https://github.com/nubo/hiprus) | Send errors to a channel in hipchat. | | ||||
| | [Honeybadger](https://github.com/agonzalezro/logrus_honeybadger) | Hook for sending exceptions to Honeybadger | | ||||
| | [InfluxDB](https://github.com/Abramovic/logrus_influxdb) | Hook for logging to influxdb | | ||||
| | [Influxus](http://github.com/vlad-doru/influxus) | Hook for concurrently logging to [InfluxDB](http://influxdata.com/) | | ||||
| | [Journalhook](https://github.com/wercker/journalhook) | Hook for logging to `systemd-journald` | | ||||
| | [KafkaLogrus](https://github.com/goibibo/KafkaLogrus) | Hook for logging to kafka | | ||||
| | [LFShook](https://github.com/rifflock/lfshook) | Hook for logging to the local filesystem | | ||||
| | [Logentries](https://github.com/jcftang/logentriesrus) | Hook for logging to [Logentries](https://logentries.com/) | | ||||
| | [Logentrus](https://github.com/puddingfactory/logentrus) | Hook for logging to [Logentries](https://logentries.com/) | | ||||
| | [Logmatic.io](https://github.com/logmatic/logmatic-go) | Hook for logging to [Logmatic.io](http://logmatic.io/) | | ||||
| | [Logrusly](https://github.com/sebest/logrusly) | Send logs to [Loggly](https://www.loggly.com/) | | ||||
| | [Logstash](https://github.com/bshuster-repo/logrus-logstash-hook) | Hook for logging to [Logstash](https://www.elastic.co/products/logstash) | | ||||
| | [Mail](https://github.com/zbindenren/logrus_mail) | Hook for sending exceptions via mail | | ||||
| | [Mongodb](https://github.com/weekface/mgorus) | Hook for logging to mongodb | | ||||
| | [NATS-Hook](https://github.com/rybit/nats_logrus_hook) | Hook for logging to [NATS](https://nats.io) | | ||||
| | [Octokit](https://github.com/dorajistyle/logrus-octokit-hook) | Hook for logging to github via octokit | | ||||
| | [Papertrail](https://github.com/polds/logrus-papertrail-hook) | Send errors to the [Papertrail](https://papertrailapp.com) hosted logging service via UDP. | | ||||
| | [PostgreSQL](https://github.com/gemnasium/logrus-postgresql-hook) | Send logs to [PostgreSQL](http://postgresql.org) | | ||||
| | [Pushover](https://github.com/toorop/logrus_pushover) | Send error via [Pushover](https://pushover.net) | | ||||
| 
 | ||||
| | [Raygun](https://github.com/squirkle/logrus-raygun-hook) | Hook for logging to [Raygun.io](http://raygun.io/) | | ||||
| | [Redis-Hook](https://github.com/rogierlommers/logrus-redis-hook) | Hook for logging to a ELK stack (through Redis) | | ||||
| | [Rollrus](https://github.com/heroku/rollrus) | Hook for sending errors to rollbar | | ||||
| | [Scribe](https://github.com/sagar8192/logrus-scribe-hook) | Hook for logging to [Scribe](https://github.com/facebookarchive/scribe)| | ||||
| | [Sentry](https://github.com/evalphobia/logrus_sentry) | Send errors to the Sentry error logging and aggregation service. | | ||||
| | [Slackrus](https://github.com/johntdyer/slackrus) | Hook for Slack chat. | | ||||
| | [Stackdriver](https://github.com/knq/sdhook) | Hook for logging to [Google Stackdriver](https://cloud.google.com/logging/) | | ||||
| | [Sumorus](https://github.com/doublefree/sumorus) | Hook for logging to [SumoLogic](https://www.sumologic.com/)| | ||||
| | [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. | | ||||
| | [Syslog TLS](https://github.com/shinji62/logrus-syslog-ng) | Send errors to remote syslog server with TLS support. | | ||||
| | [TraceView](https://github.com/evalphobia/logrus_appneta) | Hook for logging to [AppNeta TraceView](https://www.appneta.com/products/traceview/) | | ||||
| | [Typetalk](https://github.com/dragon3/logrus-typetalk-hook) | Hook for logging to [Typetalk](https://www.typetalk.in/) | | ||||
| | [logz.io](https://github.com/ripcurld00d/logrus-logzio-hook) | Hook for logging to [logz.io](https://logz.io), a Log as a Service using Logstash | | ||||
| | [SQS-Hook](https://github.com/tsarpaul/logrus_sqs) | Hook for logging to [Amazon Simple Queue Service (SQS)](https://aws.amazon.com/sqs/) | | ||||
| 
 | ||||
| #### Level logging | ||||
| 
 | ||||
|  | @ -282,7 +330,7 @@ could do: | |||
| 
 | ||||
| ```go | ||||
| import ( | ||||
|   log "github.com/Sirupsen/logrus" | ||||
|   log "github.com/sirupsen/logrus" | ||||
| ) | ||||
| 
 | ||||
| init() { | ||||
|  | @ -309,8 +357,11 @@ The built-in logging formatters are: | |||
|   without colors. | ||||
|   * *Note:* to force colored output when there is no TTY, set the `ForceColors` | ||||
|     field to `true`.  To force no colored output even if there is a TTY  set the | ||||
|     `DisableColors` field to `true` | ||||
|     `DisableColors` field to `true`. For Windows, see | ||||
|     [github.com/mattn/go-colorable](https://github.com/mattn/go-colorable). | ||||
|   * All options are listed in the [generated docs](https://godoc.org/github.com/sirupsen/logrus#TextFormatter). | ||||
| * `logrus.JSONFormatter`. Logs fields as JSON. | ||||
|   * All options are listed in the [generated docs](https://godoc.org/github.com/sirupsen/logrus#JSONFormatter). | ||||
| 
 | ||||
| Third party logging formatters: | ||||
| 
 | ||||
|  | @ -359,6 +410,18 @@ srv := http.Server{ | |||
| Each line written to that writer will be printed the usual way, using formatters | ||||
| and hooks. The level for those entries is `info`. | ||||
| 
 | ||||
| This means that we can override the standard library logger easily: | ||||
| 
 | ||||
| ```go | ||||
| logger := logrus.New() | ||||
| logger.Formatter = &logrus.JSONFormatter{} | ||||
| 
 | ||||
| // Use logrus for standard log output | ||||
| // Note that `log` here references stdlib's log | ||||
| // Not logrus imported under the name `log`. | ||||
| log.SetOutput(logger.Writer()) | ||||
| ``` | ||||
| 
 | ||||
| #### Rotation | ||||
| 
 | ||||
| Log rotation is not provided with Logrus. Log rotation should be done by an | ||||
|  | @ -370,7 +433,7 @@ entries. It should not be a feature of the application-level logger. | |||
| | Tool | Description | | ||||
| | ---- | ----------- | | ||||
| |[Logrus Mate](https://github.com/gogap/logrus_mate)|Logrus mate is a tool for Logrus to manage loggers, you can initial logger's level, hook and formatter by config file, the logger will generated with different config at different environment.| | ||||
| |[Logrus Viper Helper](https://github.com/heirko/go-contrib/tree/master/logrusHelper)|An Helper arround Logrus to wrap with spf13/Viper to load configuration with fangs! And to simplify Logrus configuration use some behavior of [Logrus Mate](https://github.com/gogap/logrus_mate). [sample](https://github.com/heirko/iris-contrib/blob/master/middleware/logrus-logger/example) | | ||||
| |[Logrus Viper Helper](https://github.com/heirko/go-contrib/tree/master/logrusHelper)|An Helper around Logrus to wrap with spf13/Viper to load configuration with fangs! And to simplify Logrus configuration use some behavior of [Logrus Mate](https://github.com/gogap/logrus_mate). [sample](https://github.com/heirko/iris-contrib/blob/master/middleware/logrus-logger/example) | | ||||
| 
 | ||||
| #### Testing | ||||
| 
 | ||||
|  | @ -380,15 +443,24 @@ Logrus has a built in facility for asserting the presence of log messages. This | |||
| * a test logger (`test.NewNullLogger`) that just records log messages (and does not output any): | ||||
| 
 | ||||
| ```go | ||||
| logger, hook := NewNullLogger() | ||||
| logger.Error("Hello error") | ||||
| import( | ||||
|   "github.com/sirupsen/logrus" | ||||
|   "github.com/sirupsen/logrus/hooks/null" | ||||
|   "github.com/stretchr/testify/assert" | ||||
|   "testing" | ||||
| ) | ||||
| 
 | ||||
| assert.Equal(1, len(hook.Entries)) | ||||
| assert.Equal(logrus.ErrorLevel, hook.LastEntry().Level) | ||||
| assert.Equal("Hello error", hook.LastEntry().Message) | ||||
| func TestSomething(t*testing.T){ | ||||
|   logger, hook := null.NewNullLogger() | ||||
|   logger.Error("Helloerror") | ||||
| 
 | ||||
| hook.Reset() | ||||
| assert.Nil(hook.LastEntry()) | ||||
|   assert.Equal(t, 1, len(hook.Entries)) | ||||
|   assert.Equal(t, logrus.ErrorLevel, hook.LastEntry().Level) | ||||
|   assert.Equal(t, "Helloerror", hook.LastEntry().Message) | ||||
| 
 | ||||
|   hook.Reset() | ||||
|   assert.Nil(t, hook.LastEntry()) | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| #### Fatal handlers | ||||
|  | @ -407,7 +479,7 @@ logrus.RegisterExitHandler(handler) | |||
| ... | ||||
| ``` | ||||
| 
 | ||||
| #### Thread safty | ||||
| #### Thread safety | ||||
| 
 | ||||
| By default Logger is protected by mutex for concurrent writes, this mutex is invoked when calling hooks and writing logs. | ||||
| If you are sure such locking is not needed, you can call logger.SetNoLock() to disable the locking. | ||||
|  | @ -1,7 +1,7 @@ | |||
| package logrus | ||||
| 
 | ||||
| // The following code was sourced and modified from the
 | ||||
| // https://bitbucket.org/tebeka/atexit package governed by the following license:
 | ||||
| // https://github.com/tebeka/atexit package governed by the following license:
 | ||||
| //
 | ||||
| // Copyright (c) 2012 Miki Tebeka <miki.tebeka@gmail.com>.
 | ||||
| //
 | ||||
							
								
								
									
										4
									
								
								vendor/github.com/Sirupsen/logrus/doc.go → vendor/github.com/sirupsen/logrus/doc.go
								
								
									generated
								
								
									vendored
								
								
							
							
						
						
									
										4
									
								
								vendor/github.com/Sirupsen/logrus/doc.go → vendor/github.com/sirupsen/logrus/doc.go
								
								
									generated
								
								
									vendored
								
								
							|  | @ -7,7 +7,7 @@ The simplest way to use Logrus is simply the package-level exported logger: | |||
|   package main | ||||
| 
 | ||||
|   import ( | ||||
|     log "github.com/Sirupsen/logrus" | ||||
|     log "github.com/sirupsen/logrus" | ||||
|   ) | ||||
| 
 | ||||
|   func main() { | ||||
|  | @ -21,6 +21,6 @@ The simplest way to use Logrus is simply the package-level exported logger: | |||
| Output: | ||||
|   time="2015-09-07T08:48:33Z" level=info msg="A walrus appears" animal=walrus number=1 size=10 | ||||
| 
 | ||||
| For a full guide visit https://github.com/Sirupsen/logrus
 | ||||
| For a full guide visit https://github.com/sirupsen/logrus
 | ||||
| */ | ||||
| package logrus | ||||
							
								
								
									
										36
									
								
								vendor/github.com/Sirupsen/logrus/entry.go → vendor/github.com/sirupsen/logrus/entry.go
								
								
									generated
								
								
									vendored
								
								
							
							
						
						
									
										36
									
								
								vendor/github.com/Sirupsen/logrus/entry.go → vendor/github.com/sirupsen/logrus/entry.go
								
								
									generated
								
								
									vendored
								
								
							|  | @ -126,7 +126,7 @@ func (entry Entry) log(level Level, msg string) { | |||
| } | ||||
| 
 | ||||
| func (entry *Entry) Debug(args ...interface{}) { | ||||
| 	if entry.Logger.Level >= DebugLevel { | ||||
| 	if entry.Logger.level() >= DebugLevel { | ||||
| 		entry.log(DebugLevel, fmt.Sprint(args...)) | ||||
| 	} | ||||
| } | ||||
|  | @ -136,13 +136,13 @@ func (entry *Entry) Print(args ...interface{}) { | |||
| } | ||||
| 
 | ||||
| func (entry *Entry) Info(args ...interface{}) { | ||||
| 	if entry.Logger.Level >= InfoLevel { | ||||
| 	if entry.Logger.level() >= InfoLevel { | ||||
| 		entry.log(InfoLevel, fmt.Sprint(args...)) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (entry *Entry) Warn(args ...interface{}) { | ||||
| 	if entry.Logger.Level >= WarnLevel { | ||||
| 	if entry.Logger.level() >= WarnLevel { | ||||
| 		entry.log(WarnLevel, fmt.Sprint(args...)) | ||||
| 	} | ||||
| } | ||||
|  | @ -152,20 +152,20 @@ func (entry *Entry) Warning(args ...interface{}) { | |||
| } | ||||
| 
 | ||||
| func (entry *Entry) Error(args ...interface{}) { | ||||
| 	if entry.Logger.Level >= ErrorLevel { | ||||
| 	if entry.Logger.level() >= ErrorLevel { | ||||
| 		entry.log(ErrorLevel, fmt.Sprint(args...)) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (entry *Entry) Fatal(args ...interface{}) { | ||||
| 	if entry.Logger.Level >= FatalLevel { | ||||
| 	if entry.Logger.level() >= FatalLevel { | ||||
| 		entry.log(FatalLevel, fmt.Sprint(args...)) | ||||
| 	} | ||||
| 	Exit(1) | ||||
| } | ||||
| 
 | ||||
| func (entry *Entry) Panic(args ...interface{}) { | ||||
| 	if entry.Logger.Level >= PanicLevel { | ||||
| 	if entry.Logger.level() >= PanicLevel { | ||||
| 		entry.log(PanicLevel, fmt.Sprint(args...)) | ||||
| 	} | ||||
| 	panic(fmt.Sprint(args...)) | ||||
|  | @ -174,13 +174,13 @@ func (entry *Entry) Panic(args ...interface{}) { | |||
| // Entry Printf family functions
 | ||||
| 
 | ||||
| func (entry *Entry) Debugf(format string, args ...interface{}) { | ||||
| 	if entry.Logger.Level >= DebugLevel { | ||||
| 	if entry.Logger.level() >= DebugLevel { | ||||
| 		entry.Debug(fmt.Sprintf(format, args...)) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (entry *Entry) Infof(format string, args ...interface{}) { | ||||
| 	if entry.Logger.Level >= InfoLevel { | ||||
| 	if entry.Logger.level() >= InfoLevel { | ||||
| 		entry.Info(fmt.Sprintf(format, args...)) | ||||
| 	} | ||||
| } | ||||
|  | @ -190,7 +190,7 @@ func (entry *Entry) Printf(format string, args ...interface{}) { | |||
| } | ||||
| 
 | ||||
| func (entry *Entry) Warnf(format string, args ...interface{}) { | ||||
| 	if entry.Logger.Level >= WarnLevel { | ||||
| 	if entry.Logger.level() >= WarnLevel { | ||||
| 		entry.Warn(fmt.Sprintf(format, args...)) | ||||
| 	} | ||||
| } | ||||
|  | @ -200,20 +200,20 @@ func (entry *Entry) Warningf(format string, args ...interface{}) { | |||
| } | ||||
| 
 | ||||
| func (entry *Entry) Errorf(format string, args ...interface{}) { | ||||
| 	if entry.Logger.Level >= ErrorLevel { | ||||
| 	if entry.Logger.level() >= ErrorLevel { | ||||
| 		entry.Error(fmt.Sprintf(format, args...)) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (entry *Entry) Fatalf(format string, args ...interface{}) { | ||||
| 	if entry.Logger.Level >= FatalLevel { | ||||
| 	if entry.Logger.level() >= FatalLevel { | ||||
| 		entry.Fatal(fmt.Sprintf(format, args...)) | ||||
| 	} | ||||
| 	Exit(1) | ||||
| } | ||||
| 
 | ||||
| func (entry *Entry) Panicf(format string, args ...interface{}) { | ||||
| 	if entry.Logger.Level >= PanicLevel { | ||||
| 	if entry.Logger.level() >= PanicLevel { | ||||
| 		entry.Panic(fmt.Sprintf(format, args...)) | ||||
| 	} | ||||
| } | ||||
|  | @ -221,13 +221,13 @@ func (entry *Entry) Panicf(format string, args ...interface{}) { | |||
| // Entry Println family functions
 | ||||
| 
 | ||||
| func (entry *Entry) Debugln(args ...interface{}) { | ||||
| 	if entry.Logger.Level >= DebugLevel { | ||||
| 	if entry.Logger.level() >= DebugLevel { | ||||
| 		entry.Debug(entry.sprintlnn(args...)) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (entry *Entry) Infoln(args ...interface{}) { | ||||
| 	if entry.Logger.Level >= InfoLevel { | ||||
| 	if entry.Logger.level() >= InfoLevel { | ||||
| 		entry.Info(entry.sprintlnn(args...)) | ||||
| 	} | ||||
| } | ||||
|  | @ -237,7 +237,7 @@ func (entry *Entry) Println(args ...interface{}) { | |||
| } | ||||
| 
 | ||||
| func (entry *Entry) Warnln(args ...interface{}) { | ||||
| 	if entry.Logger.Level >= WarnLevel { | ||||
| 	if entry.Logger.level() >= WarnLevel { | ||||
| 		entry.Warn(entry.sprintlnn(args...)) | ||||
| 	} | ||||
| } | ||||
|  | @ -247,20 +247,20 @@ func (entry *Entry) Warningln(args ...interface{}) { | |||
| } | ||||
| 
 | ||||
| func (entry *Entry) Errorln(args ...interface{}) { | ||||
| 	if entry.Logger.Level >= ErrorLevel { | ||||
| 	if entry.Logger.level() >= ErrorLevel { | ||||
| 		entry.Error(entry.sprintlnn(args...)) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (entry *Entry) Fatalln(args ...interface{}) { | ||||
| 	if entry.Logger.Level >= FatalLevel { | ||||
| 	if entry.Logger.level() >= FatalLevel { | ||||
| 		entry.Fatal(entry.sprintlnn(args...)) | ||||
| 	} | ||||
| 	Exit(1) | ||||
| } | ||||
| 
 | ||||
| func (entry *Entry) Panicln(args ...interface{}) { | ||||
| 	if entry.Logger.Level >= PanicLevel { | ||||
| 	if entry.Logger.level() >= PanicLevel { | ||||
| 		entry.Panic(entry.sprintlnn(args...)) | ||||
| 	} | ||||
| } | ||||
|  | @ -31,14 +31,14 @@ func SetFormatter(formatter Formatter) { | |||
| func SetLevel(level Level) { | ||||
| 	std.mu.Lock() | ||||
| 	defer std.mu.Unlock() | ||||
| 	std.Level = level | ||||
| 	std.setLevel(level) | ||||
| } | ||||
| 
 | ||||
| // GetLevel returns the standard logger level.
 | ||||
| func GetLevel() Level { | ||||
| 	std.mu.Lock() | ||||
| 	defer std.mu.Unlock() | ||||
| 	return std.Level | ||||
| 	return std.level() | ||||
| } | ||||
| 
 | ||||
| // AddHook adds a hook to the standard logger hooks.
 | ||||
|  | @ -0,0 +1,74 @@ | |||
| package logrus | ||||
| 
 | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| ) | ||||
| 
 | ||||
| type fieldKey string | ||||
| type FieldMap map[fieldKey]string | ||||
| 
 | ||||
| const ( | ||||
| 	FieldKeyMsg   = "msg" | ||||
| 	FieldKeyLevel = "level" | ||||
| 	FieldKeyTime  = "time" | ||||
| ) | ||||
| 
 | ||||
| func (f FieldMap) resolve(key fieldKey) string { | ||||
| 	if k, ok := f[key]; ok { | ||||
| 		return k | ||||
| 	} | ||||
| 
 | ||||
| 	return string(key) | ||||
| } | ||||
| 
 | ||||
| type JSONFormatter struct { | ||||
| 	// TimestampFormat sets the format used for marshaling timestamps.
 | ||||
| 	TimestampFormat string | ||||
| 
 | ||||
| 	// DisableTimestamp allows disabling automatic timestamps in output
 | ||||
| 	DisableTimestamp bool | ||||
| 
 | ||||
| 	// FieldMap allows users to customize the names of keys for various fields.
 | ||||
| 	// As an example:
 | ||||
| 	// formatter := &JSONFormatter{
 | ||||
| 	//   	FieldMap: FieldMap{
 | ||||
| 	// 		 FieldKeyTime: "@timestamp",
 | ||||
| 	// 		 FieldKeyLevel: "@level",
 | ||||
| 	// 		 FieldKeyMsg: "@message",
 | ||||
| 	//    },
 | ||||
| 	// }
 | ||||
| 	FieldMap FieldMap | ||||
| } | ||||
| 
 | ||||
| func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { | ||||
| 	data := make(Fields, len(entry.Data)+3) | ||||
| 	for k, v := range entry.Data { | ||||
| 		switch v := v.(type) { | ||||
| 		case error: | ||||
| 			// Otherwise errors are ignored by `encoding/json`
 | ||||
| 			// https://github.com/sirupsen/logrus/issues/137
 | ||||
| 			data[k] = v.Error() | ||||
| 		default: | ||||
| 			data[k] = v | ||||
| 		} | ||||
| 	} | ||||
| 	prefixFieldClashes(data) | ||||
| 
 | ||||
| 	timestampFormat := f.TimestampFormat | ||||
| 	if timestampFormat == "" { | ||||
| 		timestampFormat = DefaultTimestampFormat | ||||
| 	} | ||||
| 
 | ||||
| 	if !f.DisableTimestamp { | ||||
| 		data[f.FieldMap.resolve(FieldKeyTime)] = entry.Time.Format(timestampFormat) | ||||
| 	} | ||||
| 	data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message | ||||
| 	data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String() | ||||
| 
 | ||||
| 	serialized, err := json.Marshal(data) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) | ||||
| 	} | ||||
| 	return append(serialized, '\n'), nil | ||||
| } | ||||
|  | @ -4,6 +4,7 @@ import ( | |||
| 	"io" | ||||
| 	"os" | ||||
| 	"sync" | ||||
| 	"sync/atomic" | ||||
| ) | ||||
| 
 | ||||
| type Logger struct { | ||||
|  | @ -112,7 +113,7 @@ func (logger *Logger) WithError(err error) *Entry { | |||
| } | ||||
| 
 | ||||
| func (logger *Logger) Debugf(format string, args ...interface{}) { | ||||
| 	if logger.Level >= DebugLevel { | ||||
| 	if logger.level() >= DebugLevel { | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Debugf(format, args...) | ||||
| 		logger.releaseEntry(entry) | ||||
|  | @ -120,7 +121,7 @@ func (logger *Logger) Debugf(format string, args ...interface{}) { | |||
| } | ||||
| 
 | ||||
| func (logger *Logger) Infof(format string, args ...interface{}) { | ||||
| 	if logger.Level >= InfoLevel { | ||||
| 	if logger.level() >= InfoLevel { | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Infof(format, args...) | ||||
| 		logger.releaseEntry(entry) | ||||
|  | @ -134,7 +135,7 @@ func (logger *Logger) Printf(format string, args ...interface{}) { | |||
| } | ||||
| 
 | ||||
| func (logger *Logger) Warnf(format string, args ...interface{}) { | ||||
| 	if logger.Level >= WarnLevel { | ||||
| 	if logger.level() >= WarnLevel { | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Warnf(format, args...) | ||||
| 		logger.releaseEntry(entry) | ||||
|  | @ -142,7 +143,7 @@ func (logger *Logger) Warnf(format string, args ...interface{}) { | |||
| } | ||||
| 
 | ||||
| func (logger *Logger) Warningf(format string, args ...interface{}) { | ||||
| 	if logger.Level >= WarnLevel { | ||||
| 	if logger.level() >= WarnLevel { | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Warnf(format, args...) | ||||
| 		logger.releaseEntry(entry) | ||||
|  | @ -150,7 +151,7 @@ func (logger *Logger) Warningf(format string, args ...interface{}) { | |||
| } | ||||
| 
 | ||||
| func (logger *Logger) Errorf(format string, args ...interface{}) { | ||||
| 	if logger.Level >= ErrorLevel { | ||||
| 	if logger.level() >= ErrorLevel { | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Errorf(format, args...) | ||||
| 		logger.releaseEntry(entry) | ||||
|  | @ -158,7 +159,7 @@ func (logger *Logger) Errorf(format string, args ...interface{}) { | |||
| } | ||||
| 
 | ||||
| func (logger *Logger) Fatalf(format string, args ...interface{}) { | ||||
| 	if logger.Level >= FatalLevel { | ||||
| 	if logger.level() >= FatalLevel { | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Fatalf(format, args...) | ||||
| 		logger.releaseEntry(entry) | ||||
|  | @ -167,7 +168,7 @@ func (logger *Logger) Fatalf(format string, args ...interface{}) { | |||
| } | ||||
| 
 | ||||
| func (logger *Logger) Panicf(format string, args ...interface{}) { | ||||
| 	if logger.Level >= PanicLevel { | ||||
| 	if logger.level() >= PanicLevel { | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Panicf(format, args...) | ||||
| 		logger.releaseEntry(entry) | ||||
|  | @ -175,7 +176,7 @@ func (logger *Logger) Panicf(format string, args ...interface{}) { | |||
| } | ||||
| 
 | ||||
| func (logger *Logger) Debug(args ...interface{}) { | ||||
| 	if logger.Level >= DebugLevel { | ||||
| 	if logger.level() >= DebugLevel { | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Debug(args...) | ||||
| 		logger.releaseEntry(entry) | ||||
|  | @ -183,7 +184,7 @@ func (logger *Logger) Debug(args ...interface{}) { | |||
| } | ||||
| 
 | ||||
| func (logger *Logger) Info(args ...interface{}) { | ||||
| 	if logger.Level >= InfoLevel { | ||||
| 	if logger.level() >= InfoLevel { | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Info(args...) | ||||
| 		logger.releaseEntry(entry) | ||||
|  | @ -197,7 +198,7 @@ func (logger *Logger) Print(args ...interface{}) { | |||
| } | ||||
| 
 | ||||
| func (logger *Logger) Warn(args ...interface{}) { | ||||
| 	if logger.Level >= WarnLevel { | ||||
| 	if logger.level() >= WarnLevel { | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Warn(args...) | ||||
| 		logger.releaseEntry(entry) | ||||
|  | @ -205,7 +206,7 @@ func (logger *Logger) Warn(args ...interface{}) { | |||
| } | ||||
| 
 | ||||
| func (logger *Logger) Warning(args ...interface{}) { | ||||
| 	if logger.Level >= WarnLevel { | ||||
| 	if logger.level() >= WarnLevel { | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Warn(args...) | ||||
| 		logger.releaseEntry(entry) | ||||
|  | @ -213,7 +214,7 @@ func (logger *Logger) Warning(args ...interface{}) { | |||
| } | ||||
| 
 | ||||
| func (logger *Logger) Error(args ...interface{}) { | ||||
| 	if logger.Level >= ErrorLevel { | ||||
| 	if logger.level() >= ErrorLevel { | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Error(args...) | ||||
| 		logger.releaseEntry(entry) | ||||
|  | @ -221,7 +222,7 @@ func (logger *Logger) Error(args ...interface{}) { | |||
| } | ||||
| 
 | ||||
| func (logger *Logger) Fatal(args ...interface{}) { | ||||
| 	if logger.Level >= FatalLevel { | ||||
| 	if logger.level() >= FatalLevel { | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Fatal(args...) | ||||
| 		logger.releaseEntry(entry) | ||||
|  | @ -230,7 +231,7 @@ func (logger *Logger) Fatal(args ...interface{}) { | |||
| } | ||||
| 
 | ||||
| func (logger *Logger) Panic(args ...interface{}) { | ||||
| 	if logger.Level >= PanicLevel { | ||||
| 	if logger.level() >= PanicLevel { | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Panic(args...) | ||||
| 		logger.releaseEntry(entry) | ||||
|  | @ -238,7 +239,7 @@ func (logger *Logger) Panic(args ...interface{}) { | |||
| } | ||||
| 
 | ||||
| func (logger *Logger) Debugln(args ...interface{}) { | ||||
| 	if logger.Level >= DebugLevel { | ||||
| 	if logger.level() >= DebugLevel { | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Debugln(args...) | ||||
| 		logger.releaseEntry(entry) | ||||
|  | @ -246,7 +247,7 @@ func (logger *Logger) Debugln(args ...interface{}) { | |||
| } | ||||
| 
 | ||||
| func (logger *Logger) Infoln(args ...interface{}) { | ||||
| 	if logger.Level >= InfoLevel { | ||||
| 	if logger.level() >= InfoLevel { | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Infoln(args...) | ||||
| 		logger.releaseEntry(entry) | ||||
|  | @ -260,7 +261,7 @@ func (logger *Logger) Println(args ...interface{}) { | |||
| } | ||||
| 
 | ||||
| func (logger *Logger) Warnln(args ...interface{}) { | ||||
| 	if logger.Level >= WarnLevel { | ||||
| 	if logger.level() >= WarnLevel { | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Warnln(args...) | ||||
| 		logger.releaseEntry(entry) | ||||
|  | @ -268,7 +269,7 @@ func (logger *Logger) Warnln(args ...interface{}) { | |||
| } | ||||
| 
 | ||||
| func (logger *Logger) Warningln(args ...interface{}) { | ||||
| 	if logger.Level >= WarnLevel { | ||||
| 	if logger.level() >= WarnLevel { | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Warnln(args...) | ||||
| 		logger.releaseEntry(entry) | ||||
|  | @ -276,7 +277,7 @@ func (logger *Logger) Warningln(args ...interface{}) { | |||
| } | ||||
| 
 | ||||
| func (logger *Logger) Errorln(args ...interface{}) { | ||||
| 	if logger.Level >= ErrorLevel { | ||||
| 	if logger.level() >= ErrorLevel { | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Errorln(args...) | ||||
| 		logger.releaseEntry(entry) | ||||
|  | @ -284,7 +285,7 @@ func (logger *Logger) Errorln(args ...interface{}) { | |||
| } | ||||
| 
 | ||||
| func (logger *Logger) Fatalln(args ...interface{}) { | ||||
| 	if logger.Level >= FatalLevel { | ||||
| 	if logger.level() >= FatalLevel { | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Fatalln(args...) | ||||
| 		logger.releaseEntry(entry) | ||||
|  | @ -293,7 +294,7 @@ func (logger *Logger) Fatalln(args ...interface{}) { | |||
| } | ||||
| 
 | ||||
| func (logger *Logger) Panicln(args ...interface{}) { | ||||
| 	if logger.Level >= PanicLevel { | ||||
| 	if logger.level() >= PanicLevel { | ||||
| 		entry := logger.newEntry() | ||||
| 		entry.Panicln(args...) | ||||
| 		logger.releaseEntry(entry) | ||||
|  | @ -306,3 +307,11 @@ func (logger *Logger) Panicln(args ...interface{}) { | |||
| func (logger *Logger) SetNoLock() { | ||||
| 	logger.mu.Disable() | ||||
| } | ||||
| 
 | ||||
| func (logger *Logger) level() Level { | ||||
| 	return Level(atomic.LoadUint32((*uint32)(&logger.Level))) | ||||
| } | ||||
| 
 | ||||
| func (logger *Logger) setLevel(level Level) { | ||||
| 	atomic.StoreUint32((*uint32)(&logger.Level), uint32(level)) | ||||
| } | ||||
|  | @ -10,7 +10,7 @@ import ( | |||
| type Fields map[string]interface{} | ||||
| 
 | ||||
| // Level type
 | ||||
| type Level uint8 | ||||
| type Level uint32 | ||||
| 
 | ||||
| // Convert the Level to a string. E.g. PanicLevel becomes "panic".
 | ||||
| func (level Level) String() string { | ||||
|  | @ -2,7 +2,9 @@ | |||
| 
 | ||||
| package logrus | ||||
| 
 | ||||
| import "io" | ||||
| 
 | ||||
| // IsTerminal returns true if stderr's file descriptor is a terminal.
 | ||||
| func IsTerminal() bool { | ||||
| func IsTerminal(f io.Writer) bool { | ||||
| 	return true | ||||
| } | ||||
|  | @ -9,14 +9,20 @@ | |||
| package logrus | ||||
| 
 | ||||
| import ( | ||||
| 	"io" | ||||
| 	"os" | ||||
| 	"syscall" | ||||
| 	"unsafe" | ||||
| ) | ||||
| 
 | ||||
| // IsTerminal returns true if stderr's file descriptor is a terminal.
 | ||||
| func IsTerminal() bool { | ||||
| 	fd := syscall.Stderr | ||||
| func IsTerminal(f io.Writer) bool { | ||||
| 	var termios Termios | ||||
| 	_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) | ||||
| 	return err == 0 | ||||
| 	switch v := f.(type) { | ||||
| 	case *os.File: | ||||
| 		_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(v.Fd()), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) | ||||
| 		return err == 0 | ||||
| 	default: | ||||
| 		return false | ||||
| 	} | ||||
| } | ||||
|  | @ -0,0 +1,21 @@ | |||
| // +build solaris,!appengine
 | ||||
| 
 | ||||
| package logrus | ||||
| 
 | ||||
| import ( | ||||
| 	"io" | ||||
| 	"os" | ||||
| 
 | ||||
| 	"golang.org/x/sys/unix" | ||||
| ) | ||||
| 
 | ||||
| // IsTerminal returns true if the given file descriptor is a terminal.
 | ||||
| func IsTerminal(f io.Writer) bool { | ||||
| 	switch v := f.(type) { | ||||
| 	case *os.File: | ||||
| 		_, err := unix.IoctlGetTermios(int(v.Fd()), unix.TCGETA) | ||||
| 		return err == nil | ||||
| 	default: | ||||
| 		return false | ||||
| 	} | ||||
| } | ||||
|  | @ -0,0 +1,82 @@ | |||
| // Based on ssh/terminal:
 | ||||
| // Copyright 2011 The Go Authors. All rights reserved.
 | ||||
| // Use of this source code is governed by a BSD-style
 | ||||
| // license that can be found in the LICENSE file.
 | ||||
| 
 | ||||
| // +build windows,!appengine
 | ||||
| 
 | ||||
| package logrus | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"errors" | ||||
| 	"io" | ||||
| 	"os" | ||||
| 	"os/exec" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"syscall" | ||||
| 	"unsafe" | ||||
| ) | ||||
| 
 | ||||
| var kernel32 = syscall.NewLazyDLL("kernel32.dll") | ||||
| 
 | ||||
| var ( | ||||
| 	procGetConsoleMode = kernel32.NewProc("GetConsoleMode") | ||||
| 	procSetConsoleMode = kernel32.NewProc("SetConsoleMode") | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	enableProcessedOutput           = 0x0001 | ||||
| 	enableWrapAtEolOutput           = 0x0002 | ||||
| 	enableVirtualTerminalProcessing = 0x0004 | ||||
| ) | ||||
| 
 | ||||
| func getVersion() (float64, error) { | ||||
| 	stdout, stderr := &bytes.Buffer{}, &bytes.Buffer{} | ||||
| 	cmd := exec.Command("cmd", "ver") | ||||
| 	cmd.Stdout = stdout | ||||
| 	cmd.Stderr = stderr | ||||
| 	err := cmd.Run() | ||||
| 	if err != nil { | ||||
| 		return -1, err | ||||
| 	} | ||||
| 	 | ||||
| 	// The output should be like "Microsoft Windows [Version XX.X.XXXXXX]"
 | ||||
| 	version := strings.Replace(stdout.String(), "\n", "", -1) | ||||
| 	version = strings.Replace(version, "\r\n", "", -1) | ||||
| 
 | ||||
| 	x1 := strings.Index(version, "[Version") | ||||
| 
 | ||||
| 	if x1 == -1 || strings.Index(version, "]") == -1 { | ||||
| 		return -1, errors.New("Can't determine Windows version") | ||||
| 	} | ||||
| 
 | ||||
| 	return strconv.ParseFloat(version[x1+9:x1+13], 64) | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	ver, err := getVersion() | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	// Activate Virtual Processing for Windows CMD
 | ||||
| 	// Info: https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx
 | ||||
| 	if ver >= 10 { | ||||
| 		handle := syscall.Handle(os.Stderr.Fd()) | ||||
| 		procSetConsoleMode.Call(uintptr(handle), enableProcessedOutput|enableWrapAtEolOutput|enableVirtualTerminalProcessing) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // IsTerminal returns true if stderr's file descriptor is a terminal.
 | ||||
| func IsTerminal(f io.Writer) bool { | ||||
| 	switch v := f.(type) { | ||||
| 	case *os.File: | ||||
| 		var st uint32 | ||||
| 		r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(v.Fd()), uintptr(unsafe.Pointer(&st)), 0) | ||||
| 		return r != 0 && e == 0 | ||||
| 	default: | ||||
| 		return false | ||||
| 	} | ||||
| } | ||||
|  | @ -3,9 +3,9 @@ package logrus | |||
| import ( | ||||
| 	"bytes" | ||||
| 	"fmt" | ||||
| 	"runtime" | ||||
| 	"sort" | ||||
| 	"strings" | ||||
| 	"sync" | ||||
| 	"time" | ||||
| ) | ||||
| 
 | ||||
|  | @ -20,16 +20,10 @@ const ( | |||
| 
 | ||||
| var ( | ||||
| 	baseTimestamp time.Time | ||||
| 	isTerminal    bool | ||||
| ) | ||||
| 
 | ||||
| func init() { | ||||
| 	baseTimestamp = time.Now() | ||||
| 	isTerminal = IsTerminal() | ||||
| } | ||||
| 
 | ||||
| func miniTS() int { | ||||
| 	return int(time.Since(baseTimestamp) / time.Second) | ||||
| } | ||||
| 
 | ||||
| type TextFormatter struct { | ||||
|  | @ -54,11 +48,32 @@ type TextFormatter struct { | |||
| 	// that log extremely frequently and don't use the JSON formatter this may not
 | ||||
| 	// be desired.
 | ||||
| 	DisableSorting bool | ||||
| 
 | ||||
| 	// QuoteEmptyFields will wrap empty fields in quotes if true
 | ||||
| 	QuoteEmptyFields bool | ||||
| 
 | ||||
| 	// QuoteCharacter can be set to the override the default quoting character "
 | ||||
| 	// with something else. For example: ', or `.
 | ||||
| 	QuoteCharacter string | ||||
| 
 | ||||
| 	// Whether the logger's out is to a terminal
 | ||||
| 	isTerminal bool | ||||
| 
 | ||||
| 	sync.Once | ||||
| } | ||||
| 
 | ||||
| func (f *TextFormatter) init(entry *Entry) { | ||||
| 	if len(f.QuoteCharacter) == 0 { | ||||
| 		f.QuoteCharacter = "\"" | ||||
| 	} | ||||
| 	if entry.Logger != nil { | ||||
| 		f.isTerminal = IsTerminal(entry.Logger.Out) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { | ||||
| 	var b *bytes.Buffer | ||||
| 	var keys []string = make([]string, 0, len(entry.Data)) | ||||
| 	keys := make([]string, 0, len(entry.Data)) | ||||
| 	for k := range entry.Data { | ||||
| 		keys = append(keys, k) | ||||
| 	} | ||||
|  | @ -74,8 +89,9 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) { | |||
| 
 | ||||
| 	prefixFieldClashes(entry.Data) | ||||
| 
 | ||||
| 	isColorTerminal := isTerminal && (runtime.GOOS != "windows") | ||||
| 	isColored := (f.ForceColors || isColorTerminal) && !f.DisableColors | ||||
| 	f.Do(func() { f.init(entry) }) | ||||
| 
 | ||||
| 	isColored := (f.ForceColors || f.isTerminal) && !f.DisableColors | ||||
| 
 | ||||
| 	timestampFormat := f.TimestampFormat | ||||
| 	if timestampFormat == "" { | ||||
|  | @ -115,8 +131,10 @@ func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []strin | |||
| 
 | ||||
| 	levelText := strings.ToUpper(entry.Level.String())[0:4] | ||||
| 
 | ||||
| 	if !f.FullTimestamp { | ||||
| 		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, miniTS(), entry.Message) | ||||
| 	if f.DisableTimestamp { | ||||
| 		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m %-44s ", levelColor, levelText, entry.Message) | ||||
| 	} else if !f.FullTimestamp { | ||||
| 		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d] %-44s ", levelColor, levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), entry.Message) | ||||
| 	} else { | ||||
| 		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), entry.Message) | ||||
| 	} | ||||
|  | @ -127,7 +145,10 @@ func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []strin | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| func needsQuoting(text string) bool { | ||||
| func (f *TextFormatter) needsQuoting(text string) bool { | ||||
| 	if f.QuoteEmptyFields && len(text) == 0 { | ||||
| 		return true | ||||
| 	} | ||||
| 	for _, ch := range text { | ||||
| 		if !((ch >= 'a' && ch <= 'z') || | ||||
| 			(ch >= 'A' && ch <= 'Z') || | ||||
|  | @ -150,17 +171,17 @@ func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interf | |||
| func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) { | ||||
| 	switch value := value.(type) { | ||||
| 	case string: | ||||
| 		if !needsQuoting(value) { | ||||
| 		if !f.needsQuoting(value) { | ||||
| 			b.WriteString(value) | ||||
| 		} else { | ||||
| 			fmt.Fprintf(b, "%q", value) | ||||
| 			fmt.Fprintf(b, "%s%v%s", f.QuoteCharacter, value, f.QuoteCharacter) | ||||
| 		} | ||||
| 	case error: | ||||
| 		errmsg := value.Error() | ||||
| 		if !needsQuoting(errmsg) { | ||||
| 		if !f.needsQuoting(errmsg) { | ||||
| 			b.WriteString(errmsg) | ||||
| 		} else { | ||||
| 			fmt.Fprintf(b, "%q", errmsg) | ||||
| 			fmt.Fprintf(b, "%s%v%s", f.QuoteCharacter, errmsg, f.QuoteCharacter) | ||||
| 		} | ||||
| 	default: | ||||
| 		fmt.Fprint(b, value) | ||||
|  | @ -11,39 +11,48 @@ func (logger *Logger) Writer() *io.PipeWriter { | |||
| } | ||||
| 
 | ||||
| func (logger *Logger) WriterLevel(level Level) *io.PipeWriter { | ||||
| 	return NewEntry(logger).WriterLevel(level) | ||||
| } | ||||
| 
 | ||||
| func (entry *Entry) Writer() *io.PipeWriter { | ||||
| 	return entry.WriterLevel(InfoLevel) | ||||
| } | ||||
| 
 | ||||
| func (entry *Entry) WriterLevel(level Level) *io.PipeWriter { | ||||
| 	reader, writer := io.Pipe() | ||||
| 
 | ||||
| 	var printFunc func(args ...interface{}) | ||||
| 
 | ||||
| 	switch level { | ||||
| 	case DebugLevel: | ||||
| 		printFunc = logger.Debug | ||||
| 		printFunc = entry.Debug | ||||
| 	case InfoLevel: | ||||
| 		printFunc = logger.Info | ||||
| 		printFunc = entry.Info | ||||
| 	case WarnLevel: | ||||
| 		printFunc = logger.Warn | ||||
| 		printFunc = entry.Warn | ||||
| 	case ErrorLevel: | ||||
| 		printFunc = logger.Error | ||||
| 		printFunc = entry.Error | ||||
| 	case FatalLevel: | ||||
| 		printFunc = logger.Fatal | ||||
| 		printFunc = entry.Fatal | ||||
| 	case PanicLevel: | ||||
| 		printFunc = logger.Panic | ||||
| 		printFunc = entry.Panic | ||||
| 	default: | ||||
| 		printFunc = logger.Print | ||||
| 		printFunc = entry.Print | ||||
| 	} | ||||
| 
 | ||||
| 	go logger.writerScanner(reader, printFunc) | ||||
| 	go entry.writerScanner(reader, printFunc) | ||||
| 	runtime.SetFinalizer(writer, writerFinalizer) | ||||
| 
 | ||||
| 	return writer | ||||
| } | ||||
| 
 | ||||
| func (logger *Logger) writerScanner(reader *io.PipeReader, printFunc func(args ...interface{})) { | ||||
| func (entry *Entry) writerScanner(reader *io.PipeReader, printFunc func(args ...interface{})) { | ||||
| 	scanner := bufio.NewScanner(reader) | ||||
| 	for scanner.Scan() { | ||||
| 		printFunc(scanner.Text()) | ||||
| 	} | ||||
| 	if err := scanner.Err(); err != nil { | ||||
| 		logger.Errorf("Error while reading from Writer: %s", err) | ||||
| 		entry.Errorf("Error while reading from Writer: %s", err) | ||||
| 	} | ||||
| 	reader.Close() | ||||
| } | ||||
		Loading…
	
		Reference in New Issue