From 1d3157b49a52cf662d913a7dcaf667d2ec052e9e Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Tue, 22 Aug 2017 17:15:35 +0100 Subject: [PATCH 1/6] Update util and dugong --- vendor/manifest | 4 ++-- vendor/src/github.com/matrix-org/dugong/README.md | 4 ++-- vendor/src/github.com/matrix-org/dugong/fshook.go | 2 +- vendor/src/github.com/matrix-org/dugong/fshook_test.go | 2 +- vendor/src/github.com/matrix-org/util/context.go | 2 +- vendor/src/github.com/matrix-org/util/json.go | 2 +- vendor/src/github.com/matrix-org/util/json_test.go | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/vendor/manifest b/vendor/manifest index 99bb98dae..35ff3b2de 100644 --- a/vendor/manifest +++ b/vendor/manifest @@ -86,7 +86,7 @@ { "importpath": "github.com/matrix-org/dugong", "repository": "https://github.com/matrix-org/dugong", - "revision": "193b8f88e381d12f2d53023fba25e43fc81dc5ac", + "revision": "f04553160a2b197248e032f4fe23d57b9af20cde", "branch": "master" }, { @@ -110,7 +110,7 @@ { "importpath": "github.com/matrix-org/util", "repository": "https://github.com/matrix-org/util", - "revision": "53326ed5598b226681112cbd441f59f3cffc9c82", + "revision": "466baca1646be2ce6bcf3b1573296015650d9ed2", "branch": "master" }, { diff --git a/vendor/src/github.com/matrix-org/dugong/README.md b/vendor/src/github.com/matrix-org/dugong/README.md index cc2267655..fbbaf32d6 100644 --- a/vendor/src/github.com/matrix-org/dugong/README.md +++ b/vendor/src/github.com/matrix-org/dugong/README.md @@ -3,8 +3,8 @@ Logging utilities for [logrus](https://github.com/Sirupsen/logrus). To develop on this library, you need logrus on your GOPATH: - ``go get github.com/Sirupsen/logrus`` - + ``go get github.com/sirupsen/logrus`` + You can then run its tests by running ``go test`` diff --git a/vendor/src/github.com/matrix-org/dugong/fshook.go b/vendor/src/github.com/matrix-org/dugong/fshook.go index be539ab42..ab79b55bf 100644 --- a/vendor/src/github.com/matrix-org/dugong/fshook.go +++ b/vendor/src/github.com/matrix-org/dugong/fshook.go @@ -3,7 +3,7 @@ package dugong import ( "compress/gzip" "fmt" - log "github.com/Sirupsen/logrus" + log "github.com/sirupsen/logrus" "io" "os" "path/filepath" diff --git a/vendor/src/github.com/matrix-org/dugong/fshook_test.go b/vendor/src/github.com/matrix-org/dugong/fshook_test.go index a51a51fe1..4d34f6ad5 100644 --- a/vendor/src/github.com/matrix-org/dugong/fshook_test.go +++ b/vendor/src/github.com/matrix-org/dugong/fshook_test.go @@ -3,7 +3,7 @@ package dugong import ( "bufio" "encoding/json" - log "github.com/Sirupsen/logrus" + log "github.com/sirupsen/logrus" "io/ioutil" "os" "path/filepath" diff --git a/vendor/src/github.com/matrix-org/util/context.go b/vendor/src/github.com/matrix-org/util/context.go index f2477a56a..09d5ba410 100644 --- a/vendor/src/github.com/matrix-org/util/context.go +++ b/vendor/src/github.com/matrix-org/util/context.go @@ -3,7 +3,7 @@ package util import ( "context" - log "github.com/Sirupsen/logrus" + log "github.com/sirupsen/logrus" ) // contextKeys is a type alias for string to namespace Context keys per-package. diff --git a/vendor/src/github.com/matrix-org/util/json.go b/vendor/src/github.com/matrix-org/util/json.go index c02f08fe3..d5c0cad11 100644 --- a/vendor/src/github.com/matrix-org/util/json.go +++ b/vendor/src/github.com/matrix-org/util/json.go @@ -8,7 +8,7 @@ import ( "runtime/debug" "time" - log "github.com/Sirupsen/logrus" + log "github.com/sirupsen/logrus" ) // JSONResponse represents an HTTP response which contains a JSON body. diff --git a/vendor/src/github.com/matrix-org/util/json_test.go b/vendor/src/github.com/matrix-org/util/json_test.go index aeb5a9e55..7071d3022 100644 --- a/vendor/src/github.com/matrix-org/util/json_test.go +++ b/vendor/src/github.com/matrix-org/util/json_test.go @@ -7,7 +7,7 @@ import ( "net/http/httptest" "testing" - log "github.com/Sirupsen/logrus" + log "github.com/sirupsen/logrus" ) type MockJSONRequestHandler struct { From 621eaae68aa7881dd5ea1e28b3738ce9d1d3e175 Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Tue, 22 Aug 2017 17:16:13 +0100 Subject: [PATCH 2/6] Fix logrus import path --- .../matrix-org/dendrite/clientapi/consumers/roomserver.go | 2 +- .../matrix-org/dendrite/clientapi/writers/createroom.go | 2 +- .../matrix-org/dendrite/clientapi/writers/register.go | 2 +- src/github.com/matrix-org/dendrite/cmd/client-api-proxy/main.go | 2 +- .../matrix-org/dendrite/cmd/dendrite-client-api-server/main.go | 2 +- .../dendrite/cmd/dendrite-federation-api-server/main.go | 2 +- .../dendrite/cmd/dendrite-federation-sender-server/main.go | 2 +- .../matrix-org/dendrite/cmd/dendrite-media-api-server/main.go | 2 +- .../matrix-org/dendrite/cmd/dendrite-monolith-server/main.go | 2 +- .../dendrite/cmd/dendrite-public-rooms-api-server/main.go | 2 +- .../matrix-org/dendrite/cmd/dendrite-room-server/main.go | 2 +- .../matrix-org/dendrite/cmd/dendrite-sync-api-server/main.go | 2 +- .../matrix-org/dendrite/cmd/federation-api-proxy/main.go | 2 +- src/github.com/matrix-org/dendrite/common/log.go | 2 +- .../dendrite/federationsender/consumers/roomserver.go | 2 +- .../dendrite/federationsender/queue/destinationqueue.go | 2 +- .../matrix-org/dendrite/federationsender/queue/queue.go | 2 +- .../matrix-org/dendrite/mediaapi/fileutils/fileutils.go | 2 +- .../matrix-org/dendrite/mediaapi/thumbnailer/thumbnailer.go | 2 +- .../dendrite/mediaapi/thumbnailer/thumbnailer_bimg.go | 2 +- .../dendrite/mediaapi/thumbnailer/thumbnailer_nfnt.go | 2 +- src/github.com/matrix-org/dendrite/mediaapi/writers/download.go | 2 +- src/github.com/matrix-org/dendrite/mediaapi/writers/upload.go | 2 +- .../matrix-org/dendrite/publicroomsapi/consumers/roomserver.go | 2 +- .../matrix-org/dendrite/syncapi/consumers/clientapi.go | 2 +- .../matrix-org/dendrite/syncapi/consumers/roomserver.go | 2 +- .../dendrite/syncapi/storage/output_room_events_table.go | 2 +- src/github.com/matrix-org/dendrite/syncapi/sync/notifier.go | 2 +- src/github.com/matrix-org/dendrite/syncapi/sync/request.go | 2 +- src/github.com/matrix-org/dendrite/syncapi/sync/requestpool.go | 2 +- 30 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/github.com/matrix-org/dendrite/clientapi/consumers/roomserver.go b/src/github.com/matrix-org/dendrite/clientapi/consumers/roomserver.go index 314ca42bc..a94750d3c 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/consumers/roomserver.go +++ b/src/github.com/matrix-org/dendrite/clientapi/consumers/roomserver.go @@ -23,7 +23,7 @@ import ( "github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/gomatrixserverlib" - log "github.com/Sirupsen/logrus" + log "github.com/sirupsen/logrus" sarama "gopkg.in/Shopify/sarama.v1" ) diff --git a/src/github.com/matrix-org/dendrite/clientapi/writers/createroom.go b/src/github.com/matrix-org/dendrite/clientapi/writers/createroom.go index 58826c2d9..ccc4daf92 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/writers/createroom.go +++ b/src/github.com/matrix-org/dendrite/clientapi/writers/createroom.go @@ -21,7 +21,6 @@ import ( "strings" "time" - log "github.com/Sirupsen/logrus" "github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/auth/storage/accounts" "github.com/matrix-org/dendrite/clientapi/httputil" @@ -31,6 +30,7 @@ import ( "github.com/matrix-org/dendrite/common/config" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/util" + log "github.com/sirupsen/logrus" ) // https://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-createroom diff --git a/src/github.com/matrix-org/dendrite/clientapi/writers/register.go b/src/github.com/matrix-org/dendrite/clientapi/writers/register.go index d09b371d0..318771d32 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/writers/register.go +++ b/src/github.com/matrix-org/dendrite/clientapi/writers/register.go @@ -4,7 +4,6 @@ import ( "fmt" "net/http" - log "github.com/Sirupsen/logrus" "github.com/matrix-org/dendrite/clientapi/auth" "github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/auth/storage/accounts" @@ -13,6 +12,7 @@ import ( "github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/util" + log "github.com/sirupsen/logrus" ) const ( diff --git a/src/github.com/matrix-org/dendrite/cmd/client-api-proxy/main.go b/src/github.com/matrix-org/dendrite/cmd/client-api-proxy/main.go index 477f8d127..b602016d5 100644 --- a/src/github.com/matrix-org/dendrite/cmd/client-api-proxy/main.go +++ b/src/github.com/matrix-org/dendrite/cmd/client-api-proxy/main.go @@ -17,7 +17,7 @@ package main import ( "flag" "fmt" - log "github.com/Sirupsen/logrus" + log "github.com/sirupsen/logrus" "net/http" "net/http/httputil" "net/url" diff --git a/src/github.com/matrix-org/dendrite/cmd/dendrite-client-api-server/main.go b/src/github.com/matrix-org/dendrite/cmd/dendrite-client-api-server/main.go index 53ebdb934..4505c1292 100644 --- a/src/github.com/matrix-org/dendrite/cmd/dendrite-client-api-server/main.go +++ b/src/github.com/matrix-org/dendrite/cmd/dendrite-client-api-server/main.go @@ -32,7 +32,7 @@ import ( "github.com/matrix-org/gomatrixserverlib" - log "github.com/Sirupsen/logrus" + log "github.com/sirupsen/logrus" sarama "gopkg.in/Shopify/sarama.v1" ) diff --git a/src/github.com/matrix-org/dendrite/cmd/dendrite-federation-api-server/main.go b/src/github.com/matrix-org/dendrite/cmd/dendrite-federation-api-server/main.go index 70fc144e2..bb53473f5 100644 --- a/src/github.com/matrix-org/dendrite/cmd/dendrite-federation-api-server/main.go +++ b/src/github.com/matrix-org/dendrite/cmd/dendrite-federation-api-server/main.go @@ -28,7 +28,7 @@ import ( "github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/gomatrixserverlib" - log "github.com/Sirupsen/logrus" + log "github.com/sirupsen/logrus" ) var ( diff --git a/src/github.com/matrix-org/dendrite/cmd/dendrite-federation-sender-server/main.go b/src/github.com/matrix-org/dendrite/cmd/dendrite-federation-sender-server/main.go index dfc2dc2ff..f4b27a6f2 100644 --- a/src/github.com/matrix-org/dendrite/cmd/dendrite-federation-sender-server/main.go +++ b/src/github.com/matrix-org/dendrite/cmd/dendrite-federation-sender-server/main.go @@ -28,7 +28,7 @@ import ( "github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/gomatrixserverlib" - log "github.com/Sirupsen/logrus" + log "github.com/sirupsen/logrus" sarama "gopkg.in/Shopify/sarama.v1" ) diff --git a/src/github.com/matrix-org/dendrite/cmd/dendrite-media-api-server/main.go b/src/github.com/matrix-org/dendrite/cmd/dendrite-media-api-server/main.go index 34a531157..429973206 100644 --- a/src/github.com/matrix-org/dendrite/cmd/dendrite-media-api-server/main.go +++ b/src/github.com/matrix-org/dendrite/cmd/dendrite-media-api-server/main.go @@ -25,7 +25,7 @@ import ( "github.com/matrix-org/dendrite/mediaapi/routing" "github.com/matrix-org/dendrite/mediaapi/storage" - log "github.com/Sirupsen/logrus" + log "github.com/sirupsen/logrus" ) var ( diff --git a/src/github.com/matrix-org/dendrite/cmd/dendrite-monolith-server/main.go b/src/github.com/matrix-org/dendrite/cmd/dendrite-monolith-server/main.go index 25b269b89..dee5c986c 100644 --- a/src/github.com/matrix-org/dendrite/cmd/dendrite-monolith-server/main.go +++ b/src/github.com/matrix-org/dendrite/cmd/dendrite-monolith-server/main.go @@ -56,7 +56,7 @@ import ( publicroomsapi_routing "github.com/matrix-org/dendrite/publicroomsapi/routing" publicroomsapi_storage "github.com/matrix-org/dendrite/publicroomsapi/storage" - log "github.com/Sirupsen/logrus" + log "github.com/sirupsen/logrus" sarama "gopkg.in/Shopify/sarama.v1" ) diff --git a/src/github.com/matrix-org/dendrite/cmd/dendrite-public-rooms-api-server/main.go b/src/github.com/matrix-org/dendrite/cmd/dendrite-public-rooms-api-server/main.go index c8e705f91..081dfbe98 100644 --- a/src/github.com/matrix-org/dendrite/cmd/dendrite-public-rooms-api-server/main.go +++ b/src/github.com/matrix-org/dendrite/cmd/dendrite-public-rooms-api-server/main.go @@ -28,7 +28,7 @@ import ( "github.com/matrix-org/dendrite/publicroomsapi/storage" "github.com/matrix-org/dendrite/roomserver/api" - log "github.com/Sirupsen/logrus" + log "github.com/sirupsen/logrus" sarama "gopkg.in/Shopify/sarama.v1" ) diff --git a/src/github.com/matrix-org/dendrite/cmd/dendrite-room-server/main.go b/src/github.com/matrix-org/dendrite/cmd/dendrite-room-server/main.go index dea61f742..c863eba24 100644 --- a/src/github.com/matrix-org/dendrite/cmd/dendrite-room-server/main.go +++ b/src/github.com/matrix-org/dendrite/cmd/dendrite-room-server/main.go @@ -20,7 +20,6 @@ import ( _ "net/http/pprof" "os" - log "github.com/Sirupsen/logrus" "github.com/matrix-org/dendrite/common" "github.com/matrix-org/dendrite/common/config" "github.com/matrix-org/dendrite/roomserver/alias" @@ -28,6 +27,7 @@ import ( "github.com/matrix-org/dendrite/roomserver/query" "github.com/matrix-org/dendrite/roomserver/storage" "github.com/prometheus/client_golang/prometheus" + log "github.com/sirupsen/logrus" sarama "gopkg.in/Shopify/sarama.v1" ) diff --git a/src/github.com/matrix-org/dendrite/cmd/dendrite-sync-api-server/main.go b/src/github.com/matrix-org/dendrite/cmd/dendrite-sync-api-server/main.go index 7e9e4c128..4ec5e52c5 100644 --- a/src/github.com/matrix-org/dendrite/cmd/dendrite-sync-api-server/main.go +++ b/src/github.com/matrix-org/dendrite/cmd/dendrite-sync-api-server/main.go @@ -31,7 +31,7 @@ import ( "github.com/matrix-org/dendrite/syncapi/sync" "github.com/matrix-org/dendrite/syncapi/types" - log "github.com/Sirupsen/logrus" + log "github.com/sirupsen/logrus" sarama "gopkg.in/Shopify/sarama.v1" ) diff --git a/src/github.com/matrix-org/dendrite/cmd/federation-api-proxy/main.go b/src/github.com/matrix-org/dendrite/cmd/federation-api-proxy/main.go index ed0aed722..5b0fafadc 100644 --- a/src/github.com/matrix-org/dendrite/cmd/federation-api-proxy/main.go +++ b/src/github.com/matrix-org/dendrite/cmd/federation-api-proxy/main.go @@ -17,7 +17,7 @@ package main import ( "flag" "fmt" - log "github.com/Sirupsen/logrus" + log "github.com/sirupsen/logrus" "net/http" "net/http/httputil" "net/url" diff --git a/src/github.com/matrix-org/dendrite/common/log.go b/src/github.com/matrix-org/dendrite/common/log.go index 79fee40f8..fbfa34783 100644 --- a/src/github.com/matrix-org/dendrite/common/log.go +++ b/src/github.com/matrix-org/dendrite/common/log.go @@ -18,8 +18,8 @@ import ( "os" "path/filepath" - "github.com/Sirupsen/logrus" "github.com/matrix-org/dugong" + "github.com/sirupsen/logrus" ) type utcFormatter struct { diff --git a/src/github.com/matrix-org/dendrite/federationsender/consumers/roomserver.go b/src/github.com/matrix-org/dendrite/federationsender/consumers/roomserver.go index 4ebc36c77..c92fed147 100644 --- a/src/github.com/matrix-org/dendrite/federationsender/consumers/roomserver.go +++ b/src/github.com/matrix-org/dendrite/federationsender/consumers/roomserver.go @@ -18,7 +18,6 @@ import ( "encoding/json" "fmt" - log "github.com/Sirupsen/logrus" "github.com/matrix-org/dendrite/common" "github.com/matrix-org/dendrite/common/config" "github.com/matrix-org/dendrite/federationsender/queue" @@ -26,6 +25,7 @@ import ( "github.com/matrix-org/dendrite/federationsender/types" "github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/gomatrixserverlib" + log "github.com/sirupsen/logrus" sarama "gopkg.in/Shopify/sarama.v1" ) diff --git a/src/github.com/matrix-org/dendrite/federationsender/queue/destinationqueue.go b/src/github.com/matrix-org/dendrite/federationsender/queue/destinationqueue.go index bb274b08e..1f48f6c71 100644 --- a/src/github.com/matrix-org/dendrite/federationsender/queue/destinationqueue.go +++ b/src/github.com/matrix-org/dendrite/federationsender/queue/destinationqueue.go @@ -19,8 +19,8 @@ import ( "sync" "time" - log "github.com/Sirupsen/logrus" "github.com/matrix-org/gomatrixserverlib" + log "github.com/sirupsen/logrus" ) // destinationQueue is a queue of events for a single destination. diff --git a/src/github.com/matrix-org/dendrite/federationsender/queue/queue.go b/src/github.com/matrix-org/dendrite/federationsender/queue/queue.go index 79f019fdd..d31c12f99 100644 --- a/src/github.com/matrix-org/dendrite/federationsender/queue/queue.go +++ b/src/github.com/matrix-org/dendrite/federationsender/queue/queue.go @@ -18,8 +18,8 @@ import ( "fmt" "sync" - log "github.com/Sirupsen/logrus" "github.com/matrix-org/gomatrixserverlib" + log "github.com/sirupsen/logrus" ) // OutgoingQueues is a collection of queues for sending transactions to other diff --git a/src/github.com/matrix-org/dendrite/mediaapi/fileutils/fileutils.go b/src/github.com/matrix-org/dendrite/mediaapi/fileutils/fileutils.go index 706afe0d5..0125348d9 100644 --- a/src/github.com/matrix-org/dendrite/mediaapi/fileutils/fileutils.go +++ b/src/github.com/matrix-org/dendrite/mediaapi/fileutils/fileutils.go @@ -25,9 +25,9 @@ import ( "path/filepath" "strings" - log "github.com/Sirupsen/logrus" "github.com/matrix-org/dendrite/common/config" "github.com/matrix-org/dendrite/mediaapi/types" + log "github.com/sirupsen/logrus" ) // GetPathFromBase64Hash evaluates the path to a media file from its Base64Hash diff --git a/src/github.com/matrix-org/dendrite/mediaapi/thumbnailer/thumbnailer.go b/src/github.com/matrix-org/dendrite/mediaapi/thumbnailer/thumbnailer.go index ded71b651..5a0913ab2 100644 --- a/src/github.com/matrix-org/dendrite/mediaapi/thumbnailer/thumbnailer.go +++ b/src/github.com/matrix-org/dendrite/mediaapi/thumbnailer/thumbnailer.go @@ -21,10 +21,10 @@ import ( "path/filepath" "sync" - log "github.com/Sirupsen/logrus" "github.com/matrix-org/dendrite/common/config" "github.com/matrix-org/dendrite/mediaapi/storage" "github.com/matrix-org/dendrite/mediaapi/types" + log "github.com/sirupsen/logrus" ) type thumbnailFitness struct { diff --git a/src/github.com/matrix-org/dendrite/mediaapi/thumbnailer/thumbnailer_bimg.go b/src/github.com/matrix-org/dendrite/mediaapi/thumbnailer/thumbnailer_bimg.go index ad3b8b00d..34181ef11 100644 --- a/src/github.com/matrix-org/dendrite/mediaapi/thumbnailer/thumbnailer_bimg.go +++ b/src/github.com/matrix-org/dendrite/mediaapi/thumbnailer/thumbnailer_bimg.go @@ -20,10 +20,10 @@ import ( "os" "time" - log "github.com/Sirupsen/logrus" "github.com/matrix-org/dendrite/common/config" "github.com/matrix-org/dendrite/mediaapi/storage" "github.com/matrix-org/dendrite/mediaapi/types" + log "github.com/sirupsen/logrus" "gopkg.in/h2non/bimg.v1" ) diff --git a/src/github.com/matrix-org/dendrite/mediaapi/thumbnailer/thumbnailer_nfnt.go b/src/github.com/matrix-org/dendrite/mediaapi/thumbnailer/thumbnailer_nfnt.go index 3e822dd02..86e466f8c 100644 --- a/src/github.com/matrix-org/dendrite/mediaapi/thumbnailer/thumbnailer_nfnt.go +++ b/src/github.com/matrix-org/dendrite/mediaapi/thumbnailer/thumbnailer_nfnt.go @@ -27,11 +27,11 @@ import ( "os" "time" - log "github.com/Sirupsen/logrus" "github.com/matrix-org/dendrite/common/config" "github.com/matrix-org/dendrite/mediaapi/storage" "github.com/matrix-org/dendrite/mediaapi/types" "github.com/nfnt/resize" + log "github.com/sirupsen/logrus" ) // GenerateThumbnails generates the configured thumbnail sizes for the source file diff --git a/src/github.com/matrix-org/dendrite/mediaapi/writers/download.go b/src/github.com/matrix-org/dendrite/mediaapi/writers/download.go index 8066327ca..6186e24fb 100644 --- a/src/github.com/matrix-org/dendrite/mediaapi/writers/download.go +++ b/src/github.com/matrix-org/dendrite/mediaapi/writers/download.go @@ -27,7 +27,6 @@ import ( "strings" "sync" - log "github.com/Sirupsen/logrus" "github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/common/config" "github.com/matrix-org/dendrite/mediaapi/fileutils" @@ -36,6 +35,7 @@ import ( "github.com/matrix-org/dendrite/mediaapi/types" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/util" + log "github.com/sirupsen/logrus" ) const mediaIDCharacters = "A-Za-z0-9_=-" diff --git a/src/github.com/matrix-org/dendrite/mediaapi/writers/upload.go b/src/github.com/matrix-org/dendrite/mediaapi/writers/upload.go index eaea8561e..aa932b53e 100644 --- a/src/github.com/matrix-org/dendrite/mediaapi/writers/upload.go +++ b/src/github.com/matrix-org/dendrite/mediaapi/writers/upload.go @@ -21,7 +21,6 @@ import ( "net/url" "path" - log "github.com/Sirupsen/logrus" "github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/common/config" "github.com/matrix-org/dendrite/mediaapi/fileutils" @@ -30,6 +29,7 @@ import ( "github.com/matrix-org/dendrite/mediaapi/types" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/util" + log "github.com/sirupsen/logrus" ) // uploadRequest metadata included in or derivable from an upload request diff --git a/src/github.com/matrix-org/dendrite/publicroomsapi/consumers/roomserver.go b/src/github.com/matrix-org/dendrite/publicroomsapi/consumers/roomserver.go index 959151052..285fa9372 100644 --- a/src/github.com/matrix-org/dendrite/publicroomsapi/consumers/roomserver.go +++ b/src/github.com/matrix-org/dendrite/publicroomsapi/consumers/roomserver.go @@ -17,11 +17,11 @@ package consumers import ( "encoding/json" - log "github.com/Sirupsen/logrus" "github.com/matrix-org/dendrite/common" "github.com/matrix-org/dendrite/common/config" "github.com/matrix-org/dendrite/publicroomsapi/storage" "github.com/matrix-org/dendrite/roomserver/api" + log "github.com/sirupsen/logrus" sarama "gopkg.in/Shopify/sarama.v1" ) diff --git a/src/github.com/matrix-org/dendrite/syncapi/consumers/clientapi.go b/src/github.com/matrix-org/dendrite/syncapi/consumers/clientapi.go index 7cc38b815..afe74aed3 100644 --- a/src/github.com/matrix-org/dendrite/syncapi/consumers/clientapi.go +++ b/src/github.com/matrix-org/dendrite/syncapi/consumers/clientapi.go @@ -17,11 +17,11 @@ package consumers import ( "encoding/json" - log "github.com/Sirupsen/logrus" "github.com/matrix-org/dendrite/common" "github.com/matrix-org/dendrite/common/config" "github.com/matrix-org/dendrite/syncapi/storage" "github.com/matrix-org/dendrite/syncapi/sync" + log "github.com/sirupsen/logrus" sarama "gopkg.in/Shopify/sarama.v1" ) diff --git a/src/github.com/matrix-org/dendrite/syncapi/consumers/roomserver.go b/src/github.com/matrix-org/dendrite/syncapi/consumers/roomserver.go index 373577894..759050d09 100644 --- a/src/github.com/matrix-org/dendrite/syncapi/consumers/roomserver.go +++ b/src/github.com/matrix-org/dendrite/syncapi/consumers/roomserver.go @@ -18,7 +18,6 @@ import ( "encoding/json" "fmt" - log "github.com/Sirupsen/logrus" "github.com/matrix-org/dendrite/common" "github.com/matrix-org/dendrite/common/config" "github.com/matrix-org/dendrite/roomserver/api" @@ -26,6 +25,7 @@ import ( "github.com/matrix-org/dendrite/syncapi/sync" "github.com/matrix-org/dendrite/syncapi/types" "github.com/matrix-org/gomatrixserverlib" + log "github.com/sirupsen/logrus" sarama "gopkg.in/Shopify/sarama.v1" ) diff --git a/src/github.com/matrix-org/dendrite/syncapi/storage/output_room_events_table.go b/src/github.com/matrix-org/dendrite/syncapi/storage/output_room_events_table.go index 93774d1f1..2afab341d 100644 --- a/src/github.com/matrix-org/dendrite/syncapi/storage/output_room_events_table.go +++ b/src/github.com/matrix-org/dendrite/syncapi/storage/output_room_events_table.go @@ -17,11 +17,11 @@ package storage import ( "database/sql" - log "github.com/Sirupsen/logrus" "github.com/lib/pq" "github.com/matrix-org/dendrite/common" "github.com/matrix-org/dendrite/syncapi/types" "github.com/matrix-org/gomatrixserverlib" + log "github.com/sirupsen/logrus" ) const outputRoomEventsSchema = ` diff --git a/src/github.com/matrix-org/dendrite/syncapi/sync/notifier.go b/src/github.com/matrix-org/dendrite/syncapi/sync/notifier.go index 2fa4279c1..102e42311 100644 --- a/src/github.com/matrix-org/dendrite/syncapi/sync/notifier.go +++ b/src/github.com/matrix-org/dendrite/syncapi/sync/notifier.go @@ -17,10 +17,10 @@ package sync import ( "sync" - log "github.com/Sirupsen/logrus" "github.com/matrix-org/dendrite/syncapi/storage" "github.com/matrix-org/dendrite/syncapi/types" "github.com/matrix-org/gomatrixserverlib" + log "github.com/sirupsen/logrus" ) // Notifier will wake up sleeping requests when there is some new data. diff --git a/src/github.com/matrix-org/dendrite/syncapi/sync/request.go b/src/github.com/matrix-org/dendrite/syncapi/sync/request.go index 5260a3639..dd1188241 100644 --- a/src/github.com/matrix-org/dendrite/syncapi/sync/request.go +++ b/src/github.com/matrix-org/dendrite/syncapi/sync/request.go @@ -19,9 +19,9 @@ import ( "strconv" "time" - log "github.com/Sirupsen/logrus" "github.com/matrix-org/dendrite/syncapi/types" "github.com/matrix-org/util" + log "github.com/sirupsen/logrus" ) const defaultSyncTimeout = time.Duration(30) * time.Second diff --git a/src/github.com/matrix-org/dendrite/syncapi/sync/requestpool.go b/src/github.com/matrix-org/dendrite/syncapi/sync/requestpool.go index a207b8152..cdff6caef 100644 --- a/src/github.com/matrix-org/dendrite/syncapi/sync/requestpool.go +++ b/src/github.com/matrix-org/dendrite/syncapi/sync/requestpool.go @@ -18,7 +18,6 @@ import ( "net/http" "time" - log "github.com/Sirupsen/logrus" "github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/auth/storage/accounts" "github.com/matrix-org/dendrite/clientapi/httputil" @@ -27,6 +26,7 @@ import ( "github.com/matrix-org/dendrite/syncapi/types" "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/util" + log "github.com/sirupsen/logrus" ) // RequestPool manages HTTP long-poll connections for /sync From 51d1ad692ccd0353ddeecd359f07dc4913926c6c Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Tue, 22 Aug 2017 17:33:05 +0100 Subject: [PATCH 3/6] Add support for prefixed logs --- .../matrix-org/dendrite/common/log.go | 35 +- vendor/manifest | 18 + .../src/github.com/mattn/go-colorable/LICENSE | 21 + .../github.com/mattn/go-colorable/README.md | 48 + .../go-colorable/_example/escape-seq/main.go | 16 + .../go-colorable/_example/logrus/main.go | 16 + .../mattn/go-colorable/_example/title/main.go | 14 + .../go-colorable/cmd/colorable/colorable.go | 12 + .../mattn/go-colorable/colorable_appengine.go | 29 + .../mattn/go-colorable/colorable_others.go | 30 + .../mattn/go-colorable/colorable_test.go | 83 ++ .../mattn/go-colorable/colorable_windows.go | 968 ++++++++++++++++++ .../mattn/go-colorable/noncolorable.go | 55 + vendor/src/github.com/mattn/go-isatty/LICENSE | 9 + .../src/github.com/mattn/go-isatty/README.md | 50 + vendor/src/github.com/mattn/go-isatty/doc.go | 2 + .../mattn/go-isatty/example_test.go | 18 + .../mattn/go-isatty/isatty_appengine.go | 15 + .../github.com/mattn/go-isatty/isatty_bsd.go | 18 + .../mattn/go-isatty/isatty_linux.go | 18 + .../mattn/go-isatty/isatty_others.go | 10 + .../mattn/go-isatty/isatty_others_test.go | 19 + .../mattn/go-isatty/isatty_solaris.go | 16 + .../mattn/go-isatty/isatty_windows.go | 94 ++ .../mattn/go-isatty/isatty_windows_test.go | 35 + vendor/src/github.com/mgutz/ansi/LICENSE | 9 + vendor/src/github.com/mgutz/ansi/README.md | 121 +++ vendor/src/github.com/mgutz/ansi/ansi.go | 285 ++++++ vendor/src/github.com/mgutz/ansi/ansi_test.go | 52 + .../mgutz/ansi/cmd/ansi-mgutz/main.go | 135 +++ vendor/src/github.com/mgutz/ansi/doc.go | 65 ++ vendor/src/github.com/mgutz/ansi/print.go | 57 ++ 32 files changed, 2365 insertions(+), 8 deletions(-) create mode 100644 vendor/src/github.com/mattn/go-colorable/LICENSE create mode 100644 vendor/src/github.com/mattn/go-colorable/README.md create mode 100644 vendor/src/github.com/mattn/go-colorable/_example/escape-seq/main.go create mode 100644 vendor/src/github.com/mattn/go-colorable/_example/logrus/main.go create mode 100644 vendor/src/github.com/mattn/go-colorable/_example/title/main.go create mode 100644 vendor/src/github.com/mattn/go-colorable/cmd/colorable/colorable.go create mode 100644 vendor/src/github.com/mattn/go-colorable/colorable_appengine.go create mode 100644 vendor/src/github.com/mattn/go-colorable/colorable_others.go create mode 100644 vendor/src/github.com/mattn/go-colorable/colorable_test.go create mode 100644 vendor/src/github.com/mattn/go-colorable/colorable_windows.go create mode 100644 vendor/src/github.com/mattn/go-colorable/noncolorable.go create mode 100644 vendor/src/github.com/mattn/go-isatty/LICENSE create mode 100644 vendor/src/github.com/mattn/go-isatty/README.md create mode 100644 vendor/src/github.com/mattn/go-isatty/doc.go create mode 100644 vendor/src/github.com/mattn/go-isatty/example_test.go create mode 100644 vendor/src/github.com/mattn/go-isatty/isatty_appengine.go create mode 100644 vendor/src/github.com/mattn/go-isatty/isatty_bsd.go create mode 100644 vendor/src/github.com/mattn/go-isatty/isatty_linux.go create mode 100644 vendor/src/github.com/mattn/go-isatty/isatty_others.go create mode 100644 vendor/src/github.com/mattn/go-isatty/isatty_others_test.go create mode 100644 vendor/src/github.com/mattn/go-isatty/isatty_solaris.go create mode 100644 vendor/src/github.com/mattn/go-isatty/isatty_windows.go create mode 100644 vendor/src/github.com/mattn/go-isatty/isatty_windows_test.go create mode 100644 vendor/src/github.com/mgutz/ansi/LICENSE create mode 100644 vendor/src/github.com/mgutz/ansi/README.md create mode 100644 vendor/src/github.com/mgutz/ansi/ansi.go create mode 100644 vendor/src/github.com/mgutz/ansi/ansi_test.go create mode 100644 vendor/src/github.com/mgutz/ansi/cmd/ansi-mgutz/main.go create mode 100644 vendor/src/github.com/mgutz/ansi/doc.go create mode 100644 vendor/src/github.com/mgutz/ansi/print.go diff --git a/src/github.com/matrix-org/dendrite/common/log.go b/src/github.com/matrix-org/dendrite/common/log.go index fbfa34783..bcd1e66b8 100644 --- a/src/github.com/matrix-org/dendrite/common/log.go +++ b/src/github.com/matrix-org/dendrite/common/log.go @@ -15,26 +15,45 @@ package common import ( + "fmt" "os" "path/filepath" + "strings" "github.com/matrix-org/dugong" + "github.com/mgutz/ansi" "github.com/sirupsen/logrus" ) -type utcFormatter struct { - logrus.Formatter +type dendriteFormatter struct { + logrus.TextFormatter } -func (f utcFormatter) Format(entry *logrus.Entry) ([]byte, error) { +func (f dendriteFormatter) Format(entry *logrus.Entry) ([]byte, error) { + if _, ok := entry.Data["prefix"]; ok { + prefix, ok := entry.Data["prefix"].(string) + if !ok { + return f.TextFormatter.Format(entry) + } + + prefix = strings.ToUpper(prefix) + + if !f.TextFormatter.DisableColors { + prefix = ansi.Color(prefix, "white+b") + } + + entry.Message = fmt.Sprintf("%s: %s", prefix, entry.Message) + delete(entry.Data, "prefix") + } + entry.Time = entry.Time.UTC() - return f.Formatter.Format(entry) + return f.TextFormatter.Format(entry) } // SetupLogging configures the logging format and destination(s). func SetupLogging(logDir string) { - logrus.SetFormatter(&utcFormatter{ - &logrus.TextFormatter{ + logrus.SetFormatter(dendriteFormatter{ + logrus.TextFormatter{ TimestampFormat: "2006-01-02T15:04:05.000000000Z07:00", FullTimestamp: true, DisableColors: false, @@ -48,8 +67,8 @@ func SetupLogging(logDir string) { filepath.Join(logDir, "info.log"), filepath.Join(logDir, "warn.log"), filepath.Join(logDir, "error.log"), - &utcFormatter{ - &logrus.TextFormatter{ + dendriteFormatter{ + logrus.TextFormatter{ TimestampFormat: "2006-01-02T15:04:05.000000000Z07:00", DisableColors: true, DisableTimestamp: false, diff --git a/vendor/manifest b/vendor/manifest index 35ff3b2de..46f16d279 100644 --- a/vendor/manifest +++ b/vendor/manifest @@ -113,6 +113,18 @@ "revision": "466baca1646be2ce6bcf3b1573296015650d9ed2", "branch": "master" }, + { + "importpath": "github.com/mattn/go-colorable", + "repository": "https://github.com/mattn/go-colorable", + "revision": "ad5389df28cdac544c99bd7b9161a0b5b6ca9d1b", + "branch": "master" + }, + { + "importpath": "github.com/mattn/go-isatty", + "repository": "https://github.com/mattn/go-isatty", + "revision": "fc9e8d8ef48496124e79ae0df75490096eccf6fe", + "branch": "master" + }, { "importpath": "github.com/matttproud/golang_protobuf_extensions/pbutil", "repository": "https://github.com/matttproud/golang_protobuf_extensions", @@ -120,6 +132,12 @@ "branch": "master", "path": "/pbutil" }, + { + "importpath": "github.com/mgutz/ansi", + "repository": "https://github.com/mgutz/ansi", + "revision": "9520e82c474b0a04dd04f8a40959027271bab992", + "branch": "master" + }, { "importpath": "github.com/nfnt/resize", "repository": "https://github.com/nfnt/resize", diff --git a/vendor/src/github.com/mattn/go-colorable/LICENSE b/vendor/src/github.com/mattn/go-colorable/LICENSE new file mode 100644 index 000000000..91b5cef30 --- /dev/null +++ b/vendor/src/github.com/mattn/go-colorable/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Yasuhiro Matsumoto + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/src/github.com/mattn/go-colorable/README.md b/vendor/src/github.com/mattn/go-colorable/README.md new file mode 100644 index 000000000..56729a92c --- /dev/null +++ b/vendor/src/github.com/mattn/go-colorable/README.md @@ -0,0 +1,48 @@ +# go-colorable + +[![Godoc Reference](https://godoc.org/github.com/mattn/go-colorable?status.svg)](http://godoc.org/github.com/mattn/go-colorable) +[![Build Status](https://travis-ci.org/mattn/go-colorable.svg?branch=master)](https://travis-ci.org/mattn/go-colorable) +[![Coverage Status](https://coveralls.io/repos/github/mattn/go-colorable/badge.svg?branch=master)](https://coveralls.io/github/mattn/go-colorable?branch=master) +[![Go Report Card](https://goreportcard.com/badge/mattn/go-colorable)](https://goreportcard.com/report/mattn/go-colorable) + +Colorable writer for windows. + +For example, most of logger packages doesn't show colors on windows. (I know we can do it with ansicon. But I don't want.) +This package is possible to handle escape sequence for ansi color on windows. + +## Too Bad! + +![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/bad.png) + + +## So Good! + +![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/good.png) + +## Usage + +```go +logrus.SetFormatter(&logrus.TextFormatter{ForceColors: true}) +logrus.SetOutput(colorable.NewColorableStdout()) + +logrus.Info("succeeded") +logrus.Warn("not correct") +logrus.Error("something error") +logrus.Fatal("panic") +``` + +You can compile above code on non-windows OSs. + +## Installation + +``` +$ go get github.com/mattn/go-colorable +``` + +# License + +MIT + +# Author + +Yasuhiro Matsumoto (a.k.a mattn) diff --git a/vendor/src/github.com/mattn/go-colorable/_example/escape-seq/main.go b/vendor/src/github.com/mattn/go-colorable/_example/escape-seq/main.go new file mode 100644 index 000000000..8cbcb9097 --- /dev/null +++ b/vendor/src/github.com/mattn/go-colorable/_example/escape-seq/main.go @@ -0,0 +1,16 @@ +package main + +import ( + "bufio" + "fmt" + + "github.com/mattn/go-colorable" +) + +func main() { + stdOut := bufio.NewWriter(colorable.NewColorableStdout()) + + fmt.Fprint(stdOut, "\x1B[3GMove to 3rd Column\n") + fmt.Fprint(stdOut, "\x1B[1;2HMove to 2nd Column on 1st Line\n") + stdOut.Flush() +} diff --git a/vendor/src/github.com/mattn/go-colorable/_example/logrus/main.go b/vendor/src/github.com/mattn/go-colorable/_example/logrus/main.go new file mode 100644 index 000000000..c569164b2 --- /dev/null +++ b/vendor/src/github.com/mattn/go-colorable/_example/logrus/main.go @@ -0,0 +1,16 @@ +package main + +import ( + "github.com/mattn/go-colorable" + "github.com/sirupsen/logrus" +) + +func main() { + logrus.SetFormatter(&logrus.TextFormatter{ForceColors: true}) + logrus.SetOutput(colorable.NewColorableStdout()) + + logrus.Info("succeeded") + logrus.Warn("not correct") + logrus.Error("something error") + logrus.Fatal("panic") +} diff --git a/vendor/src/github.com/mattn/go-colorable/_example/title/main.go b/vendor/src/github.com/mattn/go-colorable/_example/title/main.go new file mode 100644 index 000000000..e208870e7 --- /dev/null +++ b/vendor/src/github.com/mattn/go-colorable/_example/title/main.go @@ -0,0 +1,14 @@ +package main + +import ( + "fmt" + "os" + . "github.com/mattn/go-colorable" +) + +func main() { + out := NewColorableStdout() + fmt.Fprint(out, "\x1B]0;TITLE Changed\007(See title and hit any key)") + var c [1]byte + os.Stdin.Read(c[:]) +} diff --git a/vendor/src/github.com/mattn/go-colorable/cmd/colorable/colorable.go b/vendor/src/github.com/mattn/go-colorable/cmd/colorable/colorable.go new file mode 100644 index 000000000..87904774c --- /dev/null +++ b/vendor/src/github.com/mattn/go-colorable/cmd/colorable/colorable.go @@ -0,0 +1,12 @@ +package main + +import ( + "io" + "os" + + "github.com/mattn/go-colorable" +) + +func main() { + io.Copy(colorable.NewColorableStdout(), os.Stdin) +} diff --git a/vendor/src/github.com/mattn/go-colorable/colorable_appengine.go b/vendor/src/github.com/mattn/go-colorable/colorable_appengine.go new file mode 100644 index 000000000..1f28d773d --- /dev/null +++ b/vendor/src/github.com/mattn/go-colorable/colorable_appengine.go @@ -0,0 +1,29 @@ +// +build appengine + +package colorable + +import ( + "io" + "os" + + _ "github.com/mattn/go-isatty" +) + +// NewColorable return new instance of Writer which handle escape sequence. +func NewColorable(file *os.File) io.Writer { + if file == nil { + panic("nil passed instead of *os.File to NewColorable()") + } + + return file +} + +// NewColorableStdout return new instance of Writer which handle escape sequence for stdout. +func NewColorableStdout() io.Writer { + return os.Stdout +} + +// NewColorableStderr return new instance of Writer which handle escape sequence for stderr. +func NewColorableStderr() io.Writer { + return os.Stderr +} diff --git a/vendor/src/github.com/mattn/go-colorable/colorable_others.go b/vendor/src/github.com/mattn/go-colorable/colorable_others.go new file mode 100644 index 000000000..887f203dc --- /dev/null +++ b/vendor/src/github.com/mattn/go-colorable/colorable_others.go @@ -0,0 +1,30 @@ +// +build !windows +// +build !appengine + +package colorable + +import ( + "io" + "os" + + _ "github.com/mattn/go-isatty" +) + +// NewColorable return new instance of Writer which handle escape sequence. +func NewColorable(file *os.File) io.Writer { + if file == nil { + panic("nil passed instead of *os.File to NewColorable()") + } + + return file +} + +// NewColorableStdout return new instance of Writer which handle escape sequence for stdout. +func NewColorableStdout() io.Writer { + return os.Stdout +} + +// NewColorableStderr return new instance of Writer which handle escape sequence for stderr. +func NewColorableStderr() io.Writer { + return os.Stderr +} diff --git a/vendor/src/github.com/mattn/go-colorable/colorable_test.go b/vendor/src/github.com/mattn/go-colorable/colorable_test.go new file mode 100644 index 000000000..3069869a3 --- /dev/null +++ b/vendor/src/github.com/mattn/go-colorable/colorable_test.go @@ -0,0 +1,83 @@ +package colorable + +import ( + "bytes" + "os" + "runtime" + "testing" +) + +// checkEncoding checks that colorable is output encoding agnostic as long as +// the encoding is a superset of ASCII. This implies that one byte not part of +// an ANSI sequence must give exactly one byte in output +func checkEncoding(t *testing.T, data []byte) { + // Send non-UTF8 data to colorable + b := bytes.NewBuffer(make([]byte, 0, 10)) + if b.Len() != 0 { + t.FailNow() + } + // TODO move colorable wrapping outside the test + c := NewNonColorable(b) + c.Write(data) + if b.Len() != len(data) { + t.Fatalf("%d bytes expected, got %d", len(data), b.Len()) + } +} + +func TestEncoding(t *testing.T) { + checkEncoding(t, []byte{}) // Empty + checkEncoding(t, []byte(`abc`)) // "abc" + checkEncoding(t, []byte(`é`)) // "é" in UTF-8 + checkEncoding(t, []byte{233}) // 'é' in Latin-1 +} + +func TestNonColorable(t *testing.T) { + var buf bytes.Buffer + want := "hello" + NewNonColorable(&buf).Write([]byte("\x1b[0m" + want + "\x1b[2J")) + got := buf.String() + if got != "hello" { + t.Fatalf("want %q but %q", want, got) + } + + buf.Reset() + NewNonColorable(&buf).Write([]byte("\x1b[")) + got = buf.String() + if got != "" { + t.Fatalf("want %q but %q", "", got) + } +} + +func TestNonColorableNil(t *testing.T) { + paniced := false + func() { + defer func() { + recover() + paniced = true + }() + NewNonColorable(nil) + NewColorable(nil) + }() + + if !paniced { + t.Fatalf("should panic") + } +} + +func TestColorable(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skipf("skip this test on windows") + } + _, ok := NewColorableStdout().(*os.File) + if !ok { + t.Fatalf("should os.Stdout on UNIX") + } + _, ok = NewColorableStderr().(*os.File) + if !ok { + t.Fatalf("should os.Stdout on UNIX") + } + _, ok = NewColorable(os.Stdout).(*os.File) + if !ok { + t.Fatalf("should os.Stdout on UNIX") + } +} diff --git a/vendor/src/github.com/mattn/go-colorable/colorable_windows.go b/vendor/src/github.com/mattn/go-colorable/colorable_windows.go new file mode 100644 index 000000000..15a014fd3 --- /dev/null +++ b/vendor/src/github.com/mattn/go-colorable/colorable_windows.go @@ -0,0 +1,968 @@ +// +build windows +// +build !appengine + +package colorable + +import ( + "bytes" + "io" + "math" + "os" + "strconv" + "strings" + "syscall" + "unsafe" + + "github.com/mattn/go-isatty" +) + +const ( + foregroundBlue = 0x1 + foregroundGreen = 0x2 + foregroundRed = 0x4 + foregroundIntensity = 0x8 + foregroundMask = (foregroundRed | foregroundBlue | foregroundGreen | foregroundIntensity) + backgroundBlue = 0x10 + backgroundGreen = 0x20 + backgroundRed = 0x40 + backgroundIntensity = 0x80 + backgroundMask = (backgroundRed | backgroundBlue | backgroundGreen | backgroundIntensity) +) + +const ( + genericRead = 0x80000000 + genericWrite = 0x40000000 +) + +const ( + consoleTextmodeBuffer = 0x1 +) + +type wchar uint16 +type short int16 +type dword uint32 +type word uint16 + +type coord struct { + x short + y short +} + +type smallRect struct { + left short + top short + right short + bottom short +} + +type consoleScreenBufferInfo struct { + size coord + cursorPosition coord + attributes word + window smallRect + maximumWindowSize coord +} + +type consoleCursorInfo struct { + size dword + visible int32 +} + +var ( + kernel32 = syscall.NewLazyDLL("kernel32.dll") + procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo") + procSetConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute") + procSetConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition") + procFillConsoleOutputCharacter = kernel32.NewProc("FillConsoleOutputCharacterW") + procFillConsoleOutputAttribute = kernel32.NewProc("FillConsoleOutputAttribute") + procGetConsoleCursorInfo = kernel32.NewProc("GetConsoleCursorInfo") + procSetConsoleCursorInfo = kernel32.NewProc("SetConsoleCursorInfo") + procSetConsoleTitle = kernel32.NewProc("SetConsoleTitleW") + procCreateConsoleScreenBuffer = kernel32.NewProc("CreateConsoleScreenBuffer") +) + +// Writer provide colorable Writer to the console +type Writer struct { + out io.Writer + handle syscall.Handle + althandle syscall.Handle + oldattr word + oldpos coord + rest bytes.Buffer +} + +// NewColorable return new instance of Writer which handle escape sequence from File. +func NewColorable(file *os.File) io.Writer { + if file == nil { + panic("nil passed instead of *os.File to NewColorable()") + } + + if isatty.IsTerminal(file.Fd()) { + var csbi consoleScreenBufferInfo + handle := syscall.Handle(file.Fd()) + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + return &Writer{out: file, handle: handle, oldattr: csbi.attributes, oldpos: coord{0, 0}} + } + return file +} + +// NewColorableStdout return new instance of Writer which handle escape sequence for stdout. +func NewColorableStdout() io.Writer { + return NewColorable(os.Stdout) +} + +// NewColorableStderr return new instance of Writer which handle escape sequence for stderr. +func NewColorableStderr() io.Writer { + return NewColorable(os.Stderr) +} + +var color256 = map[int]int{ + 0: 0x000000, + 1: 0x800000, + 2: 0x008000, + 3: 0x808000, + 4: 0x000080, + 5: 0x800080, + 6: 0x008080, + 7: 0xc0c0c0, + 8: 0x808080, + 9: 0xff0000, + 10: 0x00ff00, + 11: 0xffff00, + 12: 0x0000ff, + 13: 0xff00ff, + 14: 0x00ffff, + 15: 0xffffff, + 16: 0x000000, + 17: 0x00005f, + 18: 0x000087, + 19: 0x0000af, + 20: 0x0000d7, + 21: 0x0000ff, + 22: 0x005f00, + 23: 0x005f5f, + 24: 0x005f87, + 25: 0x005faf, + 26: 0x005fd7, + 27: 0x005fff, + 28: 0x008700, + 29: 0x00875f, + 30: 0x008787, + 31: 0x0087af, + 32: 0x0087d7, + 33: 0x0087ff, + 34: 0x00af00, + 35: 0x00af5f, + 36: 0x00af87, + 37: 0x00afaf, + 38: 0x00afd7, + 39: 0x00afff, + 40: 0x00d700, + 41: 0x00d75f, + 42: 0x00d787, + 43: 0x00d7af, + 44: 0x00d7d7, + 45: 0x00d7ff, + 46: 0x00ff00, + 47: 0x00ff5f, + 48: 0x00ff87, + 49: 0x00ffaf, + 50: 0x00ffd7, + 51: 0x00ffff, + 52: 0x5f0000, + 53: 0x5f005f, + 54: 0x5f0087, + 55: 0x5f00af, + 56: 0x5f00d7, + 57: 0x5f00ff, + 58: 0x5f5f00, + 59: 0x5f5f5f, + 60: 0x5f5f87, + 61: 0x5f5faf, + 62: 0x5f5fd7, + 63: 0x5f5fff, + 64: 0x5f8700, + 65: 0x5f875f, + 66: 0x5f8787, + 67: 0x5f87af, + 68: 0x5f87d7, + 69: 0x5f87ff, + 70: 0x5faf00, + 71: 0x5faf5f, + 72: 0x5faf87, + 73: 0x5fafaf, + 74: 0x5fafd7, + 75: 0x5fafff, + 76: 0x5fd700, + 77: 0x5fd75f, + 78: 0x5fd787, + 79: 0x5fd7af, + 80: 0x5fd7d7, + 81: 0x5fd7ff, + 82: 0x5fff00, + 83: 0x5fff5f, + 84: 0x5fff87, + 85: 0x5fffaf, + 86: 0x5fffd7, + 87: 0x5fffff, + 88: 0x870000, + 89: 0x87005f, + 90: 0x870087, + 91: 0x8700af, + 92: 0x8700d7, + 93: 0x8700ff, + 94: 0x875f00, + 95: 0x875f5f, + 96: 0x875f87, + 97: 0x875faf, + 98: 0x875fd7, + 99: 0x875fff, + 100: 0x878700, + 101: 0x87875f, + 102: 0x878787, + 103: 0x8787af, + 104: 0x8787d7, + 105: 0x8787ff, + 106: 0x87af00, + 107: 0x87af5f, + 108: 0x87af87, + 109: 0x87afaf, + 110: 0x87afd7, + 111: 0x87afff, + 112: 0x87d700, + 113: 0x87d75f, + 114: 0x87d787, + 115: 0x87d7af, + 116: 0x87d7d7, + 117: 0x87d7ff, + 118: 0x87ff00, + 119: 0x87ff5f, + 120: 0x87ff87, + 121: 0x87ffaf, + 122: 0x87ffd7, + 123: 0x87ffff, + 124: 0xaf0000, + 125: 0xaf005f, + 126: 0xaf0087, + 127: 0xaf00af, + 128: 0xaf00d7, + 129: 0xaf00ff, + 130: 0xaf5f00, + 131: 0xaf5f5f, + 132: 0xaf5f87, + 133: 0xaf5faf, + 134: 0xaf5fd7, + 135: 0xaf5fff, + 136: 0xaf8700, + 137: 0xaf875f, + 138: 0xaf8787, + 139: 0xaf87af, + 140: 0xaf87d7, + 141: 0xaf87ff, + 142: 0xafaf00, + 143: 0xafaf5f, + 144: 0xafaf87, + 145: 0xafafaf, + 146: 0xafafd7, + 147: 0xafafff, + 148: 0xafd700, + 149: 0xafd75f, + 150: 0xafd787, + 151: 0xafd7af, + 152: 0xafd7d7, + 153: 0xafd7ff, + 154: 0xafff00, + 155: 0xafff5f, + 156: 0xafff87, + 157: 0xafffaf, + 158: 0xafffd7, + 159: 0xafffff, + 160: 0xd70000, + 161: 0xd7005f, + 162: 0xd70087, + 163: 0xd700af, + 164: 0xd700d7, + 165: 0xd700ff, + 166: 0xd75f00, + 167: 0xd75f5f, + 168: 0xd75f87, + 169: 0xd75faf, + 170: 0xd75fd7, + 171: 0xd75fff, + 172: 0xd78700, + 173: 0xd7875f, + 174: 0xd78787, + 175: 0xd787af, + 176: 0xd787d7, + 177: 0xd787ff, + 178: 0xd7af00, + 179: 0xd7af5f, + 180: 0xd7af87, + 181: 0xd7afaf, + 182: 0xd7afd7, + 183: 0xd7afff, + 184: 0xd7d700, + 185: 0xd7d75f, + 186: 0xd7d787, + 187: 0xd7d7af, + 188: 0xd7d7d7, + 189: 0xd7d7ff, + 190: 0xd7ff00, + 191: 0xd7ff5f, + 192: 0xd7ff87, + 193: 0xd7ffaf, + 194: 0xd7ffd7, + 195: 0xd7ffff, + 196: 0xff0000, + 197: 0xff005f, + 198: 0xff0087, + 199: 0xff00af, + 200: 0xff00d7, + 201: 0xff00ff, + 202: 0xff5f00, + 203: 0xff5f5f, + 204: 0xff5f87, + 205: 0xff5faf, + 206: 0xff5fd7, + 207: 0xff5fff, + 208: 0xff8700, + 209: 0xff875f, + 210: 0xff8787, + 211: 0xff87af, + 212: 0xff87d7, + 213: 0xff87ff, + 214: 0xffaf00, + 215: 0xffaf5f, + 216: 0xffaf87, + 217: 0xffafaf, + 218: 0xffafd7, + 219: 0xffafff, + 220: 0xffd700, + 221: 0xffd75f, + 222: 0xffd787, + 223: 0xffd7af, + 224: 0xffd7d7, + 225: 0xffd7ff, + 226: 0xffff00, + 227: 0xffff5f, + 228: 0xffff87, + 229: 0xffffaf, + 230: 0xffffd7, + 231: 0xffffff, + 232: 0x080808, + 233: 0x121212, + 234: 0x1c1c1c, + 235: 0x262626, + 236: 0x303030, + 237: 0x3a3a3a, + 238: 0x444444, + 239: 0x4e4e4e, + 240: 0x585858, + 241: 0x626262, + 242: 0x6c6c6c, + 243: 0x767676, + 244: 0x808080, + 245: 0x8a8a8a, + 246: 0x949494, + 247: 0x9e9e9e, + 248: 0xa8a8a8, + 249: 0xb2b2b2, + 250: 0xbcbcbc, + 251: 0xc6c6c6, + 252: 0xd0d0d0, + 253: 0xdadada, + 254: 0xe4e4e4, + 255: 0xeeeeee, +} + +// `\033]0;TITLESTR\007` +func doTitleSequence(er *bytes.Reader) error { + var c byte + var err error + + c, err = er.ReadByte() + if err != nil { + return err + } + if c != '0' && c != '2' { + return nil + } + c, err = er.ReadByte() + if err != nil { + return err + } + if c != ';' { + return nil + } + title := make([]byte, 0, 80) + for { + c, err = er.ReadByte() + if err != nil { + return err + } + if c == 0x07 || c == '\n' { + break + } + title = append(title, c) + } + if len(title) > 0 { + title8, err := syscall.UTF16PtrFromString(string(title)) + if err == nil { + procSetConsoleTitle.Call(uintptr(unsafe.Pointer(title8))) + } + } + return nil +} + +// Write write data on console +func (w *Writer) Write(data []byte) (n int, err error) { + var csbi consoleScreenBufferInfo + procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) + + handle := w.handle + + var er *bytes.Reader + if w.rest.Len() > 0 { + var rest bytes.Buffer + w.rest.WriteTo(&rest) + w.rest.Reset() + rest.Write(data) + er = bytes.NewReader(rest.Bytes()) + } else { + er = bytes.NewReader(data) + } + var bw [1]byte +loop: + for { + c1, err := er.ReadByte() + if err != nil { + break loop + } + if c1 != 0x1b { + bw[0] = c1 + w.out.Write(bw[:]) + continue + } + c2, err := er.ReadByte() + if err != nil { + break loop + } + + if c2 == ']' { + w.rest.WriteByte(c1) + w.rest.WriteByte(c2) + er.WriteTo(&w.rest) + if bytes.IndexByte(w.rest.Bytes(), 0x07) == -1 { + break loop + } + er = bytes.NewReader(w.rest.Bytes()[2:]) + err := doTitleSequence(er) + if err != nil { + break loop + } + w.rest.Reset() + continue + } + if c2 != 0x5b { + continue + } + + w.rest.WriteByte(c1) + w.rest.WriteByte(c2) + er.WriteTo(&w.rest) + + var buf bytes.Buffer + var m byte + for i, c := range w.rest.Bytes()[2:] { + if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' { + m = c + er = bytes.NewReader(w.rest.Bytes()[2+i+1:]) + w.rest.Reset() + break + } + buf.Write([]byte(string(c))) + } + if m == 0 { + break loop + } + + switch m { + case 'A': + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.y -= short(n) + procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'B': + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.y += short(n) + procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'C': + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.x += short(n) + procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'D': + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.x -= short(n) + if csbi.cursorPosition.x < 0 { + csbi.cursorPosition.x = 0 + } + procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'E': + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.x = 0 + csbi.cursorPosition.y += short(n) + procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'F': + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.x = 0 + csbi.cursorPosition.y -= short(n) + procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'G': + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + csbi.cursorPosition.x = short(n - 1) + procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'H', 'f': + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + if buf.Len() > 0 { + token := strings.Split(buf.String(), ";") + switch len(token) { + case 1: + n1, err := strconv.Atoi(token[0]) + if err != nil { + continue + } + csbi.cursorPosition.y = short(n1 - 1) + case 2: + n1, err := strconv.Atoi(token[0]) + if err != nil { + continue + } + n2, err := strconv.Atoi(token[1]) + if err != nil { + continue + } + csbi.cursorPosition.x = short(n2 - 1) + csbi.cursorPosition.y = short(n1 - 1) + } + } else { + csbi.cursorPosition.y = 0 + } + procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) + case 'J': + n := 0 + if buf.Len() > 0 { + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + } + var count, written dword + var cursor coord + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + switch n { + case 0: + cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y} + count = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.size.y-csbi.cursorPosition.y)*csbi.size.x) + case 1: + cursor = coord{x: csbi.window.left, y: csbi.window.top} + count = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.window.top-csbi.cursorPosition.y)*csbi.size.x) + case 2: + cursor = coord{x: csbi.window.left, y: csbi.window.top} + count = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.size.y-csbi.cursorPosition.y)*csbi.size.x) + } + procFillConsoleOutputCharacter.Call(uintptr(handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) + procFillConsoleOutputAttribute.Call(uintptr(handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) + case 'K': + n := 0 + if buf.Len() > 0 { + n, err = strconv.Atoi(buf.String()) + if err != nil { + continue + } + } + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + var cursor coord + var count, written dword + switch n { + case 0: + cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y} + count = dword(csbi.size.x - csbi.cursorPosition.x) + case 1: + cursor = coord{x: csbi.window.left, y: csbi.window.top + csbi.cursorPosition.y} + count = dword(csbi.size.x - csbi.cursorPosition.x) + case 2: + cursor = coord{x: csbi.window.left, y: csbi.window.top + csbi.cursorPosition.y} + count = dword(csbi.size.x) + } + procFillConsoleOutputCharacter.Call(uintptr(handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) + procFillConsoleOutputAttribute.Call(uintptr(handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) + case 'm': + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + attr := csbi.attributes + cs := buf.String() + if cs == "" { + procSetConsoleTextAttribute.Call(uintptr(handle), uintptr(w.oldattr)) + continue + } + token := strings.Split(cs, ";") + for i := 0; i < len(token); i++ { + ns := token[i] + if n, err = strconv.Atoi(ns); err == nil { + switch { + case n == 0 || n == 100: + attr = w.oldattr + case 1 <= n && n <= 5: + attr |= foregroundIntensity + case n == 7: + attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4) + case n == 22 || n == 25: + attr |= foregroundIntensity + case n == 27: + attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4) + case 30 <= n && n <= 37: + attr &= backgroundMask + if (n-30)&1 != 0 { + attr |= foregroundRed + } + if (n-30)&2 != 0 { + attr |= foregroundGreen + } + if (n-30)&4 != 0 { + attr |= foregroundBlue + } + case n == 38: // set foreground color. + if i < len(token)-2 && (token[i+1] == "5" || token[i+1] == "05") { + if n256, err := strconv.Atoi(token[i+2]); err == nil { + if n256foreAttr == nil { + n256setup() + } + attr &= backgroundMask + attr |= n256foreAttr[n256] + i += 2 + } + } else if len(token) == 5 && token[i+1] == "2" { + var r, g, b int + r, _ = strconv.Atoi(token[i+2]) + g, _ = strconv.Atoi(token[i+3]) + b, _ = strconv.Atoi(token[i+4]) + i += 4 + if r > 127 { + attr |= foregroundRed + } + if g > 127 { + attr |= foregroundGreen + } + if b > 127 { + attr |= foregroundBlue + } + } else { + attr = attr & (w.oldattr & backgroundMask) + } + case n == 39: // reset foreground color. + attr &= backgroundMask + attr |= w.oldattr & foregroundMask + case 40 <= n && n <= 47: + attr &= foregroundMask + if (n-40)&1 != 0 { + attr |= backgroundRed + } + if (n-40)&2 != 0 { + attr |= backgroundGreen + } + if (n-40)&4 != 0 { + attr |= backgroundBlue + } + case n == 48: // set background color. + if i < len(token)-2 && token[i+1] == "5" { + if n256, err := strconv.Atoi(token[i+2]); err == nil { + if n256backAttr == nil { + n256setup() + } + attr &= foregroundMask + attr |= n256backAttr[n256] + i += 2 + } + } else if len(token) == 5 && token[i+1] == "2" { + var r, g, b int + r, _ = strconv.Atoi(token[i+2]) + g, _ = strconv.Atoi(token[i+3]) + b, _ = strconv.Atoi(token[i+4]) + i += 4 + if r > 127 { + attr |= backgroundRed + } + if g > 127 { + attr |= backgroundGreen + } + if b > 127 { + attr |= backgroundBlue + } + } else { + attr = attr & (w.oldattr & foregroundMask) + } + case n == 49: // reset foreground color. + attr &= foregroundMask + attr |= w.oldattr & backgroundMask + case 90 <= n && n <= 97: + attr = (attr & backgroundMask) + attr |= foregroundIntensity + if (n-90)&1 != 0 { + attr |= foregroundRed + } + if (n-90)&2 != 0 { + attr |= foregroundGreen + } + if (n-90)&4 != 0 { + attr |= foregroundBlue + } + case 100 <= n && n <= 107: + attr = (attr & foregroundMask) + attr |= backgroundIntensity + if (n-100)&1 != 0 { + attr |= backgroundRed + } + if (n-100)&2 != 0 { + attr |= backgroundGreen + } + if (n-100)&4 != 0 { + attr |= backgroundBlue + } + } + procSetConsoleTextAttribute.Call(uintptr(handle), uintptr(attr)) + } + } + case 'h': + var ci consoleCursorInfo + cs := buf.String() + if cs == "5>" { + procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) + ci.visible = 0 + procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) + } else if cs == "?25" { + procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) + ci.visible = 1 + procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) + } else if cs == "?1049" { + if w.althandle == 0 { + h, _, _ := procCreateConsoleScreenBuffer.Call(uintptr(genericRead|genericWrite), 0, 0, uintptr(consoleTextmodeBuffer), 0, 0) + w.althandle = syscall.Handle(h) + if w.althandle != 0 { + handle = w.althandle + } + } + } + case 'l': + var ci consoleCursorInfo + cs := buf.String() + if cs == "5>" { + procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) + ci.visible = 1 + procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) + } else if cs == "?25" { + procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) + ci.visible = 0 + procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) + } else if cs == "?1049" { + if w.althandle != 0 { + syscall.CloseHandle(w.althandle) + w.althandle = 0 + handle = w.handle + } + } + case 's': + procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + w.oldpos = csbi.cursorPosition + case 'u': + procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&w.oldpos))) + } + } + + return len(data), nil +} + +type consoleColor struct { + rgb int + red bool + green bool + blue bool + intensity bool +} + +func (c consoleColor) foregroundAttr() (attr word) { + if c.red { + attr |= foregroundRed + } + if c.green { + attr |= foregroundGreen + } + if c.blue { + attr |= foregroundBlue + } + if c.intensity { + attr |= foregroundIntensity + } + return +} + +func (c consoleColor) backgroundAttr() (attr word) { + if c.red { + attr |= backgroundRed + } + if c.green { + attr |= backgroundGreen + } + if c.blue { + attr |= backgroundBlue + } + if c.intensity { + attr |= backgroundIntensity + } + return +} + +var color16 = []consoleColor{ + {0x000000, false, false, false, false}, + {0x000080, false, false, true, false}, + {0x008000, false, true, false, false}, + {0x008080, false, true, true, false}, + {0x800000, true, false, false, false}, + {0x800080, true, false, true, false}, + {0x808000, true, true, false, false}, + {0xc0c0c0, true, true, true, false}, + {0x808080, false, false, false, true}, + {0x0000ff, false, false, true, true}, + {0x00ff00, false, true, false, true}, + {0x00ffff, false, true, true, true}, + {0xff0000, true, false, false, true}, + {0xff00ff, true, false, true, true}, + {0xffff00, true, true, false, true}, + {0xffffff, true, true, true, true}, +} + +type hsv struct { + h, s, v float32 +} + +func (a hsv) dist(b hsv) float32 { + dh := a.h - b.h + switch { + case dh > 0.5: + dh = 1 - dh + case dh < -0.5: + dh = -1 - dh + } + ds := a.s - b.s + dv := a.v - b.v + return float32(math.Sqrt(float64(dh*dh + ds*ds + dv*dv))) +} + +func toHSV(rgb int) hsv { + r, g, b := float32((rgb&0xFF0000)>>16)/256.0, + float32((rgb&0x00FF00)>>8)/256.0, + float32(rgb&0x0000FF)/256.0 + min, max := minmax3f(r, g, b) + h := max - min + if h > 0 { + if max == r { + h = (g - b) / h + if h < 0 { + h += 6 + } + } else if max == g { + h = 2 + (b-r)/h + } else { + h = 4 + (r-g)/h + } + } + h /= 6.0 + s := max - min + if max != 0 { + s /= max + } + v := max + return hsv{h: h, s: s, v: v} +} + +type hsvTable []hsv + +func toHSVTable(rgbTable []consoleColor) hsvTable { + t := make(hsvTable, len(rgbTable)) + for i, c := range rgbTable { + t[i] = toHSV(c.rgb) + } + return t +} + +func (t hsvTable) find(rgb int) consoleColor { + hsv := toHSV(rgb) + n := 7 + l := float32(5.0) + for i, p := range t { + d := hsv.dist(p) + if d < l { + l, n = d, i + } + } + return color16[n] +} + +func minmax3f(a, b, c float32) (min, max float32) { + if a < b { + if b < c { + return a, c + } else if a < c { + return a, b + } else { + return c, b + } + } else { + if a < c { + return b, c + } else if b < c { + return b, a + } else { + return c, a + } + } +} + +var n256foreAttr []word +var n256backAttr []word + +func n256setup() { + n256foreAttr = make([]word, 256) + n256backAttr = make([]word, 256) + t := toHSVTable(color16) + for i, rgb := range color256 { + c := t.find(rgb) + n256foreAttr[i] = c.foregroundAttr() + n256backAttr[i] = c.backgroundAttr() + } +} diff --git a/vendor/src/github.com/mattn/go-colorable/noncolorable.go b/vendor/src/github.com/mattn/go-colorable/noncolorable.go new file mode 100644 index 000000000..9721e16f4 --- /dev/null +++ b/vendor/src/github.com/mattn/go-colorable/noncolorable.go @@ -0,0 +1,55 @@ +package colorable + +import ( + "bytes" + "io" +) + +// NonColorable hold writer but remove escape sequence. +type NonColorable struct { + out io.Writer +} + +// NewNonColorable return new instance of Writer which remove escape sequence from Writer. +func NewNonColorable(w io.Writer) io.Writer { + return &NonColorable{out: w} +} + +// Write write data on console +func (w *NonColorable) Write(data []byte) (n int, err error) { + er := bytes.NewReader(data) + var bw [1]byte +loop: + for { + c1, err := er.ReadByte() + if err != nil { + break loop + } + if c1 != 0x1b { + bw[0] = c1 + w.out.Write(bw[:]) + continue + } + c2, err := er.ReadByte() + if err != nil { + break loop + } + if c2 != 0x5b { + continue + } + + var buf bytes.Buffer + for { + c, err := er.ReadByte() + if err != nil { + break loop + } + if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' { + break + } + buf.Write([]byte(string(c))) + } + } + + return len(data), nil +} diff --git a/vendor/src/github.com/mattn/go-isatty/LICENSE b/vendor/src/github.com/mattn/go-isatty/LICENSE new file mode 100644 index 000000000..65dc692b6 --- /dev/null +++ b/vendor/src/github.com/mattn/go-isatty/LICENSE @@ -0,0 +1,9 @@ +Copyright (c) Yasuhiro MATSUMOTO + +MIT License (Expat) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/src/github.com/mattn/go-isatty/README.md b/vendor/src/github.com/mattn/go-isatty/README.md new file mode 100644 index 000000000..1e69004bb --- /dev/null +++ b/vendor/src/github.com/mattn/go-isatty/README.md @@ -0,0 +1,50 @@ +# go-isatty + +[![Godoc Reference](https://godoc.org/github.com/mattn/go-isatty?status.svg)](http://godoc.org/github.com/mattn/go-isatty) +[![Build Status](https://travis-ci.org/mattn/go-isatty.svg?branch=master)](https://travis-ci.org/mattn/go-isatty) +[![Coverage Status](https://coveralls.io/repos/github/mattn/go-isatty/badge.svg?branch=master)](https://coveralls.io/github/mattn/go-isatty?branch=master) +[![Go Report Card](https://goreportcard.com/badge/mattn/go-isatty)](https://goreportcard.com/report/mattn/go-isatty) + +isatty for golang + +## Usage + +```go +package main + +import ( + "fmt" + "github.com/mattn/go-isatty" + "os" +) + +func main() { + if isatty.IsTerminal(os.Stdout.Fd()) { + fmt.Println("Is Terminal") + } else if isatty.IsCygwinTerminal(os.Stdout.Fd()) { + fmt.Println("Is Cygwin/MSYS2 Terminal") + } else { + fmt.Println("Is Not Terminal") + } +} +``` + +## Installation + +``` +$ go get github.com/mattn/go-isatty +``` + +## License + +MIT + +## Author + +Yasuhiro Matsumoto (a.k.a mattn) + +## Thanks + +* k-takata: base idea for IsCygwinTerminal + + https://github.com/k-takata/go-iscygpty diff --git a/vendor/src/github.com/mattn/go-isatty/doc.go b/vendor/src/github.com/mattn/go-isatty/doc.go new file mode 100644 index 000000000..17d4f90eb --- /dev/null +++ b/vendor/src/github.com/mattn/go-isatty/doc.go @@ -0,0 +1,2 @@ +// Package isatty implements interface to isatty +package isatty diff --git a/vendor/src/github.com/mattn/go-isatty/example_test.go b/vendor/src/github.com/mattn/go-isatty/example_test.go new file mode 100644 index 000000000..fa8f7e745 --- /dev/null +++ b/vendor/src/github.com/mattn/go-isatty/example_test.go @@ -0,0 +1,18 @@ +package isatty_test + +import ( + "fmt" + "os" + + "github.com/mattn/go-isatty" +) + +func Example() { + if isatty.IsTerminal(os.Stdout.Fd()) { + fmt.Println("Is Terminal") + } else if isatty.IsCygwinTerminal(os.Stdout.Fd()) { + fmt.Println("Is Cygwin/MSYS2 Terminal") + } else { + fmt.Println("Is Not Terminal") + } +} diff --git a/vendor/src/github.com/mattn/go-isatty/isatty_appengine.go b/vendor/src/github.com/mattn/go-isatty/isatty_appengine.go new file mode 100644 index 000000000..9584a9884 --- /dev/null +++ b/vendor/src/github.com/mattn/go-isatty/isatty_appengine.go @@ -0,0 +1,15 @@ +// +build appengine + +package isatty + +// IsTerminal returns true if the file descriptor is terminal which +// is always false on on appengine classic which is a sandboxed PaaS. +func IsTerminal(fd uintptr) bool { + return false +} + +// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2 +// terminal. This is also always false on this environment. +func IsCygwinTerminal(fd uintptr) bool { + return false +} diff --git a/vendor/src/github.com/mattn/go-isatty/isatty_bsd.go b/vendor/src/github.com/mattn/go-isatty/isatty_bsd.go new file mode 100644 index 000000000..42f2514d1 --- /dev/null +++ b/vendor/src/github.com/mattn/go-isatty/isatty_bsd.go @@ -0,0 +1,18 @@ +// +build darwin freebsd openbsd netbsd dragonfly +// +build !appengine + +package isatty + +import ( + "syscall" + "unsafe" +) + +const ioctlReadTermios = syscall.TIOCGETA + +// IsTerminal return true if the file descriptor is terminal. +func IsTerminal(fd uintptr) bool { + var termios syscall.Termios + _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) + return err == 0 +} diff --git a/vendor/src/github.com/mattn/go-isatty/isatty_linux.go b/vendor/src/github.com/mattn/go-isatty/isatty_linux.go new file mode 100644 index 000000000..9d24bac1d --- /dev/null +++ b/vendor/src/github.com/mattn/go-isatty/isatty_linux.go @@ -0,0 +1,18 @@ +// +build linux +// +build !appengine + +package isatty + +import ( + "syscall" + "unsafe" +) + +const ioctlReadTermios = syscall.TCGETS + +// IsTerminal return true if the file descriptor is terminal. +func IsTerminal(fd uintptr) bool { + var termios syscall.Termios + _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) + return err == 0 +} diff --git a/vendor/src/github.com/mattn/go-isatty/isatty_others.go b/vendor/src/github.com/mattn/go-isatty/isatty_others.go new file mode 100644 index 000000000..ff4de3d9a --- /dev/null +++ b/vendor/src/github.com/mattn/go-isatty/isatty_others.go @@ -0,0 +1,10 @@ +// +build !windows +// +build !appengine + +package isatty + +// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2 +// terminal. This is also always false on this environment. +func IsCygwinTerminal(fd uintptr) bool { + return false +} diff --git a/vendor/src/github.com/mattn/go-isatty/isatty_others_test.go b/vendor/src/github.com/mattn/go-isatty/isatty_others_test.go new file mode 100644 index 000000000..a2091cf47 --- /dev/null +++ b/vendor/src/github.com/mattn/go-isatty/isatty_others_test.go @@ -0,0 +1,19 @@ +// +build !windows + +package isatty + +import ( + "os" + "testing" +) + +func TestTerminal(t *testing.T) { + // test for non-panic + IsTerminal(os.Stdout.Fd()) +} + +func TestCygwinPipeName(t *testing.T) { + if IsCygwinTerminal(os.Stdout.Fd()) { + t.Fatal("should be false always") + } +} diff --git a/vendor/src/github.com/mattn/go-isatty/isatty_solaris.go b/vendor/src/github.com/mattn/go-isatty/isatty_solaris.go new file mode 100644 index 000000000..1f0c6bf53 --- /dev/null +++ b/vendor/src/github.com/mattn/go-isatty/isatty_solaris.go @@ -0,0 +1,16 @@ +// +build solaris +// +build !appengine + +package isatty + +import ( + "golang.org/x/sys/unix" +) + +// IsTerminal returns true if the given file descriptor is a terminal. +// see: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libbc/libc/gen/common/isatty.c +func IsTerminal(fd uintptr) bool { + var termio unix.Termio + err := unix.IoctlSetTermio(int(fd), unix.TCGETA, &termio) + return err == nil +} diff --git a/vendor/src/github.com/mattn/go-isatty/isatty_windows.go b/vendor/src/github.com/mattn/go-isatty/isatty_windows.go new file mode 100644 index 000000000..af51cbcaa --- /dev/null +++ b/vendor/src/github.com/mattn/go-isatty/isatty_windows.go @@ -0,0 +1,94 @@ +// +build windows +// +build !appengine + +package isatty + +import ( + "strings" + "syscall" + "unicode/utf16" + "unsafe" +) + +const ( + fileNameInfo uintptr = 2 + fileTypePipe = 3 +) + +var ( + kernel32 = syscall.NewLazyDLL("kernel32.dll") + procGetConsoleMode = kernel32.NewProc("GetConsoleMode") + procGetFileInformationByHandleEx = kernel32.NewProc("GetFileInformationByHandleEx") + procGetFileType = kernel32.NewProc("GetFileType") +) + +func init() { + // Check if GetFileInformationByHandleEx is available. + if procGetFileInformationByHandleEx.Find() != nil { + procGetFileInformationByHandleEx = nil + } +} + +// IsTerminal return true if the file descriptor is terminal. +func IsTerminal(fd uintptr) bool { + var st uint32 + r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, fd, uintptr(unsafe.Pointer(&st)), 0) + return r != 0 && e == 0 +} + +// Check pipe name is used for cygwin/msys2 pty. +// Cygwin/MSYS2 PTY has a name like: +// \{cygwin,msys}-XXXXXXXXXXXXXXXX-ptyN-{from,to}-master +func isCygwinPipeName(name string) bool { + token := strings.Split(name, "-") + if len(token) < 5 { + return false + } + + if token[0] != `\msys` && token[0] != `\cygwin` { + return false + } + + if token[1] == "" { + return false + } + + if !strings.HasPrefix(token[2], "pty") { + return false + } + + if token[3] != `from` && token[3] != `to` { + return false + } + + if token[4] != "master" { + return false + } + + return true +} + +// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2 +// terminal. +func IsCygwinTerminal(fd uintptr) bool { + if procGetFileInformationByHandleEx == nil { + return false + } + + // Cygwin/msys's pty is a pipe. + ft, _, e := syscall.Syscall(procGetFileType.Addr(), 1, fd, 0, 0) + if ft != fileTypePipe || e != 0 { + return false + } + + var buf [2 + syscall.MAX_PATH]uint16 + r, _, e := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(), + 4, fd, fileNameInfo, uintptr(unsafe.Pointer(&buf)), + uintptr(len(buf)*2), 0, 0) + if r == 0 || e != 0 { + return false + } + + l := *(*uint32)(unsafe.Pointer(&buf)) + return isCygwinPipeName(string(utf16.Decode(buf[2 : 2+l/2]))) +} diff --git a/vendor/src/github.com/mattn/go-isatty/isatty_windows_test.go b/vendor/src/github.com/mattn/go-isatty/isatty_windows_test.go new file mode 100644 index 000000000..777e8a603 --- /dev/null +++ b/vendor/src/github.com/mattn/go-isatty/isatty_windows_test.go @@ -0,0 +1,35 @@ +// +build windows + +package isatty + +import ( + "testing" +) + +func TestCygwinPipeName(t *testing.T) { + tests := []struct { + name string + result bool + }{ + {``, false}, + {`\msys-`, false}, + {`\cygwin-----`, false}, + {`\msys-x-PTY5-pty1-from-master`, false}, + {`\cygwin-x-PTY5-from-master`, false}, + {`\cygwin-x-pty2-from-toaster`, false}, + {`\cygwin--pty2-from-master`, false}, + {`\\cygwin-x-pty2-from-master`, false}, + {`\cygwin-x-pty2-from-master-`, true}, // for the feature + {`\cygwin-e022582115c10879-pty4-from-master`, true}, + {`\msys-e022582115c10879-pty4-to-master`, true}, + {`\cygwin-e022582115c10879-pty4-to-master`, true}, + } + + for _, test := range tests { + want := test.result + got := isCygwinPipeName(test.name) + if want != got { + t.Fatalf("isatty(%q): got %v, want %v:", test.name, got, want) + } + } +} diff --git a/vendor/src/github.com/mgutz/ansi/LICENSE b/vendor/src/github.com/mgutz/ansi/LICENSE new file mode 100644 index 000000000..06ce0c3b5 --- /dev/null +++ b/vendor/src/github.com/mgutz/ansi/LICENSE @@ -0,0 +1,9 @@ +The MIT License (MIT) +Copyright (c) 2013 Mario L. Gutierrez + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/vendor/src/github.com/mgutz/ansi/README.md b/vendor/src/github.com/mgutz/ansi/README.md new file mode 100644 index 000000000..8f8e20b7e --- /dev/null +++ b/vendor/src/github.com/mgutz/ansi/README.md @@ -0,0 +1,121 @@ +# ansi + +Package ansi is a small, fast library to create ANSI colored strings and codes. + +## Install + +Get it + +```sh +go get -u github.com/mgutz/ansi +``` + +## Example + +```go +import "github.com/mgutz/ansi" + +// colorize a string, SLOW +msg := ansi.Color("foo", "red+b:white") + +// create a FAST closure function to avoid computation of ANSI code +phosphorize := ansi.ColorFunc("green+h:black") +msg = phosphorize("Bring back the 80s!") +msg2 := phospohorize("Look, I'm a CRT!") + +// cache escape codes and build strings manually +lime := ansi.ColorCode("green+h:black") +reset := ansi.ColorCode("reset") + +fmt.Println(lime, "Bring back the 80s!", reset) +``` + +Other examples + +```go +Color(s, "red") // red +Color(s, "red+b") // red bold +Color(s, "red+B") // red blinking +Color(s, "red+u") // red underline +Color(s, "red+bh") // red bold bright +Color(s, "red:white") // red on white +Color(s, "red+b:white+h") // red bold on white bright +Color(s, "red+B:white+h") // red blink on white bright +Color(s, "off") // turn off ansi codes +``` + +To view color combinations, from project directory in terminal. + +```sh +go test +``` + +## Style format + +```go +"foregroundColor+attributes:backgroundColor+attributes" +``` + +Colors + +* black +* red +* green +* yellow +* blue +* magenta +* cyan +* white +* 0...255 (256 colors) + +Foreground Attributes + +* B = Blink +* b = bold +* h = high intensity (bright) +* i = inverse +* s = strikethrough +* u = underline + +Background Attributes + +* h = high intensity (bright) + +## Constants + +* ansi.Reset +* ansi.DefaultBG +* ansi.DefaultFG +* ansi.Black +* ansi.Red +* ansi.Green +* ansi.Yellow +* ansi.Blue +* ansi.Magenta +* ansi.Cyan +* ansi.White +* ansi.LightBlack +* ansi.LightRed +* ansi.LightGreen +* ansi.LightYellow +* ansi.LightBlue +* ansi.LightMagenta +* ansi.LightCyan +* ansi.LightWhite + +## References + +Wikipedia ANSI escape codes [Colors](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors) + +General [tips and formatting](http://misc.flogisoft.com/bash/tip_colors_and_formatting) + +What about support on Windows? Use [colorable by mattn](https://github.com/mattn/go-colorable). +Ansi and colorable are used by [logxi](https://github.com/mgutz/logxi) to support logging in +color on Windows. + +## MIT License + +Copyright (c) 2013 Mario Gutierrez mario@mgutz.com + +See the file LICENSE for copying permission. + diff --git a/vendor/src/github.com/mgutz/ansi/ansi.go b/vendor/src/github.com/mgutz/ansi/ansi.go new file mode 100644 index 000000000..dc0413649 --- /dev/null +++ b/vendor/src/github.com/mgutz/ansi/ansi.go @@ -0,0 +1,285 @@ +package ansi + +import ( + "bytes" + "fmt" + "strconv" + "strings" +) + +const ( + black = iota + red + green + yellow + blue + magenta + cyan + white + defaultt = 9 + + normalIntensityFG = 30 + highIntensityFG = 90 + normalIntensityBG = 40 + highIntensityBG = 100 + + start = "\033[" + bold = "1;" + blink = "5;" + underline = "4;" + inverse = "7;" + strikethrough = "9;" + + // Reset is the ANSI reset escape sequence + Reset = "\033[0m" + // DefaultBG is the default background + DefaultBG = "\033[49m" + // DefaultFG is the default foreground + DefaultFG = "\033[39m" +) + +// Black FG +var Black string + +// Red FG +var Red string + +// Green FG +var Green string + +// Yellow FG +var Yellow string + +// Blue FG +var Blue string + +// Magenta FG +var Magenta string + +// Cyan FG +var Cyan string + +// White FG +var White string + +// LightBlack FG +var LightBlack string + +// LightRed FG +var LightRed string + +// LightGreen FG +var LightGreen string + +// LightYellow FG +var LightYellow string + +// LightBlue FG +var LightBlue string + +// LightMagenta FG +var LightMagenta string + +// LightCyan FG +var LightCyan string + +// LightWhite FG +var LightWhite string + +var ( + plain = false + // Colors maps common color names to their ANSI color code. + Colors = map[string]int{ + "black": black, + "red": red, + "green": green, + "yellow": yellow, + "blue": blue, + "magenta": magenta, + "cyan": cyan, + "white": white, + "default": defaultt, + } +) + +func init() { + for i := 0; i < 256; i++ { + Colors[strconv.Itoa(i)] = i + } + + Black = ColorCode("black") + Red = ColorCode("red") + Green = ColorCode("green") + Yellow = ColorCode("yellow") + Blue = ColorCode("blue") + Magenta = ColorCode("magenta") + Cyan = ColorCode("cyan") + White = ColorCode("white") + LightBlack = ColorCode("black+h") + LightRed = ColorCode("red+h") + LightGreen = ColorCode("green+h") + LightYellow = ColorCode("yellow+h") + LightBlue = ColorCode("blue+h") + LightMagenta = ColorCode("magenta+h") + LightCyan = ColorCode("cyan+h") + LightWhite = ColorCode("white+h") +} + +// ColorCode returns the ANSI color color code for style. +func ColorCode(style string) string { + return colorCode(style).String() +} + +// Gets the ANSI color code for a style. +func colorCode(style string) *bytes.Buffer { + buf := bytes.NewBufferString("") + if plain || style == "" { + return buf + } + if style == "reset" { + buf.WriteString(Reset) + return buf + } else if style == "off" { + return buf + } + + foregroundBackground := strings.Split(style, ":") + foreground := strings.Split(foregroundBackground[0], "+") + fgKey := foreground[0] + fg := Colors[fgKey] + fgStyle := "" + if len(foreground) > 1 { + fgStyle = foreground[1] + } + + bg, bgStyle := "", "" + + if len(foregroundBackground) > 1 { + background := strings.Split(foregroundBackground[1], "+") + bg = background[0] + if len(background) > 1 { + bgStyle = background[1] + } + } + + buf.WriteString(start) + base := normalIntensityFG + if len(fgStyle) > 0 { + if strings.Contains(fgStyle, "b") { + buf.WriteString(bold) + } + if strings.Contains(fgStyle, "B") { + buf.WriteString(blink) + } + if strings.Contains(fgStyle, "u") { + buf.WriteString(underline) + } + if strings.Contains(fgStyle, "i") { + buf.WriteString(inverse) + } + if strings.Contains(fgStyle, "s") { + buf.WriteString(strikethrough) + } + if strings.Contains(fgStyle, "h") { + base = highIntensityFG + } + } + + // if 256-color + n, err := strconv.Atoi(fgKey) + if err == nil { + fmt.Fprintf(buf, "38;5;%d;", n) + } else { + fmt.Fprintf(buf, "%d;", base+fg) + } + + base = normalIntensityBG + if len(bg) > 0 { + if strings.Contains(bgStyle, "h") { + base = highIntensityBG + } + // if 256-color + n, err := strconv.Atoi(bg) + if err == nil { + fmt.Fprintf(buf, "48;5;%d;", n) + } else { + fmt.Fprintf(buf, "%d;", base+Colors[bg]) + } + } + + // remove last ";" + buf.Truncate(buf.Len() - 1) + buf.WriteRune('m') + return buf +} + +// Color colors a string based on the ANSI color code for style. +func Color(s, style string) string { + if plain || len(style) < 1 { + return s + } + buf := colorCode(style) + buf.WriteString(s) + buf.WriteString(Reset) + return buf.String() +} + +// ColorFunc creates a closure to avoid computation ANSI color code. +func ColorFunc(style string) func(string) string { + if style == "" { + return func(s string) string { + return s + } + } + color := ColorCode(style) + return func(s string) string { + if plain || s == "" { + return s + } + buf := bytes.NewBufferString(color) + buf.WriteString(s) + buf.WriteString(Reset) + result := buf.String() + return result + } +} + +// DisableColors disables ANSI color codes. The default is false (colors are on). +func DisableColors(disable bool) { + plain = disable + if plain { + Black = "" + Red = "" + Green = "" + Yellow = "" + Blue = "" + Magenta = "" + Cyan = "" + White = "" + LightBlack = "" + LightRed = "" + LightGreen = "" + LightYellow = "" + LightBlue = "" + LightMagenta = "" + LightCyan = "" + LightWhite = "" + } else { + Black = ColorCode("black") + Red = ColorCode("red") + Green = ColorCode("green") + Yellow = ColorCode("yellow") + Blue = ColorCode("blue") + Magenta = ColorCode("magenta") + Cyan = ColorCode("cyan") + White = ColorCode("white") + LightBlack = ColorCode("black+h") + LightRed = ColorCode("red+h") + LightGreen = ColorCode("green+h") + LightYellow = ColorCode("yellow+h") + LightBlue = ColorCode("blue+h") + LightMagenta = ColorCode("magenta+h") + LightCyan = ColorCode("cyan+h") + LightWhite = ColorCode("white+h") + } +} diff --git a/vendor/src/github.com/mgutz/ansi/ansi_test.go b/vendor/src/github.com/mgutz/ansi/ansi_test.go new file mode 100644 index 000000000..1630dc57c --- /dev/null +++ b/vendor/src/github.com/mgutz/ansi/ansi_test.go @@ -0,0 +1,52 @@ +package ansi + +import ( + "strings" + "testing" +) + +func TestPlain(t *testing.T) { + DisableColors(true) + PrintStyles() +} + +func TestStyles(t *testing.T) { + DisableColors(false) + PrintStyles() +} + +func TestDisableColors(t *testing.T) { + fn := ColorFunc("red") + + buf := colorCode("off") + if buf.String() != "" { + t.Fail() + } + + DisableColors(true) + if Black != "" { + t.Fail() + } + code := ColorCode("red") + if code != "" { + t.Fail() + } + s := fn("foo") + if s != "foo" { + t.Fail() + } + + DisableColors(false) + if Black == "" { + t.Fail() + } + code = ColorCode("red") + if code == "" { + t.Fail() + } + // will have escape codes around it + index := strings.Index(fn("foo"), "foo") + if index <= 0 { + t.Fail() + } +} diff --git a/vendor/src/github.com/mgutz/ansi/cmd/ansi-mgutz/main.go b/vendor/src/github.com/mgutz/ansi/cmd/ansi-mgutz/main.go new file mode 100644 index 000000000..736b45dd7 --- /dev/null +++ b/vendor/src/github.com/mgutz/ansi/cmd/ansi-mgutz/main.go @@ -0,0 +1,135 @@ +package main + +import ( + "fmt" + "sort" + "strconv" + + "github.com/mattn/go-colorable" + "github.com/mgutz/ansi" +) + +func main() { + printColors() + print256Colors() + printConstants() +} + +func pad(s string, length int) string { + for len(s) < length { + s += " " + } + return s +} + +func padColor(s string, styles []string) string { + buffer := "" + for _, style := range styles { + buffer += ansi.Color(pad(s+style, 20), s+style) + } + return buffer +} + +func printPlain() { + ansi.DisableColors(true) + bgColors := []string{ + "", + ":black", + ":red", + ":green", + ":yellow", + ":blue", + ":magenta", + ":cyan", + ":white", + } + for fg := range ansi.Colors { + for _, bg := range bgColors { + println(padColor(fg, []string{"" + bg, "+b" + bg, "+bh" + bg, "+u" + bg})) + println(padColor(fg, []string{"+uh" + bg, "+B" + bg, "+Bb" + bg /* backgrounds */, "" + bg + "+h"})) + println(padColor(fg, []string{"+b" + bg + "+h", "+bh" + bg + "+h", "+u" + bg + "+h", "+uh" + bg + "+h"})) + } + } +} + +func printColors() { + ansi.DisableColors(false) + stdout := colorable.NewColorableStdout() + + bgColors := []string{ + "", + ":black", + ":red", + ":green", + ":yellow", + ":blue", + ":magenta", + ":cyan", + ":white", + } + + keys := []string{} + for fg := range ansi.Colors { + _, err := strconv.Atoi(fg) + if err != nil { + keys = append(keys, fg) + } + } + sort.Strings(keys) + + for _, fg := range keys { + for _, bg := range bgColors { + fmt.Fprintln(stdout, padColor(fg, []string{"" + bg, "+b" + bg, "+bh" + bg, "+u" + bg})) + fmt.Fprintln(stdout, padColor(fg, []string{"+uh" + bg, "+B" + bg, "+Bb" + bg /* backgrounds */, "" + bg + "+h", "+s" + bg})) + fmt.Fprintln(stdout, padColor(fg, []string{"+b" + bg + "+h", "+bh" + bg + "+h", "+u" + bg + "+h", "+uh" + bg + "+h"})) + } + } +} + +func print256Colors() { + ansi.DisableColors(false) + stdout := colorable.NewColorableStdout() + + bgColors := []string{""} + for i := 0; i < 256; i++ { + key := fmt.Sprintf(":%d", i) + bgColors = append(bgColors, key) + } + + keys := []string{} + for fg := range ansi.Colors { + n, err := strconv.Atoi(fg) + if err == nil { + keys = append(keys, fmt.Sprintf("%3d", n)) + } + } + sort.Strings(keys) + + for _, fg := range keys { + for _, bg := range bgColors { + fmt.Fprintln(stdout, padColor(fg, []string{"" + bg, "+b" + bg, "+u" + bg})) + fmt.Fprintln(stdout, padColor(fg, []string{"+B" + bg, "+Bb" + bg, "+s" + bg})) + } + } +} + +func printConstants() { + stdout := colorable.NewColorableStdout() + fmt.Fprintln(stdout, ansi.DefaultFG, "ansi.DefaultFG", ansi.Reset) + fmt.Fprintln(stdout, ansi.Black, "ansi.Black", ansi.Reset) + fmt.Fprintln(stdout, ansi.Red, "ansi.Red", ansi.Reset) + fmt.Fprintln(stdout, ansi.Green, "ansi.Green", ansi.Reset) + fmt.Fprintln(stdout, ansi.Yellow, "ansi.Yellow", ansi.Reset) + fmt.Fprintln(stdout, ansi.Blue, "ansi.Blue", ansi.Reset) + fmt.Fprintln(stdout, ansi.Magenta, "ansi.Magenta", ansi.Reset) + fmt.Fprintln(stdout, ansi.Cyan, "ansi.Cyan", ansi.Reset) + fmt.Fprintln(stdout, ansi.White, "ansi.White", ansi.Reset) + fmt.Fprintln(stdout, ansi.LightBlack, "ansi.LightBlack", ansi.Reset) + fmt.Fprintln(stdout, ansi.LightRed, "ansi.LightRed", ansi.Reset) + fmt.Fprintln(stdout, ansi.LightGreen, "ansi.LightGreen", ansi.Reset) + fmt.Fprintln(stdout, ansi.LightYellow, "ansi.LightYellow", ansi.Reset) + fmt.Fprintln(stdout, ansi.LightBlue, "ansi.LightBlue", ansi.Reset) + fmt.Fprintln(stdout, ansi.LightMagenta, "ansi.LightMagenta", ansi.Reset) + fmt.Fprintln(stdout, ansi.LightCyan, "ansi.LightCyan", ansi.Reset) + fmt.Fprintln(stdout, ansi.LightWhite, "ansi.LightWhite", ansi.Reset) +} diff --git a/vendor/src/github.com/mgutz/ansi/doc.go b/vendor/src/github.com/mgutz/ansi/doc.go new file mode 100644 index 000000000..43c217e11 --- /dev/null +++ b/vendor/src/github.com/mgutz/ansi/doc.go @@ -0,0 +1,65 @@ +/* +Package ansi is a small, fast library to create ANSI colored strings and codes. + +Installation + + # this installs the color viewer and the package + go get -u github.com/mgutz/ansi/cmd/ansi-mgutz + +Example + + // colorize a string, SLOW + msg := ansi.Color("foo", "red+b:white") + + // create a closure to avoid recalculating ANSI code compilation + phosphorize := ansi.ColorFunc("green+h:black") + msg = phosphorize("Bring back the 80s!") + msg2 := phospohorize("Look, I'm a CRT!") + + // cache escape codes and build strings manually + lime := ansi.ColorCode("green+h:black") + reset := ansi.ColorCode("reset") + + fmt.Println(lime, "Bring back the 80s!", reset) + +Other examples + + Color(s, "red") // red + Color(s, "red+b") // red bold + Color(s, "red+B") // red blinking + Color(s, "red+u") // red underline + Color(s, "red+bh") // red bold bright + Color(s, "red:white") // red on white + Color(s, "red+b:white+h") // red bold on white bright + Color(s, "red+B:white+h") // red blink on white bright + +To view color combinations, from terminal + + ansi-mgutz + +Style format + + "foregroundColor+attributes:backgroundColor+attributes" + +Colors + + black + red + green + yellow + blue + magenta + cyan + white + +Attributes + + b = bold foreground + B = Blink foreground + u = underline foreground + h = high intensity (bright) foreground, background + i = inverse + +Wikipedia ANSI escape codes [Colors](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors) +*/ +package ansi diff --git a/vendor/src/github.com/mgutz/ansi/print.go b/vendor/src/github.com/mgutz/ansi/print.go new file mode 100644 index 000000000..806f436bb --- /dev/null +++ b/vendor/src/github.com/mgutz/ansi/print.go @@ -0,0 +1,57 @@ +package ansi + +import ( + "fmt" + "sort" + + colorable "github.com/mattn/go-colorable" +) + +// PrintStyles prints all style combinations to the terminal. +func PrintStyles() { + // for compatibility with Windows, not needed for *nix + stdout := colorable.NewColorableStdout() + + bgColors := []string{ + "", + ":black", + ":red", + ":green", + ":yellow", + ":blue", + ":magenta", + ":cyan", + ":white", + } + + keys := make([]string, 0, len(Colors)) + for k := range Colors { + keys = append(keys, k) + } + + sort.Sort(sort.StringSlice(keys)) + + for _, fg := range keys { + for _, bg := range bgColors { + fmt.Fprintln(stdout, padColor(fg, []string{"" + bg, "+b" + bg, "+bh" + bg, "+u" + bg})) + fmt.Fprintln(stdout, padColor(fg, []string{"+s" + bg, "+i" + bg})) + fmt.Fprintln(stdout, padColor(fg, []string{"+uh" + bg, "+B" + bg, "+Bb" + bg /* backgrounds */, "" + bg + "+h"})) + fmt.Fprintln(stdout, padColor(fg, []string{"+b" + bg + "+h", "+bh" + bg + "+h", "+u" + bg + "+h", "+uh" + bg + "+h"})) + } + } +} + +func pad(s string, length int) string { + for len(s) < length { + s += " " + } + return s +} + +func padColor(color string, styles []string) string { + buffer := "" + for _, style := range styles { + buffer += Color(pad(color+style, 20), color+style) + } + return buffer +} From 624c12b959973aea6a38a17b6c2451dfee2aa26a Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Wed, 23 Aug 2017 11:42:59 +0100 Subject: [PATCH 4/6] Better handling of prefix field --- .../matrix-org/dendrite/common/log.go | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/github.com/matrix-org/dendrite/common/log.go b/src/github.com/matrix-org/dendrite/common/log.go index bcd1e66b8..66948396c 100644 --- a/src/github.com/matrix-org/dendrite/common/log.go +++ b/src/github.com/matrix-org/dendrite/common/log.go @@ -29,7 +29,9 @@ type dendriteFormatter struct { logrus.TextFormatter } -func (f dendriteFormatter) Format(entry *logrus.Entry) ([]byte, error) { +func (f dendriteFormatter) Format(entry *logrus.Entry) (format []byte, err error) { + entry.Time = entry.Time.UTC() + if _, ok := entry.Data["prefix"]; ok { prefix, ok := entry.Data["prefix"].(string) if !ok { @@ -42,12 +44,27 @@ func (f dendriteFormatter) Format(entry *logrus.Entry) ([]byte, error) { prefix = ansi.Color(prefix, "white+b") } - entry.Message = fmt.Sprintf("%s: %s", prefix, entry.Message) - delete(entry.Data, "prefix") + entry.Message = fmt.Sprintf("%s: %s\t", prefix, entry.Message) + + // Generate the formatted log without the prefix as a field + // Use a copy of the entry so the same entry isn't altered by multiple + // fields at the same time + entryCpy := *entry + // Go doesn't perform deep copies, so the fields have to be manually + // copied + fields := make(logrus.Fields) + for k, v := range entry.Data { + if k != "prefix" { + fields[k] = v + } + } + entryCpy.Data = fields + format, err = f.TextFormatter.Format(&entryCpy) + } else { + format, err = f.TextFormatter.Format(entry) } - entry.Time = entry.Time.UTC() - return f.TextFormatter.Format(entry) + return } // SetupLogging configures the logging format and destination(s). From d31f6fbcc271242c4ab709ff18b751983521736a Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Wed, 23 Aug 2017 12:01:29 +0100 Subject: [PATCH 5/6] Use prefix in monolith + components --- .../clientapi/consumers/roomserver.go | 5 +- .../dendrite/clientapi/httputil/httputil.go | 2 +- .../dendrite/clientapi/readers/login.go | 2 +- .../dendrite/clientapi/writers/createroom.go | 2 +- .../dendrite/clientapi/writers/register.go | 2 +- .../cmd/dendrite-monolith-server/main.go | 55 ++++++++++--------- .../federationsender/consumers/roomserver.go | 16 +++--- .../queue/destinationqueue.go | 1 + .../dendrite/federationsender/queue/queue.go | 4 +- .../dendrite/mediaapi/writers/download.go | 1 + .../dendrite/mediaapi/writers/upload.go | 2 +- .../publicroomsapi/consumers/roomserver.go | 6 +- .../dendrite/syncapi/consumers/clientapi.go | 14 +++-- .../dendrite/syncapi/consumers/roomserver.go | 26 +++++---- .../storage/output_room_events_table.go | 1 + .../dendrite/syncapi/sync/notifier.go | 5 +- .../dendrite/syncapi/sync/request.go | 3 +- .../dendrite/syncapi/sync/requestpool.go | 2 +- 18 files changed, 85 insertions(+), 64 deletions(-) diff --git a/src/github.com/matrix-org/dendrite/clientapi/consumers/roomserver.go b/src/github.com/matrix-org/dendrite/clientapi/consumers/roomserver.go index a94750d3c..afc21040a 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/consumers/roomserver.go +++ b/src/github.com/matrix-org/dendrite/clientapi/consumers/roomserver.go @@ -23,7 +23,7 @@ import ( "github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/gomatrixserverlib" - log "github.com/sirupsen/logrus" + "github.com/sirupsen/logrus" sarama "gopkg.in/Shopify/sarama.v1" ) @@ -68,6 +68,7 @@ func (s *OutputRoomEvent) Start() error { // It is not safe for this function to be called from multiple goroutines, or else the // sync stream position may race and be incorrectly calculated. func (s *OutputRoomEvent) onMessage(msg *sarama.ConsumerMessage) error { + log := logrus.WithField("prefix", "clientapi") // Parse out the event JSON var output api.OutputEvent if err := json.Unmarshal(msg.Value, &output); err != nil { @@ -84,7 +85,7 @@ func (s *OutputRoomEvent) onMessage(msg *sarama.ConsumerMessage) error { } ev := output.NewRoomEvent.Event - log.WithFields(log.Fields{ + log.WithFields(logrus.Fields{ "event_id": ev.EventID(), "room_id": ev.RoomID(), "type": ev.Type(), diff --git a/src/github.com/matrix-org/dendrite/clientapi/httputil/httputil.go b/src/github.com/matrix-org/dendrite/clientapi/httputil/httputil.go index 7bc8a46d2..412be0074 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/httputil/httputil.go +++ b/src/github.com/matrix-org/dendrite/clientapi/httputil/httputil.go @@ -42,6 +42,6 @@ func UnmarshalJSONRequest(req *http.Request, iface interface{}) *util.JSONRespon // This should be used to log fatal errors which require investigation. It should not be used // to log client validation errors, etc. func LogThenError(req *http.Request, err error) util.JSONResponse { - util.GetLogger(req.Context()).WithError(err).Error("request failed") + util.GetLogger(req.Context()).WithField("prefix", "clientapi").WithError(err).Error("request failed") return jsonerror.InternalServerError() } diff --git a/src/github.com/matrix-org/dendrite/clientapi/readers/login.go b/src/github.com/matrix-org/dendrite/clientapi/readers/login.go index 270b2e5ac..3a1843afb 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/readers/login.go +++ b/src/github.com/matrix-org/dendrite/clientapi/readers/login.go @@ -78,7 +78,7 @@ func Login( } } - util.GetLogger(req.Context()).WithField("user", r.User).Info("Processing login request") + util.GetLogger(req.Context()).WithField("prefix", "clientapi").WithField("user", r.User).Info("Processing login request") acc, err := accountDB.GetAccountByPassword(r.User, r.Password) if err != nil { diff --git a/src/github.com/matrix-org/dendrite/clientapi/writers/createroom.go b/src/github.com/matrix-org/dendrite/clientapi/writers/createroom.go index ccc4daf92..cb9770d87 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/writers/createroom.go +++ b/src/github.com/matrix-org/dendrite/clientapi/writers/createroom.go @@ -100,7 +100,7 @@ func createRoom(req *http.Request, device *authtypes.Device, cfg config.Dendrite, roomID string, producer *producers.RoomserverProducer, accountDB *accounts.Database, ) util.JSONResponse { - logger := util.GetLogger(req.Context()) + logger := util.GetLogger(req.Context()).WithField("prefix", "clientapi") userID := device.UserID var r createRoomRequest resErr := httputil.UnmarshalJSONRequest(req, &r) diff --git a/src/github.com/matrix-org/dendrite/clientapi/writers/register.go b/src/github.com/matrix-org/dendrite/clientapi/writers/register.go index 318771d32..3057c01ac 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/writers/register.go +++ b/src/github.com/matrix-org/dendrite/clientapi/writers/register.go @@ -102,7 +102,7 @@ func Register(req *http.Request, accountDB *accounts.Database, deviceDB *devices return *resErr } - logger := util.GetLogger(req.Context()) + logger := util.GetLogger(req.Context()).WithField("prefix", "clientapi") logger.WithFields(log.Fields{ "username": r.Username, "auth.type": r.Auth.Type, diff --git a/src/github.com/matrix-org/dendrite/cmd/dendrite-monolith-server/main.go b/src/github.com/matrix-org/dendrite/cmd/dendrite-monolith-server/main.go index dee5c986c..7580e5180 100644 --- a/src/github.com/matrix-org/dendrite/cmd/dendrite-monolith-server/main.go +++ b/src/github.com/matrix-org/dendrite/cmd/dendrite-monolith-server/main.go @@ -72,6 +72,8 @@ var ( func main() { common.SetupLogging(logDir) + prefixedLog := log.WithField("prefix", "monolith") + flag.Parse() if *configPath == "" { @@ -82,7 +84,7 @@ func main() { log.Fatalf("Invalid config file: %s", err) } - m := newMonolith(cfg) + m := newMonolith(cfg, prefixedLog) m.setupDatabases() m.setupFederation() m.setupKafka() @@ -94,14 +96,14 @@ func main() { // Expose the matrix APIs directly rather than putting them under a /api path. go func() { - log.Info("Listening on ", *httpBindAddr) - log.Fatal(http.ListenAndServe(*httpBindAddr, m.api)) + prefixedLog.Info("Listening on ", *httpBindAddr) + prefixedLog.Fatal(http.ListenAndServe(*httpBindAddr, m.api)) }() // Handle HTTPS if certificate and key are provided go func() { if *certFile != "" && *keyFile != "" { - log.Info("Listening on ", *httpsBindAddr) - log.Fatal(http.ListenAndServeTLS(*httpsBindAddr, *certFile, *keyFile, m.api)) + prefixedLog.Info("Listening on ", *httpsBindAddr) + prefixedLog.Fatal(http.ListenAndServeTLS(*httpsBindAddr, *certFile, *keyFile, m.api)) } }() @@ -113,8 +115,9 @@ func main() { // Some of the setup functions depend on previous setup functions, so they must // be called in the same order as they are defined in the file. type monolith struct { - cfg *config.Dendrite - api *mux.Router + cfg *config.Dendrite + api *mux.Router + logEntry *log.Entry roomServerDB *roomserver_storage.Database accountDB *accounts.Database @@ -142,8 +145,8 @@ type monolith struct { syncAPINotifier *syncapi_sync.Notifier } -func newMonolith(cfg *config.Dendrite) *monolith { - return &monolith{cfg: cfg, api: mux.NewRouter()} +func newMonolith(cfg *config.Dendrite, log *log.Entry) *monolith { + return &monolith{cfg: cfg, api: mux.NewRouter(), logEntry: log} } func (m *monolith) setupDatabases() { @@ -154,31 +157,31 @@ func (m *monolith) setupDatabases() { } m.accountDB, err = accounts.NewDatabase(string(m.cfg.Database.Account), m.cfg.Matrix.ServerName) if err != nil { - log.Panicf("Failed to setup account database(%q): %s", m.cfg.Database.Account, err.Error()) + m.logEntry.Panicf("Failed to setup account database(%q): %s", m.cfg.Database.Account, err.Error()) } m.deviceDB, err = devices.NewDatabase(string(m.cfg.Database.Device), m.cfg.Matrix.ServerName) if err != nil { - log.Panicf("Failed to setup device database(%q): %s", m.cfg.Database.Device, err.Error()) + m.logEntry.Panicf("Failed to setup device database(%q): %s", m.cfg.Database.Device, err.Error()) } m.keyDB, err = keydb.NewDatabase(string(m.cfg.Database.ServerKey)) if err != nil { - log.Panicf("Failed to setup key database(%q): %s", m.cfg.Database.ServerKey, err.Error()) + m.logEntry.Panicf("Failed to setup key database(%q): %s", m.cfg.Database.ServerKey, err.Error()) } m.mediaAPIDB, err = mediaapi_storage.Open(string(m.cfg.Database.MediaAPI)) if err != nil { - log.Panicf("Failed to setup sync api database(%q): %s", m.cfg.Database.MediaAPI, err.Error()) + m.logEntry.Panicf("Failed to setup sync api database(%q): %s", m.cfg.Database.MediaAPI, err.Error()) } m.syncAPIDB, err = syncapi_storage.NewSyncServerDatabase(string(m.cfg.Database.SyncAPI)) if err != nil { - log.Panicf("Failed to setup sync api database(%q): %s", m.cfg.Database.SyncAPI, err.Error()) + m.logEntry.Panicf("Failed to setup sync api database(%q): %s", m.cfg.Database.SyncAPI, err.Error()) } m.federationSenderDB, err = federationsender_storage.NewDatabase(string(m.cfg.Database.FederationSender)) if err != nil { - log.Panicf("startup: failed to create federation sender database with data source %s : %s", m.cfg.Database.FederationSender, err) + m.logEntry.Panicf("startup: failed to create federation sender database with data source %s : %s", m.cfg.Database.FederationSender, err) } m.publicRoomsAPIDB, err = publicroomsapi_storage.NewPublicRoomsServerDatabase(string(m.cfg.Database.PublicRoomsAPI)) if err != nil { - log.Panicf("startup: failed to setup public rooms api database with data source %s : %s", m.cfg.Database.PublicRoomsAPI, err) + m.logEntry.Panicf("startup: failed to setup public rooms api database with data source %s : %s", m.cfg.Database.PublicRoomsAPI, err) } } @@ -201,7 +204,7 @@ func (m *monolith) setupKafka() { if m.cfg.Kafka.UseNaffka { naff, err := naffka.New(&naffka.MemoryDatabase{}) if err != nil { - log.WithFields(log.Fields{ + m.logEntry.WithFields(log.Fields{ log.ErrorKey: err, }).Panic("Failed to setup naffka") } @@ -210,7 +213,7 @@ func (m *monolith) setupKafka() { } else { m.kafkaProducer, err = sarama.NewSyncProducer(m.cfg.Kafka.Addresses, nil) if err != nil { - log.WithFields(log.Fields{ + m.logEntry.WithFields(log.Fields{ log.ErrorKey: err, "addresses": m.cfg.Kafka.Addresses, }).Panic("Failed to setup kafka producers") @@ -224,7 +227,7 @@ func (m *monolith) kafkaConsumer() sarama.Consumer { } consumer, err := sarama.NewConsumer(m.cfg.Kafka.Addresses, nil) if err != nil { - log.WithFields(log.Fields{ + m.logEntry.WithFields(log.Fields{ log.ErrorKey: err, "addresses": m.cfg.Kafka.Addresses, }).Panic("Failed to setup kafka consumers") @@ -266,12 +269,12 @@ func (m *monolith) setupProducers() { func (m *monolith) setupNotifiers() { pos, err := m.syncAPIDB.SyncStreamPosition() if err != nil { - log.Panicf("startup: failed to get latest sync stream position : %s", err) + m.logEntry.Panicf("startup: failed to get latest sync stream position : %s", err) } m.syncAPINotifier = syncapi_sync.NewNotifier(syncapi_types.StreamPosition(pos)) if err = m.syncAPINotifier.Load(m.syncAPIDB); err != nil { - log.Panicf("startup: failed to set up notifier: %s", err) + m.logEntry.Panicf("startup: failed to set up notifier: %s", err) } } @@ -282,28 +285,28 @@ func (m *monolith) setupConsumers() { m.cfg, m.kafkaConsumer(), m.accountDB, m.queryAPI, ) if err = clientAPIConsumer.Start(); err != nil { - log.Panicf("startup: failed to start room server consumer") + m.logEntry.Panicf("startup: failed to start room server consumer") } syncAPIRoomConsumer := syncapi_consumers.NewOutputRoomEvent( m.cfg, m.kafkaConsumer(), m.syncAPINotifier, m.syncAPIDB, m.queryAPI, ) if err = syncAPIRoomConsumer.Start(); err != nil { - log.Panicf("startup: failed to start room server consumer: %s", err) + m.logEntry.Panicf("startup: failed to start room server consumer: %s", err) } syncAPIClientConsumer := syncapi_consumers.NewOutputClientData( m.cfg, m.kafkaConsumer(), m.syncAPINotifier, m.syncAPIDB, ) if err = syncAPIClientConsumer.Start(); err != nil { - log.Panicf("startup: failed to start client API server consumer: %s", err) + m.logEntry.Panicf("startup: failed to start client API server consumer: %s", err) } publicRoomsAPIConsumer := publicroomsapi_consumers.NewOutputRoomEvent( m.cfg, m.kafkaConsumer(), m.publicRoomsAPIDB, m.queryAPI, ) if err = publicRoomsAPIConsumer.Start(); err != nil { - log.Panicf("startup: failed to start room server consumer: %s", err) + m.logEntry.Panicf("startup: failed to start room server consumer: %s", err) } federationSenderQueues := queue.NewOutgoingQueues(m.cfg.Matrix.ServerName, m.federation) @@ -312,7 +315,7 @@ func (m *monolith) setupConsumers() { m.cfg, m.kafkaConsumer(), federationSenderQueues, m.federationSenderDB, m.queryAPI, ) if err = federationSenderRoomConsumer.Start(); err != nil { - log.WithError(err).Panicf("startup: failed to start room server consumer") + m.logEntry.WithError(err).Panicf("startup: failed to start room server consumer") } } diff --git a/src/github.com/matrix-org/dendrite/federationsender/consumers/roomserver.go b/src/github.com/matrix-org/dendrite/federationsender/consumers/roomserver.go index c92fed147..4796f6501 100644 --- a/src/github.com/matrix-org/dendrite/federationsender/consumers/roomserver.go +++ b/src/github.com/matrix-org/dendrite/federationsender/consumers/roomserver.go @@ -25,7 +25,8 @@ import ( "github.com/matrix-org/dendrite/federationsender/types" "github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/gomatrixserverlib" - log "github.com/sirupsen/logrus" + + "github.com/sirupsen/logrus" sarama "gopkg.in/Shopify/sarama.v1" ) @@ -71,6 +72,7 @@ func (s *OutputRoomEvent) Start() error { // because updates it will likely fail with a types.EventIDMismatchError when it // realises that it cannot update the room state using the deltas. func (s *OutputRoomEvent) onMessage(msg *sarama.ConsumerMessage) error { + log := logrus.WithField("prefix", "roomserver") // Parse out the event JSON var output api.OutputEvent if err := json.Unmarshal(msg.Value, &output); err != nil { @@ -85,7 +87,7 @@ func (s *OutputRoomEvent) onMessage(msg *sarama.ConsumerMessage) error { return nil } ev := &output.NewRoomEvent.Event - log.WithFields(log.Fields{ + log.WithFields(logrus.Fields{ "event_id": ev.EventID(), "room_id": ev.RoomID(), "send_as_server": output.NewRoomEvent.SendAsServer, @@ -93,11 +95,11 @@ func (s *OutputRoomEvent) onMessage(msg *sarama.ConsumerMessage) error { if err := s.processMessage(*output.NewRoomEvent); err != nil { // panic rather than continue with an inconsistent database - log.WithFields(log.Fields{ - "event": string(ev.JSON()), - log.ErrorKey: err, - "add": output.NewRoomEvent.AddsStateEventIDs, - "del": output.NewRoomEvent.RemovesStateEventIDs, + log.WithFields(logrus.Fields{ + "event": string(ev.JSON()), + logrus.ErrorKey: err, + "add": output.NewRoomEvent.AddsStateEventIDs, + "del": output.NewRoomEvent.RemovesStateEventIDs, }).Panicf("roomserver output log: write event failure") return nil } diff --git a/src/github.com/matrix-org/dendrite/federationsender/queue/destinationqueue.go b/src/github.com/matrix-org/dendrite/federationsender/queue/destinationqueue.go index 1f48f6c71..209545967 100644 --- a/src/github.com/matrix-org/dendrite/federationsender/queue/destinationqueue.go +++ b/src/github.com/matrix-org/dendrite/federationsender/queue/destinationqueue.go @@ -68,6 +68,7 @@ func (oq *destinationQueue) backgroundSend() { _, err := oq.client.SendTransaction(*t) if err != nil { log.WithFields(log.Fields{ + "prefix": "federationsender", "destination": oq.destination, log.ErrorKey: err, }).Info("problem sending transaction") diff --git a/src/github.com/matrix-org/dendrite/federationsender/queue/queue.go b/src/github.com/matrix-org/dendrite/federationsender/queue/queue.go index d31c12f99..1ad6606c2 100644 --- a/src/github.com/matrix-org/dendrite/federationsender/queue/queue.go +++ b/src/github.com/matrix-org/dendrite/federationsender/queue/queue.go @@ -61,7 +61,9 @@ func (oqs *OutgoingQueues) SendEvent( destinations = filterDestinations(oqs.origin, destinations) log.WithFields(log.Fields{ - "destinations": destinations, "event": ev.EventID(), + "prefix": "federationsender", + "destinations": destinations, + "event": ev.EventID(), }).Info("Sending event") oqs.queuesMutex.Lock() diff --git a/src/github.com/matrix-org/dendrite/mediaapi/writers/download.go b/src/github.com/matrix-org/dendrite/mediaapi/writers/download.go index 6186e24fb..2651f8cbe 100644 --- a/src/github.com/matrix-org/dendrite/mediaapi/writers/download.go +++ b/src/github.com/matrix-org/dendrite/mediaapi/writers/download.go @@ -67,6 +67,7 @@ func Download(w http.ResponseWriter, req *http.Request, origin gomatrixserverlib }, IsThumbnailRequest: isThumbnailRequest, Logger: util.GetLogger(req.Context()).WithFields(log.Fields{ + "prefix": "mediaapi", "Origin": origin, "MediaID": mediaID, }), diff --git a/src/github.com/matrix-org/dendrite/mediaapi/writers/upload.go b/src/github.com/matrix-org/dendrite/mediaapi/writers/upload.go index aa932b53e..b08947f2f 100644 --- a/src/github.com/matrix-org/dendrite/mediaapi/writers/upload.go +++ b/src/github.com/matrix-org/dendrite/mediaapi/writers/upload.go @@ -87,7 +87,7 @@ func parseAndValidateRequest(req *http.Request, cfg *config.Dendrite) (*uploadRe ContentType: types.ContentType(req.Header.Get("Content-Type")), UploadName: types.Filename(url.PathEscape(req.FormValue("filename"))), }, - Logger: util.GetLogger(req.Context()).WithField("Origin", cfg.Matrix.ServerName), + Logger: util.GetLogger(req.Context()).WithField("Origin", cfg.Matrix.ServerName).WithField("prefix", "mediaapi"), } if resErr := r.Validate(*cfg.Media.MaxFileSizeBytes); resErr != nil { diff --git a/src/github.com/matrix-org/dendrite/publicroomsapi/consumers/roomserver.go b/src/github.com/matrix-org/dendrite/publicroomsapi/consumers/roomserver.go index 285fa9372..fe1210f6c 100644 --- a/src/github.com/matrix-org/dendrite/publicroomsapi/consumers/roomserver.go +++ b/src/github.com/matrix-org/dendrite/publicroomsapi/consumers/roomserver.go @@ -21,7 +21,8 @@ import ( "github.com/matrix-org/dendrite/common/config" "github.com/matrix-org/dendrite/publicroomsapi/storage" "github.com/matrix-org/dendrite/roomserver/api" - log "github.com/sirupsen/logrus" + + "github.com/sirupsen/logrus" sarama "gopkg.in/Shopify/sarama.v1" ) @@ -61,6 +62,7 @@ func (s *OutputRoomEvent) Start() error { // onMessage is called when the sync server receives a new event from the room server output log. func (s *OutputRoomEvent) onMessage(msg *sarama.ConsumerMessage) error { + log := logrus.WithField("prefix", "publicroomsapi") // Parse out the event JSON var output api.OutputEvent if err := json.Unmarshal(msg.Value, &output); err != nil { @@ -77,7 +79,7 @@ func (s *OutputRoomEvent) onMessage(msg *sarama.ConsumerMessage) error { } ev := output.NewRoomEvent.Event - log.WithFields(log.Fields{ + log.WithFields(logrus.Fields{ "event_id": ev.EventID(), "room_id": ev.RoomID(), "type": ev.Type(), diff --git a/src/github.com/matrix-org/dendrite/syncapi/consumers/clientapi.go b/src/github.com/matrix-org/dendrite/syncapi/consumers/clientapi.go index afe74aed3..ad6738cd5 100644 --- a/src/github.com/matrix-org/dendrite/syncapi/consumers/clientapi.go +++ b/src/github.com/matrix-org/dendrite/syncapi/consumers/clientapi.go @@ -21,7 +21,8 @@ import ( "github.com/matrix-org/dendrite/common/config" "github.com/matrix-org/dendrite/syncapi/storage" "github.com/matrix-org/dendrite/syncapi/sync" - log "github.com/sirupsen/logrus" + + "github.com/sirupsen/logrus" sarama "gopkg.in/Shopify/sarama.v1" ) @@ -64,6 +65,7 @@ func (s *OutputClientData) Start() error { // It is not safe for this function to be called from multiple goroutines, or else the // sync stream position may race and be incorrectly calculated. func (s *OutputClientData) onMessage(msg *sarama.ConsumerMessage) error { + log := logrus.WithField("prefix", "syncapi") // Parse out the event JSON var output common.AccountData if err := json.Unmarshal(msg.Value, &output); err != nil { @@ -72,17 +74,17 @@ func (s *OutputClientData) onMessage(msg *sarama.ConsumerMessage) error { return nil } - log.WithFields(log.Fields{ + log.WithFields(logrus.Fields{ "type": output.Type, "room_id": output.RoomID, }).Info("received data from client API server") syncStreamPos, err := s.db.UpsertAccountData(string(msg.Key), output.RoomID, output.Type) if err != nil { - log.WithFields(log.Fields{ - "type": output.Type, - "room_id": output.RoomID, - log.ErrorKey: err, + log.WithFields(logrus.Fields{ + "type": output.Type, + "room_id": output.RoomID, + logrus.ErrorKey: err, }).Panicf("could not save account data") } diff --git a/src/github.com/matrix-org/dendrite/syncapi/consumers/roomserver.go b/src/github.com/matrix-org/dendrite/syncapi/consumers/roomserver.go index 759050d09..30ec050d5 100644 --- a/src/github.com/matrix-org/dendrite/syncapi/consumers/roomserver.go +++ b/src/github.com/matrix-org/dendrite/syncapi/consumers/roomserver.go @@ -25,7 +25,8 @@ import ( "github.com/matrix-org/dendrite/syncapi/sync" "github.com/matrix-org/dendrite/syncapi/types" "github.com/matrix-org/gomatrixserverlib" - log "github.com/sirupsen/logrus" + + "github.com/sirupsen/logrus" sarama "gopkg.in/Shopify/sarama.v1" ) @@ -77,6 +78,7 @@ func (s *OutputRoomEvent) Start() error { // It is not safe for this function to be called from multiple goroutines, or else the // sync stream position may race and be incorrectly calculated. func (s *OutputRoomEvent) onMessage(msg *sarama.ConsumerMessage) error { + log := logrus.WithField("prefix", "syncapi") // Parse out the event JSON var output api.OutputEvent if err := json.Unmarshal(msg.Value, &output); err != nil { @@ -93,18 +95,18 @@ func (s *OutputRoomEvent) onMessage(msg *sarama.ConsumerMessage) error { } ev := output.NewRoomEvent.Event - log.WithFields(log.Fields{ + log.WithFields(logrus.Fields{ "event_id": ev.EventID(), "room_id": ev.RoomID(), }).Info("received event from roomserver") addsStateEvents, err := s.lookupStateEvents(output.NewRoomEvent.AddsStateEventIDs, ev) if err != nil { - log.WithFields(log.Fields{ - "event": string(ev.JSON()), - log.ErrorKey: err, - "add": output.NewRoomEvent.AddsStateEventIDs, - "del": output.NewRoomEvent.RemovesStateEventIDs, + log.WithFields(logrus.Fields{ + "event": string(ev.JSON()), + logrus.ErrorKey: err, + "add": output.NewRoomEvent.AddsStateEventIDs, + "del": output.NewRoomEvent.RemovesStateEventIDs, }).Panicf("roomserver output log: state event lookup failure") } @@ -126,11 +128,11 @@ func (s *OutputRoomEvent) onMessage(msg *sarama.ConsumerMessage) error { if err != nil { // panic rather than continue with an inconsistent database - log.WithFields(log.Fields{ - "event": string(ev.JSON()), - log.ErrorKey: err, - "add": output.NewRoomEvent.AddsStateEventIDs, - "del": output.NewRoomEvent.RemovesStateEventIDs, + log.WithFields(logrus.Fields{ + "event": string(ev.JSON()), + logrus.ErrorKey: err, + "add": output.NewRoomEvent.AddsStateEventIDs, + "del": output.NewRoomEvent.RemovesStateEventIDs, }).Panicf("roomserver output log: write event failure") return nil } diff --git a/src/github.com/matrix-org/dendrite/syncapi/storage/output_room_events_table.go b/src/github.com/matrix-org/dendrite/syncapi/storage/output_room_events_table.go index 2afab341d..0fffbedac 100644 --- a/src/github.com/matrix-org/dendrite/syncapi/storage/output_room_events_table.go +++ b/src/github.com/matrix-org/dendrite/syncapi/storage/output_room_events_table.go @@ -134,6 +134,7 @@ func (s *outputRoomEventsStatements) selectStateInRange( // since it'll just mark the event as not being needed. if len(addIDs) < len(delIDs) { log.WithFields(log.Fields{ + "prefix": "syncapi", "since": oldPos, "current": newPos, "adds": addIDs, diff --git a/src/github.com/matrix-org/dendrite/syncapi/sync/notifier.go b/src/github.com/matrix-org/dendrite/syncapi/sync/notifier.go index 102e42311..48069d0a8 100644 --- a/src/github.com/matrix-org/dendrite/syncapi/sync/notifier.go +++ b/src/github.com/matrix-org/dendrite/syncapi/sync/notifier.go @@ -70,7 +70,10 @@ func (n *Notifier) OnNewEvent(ev *gomatrixserverlib.Event, userID string, pos ty userID := *ev.StateKey() membership, err := ev.Membership() if err != nil { - log.WithError(err).WithField("event_id", ev.EventID()).Errorf( + log.WithError(err).WithFields(log.Fields{ + "prefix": "syncapi", + "event_id": ev.EventID(), + }).Errorf( "Notifier.OnNewEvent: Failed to unmarshal member event", ) } else { diff --git a/src/github.com/matrix-org/dendrite/syncapi/sync/request.go b/src/github.com/matrix-org/dendrite/syncapi/sync/request.go index dd1188241..5f6e109bb 100644 --- a/src/github.com/matrix-org/dendrite/syncapi/sync/request.go +++ b/src/github.com/matrix-org/dendrite/syncapi/sync/request.go @@ -45,6 +45,7 @@ func newSyncRequest(req *http.Request, userID string) (*syncRequest, error) { if err != nil { return nil, err } + log := util.GetLogger(req.Context()).WithField("prefix", "syncapi") // TODO: Additional query params: set_presence, filter return &syncRequest{ userID: userID, @@ -52,7 +53,7 @@ func newSyncRequest(req *http.Request, userID string) (*syncRequest, error) { since: since, wantFullState: wantFullState, limit: defaultTimelineLimit, // TODO: read from filter - log: util.GetLogger(req.Context()), + log: log, }, nil } diff --git a/src/github.com/matrix-org/dendrite/syncapi/sync/requestpool.go b/src/github.com/matrix-org/dendrite/syncapi/sync/requestpool.go index cdff6caef..2681d4d55 100644 --- a/src/github.com/matrix-org/dendrite/syncapi/sync/requestpool.go +++ b/src/github.com/matrix-org/dendrite/syncapi/sync/requestpool.go @@ -46,7 +46,7 @@ func NewRequestPool(db *storage.SyncServerDatabase, n *Notifier, adb *accounts.D // until a response is ready, or it times out. func (rp *RequestPool) OnIncomingSyncRequest(req *http.Request, device *authtypes.Device) util.JSONResponse { // Extract values from request - logger := util.GetLogger(req.Context()) + logger := util.GetLogger(req.Context()).WithField("prefix", "syncapi") userID := device.UserID syncReq, err := newSyncRequest(req, userID) if err != nil { From b10cf01ae449d882f416441a08fd9686654028e3 Mon Sep 17 00:00:00 2001 From: Brendan Abolivier Date: Wed, 23 Aug 2017 15:38:13 +0100 Subject: [PATCH 6/6] Fix conditional in format function --- .../matrix-org/dendrite/common/log.go | 56 +++++++++---------- 1 file changed, 26 insertions(+), 30 deletions(-) diff --git a/src/github.com/matrix-org/dendrite/common/log.go b/src/github.com/matrix-org/dendrite/common/log.go index 66948396c..ebf49f46b 100644 --- a/src/github.com/matrix-org/dendrite/common/log.go +++ b/src/github.com/matrix-org/dendrite/common/log.go @@ -32,38 +32,34 @@ type dendriteFormatter struct { func (f dendriteFormatter) Format(entry *logrus.Entry) (format []byte, err error) { entry.Time = entry.Time.UTC() - if _, ok := entry.Data["prefix"]; ok { - prefix, ok := entry.Data["prefix"].(string) - if !ok { - return f.TextFormatter.Format(entry) - } - - prefix = strings.ToUpper(prefix) - - if !f.TextFormatter.DisableColors { - prefix = ansi.Color(prefix, "white+b") - } - - entry.Message = fmt.Sprintf("%s: %s\t", prefix, entry.Message) - - // Generate the formatted log without the prefix as a field - // Use a copy of the entry so the same entry isn't altered by multiple - // fields at the same time - entryCpy := *entry - // Go doesn't perform deep copies, so the fields have to be manually - // copied - fields := make(logrus.Fields) - for k, v := range entry.Data { - if k != "prefix" { - fields[k] = v - } - } - entryCpy.Data = fields - format, err = f.TextFormatter.Format(&entryCpy) - } else { - format, err = f.TextFormatter.Format(entry) + prefix, ok := entry.Data["prefix"].(string) + if !ok { + return f.TextFormatter.Format(entry) } + prefix = strings.ToUpper(prefix) + + if !f.TextFormatter.DisableColors { + prefix = ansi.Color(prefix, "white+b") + } + + entry.Message = fmt.Sprintf("%s: %s\t", prefix, entry.Message) + + // Generate the formatted log without the prefix as a field + // Use a copy of the entry so the same entry isn't altered by multiple + // fields at the same time + entryCpy := *entry + // Go doesn't perform deep copies, so the fields have to be manually + // copied + fields := make(logrus.Fields) + for k, v := range entry.Data { + if k != "prefix" { + fields[k] = v + } + } + entryCpy.Data = fields + format, err = f.TextFormatter.Format(&entryCpy) + return }