Merge pull request #3224 from AndreasHassing/fix/bad-pointer-windows-EnableVirtualTerminalProcessing
Update logrus to v1.6.0, fixes #3223master
						commit
						5dc1f65acc
					
				
							
								
								
									
										2
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										2
									
								
								go.mod
								
								
								
								
							|  | @ -31,7 +31,7 @@ require ( | ||||||
| 	github.com/opencontainers/go-digest v1.0.0 | 	github.com/opencontainers/go-digest v1.0.0 | ||||||
| 	github.com/opencontainers/image-spec v1.0.1 | 	github.com/opencontainers/image-spec v1.0.1 | ||||||
| 	github.com/satori/go.uuid v1.2.0 // indirect | 	github.com/satori/go.uuid v1.2.0 // indirect | ||||||
| 	github.com/sirupsen/logrus v1.4.2 | 	github.com/sirupsen/logrus v1.6.0 | ||||||
| 	github.com/spf13/cobra v0.0.3 | 	github.com/spf13/cobra v0.0.3 | ||||||
| 	github.com/spf13/pflag v1.0.3 // indirect | 	github.com/spf13/pflag v1.0.3 // indirect | ||||||
| 	github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 // indirect | 	github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 // indirect | ||||||
|  |  | ||||||
							
								
								
									
										6
									
								
								go.sum
								
								
								
								
							
							
						
						
									
										6
									
								
								go.sum
								
								
								
								
							|  | @ -68,6 +68,8 @@ github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u | ||||||
| github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= | github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= | ||||||
| github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= | github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= | ||||||
| github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= | ||||||
|  | github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= | ||||||
|  | github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= | ||||||
| github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= | github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= | ||||||
| github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= | github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= | ||||||
| github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= | ||||||
|  | @ -114,8 +116,8 @@ github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDa | ||||||
| github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= | github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= | ||||||
| github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= | github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= | ||||||
| github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= | github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= | ||||||
| github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= | github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= | ||||||
| github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= | github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= | ||||||
| github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8= | github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8= | ||||||
| github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= | github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= | ||||||
| github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= | github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= | ||||||
|  |  | ||||||
|  | @ -26,6 +26,8 @@ The tool is sponsored by the [marvin + konsorten GmbH](http://www.konsorten.de). | ||||||
| We thank all the authors who provided code to this library: | We thank all the authors who provided code to this library: | ||||||
| 
 | 
 | ||||||
| * Felix Kollmann | * Felix Kollmann | ||||||
|  | * Nicolas Perraut | ||||||
|  | * @dirty49374 | ||||||
| 
 | 
 | ||||||
| ## License | ## License | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -4,7 +4,6 @@ package sequences | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"syscall" | 	"syscall" | ||||||
| 	"unsafe" |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var ( | var ( | ||||||
|  | @ -27,7 +26,7 @@ func EnableVirtualTerminalProcessing(stream syscall.Handle, enable bool) error { | ||||||
| 		mode &^= ENABLE_VIRTUAL_TERMINAL_PROCESSING | 		mode &^= ENABLE_VIRTUAL_TERMINAL_PROCESSING | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	ret, _, err := setConsoleMode.Call(uintptr(unsafe.Pointer(stream)), uintptr(mode)) | 	ret, _, err := setConsoleMode.Call(uintptr(stream), uintptr(mode)) | ||||||
| 	if ret == 0 { | 	if ret == 0 { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
							
								
								
									
										11
									
								
								vendor/github.com/konsorten/go-windows-terminal-sequences/sequences_dummy.go
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							
							
						
						
									
										11
									
								
								vendor/github.com/konsorten/go-windows-terminal-sequences/sequences_dummy.go
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							|  | @ -0,0 +1,11 @@ | ||||||
|  | // +build linux darwin
 | ||||||
|  | 
 | ||||||
|  | package sequences | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func EnableVirtualTerminalProcessing(stream uintptr, enable bool) error { | ||||||
|  | 	return fmt.Errorf("windows only package") | ||||||
|  | } | ||||||
|  | @ -0,0 +1,40 @@ | ||||||
|  | run: | ||||||
|  |   # do not run on test files yet | ||||||
|  |   tests: false | ||||||
|  | 
 | ||||||
|  | # all available settings of specific linters | ||||||
|  | linters-settings: | ||||||
|  |   errcheck: | ||||||
|  |     # report about not checking of errors in type assetions: `a := b.(MyStruct)`; | ||||||
|  |     # default is false: such cases aren't reported by default. | ||||||
|  |     check-type-assertions: false | ||||||
|  | 
 | ||||||
|  |     # report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`; | ||||||
|  |     # default is false: such cases aren't reported by default. | ||||||
|  |     check-blank: false | ||||||
|  | 
 | ||||||
|  |   lll: | ||||||
|  |     line-length: 100 | ||||||
|  |     tab-width: 4 | ||||||
|  | 
 | ||||||
|  |   prealloc: | ||||||
|  |     simple: false | ||||||
|  |     range-loops: false | ||||||
|  |     for-loops: false | ||||||
|  | 
 | ||||||
|  |   whitespace: | ||||||
|  |     multi-if: false   # Enforces newlines (or comments) after every multi-line if statement | ||||||
|  |     multi-func: false # Enforces newlines (or comments) after every multi-line function signature | ||||||
|  | 
 | ||||||
|  | linters: | ||||||
|  |   enable: | ||||||
|  |     - megacheck | ||||||
|  |     - govet | ||||||
|  |   disable: | ||||||
|  |     - maligned | ||||||
|  |     - prealloc | ||||||
|  |   disable-all: false | ||||||
|  |   presets: | ||||||
|  |     - bugs | ||||||
|  |     - unused | ||||||
|  |   fast: false | ||||||
|  | @ -4,21 +4,13 @@ git: | ||||||
|   depth: 1 |   depth: 1 | ||||||
| env: | env: | ||||||
|   - GO111MODULE=on |   - GO111MODULE=on | ||||||
|   - GO111MODULE=off | go: [1.13.x, 1.14.x] | ||||||
| go: [ 1.11.x, 1.12.x ] | os: [linux, osx] | ||||||
| os: [ linux, osx ] |  | ||||||
| matrix: |  | ||||||
|   exclude: |  | ||||||
|     - go: 1.12.x |  | ||||||
|       env: GO111MODULE=off |  | ||||||
|     - go: 1.11.x |  | ||||||
|       os: osx |  | ||||||
| install: | install: | ||||||
|   - ./travis/install.sh |   - ./travis/install.sh | ||||||
|   - if [[ "$GO111MODULE" ==  "on" ]]; then go mod download; fi |  | ||||||
|   - if [[ "$GO111MODULE" == "off" ]]; then go get github.com/stretchr/testify/assert golang.org/x/sys/unix github.com/konsorten/go-windows-terminal-sequences; fi |  | ||||||
| script: | script: | ||||||
|   - ./travis/cross_build.sh |   - ./travis/cross_build.sh | ||||||
|  |   - ./travis/lint.sh | ||||||
|   - export GOMAXPROCS=4 |   - export GOMAXPROCS=4 | ||||||
|   - export GORACE=halt_on_error=1 |   - export GORACE=halt_on_error=1 | ||||||
|   - go test -race -v ./... |   - go test -race -v ./... | ||||||
|  |  | ||||||
|  | @ -1,9 +1,32 @@ | ||||||
|  | # 1.6.0 | ||||||
|  | Fixes: | ||||||
|  |   * end of line cleanup | ||||||
|  |   * revert the entry concurrency bug fix whic leads to deadlock under some circumstances | ||||||
|  |   * update dependency on go-windows-terminal-sequences to fix a crash with go 1.14 | ||||||
|  | 
 | ||||||
|  | Features: | ||||||
|  |   * add an option to the `TextFormatter` to completely disable fields quoting | ||||||
|  | 
 | ||||||
|  | # 1.5.0 | ||||||
|  | Code quality: | ||||||
|  |   * add golangci linter run on travis | ||||||
|  | 
 | ||||||
|  | Fixes: | ||||||
|  |   * add mutex for hooks concurrent access on `Entry` data | ||||||
|  |   * caller function field for go1.14 | ||||||
|  |   * fix build issue for gopherjs target | ||||||
|  | 
 | ||||||
|  | Feature: | ||||||
|  |   * add an hooks/writer sub-package whose goal is to split output on different stream depending on the trace level | ||||||
|  |   * add a `DisableHTMLEscape` option in the `JSONFormatter` | ||||||
|  |   * add `ForceQuote` and `PadLevelText` options in the `TextFormatter` | ||||||
|  | 
 | ||||||
| # 1.4.2 | # 1.4.2 | ||||||
|   * Fixes build break for plan9, nacl, solaris |   * Fixes build break for plan9, nacl, solaris | ||||||
| # 1.4.1 | # 1.4.1 | ||||||
| This new release introduces: | This new release introduces: | ||||||
|   * Enhance TextFormatter to not print caller information when they are empty (#944) |   * Enhance TextFormatter to not print caller information when they are empty (#944) | ||||||
|   * Remove dependency on golang.org/x/crypto (#932, #943)  |   * Remove dependency on golang.org/x/crypto (#932, #943) | ||||||
| 
 | 
 | ||||||
| Fixes: | Fixes: | ||||||
|   * Fix Entry.WithContext method to return a copy of the initial entry (#941) |   * Fix Entry.WithContext method to return a copy of the initial entry (#941) | ||||||
|  | @ -11,7 +34,7 @@ Fixes: | ||||||
| # 1.4.0 | # 1.4.0 | ||||||
| This new release introduces: | This new release introduces: | ||||||
|   * Add `DeferExitHandler`, similar to `RegisterExitHandler` but prepending the handler to the list of handlers (semantically like `defer`) (#848). |   * Add `DeferExitHandler`, similar to `RegisterExitHandler` but prepending the handler to the list of handlers (semantically like `defer`) (#848). | ||||||
|   * Add `CallerPrettyfier` to `JSONFormatter` and `TextFormatter (#909, #911) |   * Add `CallerPrettyfier` to `JSONFormatter` and `TextFormatter` (#909, #911) | ||||||
|   * Add `Entry.WithContext()` and `Entry.Context`, to set a context on entries to be used e.g. in hooks (#919). |   * Add `Entry.WithContext()` and `Entry.Context`, to set a context on entries to be used e.g. in hooks (#919). | ||||||
| 
 | 
 | ||||||
| Fixes: | Fixes: | ||||||
|  |  | ||||||
|  | @ -1,8 +1,28 @@ | ||||||
| # 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. | the standard library logger. | ||||||
| 
 | 
 | ||||||
|  | **Logrus is in maintenance-mode.** We will not be introducing new features. It's | ||||||
|  | simply too hard to do in a way that won't break many people's projects, which is | ||||||
|  | the last thing you want from your Logging library (again...). | ||||||
|  | 
 | ||||||
|  | This does not mean Logrus is dead. Logrus will continue to be maintained for | ||||||
|  | security, (backwards compatible) bug fixes, and performance (where we are | ||||||
|  | limited by the interface).  | ||||||
|  | 
 | ||||||
|  | I believe Logrus' biggest contribution is to have played a part in today's | ||||||
|  | widespread use of structured logging in Golang. There doesn't seem to be a | ||||||
|  | reason to do a major, breaking iteration into Logrus V2, since the fantastic Go | ||||||
|  | community has built those independently. Many fantastic alternatives have sprung | ||||||
|  | up. Logrus would look like those, had it been re-designed with what we know | ||||||
|  | about structured logging in Go today. Check out, for example, | ||||||
|  | [Zerolog][zerolog], [Zap][zap], and [Apex][apex]. | ||||||
|  | 
 | ||||||
|  | [zerolog]: https://github.com/rs/zerolog | ||||||
|  | [zap]: https://github.com/uber-go/zap | ||||||
|  | [apex]: https://github.com/apex/log | ||||||
|  | 
 | ||||||
| **Seeing weird case-sensitive problems?** It's in the past been possible to | **Seeing weird case-sensitive problems?** It's in the past been possible to | ||||||
| import Logrus as both upper- and lower-case. Due to the Go package environment, | import Logrus as both upper- and lower-case. Due to the Go package environment, | ||||||
| this caused issues in the community and we needed a standard. Some environments | this caused issues in the community and we needed a standard. Some environments | ||||||
|  | @ -15,11 +35,6 @@ comments](https://github.com/sirupsen/logrus/issues/553#issuecomment-306591437). | ||||||
| For an in-depth explanation of the casing issue, see [this | For an in-depth explanation of the casing issue, see [this | ||||||
| comment](https://github.com/sirupsen/logrus/issues/570#issuecomment-313933276). | 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): | ||||||
| 
 | 
 | ||||||
|  | @ -187,7 +202,7 @@ func main() { | ||||||
|   log.Out = os.Stdout |   log.Out = os.Stdout | ||||||
| 
 | 
 | ||||||
|   // You could set this to any `io.Writer` such as a file |   // 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) |   // file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) | ||||||
|   // if err == nil { |   // if err == nil { | ||||||
|   //  log.Out = file |   //  log.Out = file | ||||||
|   // } else { |   // } else { | ||||||
|  | @ -272,7 +287,7 @@ func init() { | ||||||
| ``` | ``` | ||||||
| Note: Syslog hook also support connecting to local syslog (Ex. "/dev/log" or "/var/run/syslog" or "/var/run/log"). For the detail, please check the [syslog hook README](hooks/syslog/README.md). | Note: Syslog hook also support connecting to local syslog (Ex. "/dev/log" or "/var/run/syslog" or "/var/run/log"). For the detail, please check the [syslog hook README](hooks/syslog/README.md). | ||||||
| 
 | 
 | ||||||
| A list of currently known of service hook can be found in this wiki [page](https://github.com/sirupsen/logrus/wiki/Hooks) | A list of currently known service hooks can be found in this wiki [page](https://github.com/sirupsen/logrus/wiki/Hooks) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| #### Level logging | #### Level logging | ||||||
|  | @ -354,6 +369,7 @@ The built-in logging formatters are: | ||||||
|     [github.com/mattn/go-colorable](https://github.com/mattn/go-colorable). |     [github.com/mattn/go-colorable](https://github.com/mattn/go-colorable). | ||||||
|   * When colors are enabled, levels are truncated to 4 characters by default. To disable |   * When colors are enabled, levels are truncated to 4 characters by default. To disable | ||||||
|     truncation set the `DisableLevelTruncation` field to `true`. |     truncation set the `DisableLevelTruncation` field to `true`. | ||||||
|  |   * When outputting to a TTY, it's often helpful to visually scan down a column where all the levels are the same width. Setting the `PadLevelText` field to `true` enables this behavior, by adding padding to the level text. | ||||||
|   * All options are listed in the [generated docs](https://godoc.org/github.com/sirupsen/logrus#TextFormatter). |   * All options are listed in the [generated docs](https://godoc.org/github.com/sirupsen/logrus#TextFormatter). | ||||||
| * `logrus.JSONFormatter`. Logs fields as JSON. | * `logrus.JSONFormatter`. Logs fields as JSON. | ||||||
|   * All options are listed in the [generated docs](https://godoc.org/github.com/sirupsen/logrus#JSONFormatter). |   * All options are listed in the [generated docs](https://godoc.org/github.com/sirupsen/logrus#JSONFormatter). | ||||||
|  | @ -364,8 +380,10 @@ Third party logging formatters: | ||||||
| * [`GELF`](https://github.com/fabienm/go-logrus-formatters). Formats entries so they comply to Graylog's [GELF 1.1 specification](http://docs.graylog.org/en/2.4/pages/gelf.html). | * [`GELF`](https://github.com/fabienm/go-logrus-formatters). Formats entries so they comply to Graylog's [GELF 1.1 specification](http://docs.graylog.org/en/2.4/pages/gelf.html). | ||||||
| * [`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 Power of Zalgo. | ||||||
| * [`nested-logrus-formatter`](https://github.com/antonfisher/nested-logrus-formatter). Converts logrus fields to a nested structure. | * [`nested-logrus-formatter`](https://github.com/antonfisher/nested-logrus-formatter). Converts logrus fields to a nested structure. | ||||||
|  | * [`powerful-logrus-formatter`](https://github.com/zput/zxcTool). get fileName, log's line number and the latest function's name when print log; Sava log to files. | ||||||
|  | * [`caption-json-formatter`](https://github.com/nolleh/caption_json_formatter). logrus's message json formatter with human-readable caption added. | ||||||
| 
 | 
 | ||||||
| You can define your formatter by implementing the `Formatter` interface, | You can define your formatter by implementing the `Formatter` interface, | ||||||
| requiring a `Format` method. `Format` takes an `*Entry`. `entry.Data` is a | requiring a `Format` method. `Format` takes an `*Entry`. `entry.Data` is a | ||||||
|  | @ -430,14 +448,14 @@ entries. It should not be a feature of the application-level logger. | ||||||
| 
 | 
 | ||||||
| | Tool | Description | | | 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 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 be generated with different configs in different environments.| | ||||||
| |[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) | | |[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 | #### Testing | ||||||
| 
 | 
 | ||||||
| Logrus has a built in facility for asserting the presence of log messages. This is implemented through the `test` hook and provides: | Logrus has a built in facility for asserting the presence of log messages. This is implemented through the `test` hook and provides: | ||||||
| 
 | 
 | ||||||
| * decorators for existing logger (`test.NewLocal` and `test.NewGlobal`) which basically just add the `test` hook | * decorators for existing logger (`test.NewLocal` and `test.NewGlobal`) which basically just adds the `test` hook | ||||||
| * a test logger (`test.NewNullLogger`) that just records log messages (and does not output any): | * a test logger (`test.NewNullLogger`) that just records log messages (and does not output any): | ||||||
| 
 | 
 | ||||||
| ```go | ```go | ||||||
|  | @ -465,7 +483,7 @@ func TestSomething(t*testing.T){ | ||||||
| 
 | 
 | ||||||
| Logrus can register one or more functions that will be called when any `fatal` | Logrus can register one or more functions that will be called when any `fatal` | ||||||
| level message is logged. The registered handlers will be executed before | level message is logged. The registered handlers will be executed before | ||||||
| logrus performs a `os.Exit(1)`. This behavior may be helpful if callers need | logrus performs an `os.Exit(1)`. This behavior may be helpful if callers need | ||||||
| to gracefully shutdown. Unlike a `panic("Something went wrong...")` call which can be intercepted with a deferred `recover` a call to `os.Exit(1)` can not be intercepted. | to gracefully shutdown. Unlike a `panic("Something went wrong...")` call which can be intercepted with a deferred `recover` a call to `os.Exit(1)` can not be intercepted. | ||||||
| 
 | 
 | ||||||
| ``` | ``` | ||||||
|  | @ -490,6 +508,6 @@ Situation when locking is not needed includes: | ||||||
| 
 | 
 | ||||||
|   1) logger.Out is protected by locks. |   1) logger.Out is protected by locks. | ||||||
| 
 | 
 | ||||||
|   2) logger.Out is a os.File handler opened with `O_APPEND` flag, and every write is smaller than 4k. (This allow multi-thread/multi-process writing) |   2) logger.Out is an os.File handler opened with `O_APPEND` flag, and every write is smaller than 4k. (This allows multi-thread/multi-process writing) | ||||||
| 
 | 
 | ||||||
|      (Refer to http://www.notthewizard.com/2014/06/17/are-files-appends-really-atomic/) |      (Refer to http://www.notthewizard.com/2014/06/17/are-files-appends-really-atomic/) | ||||||
|  |  | ||||||
|  | @ -1,14 +1,14 @@ | ||||||
| version: "{build}" | version: "{build}" | ||||||
| platform: x64 | platform: x64 | ||||||
| clone_folder: c:\gopath\src\github.com\sirupsen\logrus | clone_folder: c:\gopath\src\github.com\sirupsen\logrus | ||||||
| environment:   | environment: | ||||||
|   GOPATH: c:\gopath |   GOPATH: c:\gopath | ||||||
| branches:   | branches: | ||||||
|   only: |   only: | ||||||
|     - master |     - master | ||||||
| install:   | install: | ||||||
|   - set PATH=%GOPATH%\bin;c:\go\bin;%PATH% |   - set PATH=%GOPATH%\bin;c:\go\bin;%PATH% | ||||||
|   - go version |   - go version | ||||||
| build_script:   | build_script: | ||||||
|   - go get -t |   - go get -t | ||||||
|   - go test |   - go test | ||||||
|  |  | ||||||
|  | @ -85,10 +85,15 @@ func NewEntry(logger *Logger) *Entry { | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Returns the bytes representation of this entry from the formatter.
 | ||||||
|  | func (entry *Entry) Bytes() ([]byte, error) { | ||||||
|  | 	return entry.Logger.Formatter.Format(entry) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Returns the string representation from the reader and ultimately the
 | // Returns the string representation from the reader and ultimately the
 | ||||||
| // formatter.
 | // formatter.
 | ||||||
| func (entry *Entry) String() (string, error) { | func (entry *Entry) String() (string, error) { | ||||||
| 	serialized, err := entry.Logger.Formatter.Format(entry) | 	serialized, err := entry.Bytes() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return "", err | 		return "", err | ||||||
| 	} | 	} | ||||||
|  | @ -103,7 +108,11 @@ func (entry *Entry) WithError(err error) *Entry { | ||||||
| 
 | 
 | ||||||
| // Add a context to the Entry.
 | // Add a context to the Entry.
 | ||||||
| func (entry *Entry) WithContext(ctx context.Context) *Entry { | func (entry *Entry) WithContext(ctx context.Context) *Entry { | ||||||
| 	return &Entry{Logger: entry.Logger, Data: entry.Data, Time: entry.Time, err: entry.err, Context: ctx} | 	dataCopy := make(Fields, len(entry.Data)) | ||||||
|  | 	for k, v := range entry.Data { | ||||||
|  | 		dataCopy[k] = v | ||||||
|  | 	} | ||||||
|  | 	return &Entry{Logger: entry.Logger, Data: dataCopy, Time: entry.Time, err: entry.err, Context: ctx} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Add a single field to the Entry.
 | // Add a single field to the Entry.
 | ||||||
|  | @ -144,7 +153,11 @@ func (entry *Entry) WithFields(fields Fields) *Entry { | ||||||
| 
 | 
 | ||||||
| // Overrides the time of the Entry.
 | // Overrides the time of the Entry.
 | ||||||
| func (entry *Entry) WithTime(t time.Time) *Entry { | func (entry *Entry) WithTime(t time.Time) *Entry { | ||||||
| 	return &Entry{Logger: entry.Logger, Data: entry.Data, Time: t, err: entry.err, Context: entry.Context} | 	dataCopy := make(Fields, len(entry.Data)) | ||||||
|  | 	for k, v := range entry.Data { | ||||||
|  | 		dataCopy[k] = v | ||||||
|  | 	} | ||||||
|  | 	return &Entry{Logger: entry.Logger, Data: dataCopy, Time: t, err: entry.err, Context: entry.Context} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // getPackageName reduces a fully qualified function name to the package name
 | // getPackageName reduces a fully qualified function name to the package name
 | ||||||
|  | @ -165,15 +178,20 @@ func getPackageName(f string) string { | ||||||
| 
 | 
 | ||||||
| // getCaller retrieves the name of the first non-logrus calling function
 | // getCaller retrieves the name of the first non-logrus calling function
 | ||||||
| func getCaller() *runtime.Frame { | func getCaller() *runtime.Frame { | ||||||
| 
 |  | ||||||
| 	// cache this package's fully-qualified name
 | 	// cache this package's fully-qualified name
 | ||||||
| 	callerInitOnce.Do(func() { | 	callerInitOnce.Do(func() { | ||||||
| 		pcs := make([]uintptr, 2) | 		pcs := make([]uintptr, maximumCallerDepth) | ||||||
| 		_ = runtime.Callers(0, pcs) | 		_ = runtime.Callers(0, pcs) | ||||||
| 		logrusPackage = getPackageName(runtime.FuncForPC(pcs[1]).Name()) |  | ||||||
| 
 | 
 | ||||||
| 		// now that we have the cache, we can skip a minimum count of known-logrus functions
 | 		// dynamic get the package name and the minimum caller depth
 | ||||||
| 		// XXX this is dubious, the number of frames may vary
 | 		for i := 0; i < maximumCallerDepth; i++ { | ||||||
|  | 			funcName := runtime.FuncForPC(pcs[i]).Name() | ||||||
|  | 			if strings.Contains(funcName, "getCaller") { | ||||||
|  | 				logrusPackage = getPackageName(funcName) | ||||||
|  | 				break | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		minimumCallerDepth = knownLogrusFrames | 		minimumCallerDepth = knownLogrusFrames | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
|  | @ -187,7 +205,7 @@ func getCaller() *runtime.Frame { | ||||||
| 
 | 
 | ||||||
| 		// If the caller isn't part of this package, we're done
 | 		// If the caller isn't part of this package, we're done
 | ||||||
| 		if pkg != logrusPackage { | 		if pkg != logrusPackage { | ||||||
| 			return &f | 			return &f //nolint:scopelint
 | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -217,9 +235,11 @@ func (entry Entry) log(level Level, msg string) { | ||||||
| 
 | 
 | ||||||
| 	entry.Level = level | 	entry.Level = level | ||||||
| 	entry.Message = msg | 	entry.Message = msg | ||||||
|  | 	entry.Logger.mu.Lock() | ||||||
| 	if entry.Logger.ReportCaller { | 	if entry.Logger.ReportCaller { | ||||||
| 		entry.Caller = getCaller() | 		entry.Caller = getCaller() | ||||||
| 	} | 	} | ||||||
|  | 	entry.Logger.mu.Unlock() | ||||||
| 
 | 
 | ||||||
| 	entry.fireHooks() | 	entry.fireHooks() | ||||||
| 
 | 
 | ||||||
|  | @ -255,11 +275,10 @@ func (entry *Entry) write() { | ||||||
| 	serialized, err := entry.Logger.Formatter.Format(entry) | 	serialized, err := entry.Logger.Formatter.Format(entry) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err) | 		fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err) | ||||||
| 	} else { | 		return | ||||||
| 		_, err = entry.Logger.Out.Write(serialized) | 	} | ||||||
| 		if err != nil { | 	if _, err = entry.Logger.Out.Write(serialized); err != nil { | ||||||
| 			fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err) | 		fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err) | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -80,7 +80,7 @@ func WithFields(fields Fields) *Entry { | ||||||
| 	return std.WithFields(fields) | 	return std.WithFields(fields) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // WithTime creats an entry from the standard logger and overrides the time of
 | // WithTime creates an entry from the standard logger and overrides the time of
 | ||||||
| // logs generated with it.
 | // logs generated with it.
 | ||||||
| //
 | //
 | ||||||
| // Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal
 | // Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal
 | ||||||
|  |  | ||||||
|  | @ -2,9 +2,10 @@ module github.com/sirupsen/logrus | ||||||
| 
 | 
 | ||||||
| require ( | require ( | ||||||
| 	github.com/davecgh/go-spew v1.1.1 // indirect | 	github.com/davecgh/go-spew v1.1.1 // indirect | ||||||
| 	github.com/konsorten/go-windows-terminal-sequences v1.0.1 | 	github.com/konsorten/go-windows-terminal-sequences v1.0.3 | ||||||
| 	github.com/pmezard/go-difflib v1.0.0 // indirect | 	github.com/pmezard/go-difflib v1.0.0 // indirect | ||||||
| 	github.com/stretchr/objx v0.1.1 // indirect |  | ||||||
| 	github.com/stretchr/testify v1.2.2 | 	github.com/stretchr/testify v1.2.2 | ||||||
| 	golang.org/x/sys v0.0.0-20190422165155-953cdadca894 | 	golang.org/x/sys v0.0.0-20190422165155-953cdadca894 | ||||||
| ) | ) | ||||||
|  | 
 | ||||||
|  | go 1.13 | ||||||
|  |  | ||||||
|  | @ -1,16 +1,12 @@ | ||||||
| github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||||||
| github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||||
| github.com/konsorten/go-windows-terminal-sequences v0.0.0-20180402223658-b729f2633dfe h1:CHRGQ8V7OlCYtwaKPJi3iA7J+YdNKdo8j7nG5IgDhjs= |  | ||||||
| github.com/konsorten/go-windows-terminal-sequences v0.0.0-20180402223658-b729f2633dfe/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= |  | ||||||
| github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= | github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= | ||||||
| github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= | ||||||
|  | github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= | ||||||
|  | github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= | ||||||
| github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||||||
| github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||||||
| github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= |  | ||||||
| github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= |  | ||||||
| github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= | github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= | ||||||
| github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= | ||||||
| golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33 h1:I6FyU15t786LL7oL/hn43zqTuEGr4PN7F4XJ1p4E3Y8= |  | ||||||
| golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= |  | ||||||
| golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= | golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= | ||||||
| golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||||
|  |  | ||||||
|  | @ -28,6 +28,9 @@ type JSONFormatter struct { | ||||||
| 	// DisableTimestamp allows disabling automatic timestamps in output
 | 	// DisableTimestamp allows disabling automatic timestamps in output
 | ||||||
| 	DisableTimestamp bool | 	DisableTimestamp bool | ||||||
| 
 | 
 | ||||||
|  | 	// DisableHTMLEscape allows disabling html escaping in output
 | ||||||
|  | 	DisableHTMLEscape bool | ||||||
|  | 
 | ||||||
| 	// DataKey allows users to put all the log entry parameters into a nested dictionary at a given key.
 | 	// DataKey allows users to put all the log entry parameters into a nested dictionary at a given key.
 | ||||||
| 	DataKey string | 	DataKey string | ||||||
| 
 | 
 | ||||||
|  | @ -110,6 +113,7 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	encoder := json.NewEncoder(b) | 	encoder := json.NewEncoder(b) | ||||||
|  | 	encoder.SetEscapeHTML(!f.DisableHTMLEscape) | ||||||
| 	if f.PrettyPrint { | 	if f.PrettyPrint { | ||||||
| 		encoder.SetIndent("", "  ") | 		encoder.SetIndent("", "  ") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -68,10 +68,10 @@ func (mw *MutexWrap) Disable() { | ||||||
| // `Out` and `Hooks` directly on the default logger instance. You can also just
 | // `Out` and `Hooks` directly on the default logger instance. You can also just
 | ||||||
| // instantiate your own:
 | // instantiate your own:
 | ||||||
| //
 | //
 | ||||||
| //    var log = &Logger{
 | //    var log = &logrus.Logger{
 | ||||||
| //      Out: os.Stderr,
 | //      Out: os.Stderr,
 | ||||||
| //      Formatter: new(JSONFormatter),
 | //      Formatter: new(logrus.JSONFormatter),
 | ||||||
| //      Hooks: make(LevelHooks),
 | //      Hooks: make(logrus.LevelHooks),
 | ||||||
| //      Level: logrus.DebugLevel,
 | //      Level: logrus.DebugLevel,
 | ||||||
| //    }
 | //    }
 | ||||||
| //
 | //
 | ||||||
|  | @ -100,8 +100,9 @@ func (logger *Logger) releaseEntry(entry *Entry) { | ||||||
| 	logger.entryPool.Put(entry) | 	logger.entryPool.Put(entry) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Adds a field to the log entry, note that it doesn't log until you call
 | // WithField allocates a new entry and adds a field to it.
 | ||||||
| // Debug, Print, Info, Warn, Error, Fatal or Panic. It only creates a log entry.
 | // Debug, Print, Info, Warn, Error, Fatal or Panic must be then applied to
 | ||||||
|  | // this new returned entry.
 | ||||||
| // If you want multiple fields, use `WithFields`.
 | // If you want multiple fields, use `WithFields`.
 | ||||||
| func (logger *Logger) WithField(key string, value interface{}) *Entry { | func (logger *Logger) WithField(key string, value interface{}) *Entry { | ||||||
| 	entry := logger.newEntry() | 	entry := logger.newEntry() | ||||||
|  |  | ||||||
|  | @ -51,7 +51,7 @@ func (level *Level) UnmarshalText(text []byte) error { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	*level = Level(l) | 	*level = l | ||||||
| 
 | 
 | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,4 +1,5 @@ | ||||||
| // +build darwin dragonfly freebsd netbsd openbsd
 | // +build darwin dragonfly freebsd netbsd openbsd
 | ||||||
|  | // +build !js
 | ||||||
| 
 | 
 | ||||||
| package logrus | package logrus | ||||||
| 
 | 
 | ||||||
|  | @ -10,4 +11,3 @@ func isTerminal(fd int) bool { | ||||||
| 	_, err := unix.IoctlGetTermios(fd, ioctlReadTermios) | 	_, err := unix.IoctlGetTermios(fd, ioctlReadTermios) | ||||||
| 	return err == nil | 	return err == nil | ||||||
| } | } | ||||||
| 
 |  | ||||||
|  |  | ||||||
|  | @ -0,0 +1,7 @@ | ||||||
|  | // +build js
 | ||||||
|  | 
 | ||||||
|  | package logrus | ||||||
|  | 
 | ||||||
|  | func isTerminal(fd int) bool { | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  | @ -1,4 +1,5 @@ | ||||||
| // +build linux aix
 | // +build linux aix
 | ||||||
|  | // +build !js
 | ||||||
| 
 | 
 | ||||||
| package logrus | package logrus | ||||||
| 
 | 
 | ||||||
|  | @ -10,4 +11,3 @@ func isTerminal(fd int) bool { | ||||||
| 	_, err := unix.IoctlGetTermios(fd, ioctlReadTermios) | 	_, err := unix.IoctlGetTermios(fd, ioctlReadTermios) | ||||||
| 	return err == nil | 	return err == nil | ||||||
| } | } | ||||||
| 
 |  | ||||||
|  |  | ||||||
|  | @ -6,9 +6,11 @@ import ( | ||||||
| 	"os" | 	"os" | ||||||
| 	"runtime" | 	"runtime" | ||||||
| 	"sort" | 	"sort" | ||||||
|  | 	"strconv" | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"sync" | 	"sync" | ||||||
| 	"time" | 	"time" | ||||||
|  | 	"unicode/utf8" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| const ( | const ( | ||||||
|  | @ -32,6 +34,14 @@ type TextFormatter struct { | ||||||
| 	// Force disabling colors.
 | 	// Force disabling colors.
 | ||||||
| 	DisableColors bool | 	DisableColors bool | ||||||
| 
 | 
 | ||||||
|  | 	// Force quoting of all values
 | ||||||
|  | 	ForceQuote bool | ||||||
|  | 
 | ||||||
|  | 	// DisableQuote disables quoting for all values.
 | ||||||
|  | 	// DisableQuote will have a lower priority than ForceQuote.
 | ||||||
|  | 	// If both of them are set to true, quote will be forced on all values.
 | ||||||
|  | 	DisableQuote bool | ||||||
|  | 
 | ||||||
| 	// Override coloring based on CLICOLOR and CLICOLOR_FORCE. - https://bixense.com/clicolors/
 | 	// Override coloring based on CLICOLOR and CLICOLOR_FORCE. - https://bixense.com/clicolors/
 | ||||||
| 	EnvironmentOverrideColors bool | 	EnvironmentOverrideColors bool | ||||||
| 
 | 
 | ||||||
|  | @ -57,6 +67,10 @@ type TextFormatter struct { | ||||||
| 	// Disables the truncation of the level text to 4 characters.
 | 	// Disables the truncation of the level text to 4 characters.
 | ||||||
| 	DisableLevelTruncation bool | 	DisableLevelTruncation bool | ||||||
| 
 | 
 | ||||||
|  | 	// PadLevelText Adds padding the level text so that all the levels output at the same length
 | ||||||
|  | 	// PadLevelText is a superset of the DisableLevelTruncation option
 | ||||||
|  | 	PadLevelText bool | ||||||
|  | 
 | ||||||
| 	// QuoteEmptyFields will wrap empty fields in quotes if true
 | 	// QuoteEmptyFields will wrap empty fields in quotes if true
 | ||||||
| 	QuoteEmptyFields bool | 	QuoteEmptyFields bool | ||||||
| 
 | 
 | ||||||
|  | @ -79,23 +93,32 @@ type TextFormatter struct { | ||||||
| 	CallerPrettyfier func(*runtime.Frame) (function string, file string) | 	CallerPrettyfier func(*runtime.Frame) (function string, file string) | ||||||
| 
 | 
 | ||||||
| 	terminalInitOnce sync.Once | 	terminalInitOnce sync.Once | ||||||
|  | 
 | ||||||
|  | 	// The max length of the level text, generated dynamically on init
 | ||||||
|  | 	levelTextMaxLength int | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (f *TextFormatter) init(entry *Entry) { | func (f *TextFormatter) init(entry *Entry) { | ||||||
| 	if entry.Logger != nil { | 	if entry.Logger != nil { | ||||||
| 		f.isTerminal = checkIfTerminal(entry.Logger.Out) | 		f.isTerminal = checkIfTerminal(entry.Logger.Out) | ||||||
| 	} | 	} | ||||||
|  | 	// Get the max length of the level text
 | ||||||
|  | 	for _, level := range AllLevels { | ||||||
|  | 		levelTextLength := utf8.RuneCount([]byte(level.String())) | ||||||
|  | 		if levelTextLength > f.levelTextMaxLength { | ||||||
|  | 			f.levelTextMaxLength = levelTextLength | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (f *TextFormatter) isColored() bool { | func (f *TextFormatter) isColored() bool { | ||||||
| 	isColored := f.ForceColors || (f.isTerminal && (runtime.GOOS != "windows")) | 	isColored := f.ForceColors || (f.isTerminal && (runtime.GOOS != "windows")) | ||||||
| 
 | 
 | ||||||
| 	if f.EnvironmentOverrideColors { | 	if f.EnvironmentOverrideColors { | ||||||
| 		if force, ok := os.LookupEnv("CLICOLOR_FORCE"); ok && force != "0" { | 		switch force, ok := os.LookupEnv("CLICOLOR_FORCE"); { | ||||||
|  | 		case ok && force != "0": | ||||||
| 			isColored = true | 			isColored = true | ||||||
| 		} else if ok && force == "0" { | 		case ok && force == "0", os.Getenv("CLICOLOR") == "0": | ||||||
| 			isColored = false |  | ||||||
| 		} else if os.Getenv("CLICOLOR") == "0" { |  | ||||||
| 			isColored = false | 			isColored = false | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | @ -217,9 +240,18 @@ func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []strin | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	levelText := strings.ToUpper(entry.Level.String()) | 	levelText := strings.ToUpper(entry.Level.String()) | ||||||
| 	if !f.DisableLevelTruncation { | 	if !f.DisableLevelTruncation && !f.PadLevelText { | ||||||
| 		levelText = levelText[0:4] | 		levelText = levelText[0:4] | ||||||
| 	} | 	} | ||||||
|  | 	if f.PadLevelText { | ||||||
|  | 		// Generates the format string used in the next line, for example "%-6s" or "%-7s".
 | ||||||
|  | 		// Based on the max level text length.
 | ||||||
|  | 		formatString := "%-" + strconv.Itoa(f.levelTextMaxLength) + "s" | ||||||
|  | 		// Formats the level text by appending spaces up to the max length, for example:
 | ||||||
|  | 		// 	- "INFO   "
 | ||||||
|  | 		//	- "WARNING"
 | ||||||
|  | 		levelText = fmt.Sprintf(formatString, levelText) | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	// Remove a single newline if it already exists in the message to keep
 | 	// Remove a single newline if it already exists in the message to keep
 | ||||||
| 	// the behavior of logrus text_formatter the same as the stdlib log package
 | 	// the behavior of logrus text_formatter the same as the stdlib log package
 | ||||||
|  | @ -243,11 +275,12 @@ func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []strin | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if f.DisableTimestamp { | 	switch { | ||||||
|  | 	case f.DisableTimestamp: | ||||||
| 		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m%s %-44s ", levelColor, levelText, caller, entry.Message) | 		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m%s %-44s ", levelColor, levelText, caller, entry.Message) | ||||||
| 	} else if !f.FullTimestamp { | 	case !f.FullTimestamp: | ||||||
| 		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d]%s %-44s ", levelColor, levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), caller, entry.Message) | 		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d]%s %-44s ", levelColor, levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), caller, entry.Message) | ||||||
| 	} else { | 	default: | ||||||
| 		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s]%s %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), caller, entry.Message) | 		fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s]%s %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), caller, entry.Message) | ||||||
| 	} | 	} | ||||||
| 	for _, k := range keys { | 	for _, k := range keys { | ||||||
|  | @ -258,9 +291,15 @@ func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []strin | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (f *TextFormatter) needsQuoting(text string) bool { | func (f *TextFormatter) needsQuoting(text string) bool { | ||||||
|  | 	if f.ForceQuote { | ||||||
|  | 		return true | ||||||
|  | 	} | ||||||
| 	if f.QuoteEmptyFields && len(text) == 0 { | 	if f.QuoteEmptyFields && len(text) == 0 { | ||||||
| 		return true | 		return true | ||||||
| 	} | 	} | ||||||
|  | 	if f.DisableQuote { | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
| 	for _, ch := range text { | 	for _, ch := range text { | ||||||
| 		if !((ch >= 'a' && ch <= 'z') || | 		if !((ch >= 'a' && ch <= 'z') || | ||||||
| 			(ch >= 'A' && ch <= 'Z') || | 			(ch >= 'A' && ch <= 'Z') || | ||||||
|  |  | ||||||
|  | @ -6,10 +6,16 @@ import ( | ||||||
| 	"runtime" | 	"runtime" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | // Writer at INFO level. See WriterLevel for details.
 | ||||||
| func (logger *Logger) Writer() *io.PipeWriter { | func (logger *Logger) Writer() *io.PipeWriter { | ||||||
| 	return logger.WriterLevel(InfoLevel) | 	return logger.WriterLevel(InfoLevel) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // WriterLevel returns an io.Writer that can be used to write arbitrary text to
 | ||||||
|  | // the logger at the given log level. Each line written to the writer will be
 | ||||||
|  | // printed in the usual way using formatters and hooks. The writer is part of an
 | ||||||
|  | // io.Pipe and it is the callers responsibility to close the writer when done.
 | ||||||
|  | // This can be used to override the standard library logger easily.
 | ||||||
| func (logger *Logger) WriterLevel(level Level) *io.PipeWriter { | func (logger *Logger) WriterLevel(level Level) *io.PipeWriter { | ||||||
| 	return NewEntry(logger).WriterLevel(level) | 	return NewEntry(logger).WriterLevel(level) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -92,7 +92,7 @@ github.com/gorilla/mux | ||||||
| github.com/inconshreveable/mousetrap | github.com/inconshreveable/mousetrap | ||||||
| # github.com/jmespath/go-jmespath v0.3.0 | # github.com/jmespath/go-jmespath v0.3.0 | ||||||
| github.com/jmespath/go-jmespath | github.com/jmespath/go-jmespath | ||||||
| # github.com/konsorten/go-windows-terminal-sequences v1.0.1 | # github.com/konsorten/go-windows-terminal-sequences v1.0.3 | ||||||
| github.com/konsorten/go-windows-terminal-sequences | github.com/konsorten/go-windows-terminal-sequences | ||||||
| # github.com/marstr/guid v1.1.0 | # github.com/marstr/guid v1.1.0 | ||||||
| github.com/marstr/guid | github.com/marstr/guid | ||||||
|  | @ -123,7 +123,7 @@ github.com/prometheus/procfs | ||||||
| github.com/prometheus/procfs/internal/fs | github.com/prometheus/procfs/internal/fs | ||||||
| # github.com/satori/go.uuid v1.2.0 | # github.com/satori/go.uuid v1.2.0 | ||||||
| github.com/satori/go.uuid | github.com/satori/go.uuid | ||||||
| # github.com/sirupsen/logrus v1.4.2 | # github.com/sirupsen/logrus v1.6.0 | ||||||
| github.com/sirupsen/logrus | github.com/sirupsen/logrus | ||||||
| # github.com/spf13/cobra v0.0.3 | # github.com/spf13/cobra v0.0.3 | ||||||
| github.com/spf13/cobra | github.com/spf13/cobra | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue