Merge pull request #2786 from jterry75/revendor_logrus
Revendor github.com/sirupsen/logrus to v1.0.3
This commit is contained in:
commit
a3c2f00c50
@ -100,7 +100,7 @@ func forwardRunhcsLogs(ctx context.Context, c net.Conn, fields logrus.Fields) {
|
|||||||
|
|
||||||
// TODO: JTERRY75 maybe we need to make this configurable so we know
|
// TODO: JTERRY75 maybe we need to make this configurable so we know
|
||||||
// that runhcs is using the same one we are deserializing.
|
// that runhcs is using the same one we are deserializing.
|
||||||
ti, err := time.Parse(logrus.DefaultTimestampFormat, e.Data[logrus.FieldKeyTime].(string))
|
ti, err := time.Parse(time.RFC3339, e.Data[logrus.FieldKeyTime].(string))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.G(ctx).WithFields(fields).WithError(err).Debug("invalid time stamp format")
|
log.G(ctx).WithFields(fields).WithError(err).Debug("invalid time stamp format")
|
||||||
ti = time.Time{}
|
ti = time.Time{}
|
||||||
|
@ -21,7 +21,7 @@ github.com/gogo/googleapis 08a7655d27152912db7aaf4f983275eaf8d128ef
|
|||||||
github.com/golang/protobuf v1.1.0
|
github.com/golang/protobuf v1.1.0
|
||||||
github.com/opencontainers/runtime-spec eba862dc2470385a233c7507392675cbeadf7353 # v1.0.1-45-geba862d
|
github.com/opencontainers/runtime-spec eba862dc2470385a233c7507392675cbeadf7353 # v1.0.1-45-geba862d
|
||||||
github.com/opencontainers/runc 58592df56734acf62e574865fe40b9e53e967910
|
github.com/opencontainers/runc 58592df56734acf62e574865fe40b9e53e967910
|
||||||
github.com/sirupsen/logrus v1.0.0
|
github.com/sirupsen/logrus v1.0.3
|
||||||
github.com/urfave/cli 7bc6a0acffa589f415f88aca16cc1de5ffd66f9c
|
github.com/urfave/cli 7bc6a0acffa589f415f88aca16cc1de5ffd66f9c
|
||||||
golang.org/x/net b3756b4b77d7b13260a0a2ec658753cf48922eac
|
golang.org/x/net b3756b4b77d7b13260a0a2ec658753cf48922eac
|
||||||
google.golang.org/grpc v1.12.0
|
google.golang.org/grpc v1.12.0
|
||||||
|
32
vendor/github.com/sirupsen/logrus/README.md
generated
vendored
32
vendor/github.com/sirupsen/logrus/README.md
generated
vendored
@ -1,22 +1,24 @@
|
|||||||
# 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
|
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
|
the standard library logger.
|
||||||
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.**
|
|
||||||
|
|
||||||
**Seeing weird case-sensitive problems?** Unfortunately, the author failed to
|
**Seeing weird case-sensitive problems?** It's in the past been possible to
|
||||||
realize the consequences of renaming to lower-case. Due to the Go package
|
import Logrus as both upper- and lower-case. Due to the Go package environment,
|
||||||
environment, this caused issues. Regretfully, there's no turning back now.
|
this caused issues in the community and we needed a standard. Some environments
|
||||||
|
experienced problems with the upper-case variant, so the lower-case was decided.
|
||||||
Everything using `logrus` will need to use the lower-case:
|
Everything using `logrus` will need to use the lower-case:
|
||||||
`github.com/sirupsen/logrus`. Any package that isn't, should be changed.
|
`github.com/sirupsen/logrus`. Any package that isn't, should be changed.
|
||||||
|
|
||||||
I am terribly sorry for this inconvenience. Logrus strives hard for backwards
|
To fix Glide, see [these
|
||||||
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).
|
comments](https://github.com/sirupsen/logrus/issues/553#issuecomment-306591437).
|
||||||
|
For an in-depth explanation of the casing issue, see [this
|
||||||
|
comment](https://github.com/sirupsen/logrus/issues/570#issuecomment-313933276).
|
||||||
|
|
||||||
|
**Are you interested in assisting in maintaining Logrus?** Currently I have a
|
||||||
|
lot of obligations, and I am unable to provide Logrus with the maintainership it
|
||||||
|
needs. If you'd like to help, please reach out to me at `simon at author's
|
||||||
|
username dot com`.
|
||||||
|
|
||||||
Nicely color-coded in development (when a TTY is attached, otherwise just
|
Nicely color-coded in development (when a TTY is attached, otherwise just
|
||||||
plain text):
|
plain text):
|
||||||
@ -266,6 +268,7 @@ Note: Syslog hook also support connecting to local syslog (Ex. "/dev/log" or "/v
|
|||||||
| [Logrusly](https://github.com/sebest/logrusly) | Send logs to [Loggly](https://www.loggly.com/) |
|
| [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) |
|
| [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 |
|
| [Mail](https://github.com/zbindenren/logrus_mail) | Hook for sending exceptions via mail |
|
||||||
|
| [Mattermost](https://github.com/shuLhan/mattermost-integration/tree/master/hooks/logrus) | Hook for logging to [Mattermost](https://mattermost.com/) |
|
||||||
| [Mongodb](https://github.com/weekface/mgorus) | Hook for logging to mongodb |
|
| [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) |
|
| [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 |
|
| [Octokit](https://github.com/dorajistyle/logrus-octokit-hook) | Hook for logging to github via octokit |
|
||||||
@ -280,7 +283,7 @@ Note: Syslog hook also support connecting to local syslog (Ex. "/dev/log" or "/v
|
|||||||
| [Slackrus](https://github.com/johntdyer/slackrus) | Hook for Slack chat. |
|
| [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/) |
|
| [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/)|
|
| [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](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. |
|
| [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/) |
|
| [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/) |
|
| [Typetalk](https://github.com/dragon3/logrus-typetalk-hook) | Hook for logging to [Typetalk](https://www.typetalk.in/) |
|
||||||
@ -369,6 +372,7 @@ The built-in logging formatters are:
|
|||||||
|
|
||||||
Third party logging formatters:
|
Third party logging formatters:
|
||||||
|
|
||||||
|
* [`FluentdFormatter`](https://github.com/joonix/log). Formats entries that can by parsed by Kubernetes and Google Container Engine.
|
||||||
* [`logstash`](https://github.com/bshuster-repo/logrus-logstash-hook). Logs fields as [Logstash](http://logstash.net) Events.
|
* [`logstash`](https://github.com/bshuster-repo/logrus-logstash-hook). Logs fields as [Logstash](http://logstash.net) Events.
|
||||||
* [`prefixed`](https://github.com/x-cray/logrus-prefixed-formatter). Displays log entry source along with alternative layout.
|
* [`prefixed`](https://github.com/x-cray/logrus-prefixed-formatter). Displays log entry source along with alternative layout.
|
||||||
* [`zalgo`](https://github.com/aybabtme/logzalgo). Invoking the P͉̫o̳̼̊w̖͈̰͎e̬͔̭͂r͚̼̹̲ ̫͓͉̳͈ō̠͕͖̚f̝͍̠ ͕̲̞͖͑Z̖̫̤̫ͪa͉̬͈̗l͖͎g̳̥o̰̥̅!̣͔̲̻͊̄ ̙̘̦̹̦.
|
* [`zalgo`](https://github.com/aybabtme/logzalgo). Invoking the P͉̫o̳̼̊w̖͈̰͎e̬͔̭͂r͚̼̹̲ ̫͓͉̳͈ō̠͕͖̚f̝͍̠ ͕̲̞͖͑Z̖̫̤̫ͪa͉̬͈̗l͖͎g̳̥o̰̥̅!̣͔̲̻͊̄ ̙̘̦̹̦.
|
||||||
@ -449,13 +453,13 @@ Logrus has a built in facility for asserting the presence of log messages. This
|
|||||||
```go
|
```go
|
||||||
import(
|
import(
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/sirupsen/logrus/hooks/null"
|
"github.com/sirupsen/logrus/hooks/test"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSomething(t*testing.T){
|
func TestSomething(t*testing.T){
|
||||||
logger, hook := null.NewNullLogger()
|
logger, hook := test.NewNullLogger()
|
||||||
logger.Error("Helloerror")
|
logger.Error("Helloerror")
|
||||||
|
|
||||||
assert.Equal(t, 1, len(hook.Entries))
|
assert.Equal(t, 1, len(hook.Entries))
|
||||||
|
1
vendor/github.com/sirupsen/logrus/entry.go
generated
vendored
1
vendor/github.com/sirupsen/logrus/entry.go
generated
vendored
@ -35,6 +35,7 @@ type Entry struct {
|
|||||||
Time time.Time
|
Time time.Time
|
||||||
|
|
||||||
// Level the log entry was logged at: Debug, Info, Warn, Error, Fatal or Panic
|
// Level the log entry was logged at: Debug, Info, Warn, Error, Fatal or Panic
|
||||||
|
// This field will be set on entry firing and the value will be equal to the one in Logger struct field.
|
||||||
Level Level
|
Level Level
|
||||||
|
|
||||||
// Message passed to Debug, Info, Warn, Error, Fatal or Panic
|
// Message passed to Debug, Info, Warn, Error, Fatal or Panic
|
||||||
|
2
vendor/github.com/sirupsen/logrus/exported.go
generated
vendored
2
vendor/github.com/sirupsen/logrus/exported.go
generated
vendored
@ -31,7 +31,7 @@ func SetFormatter(formatter Formatter) {
|
|||||||
func SetLevel(level Level) {
|
func SetLevel(level Level) {
|
||||||
std.mu.Lock()
|
std.mu.Lock()
|
||||||
defer std.mu.Unlock()
|
defer std.mu.Unlock()
|
||||||
std.setLevel(level)
|
std.SetLevel(level)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetLevel returns the standard logger level.
|
// GetLevel returns the standard logger level.
|
||||||
|
2
vendor/github.com/sirupsen/logrus/formatter.go
generated
vendored
2
vendor/github.com/sirupsen/logrus/formatter.go
generated
vendored
@ -2,7 +2,7 @@ package logrus
|
|||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
const DefaultTimestampFormat = time.RFC3339
|
const defaultTimestampFormat = time.RFC3339
|
||||||
|
|
||||||
// The Formatter interface is used to implement a custom Formatter. It takes an
|
// The Formatter interface is used to implement a custom Formatter. It takes an
|
||||||
// `Entry`. It exposes all the fields, including the default ones:
|
// `Entry`. It exposes all the fields, including the default ones:
|
||||||
|
9
vendor/github.com/sirupsen/logrus/json_formatter.go
generated
vendored
9
vendor/github.com/sirupsen/logrus/json_formatter.go
generated
vendored
@ -6,8 +6,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type fieldKey string
|
type fieldKey string
|
||||||
|
|
||||||
|
// FieldMap allows customization of the key names for default fields.
|
||||||
type FieldMap map[fieldKey]string
|
type FieldMap map[fieldKey]string
|
||||||
|
|
||||||
|
// Default key names for the default fields
|
||||||
const (
|
const (
|
||||||
FieldKeyMsg = "msg"
|
FieldKeyMsg = "msg"
|
||||||
FieldKeyLevel = "level"
|
FieldKeyLevel = "level"
|
||||||
@ -22,6 +25,7 @@ func (f FieldMap) resolve(key fieldKey) string {
|
|||||||
return string(key)
|
return string(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// JSONFormatter formats logs into parsable json
|
||||||
type JSONFormatter struct {
|
type JSONFormatter struct {
|
||||||
// TimestampFormat sets the format used for marshaling timestamps.
|
// TimestampFormat sets the format used for marshaling timestamps.
|
||||||
TimestampFormat string
|
TimestampFormat string
|
||||||
@ -29,7 +33,7 @@ type JSONFormatter struct {
|
|||||||
// DisableTimestamp allows disabling automatic timestamps in output
|
// DisableTimestamp allows disabling automatic timestamps in output
|
||||||
DisableTimestamp bool
|
DisableTimestamp bool
|
||||||
|
|
||||||
// FieldMap allows users to customize the names of keys for various fields.
|
// FieldMap allows users to customize the names of keys for default fields.
|
||||||
// As an example:
|
// As an example:
|
||||||
// formatter := &JSONFormatter{
|
// formatter := &JSONFormatter{
|
||||||
// FieldMap: FieldMap{
|
// FieldMap: FieldMap{
|
||||||
@ -41,6 +45,7 @@ type JSONFormatter struct {
|
|||||||
FieldMap FieldMap
|
FieldMap FieldMap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Format renders a single log entry
|
||||||
func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
||||||
data := make(Fields, len(entry.Data)+3)
|
data := make(Fields, len(entry.Data)+3)
|
||||||
for k, v := range entry.Data {
|
for k, v := range entry.Data {
|
||||||
@ -57,7 +62,7 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
|||||||
|
|
||||||
timestampFormat := f.TimestampFormat
|
timestampFormat := f.TimestampFormat
|
||||||
if timestampFormat == "" {
|
if timestampFormat == "" {
|
||||||
timestampFormat = DefaultTimestampFormat
|
timestampFormat = defaultTimestampFormat
|
||||||
}
|
}
|
||||||
|
|
||||||
if !f.DisableTimestamp {
|
if !f.DisableTimestamp {
|
||||||
|
4
vendor/github.com/sirupsen/logrus/logger.go
generated
vendored
4
vendor/github.com/sirupsen/logrus/logger.go
generated
vendored
@ -25,7 +25,7 @@ type Logger struct {
|
|||||||
Formatter Formatter
|
Formatter Formatter
|
||||||
// The logging level the logger should log at. This is typically (and defaults
|
// The logging level the logger should log at. This is typically (and defaults
|
||||||
// to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be
|
// to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be
|
||||||
// logged. `logrus.Debug` is useful in
|
// logged.
|
||||||
Level Level
|
Level Level
|
||||||
// Used to sync writing to the log. Locking is enabled by Default
|
// Used to sync writing to the log. Locking is enabled by Default
|
||||||
mu MutexWrap
|
mu MutexWrap
|
||||||
@ -312,6 +312,6 @@ func (logger *Logger) level() Level {
|
|||||||
return Level(atomic.LoadUint32((*uint32)(&logger.Level)))
|
return Level(atomic.LoadUint32((*uint32)(&logger.Level)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) setLevel(level Level) {
|
func (logger *Logger) SetLevel(level Level) {
|
||||||
atomic.StoreUint32((*uint32)(&logger.Level), uint32(level))
|
atomic.StoreUint32((*uint32)(&logger.Level), uint32(level))
|
||||||
}
|
}
|
||||||
|
10
vendor/github.com/sirupsen/logrus/terminal_appengine.go
generated
vendored
10
vendor/github.com/sirupsen/logrus/terminal_appengine.go
generated
vendored
@ -1,10 +0,0 @@
|
|||||||
// +build appengine
|
|
||||||
|
|
||||||
package logrus
|
|
||||||
|
|
||||||
import "io"
|
|
||||||
|
|
||||||
// IsTerminal returns true if stderr's file descriptor is a terminal.
|
|
||||||
func IsTerminal(f io.Writer) bool {
|
|
||||||
return true
|
|
||||||
}
|
|
6
vendor/github.com/sirupsen/logrus/terminal_bsd.go
generated
vendored
6
vendor/github.com/sirupsen/logrus/terminal_bsd.go
generated
vendored
@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
package logrus
|
package logrus
|
||||||
|
|
||||||
import "syscall"
|
import "golang.org/x/sys/unix"
|
||||||
|
|
||||||
const ioctlReadTermios = syscall.TIOCGETA
|
const ioctlReadTermios = unix.TIOCGETA
|
||||||
|
|
||||||
type Termios syscall.Termios
|
type Termios unix.Termios
|
||||||
|
6
vendor/github.com/sirupsen/logrus/terminal_linux.go
generated
vendored
6
vendor/github.com/sirupsen/logrus/terminal_linux.go
generated
vendored
@ -7,8 +7,8 @@
|
|||||||
|
|
||||||
package logrus
|
package logrus
|
||||||
|
|
||||||
import "syscall"
|
import "golang.org/x/sys/unix"
|
||||||
|
|
||||||
const ioctlReadTermios = syscall.TCGETS
|
const ioctlReadTermios = unix.TCGETS
|
||||||
|
|
||||||
type Termios syscall.Termios
|
type Termios unix.Termios
|
||||||
|
28
vendor/github.com/sirupsen/logrus/terminal_notwindows.go
generated
vendored
28
vendor/github.com/sirupsen/logrus/terminal_notwindows.go
generated
vendored
@ -1,28 +0,0 @@
|
|||||||
// Based on ssh/terminal:
|
|
||||||
// Copyright 2011 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build linux darwin freebsd openbsd netbsd dragonfly
|
|
||||||
// +build !appengine
|
|
||||||
|
|
||||||
package logrus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
// IsTerminal returns true if stderr's file descriptor is a terminal.
|
|
||||||
func IsTerminal(f io.Writer) bool {
|
|
||||||
var termios Termios
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
21
vendor/github.com/sirupsen/logrus/terminal_solaris.go
generated
vendored
21
vendor/github.com/sirupsen/logrus/terminal_solaris.go
generated
vendored
@ -1,21 +0,0 @@
|
|||||||
// +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
|
|
||||||
}
|
|
||||||
}
|
|
82
vendor/github.com/sirupsen/logrus/terminal_windows.go
generated
vendored
82
vendor/github.com/sirupsen/logrus/terminal_windows.go
generated
vendored
@ -1,82 +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 (
|
|
||||||
"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
|
|
||||||
}
|
|
||||||
}
|
|
56
vendor/github.com/sirupsen/logrus/text_formatter.go
generated
vendored
56
vendor/github.com/sirupsen/logrus/text_formatter.go
generated
vendored
@ -3,10 +3,14 @@ package logrus
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/ssh/terminal"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -14,7 +18,7 @@ const (
|
|||||||
red = 31
|
red = 31
|
||||||
green = 32
|
green = 32
|
||||||
yellow = 33
|
yellow = 33
|
||||||
blue = 34
|
blue = 36
|
||||||
gray = 37
|
gray = 37
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -26,6 +30,7 @@ func init() {
|
|||||||
baseTimestamp = time.Now()
|
baseTimestamp = time.Now()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TextFormatter formats logs into text
|
||||||
type TextFormatter struct {
|
type TextFormatter struct {
|
||||||
// Set to true to bypass checking for a TTY before outputting colors.
|
// Set to true to bypass checking for a TTY before outputting colors.
|
||||||
ForceColors bool
|
ForceColors bool
|
||||||
@ -52,10 +57,6 @@ type TextFormatter struct {
|
|||||||
// QuoteEmptyFields will wrap empty fields in quotes if true
|
// QuoteEmptyFields will wrap empty fields in quotes if true
|
||||||
QuoteEmptyFields bool
|
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
|
// Whether the logger's out is to a terminal
|
||||||
isTerminal bool
|
isTerminal bool
|
||||||
|
|
||||||
@ -63,14 +64,21 @@ type TextFormatter struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *TextFormatter) init(entry *Entry) {
|
func (f *TextFormatter) init(entry *Entry) {
|
||||||
if len(f.QuoteCharacter) == 0 {
|
|
||||||
f.QuoteCharacter = "\""
|
|
||||||
}
|
|
||||||
if entry.Logger != nil {
|
if entry.Logger != nil {
|
||||||
f.isTerminal = IsTerminal(entry.Logger.Out)
|
f.isTerminal = f.checkIfTerminal(entry.Logger.Out)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *TextFormatter) checkIfTerminal(w io.Writer) bool {
|
||||||
|
switch v := w.(type) {
|
||||||
|
case *os.File:
|
||||||
|
return terminal.IsTerminal(int(v.Fd()))
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format renders a single log entry
|
||||||
func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
||||||
var b *bytes.Buffer
|
var b *bytes.Buffer
|
||||||
keys := make([]string, 0, len(entry.Data))
|
keys := make([]string, 0, len(entry.Data))
|
||||||
@ -95,7 +103,7 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
|||||||
|
|
||||||
timestampFormat := f.TimestampFormat
|
timestampFormat := f.TimestampFormat
|
||||||
if timestampFormat == "" {
|
if timestampFormat == "" {
|
||||||
timestampFormat = DefaultTimestampFormat
|
timestampFormat = defaultTimestampFormat
|
||||||
}
|
}
|
||||||
if isColored {
|
if isColored {
|
||||||
f.printColored(b, entry, keys, timestampFormat)
|
f.printColored(b, entry, keys, timestampFormat)
|
||||||
@ -153,7 +161,7 @@ func (f *TextFormatter) needsQuoting(text string) bool {
|
|||||||
if !((ch >= 'a' && ch <= 'z') ||
|
if !((ch >= 'a' && ch <= 'z') ||
|
||||||
(ch >= 'A' && ch <= 'Z') ||
|
(ch >= 'A' && ch <= 'Z') ||
|
||||||
(ch >= '0' && ch <= '9') ||
|
(ch >= '0' && ch <= '9') ||
|
||||||
ch == '-' || ch == '.') {
|
ch == '-' || ch == '.' || ch == '_' || ch == '/' || ch == '@' || ch == '^' || ch == '+') {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -161,29 +169,23 @@ func (f *TextFormatter) needsQuoting(text string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) {
|
func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) {
|
||||||
|
if b.Len() > 0 {
|
||||||
|
b.WriteByte(' ')
|
||||||
|
}
|
||||||
b.WriteString(key)
|
b.WriteString(key)
|
||||||
b.WriteByte('=')
|
b.WriteByte('=')
|
||||||
f.appendValue(b, value)
|
f.appendValue(b, value)
|
||||||
b.WriteByte(' ')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) {
|
func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) {
|
||||||
switch value := value.(type) {
|
stringVal, ok := value.(string)
|
||||||
case string:
|
if !ok {
|
||||||
if !f.needsQuoting(value) {
|
stringVal = fmt.Sprint(value)
|
||||||
b.WriteString(value)
|
|
||||||
} else {
|
|
||||||
fmt.Fprintf(b, "%s%v%s", f.QuoteCharacter, value, f.QuoteCharacter)
|
|
||||||
}
|
}
|
||||||
case error:
|
|
||||||
errmsg := value.Error()
|
if !f.needsQuoting(stringVal) {
|
||||||
if !f.needsQuoting(errmsg) {
|
b.WriteString(stringVal)
|
||||||
b.WriteString(errmsg)
|
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(b, "%s%v%s", f.QuoteCharacter, errmsg, f.QuoteCharacter)
|
b.WriteString(fmt.Sprintf("%q", stringVal))
|
||||||
}
|
|
||||||
default:
|
|
||||||
fmt.Fprint(b, value)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user