From 118cfd91de98ffa3a8776b4e2d6998c37a05c258 Mon Sep 17 00:00:00 2001 From: ston1th Date: Wed, 21 Sep 2022 20:48:29 +0200 Subject: [PATCH] added better logging --- go.mod | 5 +- go.sum | 29 +- pkg/cmd/cmd.go | 62 +- pkg/server/server.go | 2 +- vendor/github.com/go-logr/zerologr/LICENSE | 201 -- vendor/github.com/go-logr/zerologr/README.md | 41 - .../github.com/go-logr/zerologr/zerologr.go | 166 -- vendor/github.com/mattn/go-colorable/LICENSE | 21 - .../github.com/mattn/go-colorable/README.md | 48 - .../mattn/go-colorable/colorable_appengine.go | 38 - .../mattn/go-colorable/colorable_others.go | 38 - .../mattn/go-colorable/colorable_windows.go | 1047 ---------- .../github.com/mattn/go-colorable/go.test.sh | 12 - .../mattn/go-colorable/noncolorable.go | 57 - vendor/github.com/mattn/go-isatty/LICENSE | 9 - vendor/github.com/mattn/go-isatty/README.md | 50 - vendor/github.com/mattn/go-isatty/doc.go | 2 - vendor/github.com/mattn/go-isatty/go.test.sh | 12 - .../github.com/mattn/go-isatty/isatty_bsd.go | 19 - .../mattn/go-isatty/isatty_others.go | 16 - .../mattn/go-isatty/isatty_plan9.go | 23 - .../mattn/go-isatty/isatty_solaris.go | 21 - .../mattn/go-isatty/isatty_tcgets.go | 19 - .../mattn/go-isatty/isatty_windows.go | 125 -- vendor/github.com/rs/zerolog/.gitignore | 25 - vendor/github.com/rs/zerolog/CNAME | 1 - vendor/github.com/rs/zerolog/LICENSE | 21 - vendor/github.com/rs/zerolog/README.md | 716 ------- vendor/github.com/rs/zerolog/_config.yml | 1 - vendor/github.com/rs/zerolog/array.go | 240 --- vendor/github.com/rs/zerolog/console.go | 446 ----- vendor/github.com/rs/zerolog/context.go | 433 ----- vendor/github.com/rs/zerolog/ctx.go | 51 - vendor/github.com/rs/zerolog/encoder.go | 56 - vendor/github.com/rs/zerolog/encoder_cbor.go | 42 - vendor/github.com/rs/zerolog/encoder_json.go | 39 - vendor/github.com/rs/zerolog/event.go | 780 -------- vendor/github.com/rs/zerolog/fields.go | 277 --- vendor/github.com/rs/zerolog/globals.go | 142 -- vendor/github.com/rs/zerolog/go112.go | 7 - vendor/github.com/rs/zerolog/hook.go | 64 - .../rs/zerolog/internal/cbor/README.md | 56 - .../rs/zerolog/internal/cbor/base.go | 19 - .../rs/zerolog/internal/cbor/cbor.go | 101 - .../rs/zerolog/internal/cbor/decode_stream.go | 614 ------ .../rs/zerolog/internal/cbor/string.go | 95 - .../rs/zerolog/internal/cbor/time.go | 93 - .../rs/zerolog/internal/cbor/types.go | 477 ----- .../rs/zerolog/internal/json/base.go | 19 - .../rs/zerolog/internal/json/bytes.go | 85 - .../rs/zerolog/internal/json/string.go | 149 -- .../rs/zerolog/internal/json/time.go | 113 -- .../rs/zerolog/internal/json/types.go | 405 ---- vendor/github.com/rs/zerolog/log.go | 476 ----- vendor/github.com/rs/zerolog/not_go112.go | 5 - vendor/github.com/rs/zerolog/pretty.png | Bin 84064 -> 0 bytes vendor/github.com/rs/zerolog/sampler.go | 134 -- vendor/github.com/rs/zerolog/syslog.go | 80 - vendor/github.com/rs/zerolog/writer.go | 154 -- vendor/k8s.io/klog/v2/.gitignore | 17 + vendor/k8s.io/klog/v2/CONTRIBUTING.md | 22 + vendor/k8s.io/klog/v2/LICENSE | 191 ++ vendor/k8s.io/klog/v2/OWNERS | 14 + vendor/k8s.io/klog/v2/README.md | 118 ++ vendor/k8s.io/klog/v2/RELEASE.md | 9 + vendor/k8s.io/klog/v2/SECURITY.md | 22 + vendor/k8s.io/klog/v2/SECURITY_CONTACTS | 20 + vendor/k8s.io/klog/v2/code-of-conduct.md | 3 + vendor/k8s.io/klog/v2/contextual.go | 186 ++ vendor/k8s.io/klog/v2/exit.go | 69 + vendor/k8s.io/klog/v2/imports.go | 38 + .../k8s.io/klog/v2/internal/buffer/buffer.go | 159 ++ .../k8s.io/klog/v2/internal/clock/README.md | 7 + vendor/k8s.io/klog/v2/internal/clock/clock.go | 178 ++ vendor/k8s.io/klog/v2/internal/dbg/dbg.go | 42 + .../klog/v2/internal/serialize/keyvalues.go | 253 +++ .../klog/v2/internal/severity/severity.go | 58 + vendor/k8s.io/klog/v2/k8s_references.go | 158 ++ vendor/k8s.io/klog/v2/klog.go | 1689 +++++++++++++++++ vendor/k8s.io/klog/v2/klog_file.go | 130 ++ vendor/k8s.io/klog/v2/klog_file_others.go | 19 + vendor/k8s.io/klog/v2/klog_file_windows.go | 34 + vendor/k8s.io/klog/v2/klogr.go | 87 + vendor/k8s.io/klog/v2/klogr/README.md | 19 + vendor/k8s.io/klog/v2/klogr/klogr.go | 185 ++ vendor/modules.txt | 23 +- 86 files changed, 3774 insertions(+), 8455 deletions(-) delete mode 100644 vendor/github.com/go-logr/zerologr/LICENSE delete mode 100644 vendor/github.com/go-logr/zerologr/README.md delete mode 100644 vendor/github.com/go-logr/zerologr/zerologr.go delete mode 100644 vendor/github.com/mattn/go-colorable/LICENSE delete mode 100644 vendor/github.com/mattn/go-colorable/README.md delete mode 100644 vendor/github.com/mattn/go-colorable/colorable_appengine.go delete mode 100644 vendor/github.com/mattn/go-colorable/colorable_others.go delete mode 100644 vendor/github.com/mattn/go-colorable/colorable_windows.go delete mode 100644 vendor/github.com/mattn/go-colorable/go.test.sh delete mode 100644 vendor/github.com/mattn/go-colorable/noncolorable.go delete mode 100644 vendor/github.com/mattn/go-isatty/LICENSE delete mode 100644 vendor/github.com/mattn/go-isatty/README.md delete mode 100644 vendor/github.com/mattn/go-isatty/doc.go delete mode 100644 vendor/github.com/mattn/go-isatty/go.test.sh delete mode 100644 vendor/github.com/mattn/go-isatty/isatty_bsd.go delete mode 100644 vendor/github.com/mattn/go-isatty/isatty_others.go delete mode 100644 vendor/github.com/mattn/go-isatty/isatty_plan9.go delete mode 100644 vendor/github.com/mattn/go-isatty/isatty_solaris.go delete mode 100644 vendor/github.com/mattn/go-isatty/isatty_tcgets.go delete mode 100644 vendor/github.com/mattn/go-isatty/isatty_windows.go delete mode 100644 vendor/github.com/rs/zerolog/.gitignore delete mode 100644 vendor/github.com/rs/zerolog/CNAME delete mode 100644 vendor/github.com/rs/zerolog/LICENSE delete mode 100644 vendor/github.com/rs/zerolog/README.md delete mode 100644 vendor/github.com/rs/zerolog/_config.yml delete mode 100644 vendor/github.com/rs/zerolog/array.go delete mode 100644 vendor/github.com/rs/zerolog/console.go delete mode 100644 vendor/github.com/rs/zerolog/context.go delete mode 100644 vendor/github.com/rs/zerolog/ctx.go delete mode 100644 vendor/github.com/rs/zerolog/encoder.go delete mode 100644 vendor/github.com/rs/zerolog/encoder_cbor.go delete mode 100644 vendor/github.com/rs/zerolog/encoder_json.go delete mode 100644 vendor/github.com/rs/zerolog/event.go delete mode 100644 vendor/github.com/rs/zerolog/fields.go delete mode 100644 vendor/github.com/rs/zerolog/globals.go delete mode 100644 vendor/github.com/rs/zerolog/go112.go delete mode 100644 vendor/github.com/rs/zerolog/hook.go delete mode 100644 vendor/github.com/rs/zerolog/internal/cbor/README.md delete mode 100644 vendor/github.com/rs/zerolog/internal/cbor/base.go delete mode 100644 vendor/github.com/rs/zerolog/internal/cbor/cbor.go delete mode 100644 vendor/github.com/rs/zerolog/internal/cbor/decode_stream.go delete mode 100644 vendor/github.com/rs/zerolog/internal/cbor/string.go delete mode 100644 vendor/github.com/rs/zerolog/internal/cbor/time.go delete mode 100644 vendor/github.com/rs/zerolog/internal/cbor/types.go delete mode 100644 vendor/github.com/rs/zerolog/internal/json/base.go delete mode 100644 vendor/github.com/rs/zerolog/internal/json/bytes.go delete mode 100644 vendor/github.com/rs/zerolog/internal/json/string.go delete mode 100644 vendor/github.com/rs/zerolog/internal/json/time.go delete mode 100644 vendor/github.com/rs/zerolog/internal/json/types.go delete mode 100644 vendor/github.com/rs/zerolog/log.go delete mode 100644 vendor/github.com/rs/zerolog/not_go112.go delete mode 100644 vendor/github.com/rs/zerolog/pretty.png delete mode 100644 vendor/github.com/rs/zerolog/sampler.go delete mode 100644 vendor/github.com/rs/zerolog/syslog.go delete mode 100644 vendor/github.com/rs/zerolog/writer.go create mode 100644 vendor/k8s.io/klog/v2/.gitignore create mode 100644 vendor/k8s.io/klog/v2/CONTRIBUTING.md create mode 100644 vendor/k8s.io/klog/v2/LICENSE create mode 100644 vendor/k8s.io/klog/v2/OWNERS create mode 100644 vendor/k8s.io/klog/v2/README.md create mode 100644 vendor/k8s.io/klog/v2/RELEASE.md create mode 100644 vendor/k8s.io/klog/v2/SECURITY.md create mode 100644 vendor/k8s.io/klog/v2/SECURITY_CONTACTS create mode 100644 vendor/k8s.io/klog/v2/code-of-conduct.md create mode 100644 vendor/k8s.io/klog/v2/contextual.go create mode 100644 vendor/k8s.io/klog/v2/exit.go create mode 100644 vendor/k8s.io/klog/v2/imports.go create mode 100644 vendor/k8s.io/klog/v2/internal/buffer/buffer.go create mode 100644 vendor/k8s.io/klog/v2/internal/clock/README.md create mode 100644 vendor/k8s.io/klog/v2/internal/clock/clock.go create mode 100644 vendor/k8s.io/klog/v2/internal/dbg/dbg.go create mode 100644 vendor/k8s.io/klog/v2/internal/serialize/keyvalues.go create mode 100644 vendor/k8s.io/klog/v2/internal/severity/severity.go create mode 100644 vendor/k8s.io/klog/v2/k8s_references.go create mode 100644 vendor/k8s.io/klog/v2/klog.go create mode 100644 vendor/k8s.io/klog/v2/klog_file.go create mode 100644 vendor/k8s.io/klog/v2/klog_file_others.go create mode 100644 vendor/k8s.io/klog/v2/klog_file_windows.go create mode 100644 vendor/k8s.io/klog/v2/klogr.go create mode 100644 vendor/k8s.io/klog/v2/klogr/README.md create mode 100644 vendor/k8s.io/klog/v2/klogr/klogr.go diff --git a/go.mod b/go.mod index 39f0af6..109c6ab 100644 --- a/go.mod +++ b/go.mod @@ -9,14 +9,13 @@ require ( github.com/bcampbell/qs v0.0.0-20161004022730-15caa99abd01 github.com/blevesearch/bleve v1.0.14 github.com/go-logr/logr v1.2.3 - github.com/go-logr/zerologr v1.2.2 github.com/gorilla/mux v1.8.0 github.com/pquerna/otp v1.3.0 - github.com/rs/zerolog v1.28.0 github.com/urfave/cli v1.22.5 go.etcd.io/bbolt v1.3.6 golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8 golang.org/x/net v0.0.0-20220812174116-3211cb980234 + k8s.io/klog/v2 v2.80.1 ) require ( @@ -36,8 +35,6 @@ require ( github.com/glycerine/go-unsnap-stream v0.0.0-20190901134440-81cf024a9e0a // indirect github.com/golang/protobuf v1.4.3 // indirect github.com/golang/snappy v0.0.2 // indirect - github.com/mattn/go-colorable v0.1.12 // indirect - github.com/mattn/go-isatty v0.0.14 // indirect github.com/mschoch/smat v0.2.0 // indirect github.com/philhofer/fwd v1.1.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect diff --git a/go.sum b/go.sum index 6e389f6..e60d86f 100644 --- a/go.sum +++ b/go.sum @@ -42,8 +42,6 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/couchbase/ghistogram v0.1.0/go.mod h1:s1Jhy76zqfEecpNWJfWUiKZookAFaiGOEoyzgHt9i7k= github.com/couchbase/moss v0.1.0/go.mod h1:9MaHIaRuy9pvLPUJxB8sh8OrLfyDczECVL37grCIubs= github.com/couchbase/vellum v1.0.2 h1:BrbP0NKiyDdndMPec8Jjhy0U47CZ0Lgx3xUC2r9rZqw= @@ -71,12 +69,9 @@ github.com/glycerine/go-unsnap-stream v0.0.0-20190901134440-81cf024a9e0a h1:FQqo github.com/glycerine/go-unsnap-stream v0.0.0-20190901134440-81cf024a9e0a/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31 h1:gclg6gY70GLy3PbkQ1AERPfmLMMagS60DKF78eWwLn8= github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/zerologr v1.2.2 h1:nKJ1glUZQPURRpe20GaqCBgNyGYg9cylaerwrwKoogE= -github.com/go-logr/zerologr v1.2.2/go.mod h1:eIsB+dwGuN3lAGytcpbXyBeiY8GKInIxy+Qwe+gI5lI= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -113,10 +108,6 @@ github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7 github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/kljensen/snowball v0.6.0/go.mod h1:27N7E8fVU5H68RlUmnWwZCfxgt4POBJfENGMvNRhldw= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= -github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= @@ -129,7 +120,6 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9 github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/philhofer/fwd v1.1.0 h1:PAdZw9+/BCf4gc/kA2L/PbGPkFe72Kl2GLZXTG8HpU8= github.com/philhofer/fwd v1.1.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pquerna/otp v1.3.0 h1:oJV/SkzR33anKXwQU3Of42rL4wbrffP4uvUf1SvS5Xs= @@ -137,11 +127,6 @@ github.com/pquerna/otp v1.3.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1 github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= -github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.26.1/go.mod h1:/wSSJWX7lVrsOwlbyTRSOJvqRlc+WjWlfes+CiJ+tmc= -github.com/rs/zerolog v1.28.0 h1:MirSo27VyNi7RJYP3078AA1+Cyzd2GB66qy3aUHvsWY= -github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0= github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -178,7 +163,6 @@ github.com/willf/bitset v1.1.11 h1:N7Z7E9UvjW+sGsEl7k/SJrvY2reP1A07MrGuCjIOjRE= github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= @@ -186,7 +170,6 @@ golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8 h1:GIAS/yBem/gq2MUqgNIzUHW7cJMmx3TGZOrnyYaNQ6c= golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -196,7 +179,6 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -207,8 +189,6 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220812174116-3211cb980234 h1:RDqmgfe7SvlMWoqC3xwQ2blLO3fcWcxMa3eBLRdRW7E= golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= @@ -218,7 +198,6 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181026144532-2772b66316d2/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -234,9 +213,6 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220818161305-2296e01440c6 h1:Sx/u41w+OwrInGdEckYmEuU5gHoGSL4QbDz3S9s6j4U= golang.org/x/sys v0.0.0-20220818161305-2296e01440c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -255,7 +231,6 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200928182047-19e03678916f/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -287,3 +262,5 @@ gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4= +k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= diff --git a/pkg/cmd/cmd.go b/pkg/cmd/cmd.go index bf0b8d6..8eb5d7d 100644 --- a/pkg/cmd/cmd.go +++ b/pkg/cmd/cmd.go @@ -10,7 +10,6 @@ import ( "os" "os/signal" "path/filepath" - "strconv" "syscall" "git.giftfish.de/ston1th/docstore/pkg/core" @@ -19,9 +18,11 @@ import ( "git.giftfish.de/ston1th/docstore/pkg/server" "git.giftfish.de/ston1th/godrop/v2" "github.com/go-logr/logr" - "github.com/go-logr/zerologr" - "github.com/rs/zerolog" "github.com/urfave/cli" + "k8s.io/klog/v2" + "k8s.io/klog/v2/klogr" + //"github.com/go-logr/zerologr" + //"github.com/rs/zerolog" ) const ( @@ -74,10 +75,12 @@ func initServer(cfg *core.Config) (err error) { return } - log, err := logFileLogger(cfg) + ll, err := logFileLogger(cfg) if err != nil { return } + log := ll.WithName("main") + log.Info("starting docstore", "version", cfg.Version) cfg.DataDir = filepath.Join(cfg.RunDir, core.DataDir) debugCfg := new(core.Config) @@ -85,7 +88,7 @@ func initServer(cfg *core.Config) (err error) { debugCfg.Secret = "[redacted]" log.V(2).Info("docstore config", "cfg", debugCfg) - scanner, err := scan.New(log.WithName("scanner"), cfg) + scanner, err := scan.New(ll.WithName("scanner"), cfg) if err != nil { return errors.New("scanner: " + err.Error()) } @@ -98,12 +101,11 @@ func initServer(cfg *core.Config) (err error) { return } - srv := server.NewHTTPServer(log, cfg, l, scanner) + srv := server.NewHTTPServer(ll, cfg, l, scanner) err = srv.Start() if err != nil { return } - log.Info("docstore started", "version", cfg.Version) sigs := make(chan os.Signal, 1) signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) <-sigs @@ -129,7 +131,8 @@ func loadConfig() error { return err } if config.Debug { - zerolog.SetGlobalLevel(zerolog.TraceLevel) + new(klog.Level).Set("2") + //zerolog.SetGlobalLevel(zerolog.TraceLevel) } if config.RunDir == "" { config.RunDir = defRunDir @@ -165,7 +168,7 @@ func fatal(err error) { var ( log logr.Logger - zl zerolog.Logger + //zl zerolog.Logger ) func logFileLogger(cfg *core.Config) (l logr.Logger, err error) { @@ -173,30 +176,31 @@ func logFileLogger(cfg *core.Config) (l logr.Logger, err error) { if err != nil { return } - zln := zl.Output(f) - l = zerologr.New(&zln) + klog.LogToStderr(false) + klog.SetOutput(f) + l = klogr.New() + //zln := zl.Output(f) + //l = zerologr.New(&zln) return } func init() { - //zerolog.TimeFieldFormat = zerolog.TimeFormatUnixMs - zerolog.CallerMarshalFunc = func(pc uintptr, file string, line int) string { - short := file - for i := len(file) - 1; i > 0; i-- { - if file[i] == '/' { - short = file[i+1:] - break - } - } - file = short - return file + ":" + strconv.Itoa(line) - } - //zerologr.NameFieldName = "logger" - //zerologr.NameSeparator = "/" - zerologr.VerbosityFieldName = "" - zl = zerolog.New(os.Stderr) - zl = zl.With().Caller().Timestamp().Logger() - log = zerologr.New(&zl) + //zerolog.CallerMarshalFunc = func(pc uintptr, file string, line int) string { + // short := file + // for i := len(file) - 1; i > 0; i-- { + // if file[i] == '/' { + // short = file[i+1:] + // break + // } + // } + // file = short + // return file + ":" + strconv.Itoa(line) + //} + //zerologr.VerbosityFieldName = "" + //zl = zerolog.New(os.Stderr) + //zl = zl.With().Caller().Timestamp().Logger() + //log = zerologr.New(&zl) + log = klogr.New() } func Run(version string) { diff --git a/pkg/server/server.go b/pkg/server/server.go index fd71158..e3fbf45 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -90,7 +90,7 @@ func (s *HTTPServer) Start() (err error) { } go func() { err = s.srv.Serve(s.listener) - if err != nil { + if err != nil && err != http.ErrServerClosed { log.Error(err, "http server error") } }() diff --git a/vendor/github.com/go-logr/zerologr/LICENSE b/vendor/github.com/go-logr/zerologr/LICENSE deleted file mode 100644 index 8dada3e..0000000 --- a/vendor/github.com/go-logr/zerologr/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/go-logr/zerologr/README.md b/vendor/github.com/go-logr/zerologr/README.md deleted file mode 100644 index 8975837..0000000 --- a/vendor/github.com/go-logr/zerologr/README.md +++ /dev/null @@ -1,41 +0,0 @@ -# Zerologr - -[![Go Reference](https://pkg.go.dev/badge/github.com/go-logr/zerologr.svg)](https://pkg.go.dev/github.com/go-logr/zerologr) -![test](https://github.com/go-logr/zerologr/workflows/test/badge.svg) -[![Go Report Card](https://goreportcard.com/badge/github.com/go-logr/zerologr)](https://goreportcard.com/report/github.com/go-logr/zerologr) - -A [logr](https://github.com/go-logr/logr) LogSink implementation using [Zerolog](https://github.com/rs/zerolog). - -## Usage - -```go -import ( - "os" - - "github.com/go-logr/logr" - "github.com/go-logr/zerologr" - "github.com/rs/zerolog" -) - -func main() { - zerolog.TimeFieldFormat = zerolog.TimeFormatUnixMs - zerologr.NameFieldName = "logger" - zerologr.NameSeparator = "/" - - zl := zerolog.New(os.Stderr) - zl = zl.With().Caller().Timestamp().Logger() - var log logr.Logger = zerologr.New(&zl) - - log.Info("Logr in action!", "the answer", 42) -} -``` - -## Implementation Details - -For the most part, concepts in Zerolog correspond directly with those in logr. - -Levels in logr correspond to custom debug levels in Zerolog. Any given level -in logr is represents by `zerologLevel = 1 - logrLevel`. - -For example `V(2)` is equivalent to Zerolog's `TraceLevel`, while `V(1)` is -equivalent to Zerolog's `DebugLevel`. diff --git a/vendor/github.com/go-logr/zerologr/zerologr.go b/vendor/github.com/go-logr/zerologr/zerologr.go deleted file mode 100644 index b69ce80..0000000 --- a/vendor/github.com/go-logr/zerologr/zerologr.go +++ /dev/null @@ -1,166 +0,0 @@ -// Package zerologr defines an implementation of the github.com/go-logr/logr -// interfaces built on top of Zerolog (https://github.com/rs/zerolog). -// -// Usage -// -// A new logr.Logger can be constructed from an existing zerolog.Logger using -// the New function: -// -// log := zerologr.New(someZeroLogger) -// -// Implementation Details -// -// For the most part, concepts in Zerolog correspond directly with those in -// logr. -// -// Levels in logr correspond to custom debug levels in Zerolog. Any given level -// in logr is represents by `zerologLevel = 1 - logrLevel`. -// For example V(2) is equivalent to Zerolog's TraceLevel, while V(1) is -// equivalent to Zerolog's DebugLevel. Verbosity value is a number and is only -// logged on Info(), not Error(). -package zerologr - -import ( - "fmt" - - "github.com/go-logr/logr" - "github.com/rs/zerolog" -) - -var ( - // NameFieldName is the field key for logr.WithName. - NameFieldName = "logger" - // NameSeparator separates names for logr.WithName. - NameSeparator = "/" - // VerbosityFieldName is the field key for logr.Info verbosity. If set to "", - // its value is not emitted. - VerbosityFieldName = "v" - - // RenderArgsHook mutates the list of key-value pairs passed directly to - // logr.Info and logr.Error. - RenderArgsHook = DefaultRender - // RenderValuesHook mutates the list of key-value pairs saved via logr.WithValues. - RenderValuesHook = DefaultRender -) - -// Logger is type alias of logr.Logger. -type Logger = logr.Logger - -// LogSink implements logr.LogSink and logr.CallDepthLogSink. -type LogSink struct { - l *zerolog.Logger - name string - depth int -} - -// Underlier exposes access to the underlying logging implementation. Since -// callers only have a logr.Logger, they have to know which implementation is -// in use, so this interface is less of an abstraction and more of way to test -// type conversion. -type Underlier interface { - GetUnderlying() *zerolog.Logger -} - -var ( - _ logr.LogSink = &LogSink{} - _ logr.CallDepthLogSink = &LogSink{} -) - -// New returns a logr.Logger with logr.LogSink implemented by Zerolog. -func New(l *zerolog.Logger) Logger { - ls := NewLogSink(l) - return logr.New(ls) -} - -// NewLogSink returns a logr.LogSink implemented by Zerolog. -func NewLogSink(l *zerolog.Logger) *LogSink { - return &LogSink{l: l} -} - -// Init receives runtime info about the logr library. -func (ls *LogSink) Init(ri logr.RuntimeInfo) { - ls.depth = ri.CallDepth + 2 -} - -// Enabled tests whether this LogSink is enabled at the specified V-level. -func (ls *LogSink) Enabled(level int) bool { - // Optimization: Info() will check level internally. - const traceLevel = 1 - int(zerolog.TraceLevel) - return level <= traceLevel -} - -// Info logs a non-error message at specified V-level with the given key/value pairs as context. -func (ls *LogSink) Info(level int, msg string, keysAndValues ...interface{}) { - e := ls.l.WithLevel(zerolog.Level(1 - level)) - if VerbosityFieldName != "" { - e.Int(VerbosityFieldName, level) - } - ls.msg(e, msg, keysAndValues) -} - -// Error logs an error, with the given message and key/value pairs as context. -func (ls *LogSink) Error(err error, msg string, keysAndValues ...interface{}) { - e := ls.l.Error().Err(err) - ls.msg(e, msg, keysAndValues) -} - -func (ls *LogSink) msg(e *zerolog.Event, msg string, keysAndValues []interface{}) { - if e == nil { - return - } - if ls.name != "" { - e.Str(NameFieldName, ls.name) - } - if RenderArgsHook != nil { - keysAndValues = RenderArgsHook(keysAndValues) - } - e = e.Fields(keysAndValues) - e.CallerSkipFrame(ls.depth) - e.Msg(msg) -} - -// WithValues returns a new LogSink with additional key/value pairs. -func (ls LogSink) WithValues(keysAndValues ...interface{}) logr.LogSink { - if RenderValuesHook != nil { - keysAndValues = RenderValuesHook(keysAndValues) - } - l := ls.l.With().Fields(keysAndValues).Logger() - ls.l = &l - return &ls -} - -// WithName returns a new LogSink with the specified name appended in NameFieldName. -// Name elements are separated by NameSeparator. -func (ls LogSink) WithName(name string) logr.LogSink { - if ls.name != "" { - ls.name += NameSeparator + name - } else { - ls.name = name - } - return &ls -} - -// WithCallDepth returns a new LogSink that offsets the call stack by adding specified depths. -func (ls LogSink) WithCallDepth(depth int) logr.LogSink { - ls.depth += depth - return &ls -} - -// GetUnderlying returns the zerolog.Logger underneath this logSink. -func (ls *LogSink) GetUnderlying() *zerolog.Logger { - return ls.l -} - -// DefaultRender supports logr.Marshaler and fmt.Stringer. -func DefaultRender(keysAndValues []interface{}) []interface{} { - for i, n := 1, len(keysAndValues); i < n; i += 2 { - value := keysAndValues[i] - switch v := value.(type) { - case logr.Marshaler: - keysAndValues[i] = v.MarshalLog() - case fmt.Stringer: - keysAndValues[i] = v.String() - } - } - return keysAndValues -} diff --git a/vendor/github.com/mattn/go-colorable/LICENSE b/vendor/github.com/mattn/go-colorable/LICENSE deleted file mode 100644 index 91b5cef..0000000 --- a/vendor/github.com/mattn/go-colorable/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -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/github.com/mattn/go-colorable/README.md b/vendor/github.com/mattn/go-colorable/README.md deleted file mode 100644 index ca04837..0000000 --- a/vendor/github.com/mattn/go-colorable/README.md +++ /dev/null @@ -1,48 +0,0 @@ -# go-colorable - -[![Build Status](https://github.com/mattn/go-colorable/workflows/test/badge.svg)](https://github.com/mattn/go-colorable/actions?query=workflow%3Atest) -[![Codecov](https://codecov.io/gh/mattn/go-colorable/branch/master/graph/badge.svg)](https://codecov.io/gh/mattn/go-colorable) -[![GoDoc](https://godoc.org/github.com/mattn/go-colorable?status.svg)](http://godoc.org/github.com/mattn/go-colorable) -[![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/github.com/mattn/go-colorable/colorable_appengine.go b/vendor/github.com/mattn/go-colorable/colorable_appengine.go deleted file mode 100644 index 416d1bb..0000000 --- a/vendor/github.com/mattn/go-colorable/colorable_appengine.go +++ /dev/null @@ -1,38 +0,0 @@ -//go:build appengine -// +build appengine - -package colorable - -import ( - "io" - "os" - - _ "github.com/mattn/go-isatty" -) - -// NewColorable returns new instance of Writer which handles escape sequence. -func NewColorable(file *os.File) io.Writer { - if file == nil { - panic("nil passed instead of *os.File to NewColorable()") - } - - return file -} - -// NewColorableStdout returns new instance of Writer which handles escape sequence for stdout. -func NewColorableStdout() io.Writer { - return os.Stdout -} - -// NewColorableStderr returns new instance of Writer which handles escape sequence for stderr. -func NewColorableStderr() io.Writer { - return os.Stderr -} - -// EnableColorsStdout enable colors if possible. -func EnableColorsStdout(enabled *bool) func() { - if enabled != nil { - *enabled = true - } - return func() {} -} diff --git a/vendor/github.com/mattn/go-colorable/colorable_others.go b/vendor/github.com/mattn/go-colorable/colorable_others.go deleted file mode 100644 index 766d946..0000000 --- a/vendor/github.com/mattn/go-colorable/colorable_others.go +++ /dev/null @@ -1,38 +0,0 @@ -//go:build !windows && !appengine -// +build !windows,!appengine - -package colorable - -import ( - "io" - "os" - - _ "github.com/mattn/go-isatty" -) - -// NewColorable returns new instance of Writer which handles escape sequence. -func NewColorable(file *os.File) io.Writer { - if file == nil { - panic("nil passed instead of *os.File to NewColorable()") - } - - return file -} - -// NewColorableStdout returns new instance of Writer which handles escape sequence for stdout. -func NewColorableStdout() io.Writer { - return os.Stdout -} - -// NewColorableStderr returns new instance of Writer which handles escape sequence for stderr. -func NewColorableStderr() io.Writer { - return os.Stderr -} - -// EnableColorsStdout enable colors if possible. -func EnableColorsStdout(enabled *bool) func() { - if enabled != nil { - *enabled = true - } - return func() {} -} diff --git a/vendor/github.com/mattn/go-colorable/colorable_windows.go b/vendor/github.com/mattn/go-colorable/colorable_windows.go deleted file mode 100644 index 1846ad5..0000000 --- a/vendor/github.com/mattn/go-colorable/colorable_windows.go +++ /dev/null @@ -1,1047 +0,0 @@ -//go:build windows && !appengine -// +build windows,!appengine - -package colorable - -import ( - "bytes" - "io" - "math" - "os" - "strconv" - "strings" - "sync" - "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) - commonLvbUnderscore = 0x8000 - - cENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x4 -) - -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") - procGetConsoleMode = kernel32.NewProc("GetConsoleMode") - procSetConsoleMode = kernel32.NewProc("SetConsoleMode") - procCreateConsoleScreenBuffer = kernel32.NewProc("CreateConsoleScreenBuffer") -) - -// Writer provides colorable Writer to the console -type Writer struct { - out io.Writer - handle syscall.Handle - althandle syscall.Handle - oldattr word - oldpos coord - rest bytes.Buffer - mutex sync.Mutex -} - -// NewColorable returns new instance of Writer which handles 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 mode uint32 - if r, _, _ := procGetConsoleMode.Call(file.Fd(), uintptr(unsafe.Pointer(&mode))); r != 0 && mode&cENABLE_VIRTUAL_TERMINAL_PROCESSING != 0 { - return file - } - 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 returns new instance of Writer which handles escape sequence for stdout. -func NewColorableStdout() io.Writer { - return NewColorable(os.Stdout) -} - -// NewColorableStderr returns new instance of Writer which handles 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 -} - -// returns Atoi(s) unless s == "" in which case it returns def -func atoiWithDefault(s string, def int) (int, error) { - if s == "" { - return def, nil - } - return strconv.Atoi(s) -} - -// Write writes data on console -func (w *Writer) Write(data []byte) (n int, err error) { - w.mutex.Lock() - defer w.mutex.Unlock() - 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 plaintext bytes.Buffer -loop: - for { - c1, err := er.ReadByte() - if err != nil { - plaintext.WriteTo(w.out) - break loop - } - if c1 != 0x1b { - plaintext.WriteByte(c1) - continue - } - _, err = plaintext.WriteTo(w.out) - if err != nil { - break loop - } - c2, err := er.ReadByte() - if err != nil { - break loop - } - - switch c2 { - case '>': - continue - case ']': - 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 - // https://github.com/mattn/go-colorable/issues/27 - case '7': - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - w.oldpos = csbi.cursorPosition - continue - case '8': - procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&w.oldpos))) - continue - case 0x5b: - // execute part after switch - default: - 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 = atoiWithDefault(buf.String(), 1) - 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 = atoiWithDefault(buf.String(), 1) - 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 = atoiWithDefault(buf.String(), 1) - 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 = atoiWithDefault(buf.String(), 1) - 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 - } - if n < 1 { - n = 1 - } - 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) - dword(csbi.cursorPosition.x) + dword(csbi.size.y-csbi.cursorPosition.y)*dword(csbi.size.x) - case 1: - cursor = coord{x: csbi.window.left, y: csbi.window.top} - count = dword(csbi.size.x) - dword(csbi.cursorPosition.x) + dword(csbi.window.top-csbi.cursorPosition.y)*dword(csbi.size.x) - case 2: - cursor = coord{x: csbi.window.left, y: csbi.window.top} - count = dword(csbi.size.x) - dword(csbi.cursorPosition.x) + dword(csbi.size.y-csbi.cursorPosition.y)*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 '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.cursorPosition.y} - count = dword(csbi.size.x - csbi.cursorPosition.x) - case 2: - cursor = coord{x: csbi.window.left, y: 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 'X': - 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 written dword - cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y} - procFillConsoleOutputCharacter.Call(uintptr(handle), uintptr(' '), uintptr(n), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) - procFillConsoleOutputAttribute.Call(uintptr(handle), uintptr(csbi.attributes), uintptr(n), *(*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 n == 4: - attr |= commonLvbUnderscore - case (1 <= n && n <= 3) || n == 5: - attr |= foregroundIntensity - case n == 7 || n == 27: - attr = - (attr &^ (foregroundMask | backgroundMask)) | - ((attr & foregroundMask) << 4) | - ((attr & backgroundMask) >> 4) - case n == 22: - attr &^= foregroundIntensity - case n == 24: - attr &^= commonLvbUnderscore - 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%len(n256foreAttr)] - 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%len(n256backAttr)] - 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() - } -} - -// EnableColorsStdout enable colors if possible. -func EnableColorsStdout(enabled *bool) func() { - var mode uint32 - h := os.Stdout.Fd() - if r, _, _ := procGetConsoleMode.Call(h, uintptr(unsafe.Pointer(&mode))); r != 0 { - if r, _, _ = procSetConsoleMode.Call(h, uintptr(mode|cENABLE_VIRTUAL_TERMINAL_PROCESSING)); r != 0 { - if enabled != nil { - *enabled = true - } - return func() { - procSetConsoleMode.Call(h, uintptr(mode)) - } - } - } - if enabled != nil { - *enabled = true - } - return func() {} -} diff --git a/vendor/github.com/mattn/go-colorable/go.test.sh b/vendor/github.com/mattn/go-colorable/go.test.sh deleted file mode 100644 index 012162b..0000000 --- a/vendor/github.com/mattn/go-colorable/go.test.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -set -e -echo "" > coverage.txt - -for d in $(go list ./... | grep -v vendor); do - go test -race -coverprofile=profile.out -covermode=atomic "$d" - if [ -f profile.out ]; then - cat profile.out >> coverage.txt - rm profile.out - fi -done diff --git a/vendor/github.com/mattn/go-colorable/noncolorable.go b/vendor/github.com/mattn/go-colorable/noncolorable.go deleted file mode 100644 index 05d6f74..0000000 --- a/vendor/github.com/mattn/go-colorable/noncolorable.go +++ /dev/null @@ -1,57 +0,0 @@ -package colorable - -import ( - "bytes" - "io" -) - -// NonColorable holds writer but removes escape sequence. -type NonColorable struct { - out io.Writer -} - -// NewNonColorable returns new instance of Writer which removes escape sequence from Writer. -func NewNonColorable(w io.Writer) io.Writer { - return &NonColorable{out: w} -} - -// Write writes data on console -func (w *NonColorable) Write(data []byte) (n int, err error) { - er := bytes.NewReader(data) - var plaintext bytes.Buffer -loop: - for { - c1, err := er.ReadByte() - if err != nil { - plaintext.WriteTo(w.out) - break loop - } - if c1 != 0x1b { - plaintext.WriteByte(c1) - continue - } - _, err = plaintext.WriteTo(w.out) - if err != nil { - break loop - } - c2, err := er.ReadByte() - if err != nil { - break loop - } - if c2 != 0x5b { - continue - } - - for { - c, err := er.ReadByte() - if err != nil { - break loop - } - if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' { - break - } - } - } - - return len(data), nil -} diff --git a/vendor/github.com/mattn/go-isatty/LICENSE b/vendor/github.com/mattn/go-isatty/LICENSE deleted file mode 100644 index 65dc692..0000000 --- a/vendor/github.com/mattn/go-isatty/LICENSE +++ /dev/null @@ -1,9 +0,0 @@ -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/github.com/mattn/go-isatty/README.md b/vendor/github.com/mattn/go-isatty/README.md deleted file mode 100644 index 3841835..0000000 --- a/vendor/github.com/mattn/go-isatty/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# go-isatty - -[![Godoc Reference](https://godoc.org/github.com/mattn/go-isatty?status.svg)](http://godoc.org/github.com/mattn/go-isatty) -[![Codecov](https://codecov.io/gh/mattn/go-isatty/branch/master/graph/badge.svg)](https://codecov.io/gh/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/github.com/mattn/go-isatty/doc.go b/vendor/github.com/mattn/go-isatty/doc.go deleted file mode 100644 index 17d4f90..0000000 --- a/vendor/github.com/mattn/go-isatty/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package isatty implements interface to isatty -package isatty diff --git a/vendor/github.com/mattn/go-isatty/go.test.sh b/vendor/github.com/mattn/go-isatty/go.test.sh deleted file mode 100644 index 012162b..0000000 --- a/vendor/github.com/mattn/go-isatty/go.test.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -set -e -echo "" > coverage.txt - -for d in $(go list ./... | grep -v vendor); do - go test -race -coverprofile=profile.out -covermode=atomic "$d" - if [ -f profile.out ]; then - cat profile.out >> coverage.txt - rm profile.out - fi -done diff --git a/vendor/github.com/mattn/go-isatty/isatty_bsd.go b/vendor/github.com/mattn/go-isatty/isatty_bsd.go deleted file mode 100644 index 39bbcf0..0000000 --- a/vendor/github.com/mattn/go-isatty/isatty_bsd.go +++ /dev/null @@ -1,19 +0,0 @@ -//go:build (darwin || freebsd || openbsd || netbsd || dragonfly) && !appengine -// +build darwin freebsd openbsd netbsd dragonfly -// +build !appengine - -package isatty - -import "golang.org/x/sys/unix" - -// IsTerminal return true if the file descriptor is terminal. -func IsTerminal(fd uintptr) bool { - _, err := unix.IoctlGetTermios(int(fd), unix.TIOCGETA) - return err == nil -} - -// 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/github.com/mattn/go-isatty/isatty_others.go b/vendor/github.com/mattn/go-isatty/isatty_others.go deleted file mode 100644 index 3150322..0000000 --- a/vendor/github.com/mattn/go-isatty/isatty_others.go +++ /dev/null @@ -1,16 +0,0 @@ -//go:build appengine || js || nacl || wasm -// +build appengine js nacl wasm - -package isatty - -// IsTerminal returns true if the file descriptor is terminal which -// is always false on js and 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/github.com/mattn/go-isatty/isatty_plan9.go b/vendor/github.com/mattn/go-isatty/isatty_plan9.go deleted file mode 100644 index bae7f9b..0000000 --- a/vendor/github.com/mattn/go-isatty/isatty_plan9.go +++ /dev/null @@ -1,23 +0,0 @@ -//go:build plan9 -// +build plan9 - -package isatty - -import ( - "syscall" -) - -// IsTerminal returns true if the given file descriptor is a terminal. -func IsTerminal(fd uintptr) bool { - path, err := syscall.Fd2path(int(fd)) - if err != nil { - return false - } - return path == "/dev/cons" || path == "/mnt/term/dev/cons" -} - -// 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/github.com/mattn/go-isatty/isatty_solaris.go b/vendor/github.com/mattn/go-isatty/isatty_solaris.go deleted file mode 100644 index 0c3acf2..0000000 --- a/vendor/github.com/mattn/go-isatty/isatty_solaris.go +++ /dev/null @@ -1,21 +0,0 @@ -//go:build solaris && !appengine -// +build solaris,!appengine - -package isatty - -import ( - "golang.org/x/sys/unix" -) - -// IsTerminal returns true if the given file descriptor is a terminal. -// see: https://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libc/port/gen/isatty.c -func IsTerminal(fd uintptr) bool { - _, err := unix.IoctlGetTermio(int(fd), unix.TCGETA) - return err == nil -} - -// 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/github.com/mattn/go-isatty/isatty_tcgets.go b/vendor/github.com/mattn/go-isatty/isatty_tcgets.go deleted file mode 100644 index 6778765..0000000 --- a/vendor/github.com/mattn/go-isatty/isatty_tcgets.go +++ /dev/null @@ -1,19 +0,0 @@ -//go:build (linux || aix || zos) && !appengine -// +build linux aix zos -// +build !appengine - -package isatty - -import "golang.org/x/sys/unix" - -// IsTerminal return true if the file descriptor is terminal. -func IsTerminal(fd uintptr) bool { - _, err := unix.IoctlGetTermios(int(fd), unix.TCGETS) - return err == nil -} - -// 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/github.com/mattn/go-isatty/isatty_windows.go b/vendor/github.com/mattn/go-isatty/isatty_windows.go deleted file mode 100644 index 8e3c991..0000000 --- a/vendor/github.com/mattn/go-isatty/isatty_windows.go +++ /dev/null @@ -1,125 +0,0 @@ -//go:build windows && !appengine -// +build windows,!appengine - -package isatty - -import ( - "errors" - "strings" - "syscall" - "unicode/utf16" - "unsafe" -) - -const ( - objectNameInfo uintptr = 1 - fileNameInfo = 2 - fileTypePipe = 3 -) - -var ( - kernel32 = syscall.NewLazyDLL("kernel32.dll") - ntdll = syscall.NewLazyDLL("ntdll.dll") - procGetConsoleMode = kernel32.NewProc("GetConsoleMode") - procGetFileInformationByHandleEx = kernel32.NewProc("GetFileInformationByHandleEx") - procGetFileType = kernel32.NewProc("GetFileType") - procNtQueryObject = ntdll.NewProc("NtQueryObject") -) - -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` && - token[0] != `\Device\NamedPipe\msys` && - token[0] != `\Device\NamedPipe\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 -} - -// getFileNameByHandle use the undocomented ntdll NtQueryObject to get file full name from file handler -// since GetFileInformationByHandleEx is not available under windows Vista and still some old fashion -// guys are using Windows XP, this is a workaround for those guys, it will also work on system from -// Windows vista to 10 -// see https://stackoverflow.com/a/18792477 for details -func getFileNameByHandle(fd uintptr) (string, error) { - if procNtQueryObject == nil { - return "", errors.New("ntdll.dll: NtQueryObject not supported") - } - - var buf [4 + syscall.MAX_PATH]uint16 - var result int - r, _, e := syscall.Syscall6(procNtQueryObject.Addr(), 5, - fd, objectNameInfo, uintptr(unsafe.Pointer(&buf)), uintptr(2*len(buf)), uintptr(unsafe.Pointer(&result)), 0) - if r != 0 { - return "", e - } - return string(utf16.Decode(buf[4 : 4+buf[0]/2])), nil -} - -// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2 -// terminal. -func IsCygwinTerminal(fd uintptr) bool { - if procGetFileInformationByHandleEx == nil { - name, err := getFileNameByHandle(fd) - if err != nil { - return false - } - return isCygwinPipeName(name) - } - - // 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/github.com/rs/zerolog/.gitignore b/vendor/github.com/rs/zerolog/.gitignore deleted file mode 100644 index 8ebe58b..0000000 --- a/vendor/github.com/rs/zerolog/.gitignore +++ /dev/null @@ -1,25 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test -tmp - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test -*.prof diff --git a/vendor/github.com/rs/zerolog/CNAME b/vendor/github.com/rs/zerolog/CNAME deleted file mode 100644 index 9ce57a6..0000000 --- a/vendor/github.com/rs/zerolog/CNAME +++ /dev/null @@ -1 +0,0 @@ -zerolog.io \ No newline at end of file diff --git a/vendor/github.com/rs/zerolog/LICENSE b/vendor/github.com/rs/zerolog/LICENSE deleted file mode 100644 index 677e07f..0000000 --- a/vendor/github.com/rs/zerolog/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2017 Olivier Poitrey - -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/github.com/rs/zerolog/README.md b/vendor/github.com/rs/zerolog/README.md deleted file mode 100644 index 95666b3..0000000 --- a/vendor/github.com/rs/zerolog/README.md +++ /dev/null @@ -1,716 +0,0 @@ -# Zero Allocation JSON Logger - -[![godoc](http://img.shields.io/badge/godoc-reference-blue.svg?style=flat)](https://godoc.org/github.com/rs/zerolog) [![license](http://img.shields.io/badge/license-MIT-red.svg?style=flat)](https://raw.githubusercontent.com/rs/zerolog/master/LICENSE) [![Build Status](https://travis-ci.org/rs/zerolog.svg?branch=master)](https://travis-ci.org/rs/zerolog) [![Coverage](http://gocover.io/_badge/github.com/rs/zerolog)](http://gocover.io/github.com/rs/zerolog) - -The zerolog package provides a fast and simple logger dedicated to JSON output. - -Zerolog's API is designed to provide both a great developer experience and stunning [performance](#benchmarks). Its unique chaining API allows zerolog to write JSON (or CBOR) log events by avoiding allocations and reflection. - -Uber's [zap](https://godoc.org/go.uber.org/zap) library pioneered this approach. Zerolog is taking this concept to the next level with a simpler to use API and even better performance. - -To keep the code base and the API simple, zerolog focuses on efficient structured logging only. Pretty logging on the console is made possible using the provided (but inefficient) [`zerolog.ConsoleWriter`](#pretty-logging). - -![Pretty Logging Image](pretty.png) - -## Who uses zerolog - -Find out [who uses zerolog](https://github.com/rs/zerolog/wiki/Who-uses-zerolog) and add your company / project to the list. - -## Features - -* [Blazing fast](#benchmarks) -* [Low to zero allocation](#benchmarks) -* [Leveled logging](#leveled-logging) -* [Sampling](#log-sampling) -* [Hooks](#hooks) -* [Contextual fields](#contextual-logging) -* `context.Context` integration -* [Integration with `net/http`](#integration-with-nethttp) -* [JSON and CBOR encoding formats](#binary-encoding) -* [Pretty logging for development](#pretty-logging) -* [Error Logging (with optional Stacktrace)](#error-logging) - -## Installation - -```bash -go get -u github.com/rs/zerolog/log -``` - -## Getting Started - -### Simple Logging Example - -For simple logging, import the global logger package **github.com/rs/zerolog/log** - -```go -package main - -import ( - "github.com/rs/zerolog" - "github.com/rs/zerolog/log" -) - -func main() { - // UNIX Time is faster and smaller than most timestamps - zerolog.TimeFieldFormat = zerolog.TimeFormatUnix - - log.Print("hello world") -} - -// Output: {"time":1516134303,"level":"debug","message":"hello world"} -``` -> Note: By default log writes to `os.Stderr` -> Note: The default log level for `log.Print` is *debug* - -### Contextual Logging - -**zerolog** allows data to be added to log messages in the form of key:value pairs. The data added to the message adds "context" about the log event that can be critical for debugging as well as myriad other purposes. An example of this is below: - -```go -package main - -import ( - "github.com/rs/zerolog" - "github.com/rs/zerolog/log" -) - -func main() { - zerolog.TimeFieldFormat = zerolog.TimeFormatUnix - - log.Debug(). - Str("Scale", "833 cents"). - Float64("Interval", 833.09). - Msg("Fibonacci is everywhere") - - log.Debug(). - Str("Name", "Tom"). - Send() -} - -// Output: {"level":"debug","Scale":"833 cents","Interval":833.09,"time":1562212768,"message":"Fibonacci is everywhere"} -// Output: {"level":"debug","Name":"Tom","time":1562212768} -``` - -> You'll note in the above example that when adding contextual fields, the fields are strongly typed. You can find the full list of supported fields [here](#standard-types) - -### Leveled Logging - -#### Simple Leveled Logging Example - -```go -package main - -import ( - "github.com/rs/zerolog" - "github.com/rs/zerolog/log" -) - -func main() { - zerolog.TimeFieldFormat = zerolog.TimeFormatUnix - - log.Info().Msg("hello world") -} - -// Output: {"time":1516134303,"level":"info","message":"hello world"} -``` - -> It is very important to note that when using the **zerolog** chaining API, as shown above (`log.Info().Msg("hello world"`), the chain must have either the `Msg` or `Msgf` method call. If you forget to add either of these, the log will not occur and there is no compile time error to alert you of this. - -**zerolog** allows for logging at the following levels (from highest to lowest): - -* panic (`zerolog.PanicLevel`, 5) -* fatal (`zerolog.FatalLevel`, 4) -* error (`zerolog.ErrorLevel`, 3) -* warn (`zerolog.WarnLevel`, 2) -* info (`zerolog.InfoLevel`, 1) -* debug (`zerolog.DebugLevel`, 0) -* trace (`zerolog.TraceLevel`, -1) - -You can set the Global logging level to any of these options using the `SetGlobalLevel` function in the zerolog package, passing in one of the given constants above, e.g. `zerolog.InfoLevel` would be the "info" level. Whichever level is chosen, all logs with a level greater than or equal to that level will be written. To turn off logging entirely, pass the `zerolog.Disabled` constant. - -#### Setting Global Log Level - -This example uses command-line flags to demonstrate various outputs depending on the chosen log level. - -```go -package main - -import ( - "flag" - - "github.com/rs/zerolog" - "github.com/rs/zerolog/log" -) - -func main() { - zerolog.TimeFieldFormat = zerolog.TimeFormatUnix - debug := flag.Bool("debug", false, "sets log level to debug") - - flag.Parse() - - // Default level for this example is info, unless debug flag is present - zerolog.SetGlobalLevel(zerolog.InfoLevel) - if *debug { - zerolog.SetGlobalLevel(zerolog.DebugLevel) - } - - log.Debug().Msg("This message appears only when log level set to Debug") - log.Info().Msg("This message appears when log level set to Debug or Info") - - if e := log.Debug(); e.Enabled() { - // Compute log output only if enabled. - value := "bar" - e.Str("foo", value).Msg("some debug message") - } -} -``` - -Info Output (no flag) - -```bash -$ ./logLevelExample -{"time":1516387492,"level":"info","message":"This message appears when log level set to Debug or Info"} -``` - -Debug Output (debug flag set) - -```bash -$ ./logLevelExample -debug -{"time":1516387573,"level":"debug","message":"This message appears only when log level set to Debug"} -{"time":1516387573,"level":"info","message":"This message appears when log level set to Debug or Info"} -{"time":1516387573,"level":"debug","foo":"bar","message":"some debug message"} -``` - -#### Logging without Level or Message - -You may choose to log without a specific level by using the `Log` method. You may also write without a message by setting an empty string in the `msg string` parameter of the `Msg` method. Both are demonstrated in the example below. - -```go -package main - -import ( - "github.com/rs/zerolog" - "github.com/rs/zerolog/log" -) - -func main() { - zerolog.TimeFieldFormat = zerolog.TimeFormatUnix - - log.Log(). - Str("foo", "bar"). - Msg("") -} - -// Output: {"time":1494567715,"foo":"bar"} -``` - -### Error Logging - -You can log errors using the `Err` method - -```go -package main - -import ( - "errors" - - "github.com/rs/zerolog" - "github.com/rs/zerolog/log" -) - -func main() { - zerolog.TimeFieldFormat = zerolog.TimeFormatUnix - - err := errors.New("seems we have an error here") - log.Error().Err(err).Msg("") -} - -// Output: {"level":"error","error":"seems we have an error here","time":1609085256} -``` - -> The default field name for errors is `error`, you can change this by setting `zerolog.ErrorFieldName` to meet your needs. - -#### Error Logging with Stacktrace - -Using `github.com/pkg/errors`, you can add a formatted stacktrace to your errors. - -```go -package main - -import ( - "github.com/pkg/errors" - "github.com/rs/zerolog/pkgerrors" - - "github.com/rs/zerolog" - "github.com/rs/zerolog/log" -) - -func main() { - zerolog.TimeFieldFormat = zerolog.TimeFormatUnix - zerolog.ErrorStackMarshaler = pkgerrors.MarshalStack - - err := outer() - log.Error().Stack().Err(err).Msg("") -} - -func inner() error { - return errors.New("seems we have an error here") -} - -func middle() error { - err := inner() - if err != nil { - return err - } - return nil -} - -func outer() error { - err := middle() - if err != nil { - return err - } - return nil -} - -// Output: {"level":"error","stack":[{"func":"inner","line":"20","source":"errors.go"},{"func":"middle","line":"24","source":"errors.go"},{"func":"outer","line":"32","source":"errors.go"},{"func":"main","line":"15","source":"errors.go"},{"func":"main","line":"204","source":"proc.go"},{"func":"goexit","line":"1374","source":"asm_amd64.s"}],"error":"seems we have an error here","time":1609086683} -``` - -> zerolog.ErrorStackMarshaler must be set in order for the stack to output anything. - -#### Logging Fatal Messages - -```go -package main - -import ( - "errors" - - "github.com/rs/zerolog" - "github.com/rs/zerolog/log" -) - -func main() { - err := errors.New("A repo man spends his life getting into tense situations") - service := "myservice" - - zerolog.TimeFieldFormat = zerolog.TimeFormatUnix - - log.Fatal(). - Err(err). - Str("service", service). - Msgf("Cannot start %s", service) -} - -// Output: {"time":1516133263,"level":"fatal","error":"A repo man spends his life getting into tense situations","service":"myservice","message":"Cannot start myservice"} -// exit status 1 -``` - -> NOTE: Using `Msgf` generates one allocation even when the logger is disabled. - - -### Create logger instance to manage different outputs - -```go -logger := zerolog.New(os.Stderr).With().Timestamp().Logger() - -logger.Info().Str("foo", "bar").Msg("hello world") - -// Output: {"level":"info","time":1494567715,"message":"hello world","foo":"bar"} -``` - -### Sub-loggers let you chain loggers with additional context - -```go -sublogger := log.With(). - Str("component", "foo"). - Logger() -sublogger.Info().Msg("hello world") - -// Output: {"level":"info","time":1494567715,"message":"hello world","component":"foo"} -``` - -### Pretty logging - -To log a human-friendly, colorized output, use `zerolog.ConsoleWriter`: - -```go -log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}) - -log.Info().Str("foo", "bar").Msg("Hello world") - -// Output: 3:04PM INF Hello World foo=bar -``` - -To customize the configuration and formatting: - -```go -output := zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: time.RFC3339} -output.FormatLevel = func(i interface{}) string { - return strings.ToUpper(fmt.Sprintf("| %-6s|", i)) -} -output.FormatMessage = func(i interface{}) string { - return fmt.Sprintf("***%s****", i) -} -output.FormatFieldName = func(i interface{}) string { - return fmt.Sprintf("%s:", i) -} -output.FormatFieldValue = func(i interface{}) string { - return strings.ToUpper(fmt.Sprintf("%s", i)) -} - -log := zerolog.New(output).With().Timestamp().Logger() - -log.Info().Str("foo", "bar").Msg("Hello World") - -// Output: 2006-01-02T15:04:05Z07:00 | INFO | ***Hello World**** foo:BAR -``` - -### Sub dictionary - -```go -log.Info(). - Str("foo", "bar"). - Dict("dict", zerolog.Dict(). - Str("bar", "baz"). - Int("n", 1), - ).Msg("hello world") - -// Output: {"level":"info","time":1494567715,"foo":"bar","dict":{"bar":"baz","n":1},"message":"hello world"} -``` - -### Customize automatic field names - -```go -zerolog.TimestampFieldName = "t" -zerolog.LevelFieldName = "l" -zerolog.MessageFieldName = "m" - -log.Info().Msg("hello world") - -// Output: {"l":"info","t":1494567715,"m":"hello world"} -``` - -### Add contextual fields to the global logger - -```go -log.Logger = log.With().Str("foo", "bar").Logger() -``` - -### Add file and line number to log - -Equivalent of `Llongfile`: - -```go -log.Logger = log.With().Caller().Logger() -log.Info().Msg("hello world") - -// Output: {"level": "info", "message": "hello world", "caller": "/go/src/your_project/some_file:21"} -``` - -Equivalent of `Lshortfile`: - -```go -zerolog.CallerMarshalFunc = func(file string, line int) string { - short := file - for i := len(file) - 1; i > 0; i-- { - if file[i] == '/' { - short = file[i+1:] - break - } - } - file = short - return file + ":" + strconv.Itoa(line) -} -log.Logger = log.With().Caller().Logger() -log.Info().Msg("hello world") - -// Output: {"level": "info", "message": "hello world", "caller": "some_file:21"} -``` - -### Thread-safe, lock-free, non-blocking writer - -If your writer might be slow or not thread-safe and you need your log producers to never get slowed down by a slow writer, you can use a `diode.Writer` as follows: - -```go -wr := diode.NewWriter(os.Stdout, 1000, 10*time.Millisecond, func(missed int) { - fmt.Printf("Logger Dropped %d messages", missed) - }) -log := zerolog.New(wr) -log.Print("test") -``` - -You will need to install `code.cloudfoundry.org/go-diodes` to use this feature. - -### Log Sampling - -```go -sampled := log.Sample(&zerolog.BasicSampler{N: 10}) -sampled.Info().Msg("will be logged every 10 messages") - -// Output: {"time":1494567715,"level":"info","message":"will be logged every 10 messages"} -``` - -More advanced sampling: - -```go -// Will let 5 debug messages per period of 1 second. -// Over 5 debug message, 1 every 100 debug messages are logged. -// Other levels are not sampled. -sampled := log.Sample(zerolog.LevelSampler{ - DebugSampler: &zerolog.BurstSampler{ - Burst: 5, - Period: 1*time.Second, - NextSampler: &zerolog.BasicSampler{N: 100}, - }, -}) -sampled.Debug().Msg("hello world") - -// Output: {"time":1494567715,"level":"debug","message":"hello world"} -``` - -### Hooks - -```go -type SeverityHook struct{} - -func (h SeverityHook) Run(e *zerolog.Event, level zerolog.Level, msg string) { - if level != zerolog.NoLevel { - e.Str("severity", level.String()) - } -} - -hooked := log.Hook(SeverityHook{}) -hooked.Warn().Msg("") - -// Output: {"level":"warn","severity":"warn"} -``` - -### Pass a sub-logger by context - -```go -ctx := log.With().Str("component", "module").Logger().WithContext(ctx) - -log.Ctx(ctx).Info().Msg("hello world") - -// Output: {"component":"module","level":"info","message":"hello world"} -``` - -### Set as standard logger output - -```go -log := zerolog.New(os.Stdout).With(). - Str("foo", "bar"). - Logger() - -stdlog.SetFlags(0) -stdlog.SetOutput(log) - -stdlog.Print("hello world") - -// Output: {"foo":"bar","message":"hello world"} -``` - -### Integration with `net/http` - -The `github.com/rs/zerolog/hlog` package provides some helpers to integrate zerolog with `http.Handler`. - -In this example we use [alice](https://github.com/justinas/alice) to install logger for better readability. - -```go -log := zerolog.New(os.Stdout).With(). - Timestamp(). - Str("role", "my-service"). - Str("host", host). - Logger() - -c := alice.New() - -// Install the logger handler with default output on the console -c = c.Append(hlog.NewHandler(log)) - -// Install some provided extra handler to set some request's context fields. -// Thanks to that handler, all our logs will come with some prepopulated fields. -c = c.Append(hlog.AccessHandler(func(r *http.Request, status, size int, duration time.Duration) { - hlog.FromRequest(r).Info(). - Str("method", r.Method). - Stringer("url", r.URL). - Int("status", status). - Int("size", size). - Dur("duration", duration). - Msg("") -})) -c = c.Append(hlog.RemoteAddrHandler("ip")) -c = c.Append(hlog.UserAgentHandler("user_agent")) -c = c.Append(hlog.RefererHandler("referer")) -c = c.Append(hlog.RequestIDHandler("req_id", "Request-Id")) - -// Here is your final handler -h := c.Then(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // Get the logger from the request's context. You can safely assume it - // will be always there: if the handler is removed, hlog.FromRequest - // will return a no-op logger. - hlog.FromRequest(r).Info(). - Str("user", "current user"). - Str("status", "ok"). - Msg("Something happened") - - // Output: {"level":"info","time":"2001-02-03T04:05:06Z","role":"my-service","host":"local-hostname","req_id":"b4g0l5t6tfid6dtrapu0","user":"current user","status":"ok","message":"Something happened"} -})) -http.Handle("/", h) - -if err := http.ListenAndServe(":8080", nil); err != nil { - log.Fatal().Err(err).Msg("Startup failed") -} -``` - -## Multiple Log Output -`zerolog.MultiLevelWriter` may be used to send the log message to multiple outputs. -In this example, we send the log message to both `os.Stdout` and the in-built ConsoleWriter. -```go -func main() { - consoleWriter := zerolog.ConsoleWriter{Out: os.Stdout} - - multi := zerolog.MultiLevelWriter(consoleWriter, os.Stdout) - - logger := zerolog.New(multi).With().Timestamp().Logger() - - logger.Info().Msg("Hello World!") -} - -// Output (Line 1: Console; Line 2: Stdout) -// 12:36PM INF Hello World! -// {"level":"info","time":"2019-11-07T12:36:38+03:00","message":"Hello World!"} -``` - -## Global Settings - -Some settings can be changed and will be applied to all loggers: - -* `log.Logger`: You can set this value to customize the global logger (the one used by package level methods). -* `zerolog.SetGlobalLevel`: Can raise the minimum level of all loggers. Call this with `zerolog.Disabled` to disable logging altogether (quiet mode). -* `zerolog.DisableSampling`: If argument is `true`, all sampled loggers will stop sampling and issue 100% of their log events. -* `zerolog.TimestampFieldName`: Can be set to customize `Timestamp` field name. -* `zerolog.LevelFieldName`: Can be set to customize level field name. -* `zerolog.MessageFieldName`: Can be set to customize message field name. -* `zerolog.ErrorFieldName`: Can be set to customize `Err` field name. -* `zerolog.TimeFieldFormat`: Can be set to customize `Time` field value formatting. If set with `zerolog.TimeFormatUnix`, `zerolog.TimeFormatUnixMs` or `zerolog.TimeFormatUnixMicro`, times are formated as UNIX timestamp. -* `zerolog.DurationFieldUnit`: Can be set to customize the unit for time.Duration type fields added by `Dur` (default: `time.Millisecond`). -* `zerolog.DurationFieldInteger`: If set to `true`, `Dur` fields are formatted as integers instead of floats (default: `false`). -* `zerolog.ErrorHandler`: Called whenever zerolog fails to write an event on its output. If not set, an error is printed on the stderr. This handler must be thread safe and non-blocking. - -## Field Types - -### Standard Types - -* `Str` -* `Bool` -* `Int`, `Int8`, `Int16`, `Int32`, `Int64` -* `Uint`, `Uint8`, `Uint16`, `Uint32`, `Uint64` -* `Float32`, `Float64` - -### Advanced Fields - -* `Err`: Takes an `error` and renders it as a string using the `zerolog.ErrorFieldName` field name. -* `Func`: Run a `func` only if the level is enabled. -* `Timestamp`: Inserts a timestamp field with `zerolog.TimestampFieldName` field name, formatted using `zerolog.TimeFieldFormat`. -* `Time`: Adds a field with time formatted with `zerolog.TimeFieldFormat`. -* `Dur`: Adds a field with `time.Duration`. -* `Dict`: Adds a sub-key/value as a field of the event. -* `RawJSON`: Adds a field with an already encoded JSON (`[]byte`) -* `Hex`: Adds a field with value formatted as a hexadecimal string (`[]byte`) -* `Interface`: Uses reflection to marshal the type. - -Most fields are also available in the slice format (`Strs` for `[]string`, `Errs` for `[]error` etc.) - -## Binary Encoding - -In addition to the default JSON encoding, `zerolog` can produce binary logs using [CBOR](https://cbor.io) encoding. The choice of encoding can be decided at compile time using the build tag `binary_log` as follows: - -```bash -go build -tags binary_log . -``` - -To Decode binary encoded log files you can use any CBOR decoder. One has been tested to work -with zerolog library is [CSD](https://github.com/toravir/csd/). - -## Related Projects - -* [grpc-zerolog](https://github.com/cheapRoc/grpc-zerolog): Implementation of `grpclog.LoggerV2` interface using `zerolog` -* [overlog](https://github.com/Trendyol/overlog): Implementation of `Mapped Diagnostic Context` interface using `zerolog` -* [zerologr](https://github.com/go-logr/zerologr): Implementation of `logr.LogSink` interface using `zerolog` - -## Benchmarks - -See [logbench](http://hackemist.com/logbench/) for more comprehensive and up-to-date benchmarks. - -All operations are allocation free (those numbers *include* JSON encoding): - -```text -BenchmarkLogEmpty-8 100000000 19.1 ns/op 0 B/op 0 allocs/op -BenchmarkDisabled-8 500000000 4.07 ns/op 0 B/op 0 allocs/op -BenchmarkInfo-8 30000000 42.5 ns/op 0 B/op 0 allocs/op -BenchmarkContextFields-8 30000000 44.9 ns/op 0 B/op 0 allocs/op -BenchmarkLogFields-8 10000000 184 ns/op 0 B/op 0 allocs/op -``` - -There are a few Go logging benchmarks and comparisons that include zerolog. - -* [imkira/go-loggers-bench](https://github.com/imkira/go-loggers-bench) -* [uber-common/zap](https://github.com/uber-go/zap#performance) - -Using Uber's zap comparison benchmark: - -Log a message and 10 fields: - -| Library | Time | Bytes Allocated | Objects Allocated | -| :--- | :---: | :---: | :---: | -| zerolog | 767 ns/op | 552 B/op | 6 allocs/op | -| :zap: zap | 848 ns/op | 704 B/op | 2 allocs/op | -| :zap: zap (sugared) | 1363 ns/op | 1610 B/op | 20 allocs/op | -| go-kit | 3614 ns/op | 2895 B/op | 66 allocs/op | -| lion | 5392 ns/op | 5807 B/op | 63 allocs/op | -| logrus | 5661 ns/op | 6092 B/op | 78 allocs/op | -| apex/log | 15332 ns/op | 3832 B/op | 65 allocs/op | -| log15 | 20657 ns/op | 5632 B/op | 93 allocs/op | - -Log a message with a logger that already has 10 fields of context: - -| Library | Time | Bytes Allocated | Objects Allocated | -| :--- | :---: | :---: | :---: | -| zerolog | 52 ns/op | 0 B/op | 0 allocs/op | -| :zap: zap | 283 ns/op | 0 B/op | 0 allocs/op | -| :zap: zap (sugared) | 337 ns/op | 80 B/op | 2 allocs/op | -| lion | 2702 ns/op | 4074 B/op | 38 allocs/op | -| go-kit | 3378 ns/op | 3046 B/op | 52 allocs/op | -| logrus | 4309 ns/op | 4564 B/op | 63 allocs/op | -| apex/log | 13456 ns/op | 2898 B/op | 51 allocs/op | -| log15 | 14179 ns/op | 2642 B/op | 44 allocs/op | - -Log a static string, without any context or `printf`-style templating: - -| Library | Time | Bytes Allocated | Objects Allocated | -| :--- | :---: | :---: | :---: | -| zerolog | 50 ns/op | 0 B/op | 0 allocs/op | -| :zap: zap | 236 ns/op | 0 B/op | 0 allocs/op | -| standard library | 453 ns/op | 80 B/op | 2 allocs/op | -| :zap: zap (sugared) | 337 ns/op | 80 B/op | 2 allocs/op | -| go-kit | 508 ns/op | 656 B/op | 13 allocs/op | -| lion | 771 ns/op | 1224 B/op | 10 allocs/op | -| logrus | 1244 ns/op | 1505 B/op | 27 allocs/op | -| apex/log | 2751 ns/op | 584 B/op | 11 allocs/op | -| log15 | 5181 ns/op | 1592 B/op | 26 allocs/op | - -## Caveats - -Note that zerolog does no de-duplication of fields. Using the same key multiple times creates multiple keys in final JSON: - -```go -logger := zerolog.New(os.Stderr).With().Timestamp().Logger() -logger.Info(). - Timestamp(). - Msg("dup") -// Output: {"level":"info","time":1494567715,"time":1494567715,"message":"dup"} -``` - -In this case, many consumers will take the last value, but this is not guaranteed; check yours if in doubt. diff --git a/vendor/github.com/rs/zerolog/_config.yml b/vendor/github.com/rs/zerolog/_config.yml deleted file mode 100644 index a1e896d..0000000 --- a/vendor/github.com/rs/zerolog/_config.yml +++ /dev/null @@ -1 +0,0 @@ -remote_theme: rs/gh-readme diff --git a/vendor/github.com/rs/zerolog/array.go b/vendor/github.com/rs/zerolog/array.go deleted file mode 100644 index c75c052..0000000 --- a/vendor/github.com/rs/zerolog/array.go +++ /dev/null @@ -1,240 +0,0 @@ -package zerolog - -import ( - "net" - "sync" - "time" -) - -var arrayPool = &sync.Pool{ - New: func() interface{} { - return &Array{ - buf: make([]byte, 0, 500), - } - }, -} - -// Array is used to prepopulate an array of items -// which can be re-used to add to log messages. -type Array struct { - buf []byte -} - -func putArray(a *Array) { - // Proper usage of a sync.Pool requires each entry to have approximately - // the same memory cost. To obtain this property when the stored type - // contains a variably-sized buffer, we add a hard limit on the maximum buffer - // to place back in the pool. - // - // See https://golang.org/issue/23199 - const maxSize = 1 << 16 // 64KiB - if cap(a.buf) > maxSize { - return - } - arrayPool.Put(a) -} - -// Arr creates an array to be added to an Event or Context. -func Arr() *Array { - a := arrayPool.Get().(*Array) - a.buf = a.buf[:0] - return a -} - -// MarshalZerologArray method here is no-op - since data is -// already in the needed format. -func (*Array) MarshalZerologArray(*Array) { -} - -func (a *Array) write(dst []byte) []byte { - dst = enc.AppendArrayStart(dst) - if len(a.buf) > 0 { - dst = append(dst, a.buf...) - } - dst = enc.AppendArrayEnd(dst) - putArray(a) - return dst -} - -// Object marshals an object that implement the LogObjectMarshaler -// interface and append append it to the array. -func (a *Array) Object(obj LogObjectMarshaler) *Array { - e := Dict() - obj.MarshalZerologObject(e) - e.buf = enc.AppendEndMarker(e.buf) - a.buf = append(enc.AppendArrayDelim(a.buf), e.buf...) - putEvent(e) - return a -} - -// Str append append the val as a string to the array. -func (a *Array) Str(val string) *Array { - a.buf = enc.AppendString(enc.AppendArrayDelim(a.buf), val) - return a -} - -// Bytes append append the val as a string to the array. -func (a *Array) Bytes(val []byte) *Array { - a.buf = enc.AppendBytes(enc.AppendArrayDelim(a.buf), val) - return a -} - -// Hex append append the val as a hex string to the array. -func (a *Array) Hex(val []byte) *Array { - a.buf = enc.AppendHex(enc.AppendArrayDelim(a.buf), val) - return a -} - -// RawJSON adds already encoded JSON to the array. -func (a *Array) RawJSON(val []byte) *Array { - a.buf = appendJSON(enc.AppendArrayDelim(a.buf), val) - return a -} - -// Err serializes and appends the err to the array. -func (a *Array) Err(err error) *Array { - switch m := ErrorMarshalFunc(err).(type) { - case LogObjectMarshaler: - e := newEvent(nil, 0) - e.buf = e.buf[:0] - e.appendObject(m) - a.buf = append(enc.AppendArrayDelim(a.buf), e.buf...) - putEvent(e) - case error: - if m == nil || isNilValue(m) { - a.buf = enc.AppendNil(enc.AppendArrayDelim(a.buf)) - } else { - a.buf = enc.AppendString(enc.AppendArrayDelim(a.buf), m.Error()) - } - case string: - a.buf = enc.AppendString(enc.AppendArrayDelim(a.buf), m) - default: - a.buf = enc.AppendInterface(enc.AppendArrayDelim(a.buf), m) - } - - return a -} - -// Bool append append the val as a bool to the array. -func (a *Array) Bool(b bool) *Array { - a.buf = enc.AppendBool(enc.AppendArrayDelim(a.buf), b) - return a -} - -// Int append append i as a int to the array. -func (a *Array) Int(i int) *Array { - a.buf = enc.AppendInt(enc.AppendArrayDelim(a.buf), i) - return a -} - -// Int8 append append i as a int8 to the array. -func (a *Array) Int8(i int8) *Array { - a.buf = enc.AppendInt8(enc.AppendArrayDelim(a.buf), i) - return a -} - -// Int16 append append i as a int16 to the array. -func (a *Array) Int16(i int16) *Array { - a.buf = enc.AppendInt16(enc.AppendArrayDelim(a.buf), i) - return a -} - -// Int32 append append i as a int32 to the array. -func (a *Array) Int32(i int32) *Array { - a.buf = enc.AppendInt32(enc.AppendArrayDelim(a.buf), i) - return a -} - -// Int64 append append i as a int64 to the array. -func (a *Array) Int64(i int64) *Array { - a.buf = enc.AppendInt64(enc.AppendArrayDelim(a.buf), i) - return a -} - -// Uint append append i as a uint to the array. -func (a *Array) Uint(i uint) *Array { - a.buf = enc.AppendUint(enc.AppendArrayDelim(a.buf), i) - return a -} - -// Uint8 append append i as a uint8 to the array. -func (a *Array) Uint8(i uint8) *Array { - a.buf = enc.AppendUint8(enc.AppendArrayDelim(a.buf), i) - return a -} - -// Uint16 append append i as a uint16 to the array. -func (a *Array) Uint16(i uint16) *Array { - a.buf = enc.AppendUint16(enc.AppendArrayDelim(a.buf), i) - return a -} - -// Uint32 append append i as a uint32 to the array. -func (a *Array) Uint32(i uint32) *Array { - a.buf = enc.AppendUint32(enc.AppendArrayDelim(a.buf), i) - return a -} - -// Uint64 append append i as a uint64 to the array. -func (a *Array) Uint64(i uint64) *Array { - a.buf = enc.AppendUint64(enc.AppendArrayDelim(a.buf), i) - return a -} - -// Float32 append append f as a float32 to the array. -func (a *Array) Float32(f float32) *Array { - a.buf = enc.AppendFloat32(enc.AppendArrayDelim(a.buf), f) - return a -} - -// Float64 append append f as a float64 to the array. -func (a *Array) Float64(f float64) *Array { - a.buf = enc.AppendFloat64(enc.AppendArrayDelim(a.buf), f) - return a -} - -// Time append append t formatted as string using zerolog.TimeFieldFormat. -func (a *Array) Time(t time.Time) *Array { - a.buf = enc.AppendTime(enc.AppendArrayDelim(a.buf), t, TimeFieldFormat) - return a -} - -// Dur append append d to the array. -func (a *Array) Dur(d time.Duration) *Array { - a.buf = enc.AppendDuration(enc.AppendArrayDelim(a.buf), d, DurationFieldUnit, DurationFieldInteger) - return a -} - -// Interface append append i marshaled using reflection. -func (a *Array) Interface(i interface{}) *Array { - if obj, ok := i.(LogObjectMarshaler); ok { - return a.Object(obj) - } - a.buf = enc.AppendInterface(enc.AppendArrayDelim(a.buf), i) - return a -} - -// IPAddr adds IPv4 or IPv6 address to the array -func (a *Array) IPAddr(ip net.IP) *Array { - a.buf = enc.AppendIPAddr(enc.AppendArrayDelim(a.buf), ip) - return a -} - -// IPPrefix adds IPv4 or IPv6 Prefix (IP + mask) to the array -func (a *Array) IPPrefix(pfx net.IPNet) *Array { - a.buf = enc.AppendIPPrefix(enc.AppendArrayDelim(a.buf), pfx) - return a -} - -// MACAddr adds a MAC (Ethernet) address to the array -func (a *Array) MACAddr(ha net.HardwareAddr) *Array { - a.buf = enc.AppendMACAddr(enc.AppendArrayDelim(a.buf), ha) - return a -} - -// Dict adds the dict Event to the array -func (a *Array) Dict(dict *Event) *Array { - dict.buf = enc.AppendEndMarker(dict.buf) - a.buf = append(enc.AppendArrayDelim(a.buf), dict.buf...) - return a -} diff --git a/vendor/github.com/rs/zerolog/console.go b/vendor/github.com/rs/zerolog/console.go deleted file mode 100644 index ac34b7e..0000000 --- a/vendor/github.com/rs/zerolog/console.go +++ /dev/null @@ -1,446 +0,0 @@ -package zerolog - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "os" - "path/filepath" - "sort" - "strconv" - "strings" - "sync" - "time" - - "github.com/mattn/go-colorable" -) - -const ( - colorBlack = iota + 30 - colorRed - colorGreen - colorYellow - colorBlue - colorMagenta - colorCyan - colorWhite - - colorBold = 1 - colorDarkGray = 90 -) - -var ( - consoleBufPool = sync.Pool{ - New: func() interface{} { - return bytes.NewBuffer(make([]byte, 0, 100)) - }, - } -) - -const ( - consoleDefaultTimeFormat = time.Kitchen -) - -// Formatter transforms the input into a formatted string. -type Formatter func(interface{}) string - -// ConsoleWriter parses the JSON input and writes it in an -// (optionally) colorized, human-friendly format to Out. -type ConsoleWriter struct { - // Out is the output destination. - Out io.Writer - - // NoColor disables the colorized output. - NoColor bool - - // TimeFormat specifies the format for timestamp in output. - TimeFormat string - - // PartsOrder defines the order of parts in output. - PartsOrder []string - - // PartsExclude defines parts to not display in output. - PartsExclude []string - - // FieldsExclude defines contextual fields to not display in output. - FieldsExclude []string - - FormatTimestamp Formatter - FormatLevel Formatter - FormatCaller Formatter - FormatMessage Formatter - FormatFieldName Formatter - FormatFieldValue Formatter - FormatErrFieldName Formatter - FormatErrFieldValue Formatter - - FormatExtra func(map[string]interface{}, *bytes.Buffer) error -} - -// NewConsoleWriter creates and initializes a new ConsoleWriter. -func NewConsoleWriter(options ...func(w *ConsoleWriter)) ConsoleWriter { - w := ConsoleWriter{ - Out: os.Stdout, - TimeFormat: consoleDefaultTimeFormat, - PartsOrder: consoleDefaultPartsOrder(), - } - - for _, opt := range options { - opt(&w) - } - - // Fix color on Windows - if w.Out == os.Stdout || w.Out == os.Stderr { - w.Out = colorable.NewColorable(w.Out.(*os.File)) - } - - return w -} - -// Write transforms the JSON input with formatters and appends to w.Out. -func (w ConsoleWriter) Write(p []byte) (n int, err error) { - // Fix color on Windows - if w.Out == os.Stdout || w.Out == os.Stderr { - w.Out = colorable.NewColorable(w.Out.(*os.File)) - } - - if w.PartsOrder == nil { - w.PartsOrder = consoleDefaultPartsOrder() - } - - var buf = consoleBufPool.Get().(*bytes.Buffer) - defer func() { - buf.Reset() - consoleBufPool.Put(buf) - }() - - var evt map[string]interface{} - p = decodeIfBinaryToBytes(p) - d := json.NewDecoder(bytes.NewReader(p)) - d.UseNumber() - err = d.Decode(&evt) - if err != nil { - return n, fmt.Errorf("cannot decode event: %s", err) - } - - for _, p := range w.PartsOrder { - w.writePart(buf, evt, p) - } - - w.writeFields(evt, buf) - - if w.FormatExtra != nil { - err = w.FormatExtra(evt, buf) - if err != nil { - return n, err - } - } - - err = buf.WriteByte('\n') - if err != nil { - return n, err - } - - _, err = buf.WriteTo(w.Out) - return len(p), err -} - -// writeFields appends formatted key-value pairs to buf. -func (w ConsoleWriter) writeFields(evt map[string]interface{}, buf *bytes.Buffer) { - var fields = make([]string, 0, len(evt)) - for field := range evt { - var isExcluded bool - for _, excluded := range w.FieldsExclude { - if field == excluded { - isExcluded = true - break - } - } - if isExcluded { - continue - } - - switch field { - case LevelFieldName, TimestampFieldName, MessageFieldName, CallerFieldName: - continue - } - fields = append(fields, field) - } - sort.Strings(fields) - - // Write space only if something has already been written to the buffer, and if there are fields. - if buf.Len() > 0 && len(fields) > 0 { - buf.WriteByte(' ') - } - - // Move the "error" field to the front - ei := sort.Search(len(fields), func(i int) bool { return fields[i] >= ErrorFieldName }) - if ei < len(fields) && fields[ei] == ErrorFieldName { - fields[ei] = "" - fields = append([]string{ErrorFieldName}, fields...) - var xfields = make([]string, 0, len(fields)) - for _, field := range fields { - if field == "" { // Skip empty fields - continue - } - xfields = append(xfields, field) - } - fields = xfields - } - - for i, field := range fields { - var fn Formatter - var fv Formatter - - if field == ErrorFieldName { - if w.FormatErrFieldName == nil { - fn = consoleDefaultFormatErrFieldName(w.NoColor) - } else { - fn = w.FormatErrFieldName - } - - if w.FormatErrFieldValue == nil { - fv = consoleDefaultFormatErrFieldValue(w.NoColor) - } else { - fv = w.FormatErrFieldValue - } - } else { - if w.FormatFieldName == nil { - fn = consoleDefaultFormatFieldName(w.NoColor) - } else { - fn = w.FormatFieldName - } - - if w.FormatFieldValue == nil { - fv = consoleDefaultFormatFieldValue - } else { - fv = w.FormatFieldValue - } - } - - buf.WriteString(fn(field)) - - switch fValue := evt[field].(type) { - case string: - if needsQuote(fValue) { - buf.WriteString(fv(strconv.Quote(fValue))) - } else { - buf.WriteString(fv(fValue)) - } - case json.Number: - buf.WriteString(fv(fValue)) - default: - b, err := InterfaceMarshalFunc(fValue) - if err != nil { - fmt.Fprintf(buf, colorize("[error: %v]", colorRed, w.NoColor), err) - } else { - fmt.Fprint(buf, fv(b)) - } - } - - if i < len(fields)-1 { // Skip space for last field - buf.WriteByte(' ') - } - } -} - -// writePart appends a formatted part to buf. -func (w ConsoleWriter) writePart(buf *bytes.Buffer, evt map[string]interface{}, p string) { - var f Formatter - - if w.PartsExclude != nil && len(w.PartsExclude) > 0 { - for _, exclude := range w.PartsExclude { - if exclude == p { - return - } - } - } - - switch p { - case LevelFieldName: - if w.FormatLevel == nil { - f = consoleDefaultFormatLevel(w.NoColor) - } else { - f = w.FormatLevel - } - case TimestampFieldName: - if w.FormatTimestamp == nil { - f = consoleDefaultFormatTimestamp(w.TimeFormat, w.NoColor) - } else { - f = w.FormatTimestamp - } - case MessageFieldName: - if w.FormatMessage == nil { - f = consoleDefaultFormatMessage - } else { - f = w.FormatMessage - } - case CallerFieldName: - if w.FormatCaller == nil { - f = consoleDefaultFormatCaller(w.NoColor) - } else { - f = w.FormatCaller - } - default: - if w.FormatFieldValue == nil { - f = consoleDefaultFormatFieldValue - } else { - f = w.FormatFieldValue - } - } - - var s = f(evt[p]) - - if len(s) > 0 { - if buf.Len() > 0 { - buf.WriteByte(' ') // Write space only if not the first part - } - buf.WriteString(s) - } -} - -// needsQuote returns true when the string s should be quoted in output. -func needsQuote(s string) bool { - for i := range s { - if s[i] < 0x20 || s[i] > 0x7e || s[i] == ' ' || s[i] == '\\' || s[i] == '"' { - return true - } - } - return false -} - -// colorize returns the string s wrapped in ANSI code c, unless disabled is true. -func colorize(s interface{}, c int, disabled bool) string { - if disabled { - return fmt.Sprintf("%s", s) - } - return fmt.Sprintf("\x1b[%dm%v\x1b[0m", c, s) -} - -// ----- DEFAULT FORMATTERS --------------------------------------------------- - -func consoleDefaultPartsOrder() []string { - return []string{ - TimestampFieldName, - LevelFieldName, - CallerFieldName, - MessageFieldName, - } -} - -func consoleDefaultFormatTimestamp(timeFormat string, noColor bool) Formatter { - if timeFormat == "" { - timeFormat = consoleDefaultTimeFormat - } - return func(i interface{}) string { - t := "" - switch tt := i.(type) { - case string: - ts, err := time.Parse(TimeFieldFormat, tt) - if err != nil { - t = tt - } else { - t = ts.Local().Format(timeFormat) - } - case json.Number: - i, err := tt.Int64() - if err != nil { - t = tt.String() - } else { - var sec, nsec int64 = i, 0 - switch TimeFieldFormat { - case TimeFormatUnixMs: - nsec = int64(time.Duration(i) * time.Millisecond) - sec = 0 - case TimeFormatUnixMicro: - nsec = int64(time.Duration(i) * time.Microsecond) - sec = 0 - } - ts := time.Unix(sec, nsec) - t = ts.Format(timeFormat) - } - } - return colorize(t, colorDarkGray, noColor) - } -} - -func consoleDefaultFormatLevel(noColor bool) Formatter { - return func(i interface{}) string { - var l string - if ll, ok := i.(string); ok { - switch ll { - case LevelTraceValue: - l = colorize("TRC", colorMagenta, noColor) - case LevelDebugValue: - l = colorize("DBG", colorYellow, noColor) - case LevelInfoValue: - l = colorize("INF", colorGreen, noColor) - case LevelWarnValue: - l = colorize("WRN", colorRed, noColor) - case LevelErrorValue: - l = colorize(colorize("ERR", colorRed, noColor), colorBold, noColor) - case LevelFatalValue: - l = colorize(colorize("FTL", colorRed, noColor), colorBold, noColor) - case LevelPanicValue: - l = colorize(colorize("PNC", colorRed, noColor), colorBold, noColor) - default: - l = colorize("???", colorBold, noColor) - } - } else { - if i == nil { - l = colorize("???", colorBold, noColor) - } else { - l = strings.ToUpper(fmt.Sprintf("%s", i))[0:3] - } - } - return l - } -} - -func consoleDefaultFormatCaller(noColor bool) Formatter { - return func(i interface{}) string { - var c string - if cc, ok := i.(string); ok { - c = cc - } - if len(c) > 0 { - if cwd, err := os.Getwd(); err == nil { - if rel, err := filepath.Rel(cwd, c); err == nil { - c = rel - } - } - c = colorize(c, colorBold, noColor) + colorize(" >", colorCyan, noColor) - } - return c - } -} - -func consoleDefaultFormatMessage(i interface{}) string { - if i == nil { - return "" - } - return fmt.Sprintf("%s", i) -} - -func consoleDefaultFormatFieldName(noColor bool) Formatter { - return func(i interface{}) string { - return colorize(fmt.Sprintf("%s=", i), colorCyan, noColor) - } -} - -func consoleDefaultFormatFieldValue(i interface{}) string { - return fmt.Sprintf("%s", i) -} - -func consoleDefaultFormatErrFieldName(noColor bool) Formatter { - return func(i interface{}) string { - return colorize(fmt.Sprintf("%s=", i), colorCyan, noColor) - } -} - -func consoleDefaultFormatErrFieldValue(noColor bool) Formatter { - return func(i interface{}) string { - return colorize(fmt.Sprintf("%s", i), colorRed, noColor) - } -} diff --git a/vendor/github.com/rs/zerolog/context.go b/vendor/github.com/rs/zerolog/context.go deleted file mode 100644 index f398e31..0000000 --- a/vendor/github.com/rs/zerolog/context.go +++ /dev/null @@ -1,433 +0,0 @@ -package zerolog - -import ( - "fmt" - "io/ioutil" - "math" - "net" - "time" -) - -// Context configures a new sub-logger with contextual fields. -type Context struct { - l Logger -} - -// Logger returns the logger with the context previously set. -func (c Context) Logger() Logger { - return c.l -} - -// Fields is a helper function to use a map or slice to set fields using type assertion. -// Only map[string]interface{} and []interface{} are accepted. []interface{} must -// alternate string keys and arbitrary values, and extraneous ones are ignored. -func (c Context) Fields(fields interface{}) Context { - c.l.context = appendFields(c.l.context, fields) - return c -} - -// Dict adds the field key with the dict to the logger context. -func (c Context) Dict(key string, dict *Event) Context { - dict.buf = enc.AppendEndMarker(dict.buf) - c.l.context = append(enc.AppendKey(c.l.context, key), dict.buf...) - putEvent(dict) - return c -} - -// Array adds the field key with an array to the event context. -// Use zerolog.Arr() to create the array or pass a type that -// implement the LogArrayMarshaler interface. -func (c Context) Array(key string, arr LogArrayMarshaler) Context { - c.l.context = enc.AppendKey(c.l.context, key) - if arr, ok := arr.(*Array); ok { - c.l.context = arr.write(c.l.context) - return c - } - var a *Array - if aa, ok := arr.(*Array); ok { - a = aa - } else { - a = Arr() - arr.MarshalZerologArray(a) - } - c.l.context = a.write(c.l.context) - return c -} - -// Object marshals an object that implement the LogObjectMarshaler interface. -func (c Context) Object(key string, obj LogObjectMarshaler) Context { - e := newEvent(levelWriterAdapter{ioutil.Discard}, 0) - e.Object(key, obj) - c.l.context = enc.AppendObjectData(c.l.context, e.buf) - putEvent(e) - return c -} - -// EmbedObject marshals and Embeds an object that implement the LogObjectMarshaler interface. -func (c Context) EmbedObject(obj LogObjectMarshaler) Context { - e := newEvent(levelWriterAdapter{ioutil.Discard}, 0) - e.EmbedObject(obj) - c.l.context = enc.AppendObjectData(c.l.context, e.buf) - putEvent(e) - return c -} - -// Str adds the field key with val as a string to the logger context. -func (c Context) Str(key, val string) Context { - c.l.context = enc.AppendString(enc.AppendKey(c.l.context, key), val) - return c -} - -// Strs adds the field key with val as a string to the logger context. -func (c Context) Strs(key string, vals []string) Context { - c.l.context = enc.AppendStrings(enc.AppendKey(c.l.context, key), vals) - return c -} - -// Stringer adds the field key with val.String() (or null if val is nil) to the logger context. -func (c Context) Stringer(key string, val fmt.Stringer) Context { - if val != nil { - c.l.context = enc.AppendString(enc.AppendKey(c.l.context, key), val.String()) - return c - } - - c.l.context = enc.AppendInterface(enc.AppendKey(c.l.context, key), nil) - return c -} - -// Bytes adds the field key with val as a []byte to the logger context. -func (c Context) Bytes(key string, val []byte) Context { - c.l.context = enc.AppendBytes(enc.AppendKey(c.l.context, key), val) - return c -} - -// Hex adds the field key with val as a hex string to the logger context. -func (c Context) Hex(key string, val []byte) Context { - c.l.context = enc.AppendHex(enc.AppendKey(c.l.context, key), val) - return c -} - -// RawJSON adds already encoded JSON to context. -// -// No sanity check is performed on b; it must not contain carriage returns and -// be valid JSON. -func (c Context) RawJSON(key string, b []byte) Context { - c.l.context = appendJSON(enc.AppendKey(c.l.context, key), b) - return c -} - -// AnErr adds the field key with serialized err to the logger context. -func (c Context) AnErr(key string, err error) Context { - switch m := ErrorMarshalFunc(err).(type) { - case nil: - return c - case LogObjectMarshaler: - return c.Object(key, m) - case error: - if m == nil || isNilValue(m) { - return c - } else { - return c.Str(key, m.Error()) - } - case string: - return c.Str(key, m) - default: - return c.Interface(key, m) - } -} - -// Errs adds the field key with errs as an array of serialized errors to the -// logger context. -func (c Context) Errs(key string, errs []error) Context { - arr := Arr() - for _, err := range errs { - switch m := ErrorMarshalFunc(err).(type) { - case LogObjectMarshaler: - arr = arr.Object(m) - case error: - if m == nil || isNilValue(m) { - arr = arr.Interface(nil) - } else { - arr = arr.Str(m.Error()) - } - case string: - arr = arr.Str(m) - default: - arr = arr.Interface(m) - } - } - - return c.Array(key, arr) -} - -// Err adds the field "error" with serialized err to the logger context. -func (c Context) Err(err error) Context { - return c.AnErr(ErrorFieldName, err) -} - -// Bool adds the field key with val as a bool to the logger context. -func (c Context) Bool(key string, b bool) Context { - c.l.context = enc.AppendBool(enc.AppendKey(c.l.context, key), b) - return c -} - -// Bools adds the field key with val as a []bool to the logger context. -func (c Context) Bools(key string, b []bool) Context { - c.l.context = enc.AppendBools(enc.AppendKey(c.l.context, key), b) - return c -} - -// Int adds the field key with i as a int to the logger context. -func (c Context) Int(key string, i int) Context { - c.l.context = enc.AppendInt(enc.AppendKey(c.l.context, key), i) - return c -} - -// Ints adds the field key with i as a []int to the logger context. -func (c Context) Ints(key string, i []int) Context { - c.l.context = enc.AppendInts(enc.AppendKey(c.l.context, key), i) - return c -} - -// Int8 adds the field key with i as a int8 to the logger context. -func (c Context) Int8(key string, i int8) Context { - c.l.context = enc.AppendInt8(enc.AppendKey(c.l.context, key), i) - return c -} - -// Ints8 adds the field key with i as a []int8 to the logger context. -func (c Context) Ints8(key string, i []int8) Context { - c.l.context = enc.AppendInts8(enc.AppendKey(c.l.context, key), i) - return c -} - -// Int16 adds the field key with i as a int16 to the logger context. -func (c Context) Int16(key string, i int16) Context { - c.l.context = enc.AppendInt16(enc.AppendKey(c.l.context, key), i) - return c -} - -// Ints16 adds the field key with i as a []int16 to the logger context. -func (c Context) Ints16(key string, i []int16) Context { - c.l.context = enc.AppendInts16(enc.AppendKey(c.l.context, key), i) - return c -} - -// Int32 adds the field key with i as a int32 to the logger context. -func (c Context) Int32(key string, i int32) Context { - c.l.context = enc.AppendInt32(enc.AppendKey(c.l.context, key), i) - return c -} - -// Ints32 adds the field key with i as a []int32 to the logger context. -func (c Context) Ints32(key string, i []int32) Context { - c.l.context = enc.AppendInts32(enc.AppendKey(c.l.context, key), i) - return c -} - -// Int64 adds the field key with i as a int64 to the logger context. -func (c Context) Int64(key string, i int64) Context { - c.l.context = enc.AppendInt64(enc.AppendKey(c.l.context, key), i) - return c -} - -// Ints64 adds the field key with i as a []int64 to the logger context. -func (c Context) Ints64(key string, i []int64) Context { - c.l.context = enc.AppendInts64(enc.AppendKey(c.l.context, key), i) - return c -} - -// Uint adds the field key with i as a uint to the logger context. -func (c Context) Uint(key string, i uint) Context { - c.l.context = enc.AppendUint(enc.AppendKey(c.l.context, key), i) - return c -} - -// Uints adds the field key with i as a []uint to the logger context. -func (c Context) Uints(key string, i []uint) Context { - c.l.context = enc.AppendUints(enc.AppendKey(c.l.context, key), i) - return c -} - -// Uint8 adds the field key with i as a uint8 to the logger context. -func (c Context) Uint8(key string, i uint8) Context { - c.l.context = enc.AppendUint8(enc.AppendKey(c.l.context, key), i) - return c -} - -// Uints8 adds the field key with i as a []uint8 to the logger context. -func (c Context) Uints8(key string, i []uint8) Context { - c.l.context = enc.AppendUints8(enc.AppendKey(c.l.context, key), i) - return c -} - -// Uint16 adds the field key with i as a uint16 to the logger context. -func (c Context) Uint16(key string, i uint16) Context { - c.l.context = enc.AppendUint16(enc.AppendKey(c.l.context, key), i) - return c -} - -// Uints16 adds the field key with i as a []uint16 to the logger context. -func (c Context) Uints16(key string, i []uint16) Context { - c.l.context = enc.AppendUints16(enc.AppendKey(c.l.context, key), i) - return c -} - -// Uint32 adds the field key with i as a uint32 to the logger context. -func (c Context) Uint32(key string, i uint32) Context { - c.l.context = enc.AppendUint32(enc.AppendKey(c.l.context, key), i) - return c -} - -// Uints32 adds the field key with i as a []uint32 to the logger context. -func (c Context) Uints32(key string, i []uint32) Context { - c.l.context = enc.AppendUints32(enc.AppendKey(c.l.context, key), i) - return c -} - -// Uint64 adds the field key with i as a uint64 to the logger context. -func (c Context) Uint64(key string, i uint64) Context { - c.l.context = enc.AppendUint64(enc.AppendKey(c.l.context, key), i) - return c -} - -// Uints64 adds the field key with i as a []uint64 to the logger context. -func (c Context) Uints64(key string, i []uint64) Context { - c.l.context = enc.AppendUints64(enc.AppendKey(c.l.context, key), i) - return c -} - -// Float32 adds the field key with f as a float32 to the logger context. -func (c Context) Float32(key string, f float32) Context { - c.l.context = enc.AppendFloat32(enc.AppendKey(c.l.context, key), f) - return c -} - -// Floats32 adds the field key with f as a []float32 to the logger context. -func (c Context) Floats32(key string, f []float32) Context { - c.l.context = enc.AppendFloats32(enc.AppendKey(c.l.context, key), f) - return c -} - -// Float64 adds the field key with f as a float64 to the logger context. -func (c Context) Float64(key string, f float64) Context { - c.l.context = enc.AppendFloat64(enc.AppendKey(c.l.context, key), f) - return c -} - -// Floats64 adds the field key with f as a []float64 to the logger context. -func (c Context) Floats64(key string, f []float64) Context { - c.l.context = enc.AppendFloats64(enc.AppendKey(c.l.context, key), f) - return c -} - -type timestampHook struct{} - -func (ts timestampHook) Run(e *Event, level Level, msg string) { - e.Timestamp() -} - -var th = timestampHook{} - -// Timestamp adds the current local time as UNIX timestamp to the logger context with the "time" key. -// To customize the key name, change zerolog.TimestampFieldName. -// -// NOTE: It won't dedupe the "time" key if the *Context has one already. -func (c Context) Timestamp() Context { - c.l = c.l.Hook(th) - return c -} - -// Time adds the field key with t formated as string using zerolog.TimeFieldFormat. -func (c Context) Time(key string, t time.Time) Context { - c.l.context = enc.AppendTime(enc.AppendKey(c.l.context, key), t, TimeFieldFormat) - return c -} - -// Times adds the field key with t formated as string using zerolog.TimeFieldFormat. -func (c Context) Times(key string, t []time.Time) Context { - c.l.context = enc.AppendTimes(enc.AppendKey(c.l.context, key), t, TimeFieldFormat) - return c -} - -// Dur adds the fields key with d divided by unit and stored as a float. -func (c Context) Dur(key string, d time.Duration) Context { - c.l.context = enc.AppendDuration(enc.AppendKey(c.l.context, key), d, DurationFieldUnit, DurationFieldInteger) - return c -} - -// Durs adds the fields key with d divided by unit and stored as a float. -func (c Context) Durs(key string, d []time.Duration) Context { - c.l.context = enc.AppendDurations(enc.AppendKey(c.l.context, key), d, DurationFieldUnit, DurationFieldInteger) - return c -} - -// Interface adds the field key with obj marshaled using reflection. -func (c Context) Interface(key string, i interface{}) Context { - c.l.context = enc.AppendInterface(enc.AppendKey(c.l.context, key), i) - return c -} - -type callerHook struct { - callerSkipFrameCount int -} - -func newCallerHook(skipFrameCount int) callerHook { - return callerHook{callerSkipFrameCount: skipFrameCount} -} - -func (ch callerHook) Run(e *Event, level Level, msg string) { - switch ch.callerSkipFrameCount { - case useGlobalSkipFrameCount: - // Extra frames to skip (added by hook infra). - e.caller(CallerSkipFrameCount + contextCallerSkipFrameCount) - default: - // Extra frames to skip (added by hook infra). - e.caller(ch.callerSkipFrameCount + contextCallerSkipFrameCount) - } -} - -// useGlobalSkipFrameCount acts as a flag to informat callerHook.Run -// to use the global CallerSkipFrameCount. -const useGlobalSkipFrameCount = math.MinInt32 - -// ch is the default caller hook using the global CallerSkipFrameCount. -var ch = newCallerHook(useGlobalSkipFrameCount) - -// Caller adds the file:line of the caller with the zerolog.CallerFieldName key. -func (c Context) Caller() Context { - c.l = c.l.Hook(ch) - return c -} - -// CallerWithSkipFrameCount adds the file:line of the caller with the zerolog.CallerFieldName key. -// The specified skipFrameCount int will override the global CallerSkipFrameCount for this context's respective logger. -// If set to -1 the global CallerSkipFrameCount will be used. -func (c Context) CallerWithSkipFrameCount(skipFrameCount int) Context { - c.l = c.l.Hook(newCallerHook(skipFrameCount)) - return c -} - -// Stack enables stack trace printing for the error passed to Err(). -func (c Context) Stack() Context { - c.l.stack = true - return c -} - -// IPAddr adds IPv4 or IPv6 Address to the context -func (c Context) IPAddr(key string, ip net.IP) Context { - c.l.context = enc.AppendIPAddr(enc.AppendKey(c.l.context, key), ip) - return c -} - -// IPPrefix adds IPv4 or IPv6 Prefix (address and mask) to the context -func (c Context) IPPrefix(key string, pfx net.IPNet) Context { - c.l.context = enc.AppendIPPrefix(enc.AppendKey(c.l.context, key), pfx) - return c -} - -// MACAddr adds MAC address to the context -func (c Context) MACAddr(key string, ha net.HardwareAddr) Context { - c.l.context = enc.AppendMACAddr(enc.AppendKey(c.l.context, key), ha) - return c -} diff --git a/vendor/github.com/rs/zerolog/ctx.go b/vendor/github.com/rs/zerolog/ctx.go deleted file mode 100644 index 44d3f4b..0000000 --- a/vendor/github.com/rs/zerolog/ctx.go +++ /dev/null @@ -1,51 +0,0 @@ -package zerolog - -import ( - "context" -) - -var disabledLogger *Logger - -func init() { - SetGlobalLevel(TraceLevel) - l := Nop() - disabledLogger = &l -} - -type ctxKey struct{} - -// WithContext returns a copy of ctx with l associated. If an instance of Logger -// is already in the context, the context is not updated. -// -// For instance, to add a field to an existing logger in the context, use this -// notation: -// -// ctx := r.Context() -// l := zerolog.Ctx(ctx) -// l.UpdateContext(func(c Context) Context { -// return c.Str("bar", "baz") -// }) -func (l Logger) WithContext(ctx context.Context) context.Context { - if lp, ok := ctx.Value(ctxKey{}).(*Logger); ok { - if lp == &l { - // Do not store same logger. - return ctx - } - } else if l.level == Disabled { - // Do not store disabled logger. - return ctx - } - return context.WithValue(ctx, ctxKey{}, &l) -} - -// Ctx returns the Logger associated with the ctx. If no logger -// is associated, DefaultContextLogger is returned, unless DefaultContextLogger -// is nil, in which case a disabled logger is returned. -func Ctx(ctx context.Context) *Logger { - if l, ok := ctx.Value(ctxKey{}).(*Logger); ok { - return l - } else if l = DefaultContextLogger; l != nil { - return l - } - return disabledLogger -} diff --git a/vendor/github.com/rs/zerolog/encoder.go b/vendor/github.com/rs/zerolog/encoder.go deleted file mode 100644 index 09b24e8..0000000 --- a/vendor/github.com/rs/zerolog/encoder.go +++ /dev/null @@ -1,56 +0,0 @@ -package zerolog - -import ( - "net" - "time" -) - -type encoder interface { - AppendArrayDelim(dst []byte) []byte - AppendArrayEnd(dst []byte) []byte - AppendArrayStart(dst []byte) []byte - AppendBeginMarker(dst []byte) []byte - AppendBool(dst []byte, val bool) []byte - AppendBools(dst []byte, vals []bool) []byte - AppendBytes(dst, s []byte) []byte - AppendDuration(dst []byte, d time.Duration, unit time.Duration, useInt bool) []byte - AppendDurations(dst []byte, vals []time.Duration, unit time.Duration, useInt bool) []byte - AppendEndMarker(dst []byte) []byte - AppendFloat32(dst []byte, val float32) []byte - AppendFloat64(dst []byte, val float64) []byte - AppendFloats32(dst []byte, vals []float32) []byte - AppendFloats64(dst []byte, vals []float64) []byte - AppendHex(dst, s []byte) []byte - AppendIPAddr(dst []byte, ip net.IP) []byte - AppendIPPrefix(dst []byte, pfx net.IPNet) []byte - AppendInt(dst []byte, val int) []byte - AppendInt16(dst []byte, val int16) []byte - AppendInt32(dst []byte, val int32) []byte - AppendInt64(dst []byte, val int64) []byte - AppendInt8(dst []byte, val int8) []byte - AppendInterface(dst []byte, i interface{}) []byte - AppendInts(dst []byte, vals []int) []byte - AppendInts16(dst []byte, vals []int16) []byte - AppendInts32(dst []byte, vals []int32) []byte - AppendInts64(dst []byte, vals []int64) []byte - AppendInts8(dst []byte, vals []int8) []byte - AppendKey(dst []byte, key string) []byte - AppendLineBreak(dst []byte) []byte - AppendMACAddr(dst []byte, ha net.HardwareAddr) []byte - AppendNil(dst []byte) []byte - AppendObjectData(dst []byte, o []byte) []byte - AppendString(dst []byte, s string) []byte - AppendStrings(dst []byte, vals []string) []byte - AppendTime(dst []byte, t time.Time, format string) []byte - AppendTimes(dst []byte, vals []time.Time, format string) []byte - AppendUint(dst []byte, val uint) []byte - AppendUint16(dst []byte, val uint16) []byte - AppendUint32(dst []byte, val uint32) []byte - AppendUint64(dst []byte, val uint64) []byte - AppendUint8(dst []byte, val uint8) []byte - AppendUints(dst []byte, vals []uint) []byte - AppendUints16(dst []byte, vals []uint16) []byte - AppendUints32(dst []byte, vals []uint32) []byte - AppendUints64(dst []byte, vals []uint64) []byte - AppendUints8(dst []byte, vals []uint8) []byte -} diff --git a/vendor/github.com/rs/zerolog/encoder_cbor.go b/vendor/github.com/rs/zerolog/encoder_cbor.go deleted file mode 100644 index 7b0dafe..0000000 --- a/vendor/github.com/rs/zerolog/encoder_cbor.go +++ /dev/null @@ -1,42 +0,0 @@ -// +build binary_log - -package zerolog - -// This file contains bindings to do binary encoding. - -import ( - "github.com/rs/zerolog/internal/cbor" -) - -var ( - _ encoder = (*cbor.Encoder)(nil) - - enc = cbor.Encoder{} -) - -func init() { - // using closure to reflect the changes at runtime. - cbor.JSONMarshalFunc = func(v interface{}) ([]byte, error) { - return InterfaceMarshalFunc(v) - } -} - -func appendJSON(dst []byte, j []byte) []byte { - return cbor.AppendEmbeddedJSON(dst, j) -} - -// decodeIfBinaryToString - converts a binary formatted log msg to a -// JSON formatted String Log message. -func decodeIfBinaryToString(in []byte) string { - return cbor.DecodeIfBinaryToString(in) -} - -func decodeObjectToStr(in []byte) string { - return cbor.DecodeObjectToStr(in) -} - -// decodeIfBinaryToBytes - converts a binary formatted log msg to a -// JSON formatted Bytes Log message. -func decodeIfBinaryToBytes(in []byte) []byte { - return cbor.DecodeIfBinaryToBytes(in) -} diff --git a/vendor/github.com/rs/zerolog/encoder_json.go b/vendor/github.com/rs/zerolog/encoder_json.go deleted file mode 100644 index 0e0450e..0000000 --- a/vendor/github.com/rs/zerolog/encoder_json.go +++ /dev/null @@ -1,39 +0,0 @@ -// +build !binary_log - -package zerolog - -// encoder_json.go file contains bindings to generate -// JSON encoded byte stream. - -import ( - "github.com/rs/zerolog/internal/json" -) - -var ( - _ encoder = (*json.Encoder)(nil) - - enc = json.Encoder{} -) - -func init() { - // using closure to reflect the changes at runtime. - json.JSONMarshalFunc = func(v interface{}) ([]byte, error) { - return InterfaceMarshalFunc(v) - } -} - -func appendJSON(dst []byte, j []byte) []byte { - return append(dst, j...) -} - -func decodeIfBinaryToString(in []byte) string { - return string(in) -} - -func decodeObjectToStr(in []byte) string { - return string(in) -} - -func decodeIfBinaryToBytes(in []byte) []byte { - return in -} diff --git a/vendor/github.com/rs/zerolog/event.go b/vendor/github.com/rs/zerolog/event.go deleted file mode 100644 index 0e2eaa6..0000000 --- a/vendor/github.com/rs/zerolog/event.go +++ /dev/null @@ -1,780 +0,0 @@ -package zerolog - -import ( - "fmt" - "net" - "os" - "runtime" - "sync" - "time" -) - -var eventPool = &sync.Pool{ - New: func() interface{} { - return &Event{ - buf: make([]byte, 0, 500), - } - }, -} - -// Event represents a log event. It is instanced by one of the level method of -// Logger and finalized by the Msg or Msgf method. -type Event struct { - buf []byte - w LevelWriter - level Level - done func(msg string) - stack bool // enable error stack trace - ch []Hook // hooks from context - skipFrame int // The number of additional frames to skip when printing the caller. -} - -func putEvent(e *Event) { - // Proper usage of a sync.Pool requires each entry to have approximately - // the same memory cost. To obtain this property when the stored type - // contains a variably-sized buffer, we add a hard limit on the maximum buffer - // to place back in the pool. - // - // See https://golang.org/issue/23199 - const maxSize = 1 << 16 // 64KiB - if cap(e.buf) > maxSize { - return - } - eventPool.Put(e) -} - -// LogObjectMarshaler provides a strongly-typed and encoding-agnostic interface -// to be implemented by types used with Event/Context's Object methods. -type LogObjectMarshaler interface { - MarshalZerologObject(e *Event) -} - -// LogArrayMarshaler provides a strongly-typed and encoding-agnostic interface -// to be implemented by types used with Event/Context's Array methods. -type LogArrayMarshaler interface { - MarshalZerologArray(a *Array) -} - -func newEvent(w LevelWriter, level Level) *Event { - e := eventPool.Get().(*Event) - e.buf = e.buf[:0] - e.ch = nil - e.buf = enc.AppendBeginMarker(e.buf) - e.w = w - e.level = level - e.stack = false - e.skipFrame = 0 - return e -} - -func (e *Event) write() (err error) { - if e == nil { - return nil - } - if e.level != Disabled { - e.buf = enc.AppendEndMarker(e.buf) - e.buf = enc.AppendLineBreak(e.buf) - if e.w != nil { - _, err = e.w.WriteLevel(e.level, e.buf) - } - } - putEvent(e) - return -} - -// Enabled return false if the *Event is going to be filtered out by -// log level or sampling. -func (e *Event) Enabled() bool { - return e != nil && e.level != Disabled -} - -// Discard disables the event so Msg(f) won't print it. -func (e *Event) Discard() *Event { - if e == nil { - return e - } - e.level = Disabled - return nil -} - -// Msg sends the *Event with msg added as the message field if not empty. -// -// NOTICE: once this method is called, the *Event should be disposed. -// Calling Msg twice can have unexpected result. -func (e *Event) Msg(msg string) { - if e == nil { - return - } - e.msg(msg) -} - -// Send is equivalent to calling Msg(""). -// -// NOTICE: once this method is called, the *Event should be disposed. -func (e *Event) Send() { - if e == nil { - return - } - e.msg("") -} - -// Msgf sends the event with formatted msg added as the message field if not empty. -// -// NOTICE: once this method is called, the *Event should be disposed. -// Calling Msgf twice can have unexpected result. -func (e *Event) Msgf(format string, v ...interface{}) { - if e == nil { - return - } - e.msg(fmt.Sprintf(format, v...)) -} - -func (e *Event) MsgFunc(createMsg func() string) { - if e == nil { - return - } - e.msg(createMsg()) -} - -func (e *Event) msg(msg string) { - for _, hook := range e.ch { - hook.Run(e, e.level, msg) - } - if msg != "" { - e.buf = enc.AppendString(enc.AppendKey(e.buf, MessageFieldName), msg) - } - if e.done != nil { - defer e.done(msg) - } - if err := e.write(); err != nil { - if ErrorHandler != nil { - ErrorHandler(err) - } else { - fmt.Fprintf(os.Stderr, "zerolog: could not write event: %v\n", err) - } - } -} - -// Fields is a helper function to use a map or slice to set fields using type assertion. -// Only map[string]interface{} and []interface{} are accepted. []interface{} must -// alternate string keys and arbitrary values, and extraneous ones are ignored. -func (e *Event) Fields(fields interface{}) *Event { - if e == nil { - return e - } - e.buf = appendFields(e.buf, fields) - return e -} - -// Dict adds the field key with a dict to the event context. -// Use zerolog.Dict() to create the dictionary. -func (e *Event) Dict(key string, dict *Event) *Event { - if e == nil { - return e - } - dict.buf = enc.AppendEndMarker(dict.buf) - e.buf = append(enc.AppendKey(e.buf, key), dict.buf...) - putEvent(dict) - return e -} - -// Dict creates an Event to be used with the *Event.Dict method. -// Call usual field methods like Str, Int etc to add fields to this -// event and give it as argument the *Event.Dict method. -func Dict() *Event { - return newEvent(nil, 0) -} - -// Array adds the field key with an array to the event context. -// Use zerolog.Arr() to create the array or pass a type that -// implement the LogArrayMarshaler interface. -func (e *Event) Array(key string, arr LogArrayMarshaler) *Event { - if e == nil { - return e - } - e.buf = enc.AppendKey(e.buf, key) - var a *Array - if aa, ok := arr.(*Array); ok { - a = aa - } else { - a = Arr() - arr.MarshalZerologArray(a) - } - e.buf = a.write(e.buf) - return e -} - -func (e *Event) appendObject(obj LogObjectMarshaler) { - e.buf = enc.AppendBeginMarker(e.buf) - obj.MarshalZerologObject(e) - e.buf = enc.AppendEndMarker(e.buf) -} - -// Object marshals an object that implement the LogObjectMarshaler interface. -func (e *Event) Object(key string, obj LogObjectMarshaler) *Event { - if e == nil { - return e - } - e.buf = enc.AppendKey(e.buf, key) - if obj == nil { - e.buf = enc.AppendNil(e.buf) - - return e - } - - e.appendObject(obj) - return e -} - -// Func allows an anonymous func to run only if the event is enabled. -func (e *Event) Func(f func(e *Event)) *Event { - if e != nil && e.Enabled() { - f(e) - } - return e -} - -// EmbedObject marshals an object that implement the LogObjectMarshaler interface. -func (e *Event) EmbedObject(obj LogObjectMarshaler) *Event { - if e == nil { - return e - } - if obj == nil { - return e - } - obj.MarshalZerologObject(e) - return e -} - -// Str adds the field key with val as a string to the *Event context. -func (e *Event) Str(key, val string) *Event { - if e == nil { - return e - } - e.buf = enc.AppendString(enc.AppendKey(e.buf, key), val) - return e -} - -// Strs adds the field key with vals as a []string to the *Event context. -func (e *Event) Strs(key string, vals []string) *Event { - if e == nil { - return e - } - e.buf = enc.AppendStrings(enc.AppendKey(e.buf, key), vals) - return e -} - -// Stringer adds the field key with val.String() (or null if val is nil) -// to the *Event context. -func (e *Event) Stringer(key string, val fmt.Stringer) *Event { - if e == nil { - return e - } - e.buf = enc.AppendStringer(enc.AppendKey(e.buf, key), val) - return e -} - -// Stringers adds the field key with vals where each individual val -// is used as val.String() (or null if val is empty) to the *Event -// context. -func (e *Event) Stringers(key string, vals []fmt.Stringer) *Event { - if e == nil { - return e - } - e.buf = enc.AppendStringers(enc.AppendKey(e.buf, key), vals) - return e -} - -// Bytes adds the field key with val as a string to the *Event context. -// -// Runes outside of normal ASCII ranges will be hex-encoded in the resulting -// JSON. -func (e *Event) Bytes(key string, val []byte) *Event { - if e == nil { - return e - } - e.buf = enc.AppendBytes(enc.AppendKey(e.buf, key), val) - return e -} - -// Hex adds the field key with val as a hex string to the *Event context. -func (e *Event) Hex(key string, val []byte) *Event { - if e == nil { - return e - } - e.buf = enc.AppendHex(enc.AppendKey(e.buf, key), val) - return e -} - -// RawJSON adds already encoded JSON to the log line under key. -// -// No sanity check is performed on b; it must not contain carriage returns and -// be valid JSON. -func (e *Event) RawJSON(key string, b []byte) *Event { - if e == nil { - return e - } - e.buf = appendJSON(enc.AppendKey(e.buf, key), b) - return e -} - -// AnErr adds the field key with serialized err to the *Event context. -// If err is nil, no field is added. -func (e *Event) AnErr(key string, err error) *Event { - if e == nil { - return e - } - switch m := ErrorMarshalFunc(err).(type) { - case nil: - return e - case LogObjectMarshaler: - return e.Object(key, m) - case error: - if m == nil || isNilValue(m) { - return e - } else { - return e.Str(key, m.Error()) - } - case string: - return e.Str(key, m) - default: - return e.Interface(key, m) - } -} - -// Errs adds the field key with errs as an array of serialized errors to the -// *Event context. -func (e *Event) Errs(key string, errs []error) *Event { - if e == nil { - return e - } - arr := Arr() - for _, err := range errs { - switch m := ErrorMarshalFunc(err).(type) { - case LogObjectMarshaler: - arr = arr.Object(m) - case error: - arr = arr.Err(m) - case string: - arr = arr.Str(m) - default: - arr = arr.Interface(m) - } - } - - return e.Array(key, arr) -} - -// Err adds the field "error" with serialized err to the *Event context. -// If err is nil, no field is added. -// -// To customize the key name, change zerolog.ErrorFieldName. -// -// If Stack() has been called before and zerolog.ErrorStackMarshaler is defined, -// the err is passed to ErrorStackMarshaler and the result is appended to the -// zerolog.ErrorStackFieldName. -func (e *Event) Err(err error) *Event { - if e == nil { - return e - } - if e.stack && ErrorStackMarshaler != nil { - switch m := ErrorStackMarshaler(err).(type) { - case nil: - case LogObjectMarshaler: - e.Object(ErrorStackFieldName, m) - case error: - if m != nil && !isNilValue(m) { - e.Str(ErrorStackFieldName, m.Error()) - } - case string: - e.Str(ErrorStackFieldName, m) - default: - e.Interface(ErrorStackFieldName, m) - } - } - return e.AnErr(ErrorFieldName, err) -} - -// Stack enables stack trace printing for the error passed to Err(). -// -// ErrorStackMarshaler must be set for this method to do something. -func (e *Event) Stack() *Event { - if e != nil { - e.stack = true - } - return e -} - -// Bool adds the field key with val as a bool to the *Event context. -func (e *Event) Bool(key string, b bool) *Event { - if e == nil { - return e - } - e.buf = enc.AppendBool(enc.AppendKey(e.buf, key), b) - return e -} - -// Bools adds the field key with val as a []bool to the *Event context. -func (e *Event) Bools(key string, b []bool) *Event { - if e == nil { - return e - } - e.buf = enc.AppendBools(enc.AppendKey(e.buf, key), b) - return e -} - -// Int adds the field key with i as a int to the *Event context. -func (e *Event) Int(key string, i int) *Event { - if e == nil { - return e - } - e.buf = enc.AppendInt(enc.AppendKey(e.buf, key), i) - return e -} - -// Ints adds the field key with i as a []int to the *Event context. -func (e *Event) Ints(key string, i []int) *Event { - if e == nil { - return e - } - e.buf = enc.AppendInts(enc.AppendKey(e.buf, key), i) - return e -} - -// Int8 adds the field key with i as a int8 to the *Event context. -func (e *Event) Int8(key string, i int8) *Event { - if e == nil { - return e - } - e.buf = enc.AppendInt8(enc.AppendKey(e.buf, key), i) - return e -} - -// Ints8 adds the field key with i as a []int8 to the *Event context. -func (e *Event) Ints8(key string, i []int8) *Event { - if e == nil { - return e - } - e.buf = enc.AppendInts8(enc.AppendKey(e.buf, key), i) - return e -} - -// Int16 adds the field key with i as a int16 to the *Event context. -func (e *Event) Int16(key string, i int16) *Event { - if e == nil { - return e - } - e.buf = enc.AppendInt16(enc.AppendKey(e.buf, key), i) - return e -} - -// Ints16 adds the field key with i as a []int16 to the *Event context. -func (e *Event) Ints16(key string, i []int16) *Event { - if e == nil { - return e - } - e.buf = enc.AppendInts16(enc.AppendKey(e.buf, key), i) - return e -} - -// Int32 adds the field key with i as a int32 to the *Event context. -func (e *Event) Int32(key string, i int32) *Event { - if e == nil { - return e - } - e.buf = enc.AppendInt32(enc.AppendKey(e.buf, key), i) - return e -} - -// Ints32 adds the field key with i as a []int32 to the *Event context. -func (e *Event) Ints32(key string, i []int32) *Event { - if e == nil { - return e - } - e.buf = enc.AppendInts32(enc.AppendKey(e.buf, key), i) - return e -} - -// Int64 adds the field key with i as a int64 to the *Event context. -func (e *Event) Int64(key string, i int64) *Event { - if e == nil { - return e - } - e.buf = enc.AppendInt64(enc.AppendKey(e.buf, key), i) - return e -} - -// Ints64 adds the field key with i as a []int64 to the *Event context. -func (e *Event) Ints64(key string, i []int64) *Event { - if e == nil { - return e - } - e.buf = enc.AppendInts64(enc.AppendKey(e.buf, key), i) - return e -} - -// Uint adds the field key with i as a uint to the *Event context. -func (e *Event) Uint(key string, i uint) *Event { - if e == nil { - return e - } - e.buf = enc.AppendUint(enc.AppendKey(e.buf, key), i) - return e -} - -// Uints adds the field key with i as a []int to the *Event context. -func (e *Event) Uints(key string, i []uint) *Event { - if e == nil { - return e - } - e.buf = enc.AppendUints(enc.AppendKey(e.buf, key), i) - return e -} - -// Uint8 adds the field key with i as a uint8 to the *Event context. -func (e *Event) Uint8(key string, i uint8) *Event { - if e == nil { - return e - } - e.buf = enc.AppendUint8(enc.AppendKey(e.buf, key), i) - return e -} - -// Uints8 adds the field key with i as a []int8 to the *Event context. -func (e *Event) Uints8(key string, i []uint8) *Event { - if e == nil { - return e - } - e.buf = enc.AppendUints8(enc.AppendKey(e.buf, key), i) - return e -} - -// Uint16 adds the field key with i as a uint16 to the *Event context. -func (e *Event) Uint16(key string, i uint16) *Event { - if e == nil { - return e - } - e.buf = enc.AppendUint16(enc.AppendKey(e.buf, key), i) - return e -} - -// Uints16 adds the field key with i as a []int16 to the *Event context. -func (e *Event) Uints16(key string, i []uint16) *Event { - if e == nil { - return e - } - e.buf = enc.AppendUints16(enc.AppendKey(e.buf, key), i) - return e -} - -// Uint32 adds the field key with i as a uint32 to the *Event context. -func (e *Event) Uint32(key string, i uint32) *Event { - if e == nil { - return e - } - e.buf = enc.AppendUint32(enc.AppendKey(e.buf, key), i) - return e -} - -// Uints32 adds the field key with i as a []int32 to the *Event context. -func (e *Event) Uints32(key string, i []uint32) *Event { - if e == nil { - return e - } - e.buf = enc.AppendUints32(enc.AppendKey(e.buf, key), i) - return e -} - -// Uint64 adds the field key with i as a uint64 to the *Event context. -func (e *Event) Uint64(key string, i uint64) *Event { - if e == nil { - return e - } - e.buf = enc.AppendUint64(enc.AppendKey(e.buf, key), i) - return e -} - -// Uints64 adds the field key with i as a []int64 to the *Event context. -func (e *Event) Uints64(key string, i []uint64) *Event { - if e == nil { - return e - } - e.buf = enc.AppendUints64(enc.AppendKey(e.buf, key), i) - return e -} - -// Float32 adds the field key with f as a float32 to the *Event context. -func (e *Event) Float32(key string, f float32) *Event { - if e == nil { - return e - } - e.buf = enc.AppendFloat32(enc.AppendKey(e.buf, key), f) - return e -} - -// Floats32 adds the field key with f as a []float32 to the *Event context. -func (e *Event) Floats32(key string, f []float32) *Event { - if e == nil { - return e - } - e.buf = enc.AppendFloats32(enc.AppendKey(e.buf, key), f) - return e -} - -// Float64 adds the field key with f as a float64 to the *Event context. -func (e *Event) Float64(key string, f float64) *Event { - if e == nil { - return e - } - e.buf = enc.AppendFloat64(enc.AppendKey(e.buf, key), f) - return e -} - -// Floats64 adds the field key with f as a []float64 to the *Event context. -func (e *Event) Floats64(key string, f []float64) *Event { - if e == nil { - return e - } - e.buf = enc.AppendFloats64(enc.AppendKey(e.buf, key), f) - return e -} - -// Timestamp adds the current local time as UNIX timestamp to the *Event context with the "time" key. -// To customize the key name, change zerolog.TimestampFieldName. -// -// NOTE: It won't dedupe the "time" key if the *Event (or *Context) has one -// already. -func (e *Event) Timestamp() *Event { - if e == nil { - return e - } - e.buf = enc.AppendTime(enc.AppendKey(e.buf, TimestampFieldName), TimestampFunc(), TimeFieldFormat) - return e -} - -// Time adds the field key with t formatted as string using zerolog.TimeFieldFormat. -func (e *Event) Time(key string, t time.Time) *Event { - if e == nil { - return e - } - e.buf = enc.AppendTime(enc.AppendKey(e.buf, key), t, TimeFieldFormat) - return e -} - -// Times adds the field key with t formatted as string using zerolog.TimeFieldFormat. -func (e *Event) Times(key string, t []time.Time) *Event { - if e == nil { - return e - } - e.buf = enc.AppendTimes(enc.AppendKey(e.buf, key), t, TimeFieldFormat) - return e -} - -// Dur adds the field key with duration d stored as zerolog.DurationFieldUnit. -// If zerolog.DurationFieldInteger is true, durations are rendered as integer -// instead of float. -func (e *Event) Dur(key string, d time.Duration) *Event { - if e == nil { - return e - } - e.buf = enc.AppendDuration(enc.AppendKey(e.buf, key), d, DurationFieldUnit, DurationFieldInteger) - return e -} - -// Durs adds the field key with duration d stored as zerolog.DurationFieldUnit. -// If zerolog.DurationFieldInteger is true, durations are rendered as integer -// instead of float. -func (e *Event) Durs(key string, d []time.Duration) *Event { - if e == nil { - return e - } - e.buf = enc.AppendDurations(enc.AppendKey(e.buf, key), d, DurationFieldUnit, DurationFieldInteger) - return e -} - -// TimeDiff adds the field key with positive duration between time t and start. -// If time t is not greater than start, duration will be 0. -// Duration format follows the same principle as Dur(). -func (e *Event) TimeDiff(key string, t time.Time, start time.Time) *Event { - if e == nil { - return e - } - var d time.Duration - if t.After(start) { - d = t.Sub(start) - } - e.buf = enc.AppendDuration(enc.AppendKey(e.buf, key), d, DurationFieldUnit, DurationFieldInteger) - return e -} - -// Interface adds the field key with i marshaled using reflection. -func (e *Event) Interface(key string, i interface{}) *Event { - if e == nil { - return e - } - if obj, ok := i.(LogObjectMarshaler); ok { - return e.Object(key, obj) - } - e.buf = enc.AppendInterface(enc.AppendKey(e.buf, key), i) - return e -} - -// CallerSkipFrame instructs any future Caller calls to skip the specified number of frames. -// This includes those added via hooks from the context. -func (e *Event) CallerSkipFrame(skip int) *Event { - if e == nil { - return e - } - e.skipFrame += skip - return e -} - -// Caller adds the file:line of the caller with the zerolog.CallerFieldName key. -// The argument skip is the number of stack frames to ascend -// Skip If not passed, use the global variable CallerSkipFrameCount -func (e *Event) Caller(skip ...int) *Event { - sk := CallerSkipFrameCount - if len(skip) > 0 { - sk = skip[0] + CallerSkipFrameCount - } - return e.caller(sk) -} - -func (e *Event) caller(skip int) *Event { - if e == nil { - return e - } - pc, file, line, ok := runtime.Caller(skip + e.skipFrame) - if !ok { - return e - } - e.buf = enc.AppendString(enc.AppendKey(e.buf, CallerFieldName), CallerMarshalFunc(pc, file, line)) - return e -} - -// IPAddr adds IPv4 or IPv6 Address to the event -func (e *Event) IPAddr(key string, ip net.IP) *Event { - if e == nil { - return e - } - e.buf = enc.AppendIPAddr(enc.AppendKey(e.buf, key), ip) - return e -} - -// IPPrefix adds IPv4 or IPv6 Prefix (address and mask) to the event -func (e *Event) IPPrefix(key string, pfx net.IPNet) *Event { - if e == nil { - return e - } - e.buf = enc.AppendIPPrefix(enc.AppendKey(e.buf, key), pfx) - return e -} - -// MACAddr adds MAC address to the event -func (e *Event) MACAddr(key string, ha net.HardwareAddr) *Event { - if e == nil { - return e - } - e.buf = enc.AppendMACAddr(enc.AppendKey(e.buf, key), ha) - return e -} diff --git a/vendor/github.com/rs/zerolog/fields.go b/vendor/github.com/rs/zerolog/fields.go deleted file mode 100644 index c1eb5ce..0000000 --- a/vendor/github.com/rs/zerolog/fields.go +++ /dev/null @@ -1,277 +0,0 @@ -package zerolog - -import ( - "encoding/json" - "net" - "sort" - "time" - "unsafe" -) - -func isNilValue(i interface{}) bool { - return (*[2]uintptr)(unsafe.Pointer(&i))[1] == 0 -} - -func appendFields(dst []byte, fields interface{}) []byte { - switch fields := fields.(type) { - case []interface{}: - if n := len(fields); n&0x1 == 1 { // odd number - fields = fields[:n-1] - } - dst = appendFieldList(dst, fields) - case map[string]interface{}: - keys := make([]string, 0, len(fields)) - for key := range fields { - keys = append(keys, key) - } - sort.Strings(keys) - kv := make([]interface{}, 2) - for _, key := range keys { - kv[0], kv[1] = key, fields[key] - dst = appendFieldList(dst, kv) - } - } - return dst -} - -func appendFieldList(dst []byte, kvList []interface{}) []byte { - for i, n := 0, len(kvList); i < n; i += 2 { - key, val := kvList[i], kvList[i+1] - if key, ok := key.(string); ok { - dst = enc.AppendKey(dst, key) - } else { - continue - } - if val, ok := val.(LogObjectMarshaler); ok { - e := newEvent(nil, 0) - e.buf = e.buf[:0] - e.appendObject(val) - dst = append(dst, e.buf...) - putEvent(e) - continue - } - switch val := val.(type) { - case string: - dst = enc.AppendString(dst, val) - case []byte: - dst = enc.AppendBytes(dst, val) - case error: - switch m := ErrorMarshalFunc(val).(type) { - case LogObjectMarshaler: - e := newEvent(nil, 0) - e.buf = e.buf[:0] - e.appendObject(m) - dst = append(dst, e.buf...) - putEvent(e) - case error: - if m == nil || isNilValue(m) { - dst = enc.AppendNil(dst) - } else { - dst = enc.AppendString(dst, m.Error()) - } - case string: - dst = enc.AppendString(dst, m) - default: - dst = enc.AppendInterface(dst, m) - } - case []error: - dst = enc.AppendArrayStart(dst) - for i, err := range val { - switch m := ErrorMarshalFunc(err).(type) { - case LogObjectMarshaler: - e := newEvent(nil, 0) - e.buf = e.buf[:0] - e.appendObject(m) - dst = append(dst, e.buf...) - putEvent(e) - case error: - if m == nil || isNilValue(m) { - dst = enc.AppendNil(dst) - } else { - dst = enc.AppendString(dst, m.Error()) - } - case string: - dst = enc.AppendString(dst, m) - default: - dst = enc.AppendInterface(dst, m) - } - - if i < (len(val) - 1) { - enc.AppendArrayDelim(dst) - } - } - dst = enc.AppendArrayEnd(dst) - case bool: - dst = enc.AppendBool(dst, val) - case int: - dst = enc.AppendInt(dst, val) - case int8: - dst = enc.AppendInt8(dst, val) - case int16: - dst = enc.AppendInt16(dst, val) - case int32: - dst = enc.AppendInt32(dst, val) - case int64: - dst = enc.AppendInt64(dst, val) - case uint: - dst = enc.AppendUint(dst, val) - case uint8: - dst = enc.AppendUint8(dst, val) - case uint16: - dst = enc.AppendUint16(dst, val) - case uint32: - dst = enc.AppendUint32(dst, val) - case uint64: - dst = enc.AppendUint64(dst, val) - case float32: - dst = enc.AppendFloat32(dst, val) - case float64: - dst = enc.AppendFloat64(dst, val) - case time.Time: - dst = enc.AppendTime(dst, val, TimeFieldFormat) - case time.Duration: - dst = enc.AppendDuration(dst, val, DurationFieldUnit, DurationFieldInteger) - case *string: - if val != nil { - dst = enc.AppendString(dst, *val) - } else { - dst = enc.AppendNil(dst) - } - case *bool: - if val != nil { - dst = enc.AppendBool(dst, *val) - } else { - dst = enc.AppendNil(dst) - } - case *int: - if val != nil { - dst = enc.AppendInt(dst, *val) - } else { - dst = enc.AppendNil(dst) - } - case *int8: - if val != nil { - dst = enc.AppendInt8(dst, *val) - } else { - dst = enc.AppendNil(dst) - } - case *int16: - if val != nil { - dst = enc.AppendInt16(dst, *val) - } else { - dst = enc.AppendNil(dst) - } - case *int32: - if val != nil { - dst = enc.AppendInt32(dst, *val) - } else { - dst = enc.AppendNil(dst) - } - case *int64: - if val != nil { - dst = enc.AppendInt64(dst, *val) - } else { - dst = enc.AppendNil(dst) - } - case *uint: - if val != nil { - dst = enc.AppendUint(dst, *val) - } else { - dst = enc.AppendNil(dst) - } - case *uint8: - if val != nil { - dst = enc.AppendUint8(dst, *val) - } else { - dst = enc.AppendNil(dst) - } - case *uint16: - if val != nil { - dst = enc.AppendUint16(dst, *val) - } else { - dst = enc.AppendNil(dst) - } - case *uint32: - if val != nil { - dst = enc.AppendUint32(dst, *val) - } else { - dst = enc.AppendNil(dst) - } - case *uint64: - if val != nil { - dst = enc.AppendUint64(dst, *val) - } else { - dst = enc.AppendNil(dst) - } - case *float32: - if val != nil { - dst = enc.AppendFloat32(dst, *val) - } else { - dst = enc.AppendNil(dst) - } - case *float64: - if val != nil { - dst = enc.AppendFloat64(dst, *val) - } else { - dst = enc.AppendNil(dst) - } - case *time.Time: - if val != nil { - dst = enc.AppendTime(dst, *val, TimeFieldFormat) - } else { - dst = enc.AppendNil(dst) - } - case *time.Duration: - if val != nil { - dst = enc.AppendDuration(dst, *val, DurationFieldUnit, DurationFieldInteger) - } else { - dst = enc.AppendNil(dst) - } - case []string: - dst = enc.AppendStrings(dst, val) - case []bool: - dst = enc.AppendBools(dst, val) - case []int: - dst = enc.AppendInts(dst, val) - case []int8: - dst = enc.AppendInts8(dst, val) - case []int16: - dst = enc.AppendInts16(dst, val) - case []int32: - dst = enc.AppendInts32(dst, val) - case []int64: - dst = enc.AppendInts64(dst, val) - case []uint: - dst = enc.AppendUints(dst, val) - // case []uint8: - // dst = enc.AppendUints8(dst, val) - case []uint16: - dst = enc.AppendUints16(dst, val) - case []uint32: - dst = enc.AppendUints32(dst, val) - case []uint64: - dst = enc.AppendUints64(dst, val) - case []float32: - dst = enc.AppendFloats32(dst, val) - case []float64: - dst = enc.AppendFloats64(dst, val) - case []time.Time: - dst = enc.AppendTimes(dst, val, TimeFieldFormat) - case []time.Duration: - dst = enc.AppendDurations(dst, val, DurationFieldUnit, DurationFieldInteger) - case nil: - dst = enc.AppendNil(dst) - case net.IP: - dst = enc.AppendIPAddr(dst, val) - case net.IPNet: - dst = enc.AppendIPPrefix(dst, val) - case net.HardwareAddr: - dst = enc.AppendMACAddr(dst, val) - case json.RawMessage: - dst = appendJSON(dst, val) - default: - dst = enc.AppendInterface(dst, val) - } - } - return dst -} diff --git a/vendor/github.com/rs/zerolog/globals.go b/vendor/github.com/rs/zerolog/globals.go deleted file mode 100644 index e1067de..0000000 --- a/vendor/github.com/rs/zerolog/globals.go +++ /dev/null @@ -1,142 +0,0 @@ -package zerolog - -import ( - "encoding/json" - "strconv" - "sync/atomic" - "time" -) - -const ( - // TimeFormatUnix defines a time format that makes time fields to be - // serialized as Unix timestamp integers. - TimeFormatUnix = "" - - // TimeFormatUnixMs defines a time format that makes time fields to be - // serialized as Unix timestamp integers in milliseconds. - TimeFormatUnixMs = "UNIXMS" - - // TimeFormatUnixMicro defines a time format that makes time fields to be - // serialized as Unix timestamp integers in microseconds. - TimeFormatUnixMicro = "UNIXMICRO" - - // TimeFormatUnixNano defines a time format that makes time fields to be - // serialized as Unix timestamp integers in nanoseconds. - TimeFormatUnixNano = "UNIXNANO" -) - -var ( - // TimestampFieldName is the field name used for the timestamp field. - TimestampFieldName = "time" - - // LevelFieldName is the field name used for the level field. - LevelFieldName = "level" - - // LevelTraceValue is the value used for the trace level field. - LevelTraceValue = "trace" - // LevelDebugValue is the value used for the debug level field. - LevelDebugValue = "debug" - // LevelInfoValue is the value used for the info level field. - LevelInfoValue = "info" - // LevelWarnValue is the value used for the warn level field. - LevelWarnValue = "warn" - // LevelErrorValue is the value used for the error level field. - LevelErrorValue = "error" - // LevelFatalValue is the value used for the fatal level field. - LevelFatalValue = "fatal" - // LevelPanicValue is the value used for the panic level field. - LevelPanicValue = "panic" - - // LevelFieldMarshalFunc allows customization of global level field marshaling. - LevelFieldMarshalFunc = func(l Level) string { - return l.String() - } - - // MessageFieldName is the field name used for the message field. - MessageFieldName = "message" - - // ErrorFieldName is the field name used for error fields. - ErrorFieldName = "error" - - // CallerFieldName is the field name used for caller field. - CallerFieldName = "caller" - - // CallerSkipFrameCount is the number of stack frames to skip to find the caller. - CallerSkipFrameCount = 2 - - // CallerMarshalFunc allows customization of global caller marshaling - CallerMarshalFunc = func(pc uintptr, file string, line int) string { - return file + ":" + strconv.Itoa(line) - } - - // ErrorStackFieldName is the field name used for error stacks. - ErrorStackFieldName = "stack" - - // ErrorStackMarshaler extract the stack from err if any. - ErrorStackMarshaler func(err error) interface{} - - // ErrorMarshalFunc allows customization of global error marshaling - ErrorMarshalFunc = func(err error) interface{} { - return err - } - - // InterfaceMarshalFunc allows customization of interface marshaling. - // Default: "encoding/json.Marshal" - InterfaceMarshalFunc = json.Marshal - - // TimeFieldFormat defines the time format of the Time field type. If set to - // TimeFormatUnix, TimeFormatUnixMs, TimeFormatUnixMicro or TimeFormatUnixNano, the time is formatted as a UNIX - // timestamp as integer. - TimeFieldFormat = time.RFC3339 - - // TimestampFunc defines the function called to generate a timestamp. - TimestampFunc = time.Now - - // DurationFieldUnit defines the unit for time.Duration type fields added - // using the Dur method. - DurationFieldUnit = time.Millisecond - - // DurationFieldInteger renders Dur fields as integer instead of float if - // set to true. - DurationFieldInteger = false - - // ErrorHandler is called whenever zerolog fails to write an event on its - // output. If not set, an error is printed on the stderr. This handler must - // be thread safe and non-blocking. - ErrorHandler func(err error) - - // DefaultContextLogger is returned from Ctx() if there is no logger associated - // with the context. - DefaultContextLogger *Logger -) - -var ( - gLevel = new(int32) - disableSampling = new(int32) -) - -// SetGlobalLevel sets the global override for log level. If this -// values is raised, all Loggers will use at least this value. -// -// To globally disable logs, set GlobalLevel to Disabled. -func SetGlobalLevel(l Level) { - atomic.StoreInt32(gLevel, int32(l)) -} - -// GlobalLevel returns the current global log level -func GlobalLevel() Level { - return Level(atomic.LoadInt32(gLevel)) -} - -// DisableSampling will disable sampling in all Loggers if true. -func DisableSampling(v bool) { - var i int32 - if v { - i = 1 - } - atomic.StoreInt32(disableSampling, i) -} - -func samplingDisabled() bool { - return atomic.LoadInt32(disableSampling) == 1 -} diff --git a/vendor/github.com/rs/zerolog/go112.go b/vendor/github.com/rs/zerolog/go112.go deleted file mode 100644 index e7b5a1b..0000000 --- a/vendor/github.com/rs/zerolog/go112.go +++ /dev/null @@ -1,7 +0,0 @@ -// +build go1.12 - -package zerolog - -// Since go 1.12, some auto generated init functions are hidden from -// runtime.Caller. -const contextCallerSkipFrameCount = 2 diff --git a/vendor/github.com/rs/zerolog/hook.go b/vendor/github.com/rs/zerolog/hook.go deleted file mode 100644 index ec6effc..0000000 --- a/vendor/github.com/rs/zerolog/hook.go +++ /dev/null @@ -1,64 +0,0 @@ -package zerolog - -// Hook defines an interface to a log hook. -type Hook interface { - // Run runs the hook with the event. - Run(e *Event, level Level, message string) -} - -// HookFunc is an adaptor to allow the use of an ordinary function -// as a Hook. -type HookFunc func(e *Event, level Level, message string) - -// Run implements the Hook interface. -func (h HookFunc) Run(e *Event, level Level, message string) { - h(e, level, message) -} - -// LevelHook applies a different hook for each level. -type LevelHook struct { - NoLevelHook, TraceHook, DebugHook, InfoHook, WarnHook, ErrorHook, FatalHook, PanicHook Hook -} - -// Run implements the Hook interface. -func (h LevelHook) Run(e *Event, level Level, message string) { - switch level { - case TraceLevel: - if h.TraceHook != nil { - h.TraceHook.Run(e, level, message) - } - case DebugLevel: - if h.DebugHook != nil { - h.DebugHook.Run(e, level, message) - } - case InfoLevel: - if h.InfoHook != nil { - h.InfoHook.Run(e, level, message) - } - case WarnLevel: - if h.WarnHook != nil { - h.WarnHook.Run(e, level, message) - } - case ErrorLevel: - if h.ErrorHook != nil { - h.ErrorHook.Run(e, level, message) - } - case FatalLevel: - if h.FatalHook != nil { - h.FatalHook.Run(e, level, message) - } - case PanicLevel: - if h.PanicHook != nil { - h.PanicHook.Run(e, level, message) - } - case NoLevel: - if h.NoLevelHook != nil { - h.NoLevelHook.Run(e, level, message) - } - } -} - -// NewLevelHook returns a new LevelHook. -func NewLevelHook() LevelHook { - return LevelHook{} -} diff --git a/vendor/github.com/rs/zerolog/internal/cbor/README.md b/vendor/github.com/rs/zerolog/internal/cbor/README.md deleted file mode 100644 index 92c2e8c..0000000 --- a/vendor/github.com/rs/zerolog/internal/cbor/README.md +++ /dev/null @@ -1,56 +0,0 @@ -## Reference: - CBOR Encoding is described in [RFC7049](https://tools.ietf.org/html/rfc7049) - -## Comparison of JSON vs CBOR - -Two main areas of reduction are: - -1. CPU usage to write a log msg -2. Size (in bytes) of log messages. - - -CPU Usage savings are below: -``` -name JSON time/op CBOR time/op delta -Info-32 15.3ns ± 1% 11.7ns ± 3% -23.78% (p=0.000 n=9+10) -ContextFields-32 16.2ns ± 2% 12.3ns ± 3% -23.97% (p=0.000 n=9+9) -ContextAppend-32 6.70ns ± 0% 6.20ns ± 0% -7.44% (p=0.000 n=9+9) -LogFields-32 66.4ns ± 0% 24.6ns ± 2% -62.89% (p=0.000 n=10+9) -LogArrayObject-32 911ns ±11% 768ns ± 6% -15.64% (p=0.000 n=10+10) -LogFieldType/Floats-32 70.3ns ± 2% 29.5ns ± 1% -57.98% (p=0.000 n=10+10) -LogFieldType/Err-32 14.0ns ± 3% 12.1ns ± 8% -13.20% (p=0.000 n=8+10) -LogFieldType/Dur-32 17.2ns ± 2% 13.1ns ± 1% -24.27% (p=0.000 n=10+9) -LogFieldType/Object-32 54.3ns ±11% 52.3ns ± 7% ~ (p=0.239 n=10+10) -LogFieldType/Ints-32 20.3ns ± 2% 15.1ns ± 2% -25.50% (p=0.000 n=9+10) -LogFieldType/Interfaces-32 642ns ±11% 621ns ± 9% ~ (p=0.118 n=10+10) -LogFieldType/Interface(Objects)-32 635ns ±13% 632ns ± 9% ~ (p=0.592 n=10+10) -LogFieldType/Times-32 294ns ± 0% 27ns ± 1% -90.71% (p=0.000 n=10+9) -LogFieldType/Durs-32 121ns ± 0% 33ns ± 2% -72.44% (p=0.000 n=9+9) -LogFieldType/Interface(Object)-32 56.6ns ± 8% 52.3ns ± 8% -7.54% (p=0.007 n=10+10) -LogFieldType/Errs-32 17.8ns ± 3% 16.1ns ± 2% -9.71% (p=0.000 n=10+9) -LogFieldType/Time-32 40.5ns ± 1% 12.7ns ± 6% -68.66% (p=0.000 n=8+9) -LogFieldType/Bool-32 12.0ns ± 5% 10.2ns ± 2% -15.18% (p=0.000 n=10+8) -LogFieldType/Bools-32 17.2ns ± 2% 12.6ns ± 4% -26.63% (p=0.000 n=10+10) -LogFieldType/Int-32 12.3ns ± 2% 11.2ns ± 4% -9.27% (p=0.000 n=9+10) -LogFieldType/Float-32 16.7ns ± 1% 12.6ns ± 2% -24.42% (p=0.000 n=7+9) -LogFieldType/Str-32 12.7ns ± 7% 11.3ns ± 7% -10.88% (p=0.000 n=10+9) -LogFieldType/Strs-32 20.3ns ± 3% 18.2ns ± 3% -10.25% (p=0.000 n=9+10) -LogFieldType/Interface-32 183ns ±12% 175ns ± 9% ~ (p=0.078 n=10+10) -``` - -Log message size savings is greatly dependent on the number and type of fields in the log message. -Assuming this log message (with an Integer, timestamp and string, in addition to level). - -`{"level":"error","Fault":41650,"time":"2018-04-01T15:18:19-07:00","message":"Some Message"}` - -Two measurements were done for the log file sizes - one without any compression, second -using [compress/zlib](https://golang.org/pkg/compress/zlib/). - -Results for 10,000 log messages: - -| Log Format | Plain File Size (in KB) | Compressed File Size (in KB) | -| :--- | :---: | :---: | -| JSON | 920 | 28 | -| CBOR | 550 | 28 | - -The example used to calculate the above data is available in [Examples](examples). diff --git a/vendor/github.com/rs/zerolog/internal/cbor/base.go b/vendor/github.com/rs/zerolog/internal/cbor/base.go deleted file mode 100644 index 51fe86c..0000000 --- a/vendor/github.com/rs/zerolog/internal/cbor/base.go +++ /dev/null @@ -1,19 +0,0 @@ -package cbor - -// JSONMarshalFunc is used to marshal interface to JSON encoded byte slice. -// Making it package level instead of embedded in Encoder brings -// some extra efforts at importing, but avoids value copy when the functions -// of Encoder being invoked. -// DO REMEMBER to set this variable at importing, or -// you might get a nil pointer dereference panic at runtime. -var JSONMarshalFunc func(v interface{}) ([]byte, error) - -type Encoder struct{} - -// AppendKey adds a key (string) to the binary encoded log message -func (e Encoder) AppendKey(dst []byte, key string) []byte { - if len(dst) < 1 { - dst = e.AppendBeginMarker(dst) - } - return e.AppendString(dst, key) -} diff --git a/vendor/github.com/rs/zerolog/internal/cbor/cbor.go b/vendor/github.com/rs/zerolog/internal/cbor/cbor.go deleted file mode 100644 index bc54e37..0000000 --- a/vendor/github.com/rs/zerolog/internal/cbor/cbor.go +++ /dev/null @@ -1,101 +0,0 @@ -// Package cbor provides primitives for storing different data -// in the CBOR (binary) format. CBOR is defined in RFC7049. -package cbor - -import "time" - -const ( - majorOffset = 5 - additionalMax = 23 - - // Non Values. - additionalTypeBoolFalse byte = 20 - additionalTypeBoolTrue byte = 21 - additionalTypeNull byte = 22 - - // Integer (+ve and -ve) Sub-types. - additionalTypeIntUint8 byte = 24 - additionalTypeIntUint16 byte = 25 - additionalTypeIntUint32 byte = 26 - additionalTypeIntUint64 byte = 27 - - // Float Sub-types. - additionalTypeFloat16 byte = 25 - additionalTypeFloat32 byte = 26 - additionalTypeFloat64 byte = 27 - additionalTypeBreak byte = 31 - - // Tag Sub-types. - additionalTypeTimestamp byte = 01 - - // Extended Tags - from https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml - additionalTypeTagNetworkAddr uint16 = 260 - additionalTypeTagNetworkPrefix uint16 = 261 - additionalTypeEmbeddedJSON uint16 = 262 - additionalTypeTagHexString uint16 = 263 - - // Unspecified number of elements. - additionalTypeInfiniteCount byte = 31 -) -const ( - majorTypeUnsignedInt byte = iota << majorOffset // Major type 0 - majorTypeNegativeInt // Major type 1 - majorTypeByteString // Major type 2 - majorTypeUtf8String // Major type 3 - majorTypeArray // Major type 4 - majorTypeMap // Major type 5 - majorTypeTags // Major type 6 - majorTypeSimpleAndFloat // Major type 7 -) - -const ( - maskOutAdditionalType byte = (7 << majorOffset) - maskOutMajorType byte = 31 -) - -const ( - float32Nan = "\xfa\x7f\xc0\x00\x00" - float32PosInfinity = "\xfa\x7f\x80\x00\x00" - float32NegInfinity = "\xfa\xff\x80\x00\x00" - float64Nan = "\xfb\x7f\xf8\x00\x00\x00\x00\x00\x00" - float64PosInfinity = "\xfb\x7f\xf0\x00\x00\x00\x00\x00\x00" - float64NegInfinity = "\xfb\xff\xf0\x00\x00\x00\x00\x00\x00" -) - -// IntegerTimeFieldFormat indicates the format of timestamp decoded -// from an integer (time in seconds). -var IntegerTimeFieldFormat = time.RFC3339 - -// NanoTimeFieldFormat indicates the format of timestamp decoded -// from a float value (time in seconds and nanoseconds). -var NanoTimeFieldFormat = time.RFC3339Nano - -func appendCborTypePrefix(dst []byte, major byte, number uint64) []byte { - byteCount := 8 - var minor byte - switch { - case number < 256: - byteCount = 1 - minor = additionalTypeIntUint8 - - case number < 65536: - byteCount = 2 - minor = additionalTypeIntUint16 - - case number < 4294967296: - byteCount = 4 - minor = additionalTypeIntUint32 - - default: - byteCount = 8 - minor = additionalTypeIntUint64 - - } - - dst = append(dst, major|minor) - byteCount-- - for ; byteCount >= 0; byteCount-- { - dst = append(dst, byte(number>>(uint(byteCount)*8))) - } - return dst -} diff --git a/vendor/github.com/rs/zerolog/internal/cbor/decode_stream.go b/vendor/github.com/rs/zerolog/internal/cbor/decode_stream.go deleted file mode 100644 index fc16f98..0000000 --- a/vendor/github.com/rs/zerolog/internal/cbor/decode_stream.go +++ /dev/null @@ -1,614 +0,0 @@ -package cbor - -// This file contains code to decode a stream of CBOR Data into JSON. - -import ( - "bufio" - "bytes" - "fmt" - "io" - "math" - "net" - "runtime" - "strconv" - "strings" - "time" - "unicode/utf8" -) - -var decodeTimeZone *time.Location - -const hexTable = "0123456789abcdef" - -const isFloat32 = 4 -const isFloat64 = 8 - -func readNBytes(src *bufio.Reader, n int) []byte { - ret := make([]byte, n) - for i := 0; i < n; i++ { - ch, e := src.ReadByte() - if e != nil { - panic(fmt.Errorf("Tried to Read %d Bytes.. But hit end of file", n)) - } - ret[i] = ch - } - return ret -} - -func readByte(src *bufio.Reader) byte { - b, e := src.ReadByte() - if e != nil { - panic(fmt.Errorf("Tried to Read 1 Byte.. But hit end of file")) - } - return b -} - -func decodeIntAdditionalType(src *bufio.Reader, minor byte) int64 { - val := int64(0) - if minor <= 23 { - val = int64(minor) - } else { - bytesToRead := 0 - switch minor { - case additionalTypeIntUint8: - bytesToRead = 1 - case additionalTypeIntUint16: - bytesToRead = 2 - case additionalTypeIntUint32: - bytesToRead = 4 - case additionalTypeIntUint64: - bytesToRead = 8 - default: - panic(fmt.Errorf("Invalid Additional Type: %d in decodeInteger (expected <28)", minor)) - } - pb := readNBytes(src, bytesToRead) - for i := 0; i < bytesToRead; i++ { - val = val * 256 - val += int64(pb[i]) - } - } - return val -} - -func decodeInteger(src *bufio.Reader) int64 { - pb := readByte(src) - major := pb & maskOutAdditionalType - minor := pb & maskOutMajorType - if major != majorTypeUnsignedInt && major != majorTypeNegativeInt { - panic(fmt.Errorf("Major type is: %d in decodeInteger!! (expected 0 or 1)", major)) - } - val := decodeIntAdditionalType(src, minor) - if major == 0 { - return val - } - return (-1 - val) -} - -func decodeFloat(src *bufio.Reader) (float64, int) { - pb := readByte(src) - major := pb & maskOutAdditionalType - minor := pb & maskOutMajorType - if major != majorTypeSimpleAndFloat { - panic(fmt.Errorf("Incorrect Major type is: %d in decodeFloat", major)) - } - - switch minor { - case additionalTypeFloat16: - panic(fmt.Errorf("float16 is not suppported in decodeFloat")) - - case additionalTypeFloat32: - pb := readNBytes(src, 4) - switch string(pb) { - case float32Nan: - return math.NaN(), isFloat32 - case float32PosInfinity: - return math.Inf(0), isFloat32 - case float32NegInfinity: - return math.Inf(-1), isFloat32 - } - n := uint32(0) - for i := 0; i < 4; i++ { - n = n * 256 - n += uint32(pb[i]) - } - val := math.Float32frombits(n) - return float64(val), isFloat32 - case additionalTypeFloat64: - pb := readNBytes(src, 8) - switch string(pb) { - case float64Nan: - return math.NaN(), isFloat64 - case float64PosInfinity: - return math.Inf(0), isFloat64 - case float64NegInfinity: - return math.Inf(-1), isFloat64 - } - n := uint64(0) - for i := 0; i < 8; i++ { - n = n * 256 - n += uint64(pb[i]) - } - val := math.Float64frombits(n) - return val, isFloat64 - } - panic(fmt.Errorf("Invalid Additional Type: %d in decodeFloat", minor)) -} - -func decodeStringComplex(dst []byte, s string, pos uint) []byte { - i := int(pos) - start := 0 - - for i < len(s) { - b := s[i] - if b >= utf8.RuneSelf { - r, size := utf8.DecodeRuneInString(s[i:]) - if r == utf8.RuneError && size == 1 { - // In case of error, first append previous simple characters to - // the byte slice if any and append a replacement character code - // in place of the invalid sequence. - if start < i { - dst = append(dst, s[start:i]...) - } - dst = append(dst, `\ufffd`...) - i += size - start = i - continue - } - i += size - continue - } - if b >= 0x20 && b <= 0x7e && b != '\\' && b != '"' { - i++ - continue - } - // We encountered a character that needs to be encoded. - // Let's append the previous simple characters to the byte slice - // and switch our operation to read and encode the remainder - // characters byte-by-byte. - if start < i { - dst = append(dst, s[start:i]...) - } - switch b { - case '"', '\\': - dst = append(dst, '\\', b) - case '\b': - dst = append(dst, '\\', 'b') - case '\f': - dst = append(dst, '\\', 'f') - case '\n': - dst = append(dst, '\\', 'n') - case '\r': - dst = append(dst, '\\', 'r') - case '\t': - dst = append(dst, '\\', 't') - default: - dst = append(dst, '\\', 'u', '0', '0', hexTable[b>>4], hexTable[b&0xF]) - } - i++ - start = i - } - if start < len(s) { - dst = append(dst, s[start:]...) - } - return dst -} - -func decodeString(src *bufio.Reader, noQuotes bool) []byte { - pb := readByte(src) - major := pb & maskOutAdditionalType - minor := pb & maskOutMajorType - if major != majorTypeByteString { - panic(fmt.Errorf("Major type is: %d in decodeString", major)) - } - result := []byte{} - if !noQuotes { - result = append(result, '"') - } - length := decodeIntAdditionalType(src, minor) - len := int(length) - pbs := readNBytes(src, len) - result = append(result, pbs...) - if noQuotes { - return result - } - return append(result, '"') -} - -func decodeUTF8String(src *bufio.Reader) []byte { - pb := readByte(src) - major := pb & maskOutAdditionalType - minor := pb & maskOutMajorType - if major != majorTypeUtf8String { - panic(fmt.Errorf("Major type is: %d in decodeUTF8String", major)) - } - result := []byte{'"'} - length := decodeIntAdditionalType(src, minor) - len := int(length) - pbs := readNBytes(src, len) - - for i := 0; i < len; i++ { - // Check if the character needs encoding. Control characters, slashes, - // and the double quote need json encoding. Bytes above the ascii - // boundary needs utf8 encoding. - if pbs[i] < 0x20 || pbs[i] > 0x7e || pbs[i] == '\\' || pbs[i] == '"' { - // We encountered a character that needs to be encoded. Switch - // to complex version of the algorithm. - dst := []byte{'"'} - dst = decodeStringComplex(dst, string(pbs), uint(i)) - return append(dst, '"') - } - } - // The string has no need for encoding and therefore is directly - // appended to the byte slice. - result = append(result, pbs...) - return append(result, '"') -} - -func array2Json(src *bufio.Reader, dst io.Writer) { - dst.Write([]byte{'['}) - pb := readByte(src) - major := pb & maskOutAdditionalType - minor := pb & maskOutMajorType - if major != majorTypeArray { - panic(fmt.Errorf("Major type is: %d in array2Json", major)) - } - len := 0 - unSpecifiedCount := false - if minor == additionalTypeInfiniteCount { - unSpecifiedCount = true - } else { - length := decodeIntAdditionalType(src, minor) - len = int(length) - } - for i := 0; unSpecifiedCount || i < len; i++ { - if unSpecifiedCount { - pb, e := src.Peek(1) - if e != nil { - panic(e) - } - if pb[0] == majorTypeSimpleAndFloat|additionalTypeBreak { - readByte(src) - break - } - } - cbor2JsonOneObject(src, dst) - if unSpecifiedCount { - pb, e := src.Peek(1) - if e != nil { - panic(e) - } - if pb[0] == majorTypeSimpleAndFloat|additionalTypeBreak { - readByte(src) - break - } - dst.Write([]byte{','}) - } else if i+1 < len { - dst.Write([]byte{','}) - } - } - dst.Write([]byte{']'}) -} - -func map2Json(src *bufio.Reader, dst io.Writer) { - pb := readByte(src) - major := pb & maskOutAdditionalType - minor := pb & maskOutMajorType - if major != majorTypeMap { - panic(fmt.Errorf("Major type is: %d in map2Json", major)) - } - len := 0 - unSpecifiedCount := false - if minor == additionalTypeInfiniteCount { - unSpecifiedCount = true - } else { - length := decodeIntAdditionalType(src, minor) - len = int(length) - } - dst.Write([]byte{'{'}) - for i := 0; unSpecifiedCount || i < len; i++ { - if unSpecifiedCount { - pb, e := src.Peek(1) - if e != nil { - panic(e) - } - if pb[0] == majorTypeSimpleAndFloat|additionalTypeBreak { - readByte(src) - break - } - } - cbor2JsonOneObject(src, dst) - if i%2 == 0 { - // Even position values are keys. - dst.Write([]byte{':'}) - } else { - if unSpecifiedCount { - pb, e := src.Peek(1) - if e != nil { - panic(e) - } - if pb[0] == majorTypeSimpleAndFloat|additionalTypeBreak { - readByte(src) - break - } - dst.Write([]byte{','}) - } else if i+1 < len { - dst.Write([]byte{','}) - } - } - } - dst.Write([]byte{'}'}) -} - -func decodeTagData(src *bufio.Reader) []byte { - pb := readByte(src) - major := pb & maskOutAdditionalType - minor := pb & maskOutMajorType - if major != majorTypeTags { - panic(fmt.Errorf("Major type is: %d in decodeTagData", major)) - } - switch minor { - case additionalTypeTimestamp: - return decodeTimeStamp(src) - - // Tag value is larger than 256 (so uint16). - case additionalTypeIntUint16: - val := decodeIntAdditionalType(src, minor) - - switch uint16(val) { - case additionalTypeEmbeddedJSON: - pb := readByte(src) - dataMajor := pb & maskOutAdditionalType - if dataMajor != majorTypeByteString { - panic(fmt.Errorf("Unsupported embedded Type: %d in decodeEmbeddedJSON", dataMajor)) - } - src.UnreadByte() - return decodeString(src, true) - - case additionalTypeTagNetworkAddr: - octets := decodeString(src, true) - ss := []byte{'"'} - switch len(octets) { - case 6: // MAC address. - ha := net.HardwareAddr(octets) - ss = append(append(ss, ha.String()...), '"') - case 4: // IPv4 address. - fallthrough - case 16: // IPv6 address. - ip := net.IP(octets) - ss = append(append(ss, ip.String()...), '"') - default: - panic(fmt.Errorf("Unexpected Network Address length: %d (expected 4,6,16)", len(octets))) - } - return ss - - case additionalTypeTagNetworkPrefix: - pb := readByte(src) - if pb != majorTypeMap|0x1 { - panic(fmt.Errorf("IP Prefix is NOT of MAP of 1 elements as expected")) - } - octets := decodeString(src, true) - val := decodeInteger(src) - ip := net.IP(octets) - var mask net.IPMask - pfxLen := int(val) - if len(octets) == 4 { - mask = net.CIDRMask(pfxLen, 32) - } else { - mask = net.CIDRMask(pfxLen, 128) - } - ipPfx := net.IPNet{IP: ip, Mask: mask} - ss := []byte{'"'} - ss = append(append(ss, ipPfx.String()...), '"') - return ss - - case additionalTypeTagHexString: - octets := decodeString(src, true) - ss := []byte{'"'} - for _, v := range octets { - ss = append(ss, hexTable[v>>4], hexTable[v&0x0f]) - } - return append(ss, '"') - - default: - panic(fmt.Errorf("Unsupported Additional Tag Type: %d in decodeTagData", val)) - } - } - panic(fmt.Errorf("Unsupported Additional Type: %d in decodeTagData", minor)) -} - -func decodeTimeStamp(src *bufio.Reader) []byte { - pb := readByte(src) - src.UnreadByte() - tsMajor := pb & maskOutAdditionalType - if tsMajor == majorTypeUnsignedInt || tsMajor == majorTypeNegativeInt { - n := decodeInteger(src) - t := time.Unix(n, 0) - if decodeTimeZone != nil { - t = t.In(decodeTimeZone) - } else { - t = t.In(time.UTC) - } - tsb := []byte{} - tsb = append(tsb, '"') - tsb = t.AppendFormat(tsb, IntegerTimeFieldFormat) - tsb = append(tsb, '"') - return tsb - } else if tsMajor == majorTypeSimpleAndFloat { - n, _ := decodeFloat(src) - secs := int64(n) - n -= float64(secs) - n *= float64(1e9) - t := time.Unix(secs, int64(n)) - if decodeTimeZone != nil { - t = t.In(decodeTimeZone) - } else { - t = t.In(time.UTC) - } - tsb := []byte{} - tsb = append(tsb, '"') - tsb = t.AppendFormat(tsb, NanoTimeFieldFormat) - tsb = append(tsb, '"') - return tsb - } - panic(fmt.Errorf("TS format is neigther int nor float: %d", tsMajor)) -} - -func decodeSimpleFloat(src *bufio.Reader) []byte { - pb := readByte(src) - major := pb & maskOutAdditionalType - minor := pb & maskOutMajorType - if major != majorTypeSimpleAndFloat { - panic(fmt.Errorf("Major type is: %d in decodeSimpleFloat", major)) - } - switch minor { - case additionalTypeBoolTrue: - return []byte("true") - case additionalTypeBoolFalse: - return []byte("false") - case additionalTypeNull: - return []byte("null") - case additionalTypeFloat16: - fallthrough - case additionalTypeFloat32: - fallthrough - case additionalTypeFloat64: - src.UnreadByte() - v, bc := decodeFloat(src) - ba := []byte{} - switch { - case math.IsNaN(v): - return []byte("\"NaN\"") - case math.IsInf(v, 1): - return []byte("\"+Inf\"") - case math.IsInf(v, -1): - return []byte("\"-Inf\"") - } - if bc == isFloat32 { - ba = strconv.AppendFloat(ba, v, 'f', -1, 32) - } else if bc == isFloat64 { - ba = strconv.AppendFloat(ba, v, 'f', -1, 64) - } else { - panic(fmt.Errorf("Invalid Float precision from decodeFloat: %d", bc)) - } - return ba - default: - panic(fmt.Errorf("Invalid Additional Type: %d in decodeSimpleFloat", minor)) - } -} - -func cbor2JsonOneObject(src *bufio.Reader, dst io.Writer) { - pb, e := src.Peek(1) - if e != nil { - panic(e) - } - major := (pb[0] & maskOutAdditionalType) - - switch major { - case majorTypeUnsignedInt: - fallthrough - case majorTypeNegativeInt: - n := decodeInteger(src) - dst.Write([]byte(strconv.Itoa(int(n)))) - - case majorTypeByteString: - s := decodeString(src, false) - dst.Write(s) - - case majorTypeUtf8String: - s := decodeUTF8String(src) - dst.Write(s) - - case majorTypeArray: - array2Json(src, dst) - - case majorTypeMap: - map2Json(src, dst) - - case majorTypeTags: - s := decodeTagData(src) - dst.Write(s) - - case majorTypeSimpleAndFloat: - s := decodeSimpleFloat(src) - dst.Write(s) - } -} - -func moreBytesToRead(src *bufio.Reader) bool { - _, e := src.ReadByte() - if e == nil { - src.UnreadByte() - return true - } - return false -} - -// Cbor2JsonManyObjects decodes all the CBOR Objects read from src -// reader. It keeps on decoding until reader returns EOF (error when reading). -// Decoded string is written to the dst. At the end of every CBOR Object -// newline is written to the output stream. -// -// Returns error (if any) that was encountered during decode. -// The child functions will generate a panic when error is encountered and -// this function will recover non-runtime Errors and return the reason as error. -func Cbor2JsonManyObjects(src io.Reader, dst io.Writer) (err error) { - defer func() { - if r := recover(); r != nil { - if _, ok := r.(runtime.Error); ok { - panic(r) - } - err = r.(error) - } - }() - bufRdr := bufio.NewReader(src) - for moreBytesToRead(bufRdr) { - cbor2JsonOneObject(bufRdr, dst) - dst.Write([]byte("\n")) - } - return nil -} - -// Detect if the bytes to be printed is Binary or not. -func binaryFmt(p []byte) bool { - if len(p) > 0 && p[0] > 0x7F { - return true - } - return false -} - -func getReader(str string) *bufio.Reader { - return bufio.NewReader(strings.NewReader(str)) -} - -// DecodeIfBinaryToString converts a binary formatted log msg to a -// JSON formatted String Log message - suitable for printing to Console/Syslog. -func DecodeIfBinaryToString(in []byte) string { - if binaryFmt(in) { - var b bytes.Buffer - Cbor2JsonManyObjects(strings.NewReader(string(in)), &b) - return b.String() - } - return string(in) -} - -// DecodeObjectToStr checks if the input is a binary format, if so, -// it will decode a single Object and return the decoded string. -func DecodeObjectToStr(in []byte) string { - if binaryFmt(in) { - var b bytes.Buffer - cbor2JsonOneObject(getReader(string(in)), &b) - return b.String() - } - return string(in) -} - -// DecodeIfBinaryToBytes checks if the input is a binary format, if so, -// it will decode all Objects and return the decoded string as byte array. -func DecodeIfBinaryToBytes(in []byte) []byte { - if binaryFmt(in) { - var b bytes.Buffer - Cbor2JsonManyObjects(bytes.NewReader(in), &b) - return b.Bytes() - } - return in -} diff --git a/vendor/github.com/rs/zerolog/internal/cbor/string.go b/vendor/github.com/rs/zerolog/internal/cbor/string.go deleted file mode 100644 index a33890a..0000000 --- a/vendor/github.com/rs/zerolog/internal/cbor/string.go +++ /dev/null @@ -1,95 +0,0 @@ -package cbor - -import "fmt" - -// AppendStrings encodes and adds an array of strings to the dst byte array. -func (e Encoder) AppendStrings(dst []byte, vals []string) []byte { - major := majorTypeArray - l := len(vals) - if l <= additionalMax { - lb := byte(l) - dst = append(dst, major|lb) - } else { - dst = appendCborTypePrefix(dst, major, uint64(l)) - } - for _, v := range vals { - dst = e.AppendString(dst, v) - } - return dst -} - -// AppendString encodes and adds a string to the dst byte array. -func (Encoder) AppendString(dst []byte, s string) []byte { - major := majorTypeUtf8String - - l := len(s) - if l <= additionalMax { - lb := byte(l) - dst = append(dst, major|lb) - } else { - dst = appendCborTypePrefix(dst, majorTypeUtf8String, uint64(l)) - } - return append(dst, s...) -} - -// AppendStringers encodes and adds an array of Stringer values -// to the dst byte array. -func (e Encoder) AppendStringers(dst []byte, vals []fmt.Stringer) []byte { - if len(vals) == 0 { - return e.AppendArrayEnd(e.AppendArrayStart(dst)) - } - dst = e.AppendArrayStart(dst) - dst = e.AppendStringer(dst, vals[0]) - if len(vals) > 1 { - for _, val := range vals[1:] { - dst = e.AppendStringer(dst, val) - } - } - return e.AppendArrayEnd(dst) -} - -// AppendStringer encodes and adds the Stringer value to the dst -// byte array. -func (e Encoder) AppendStringer(dst []byte, val fmt.Stringer) []byte { - if val == nil { - return e.AppendNil(dst) - } - return e.AppendString(dst, val.String()) -} - -// AppendBytes encodes and adds an array of bytes to the dst byte array. -func (Encoder) AppendBytes(dst, s []byte) []byte { - major := majorTypeByteString - - l := len(s) - if l <= additionalMax { - lb := byte(l) - dst = append(dst, major|lb) - } else { - dst = appendCborTypePrefix(dst, major, uint64(l)) - } - return append(dst, s...) -} - -// AppendEmbeddedJSON adds a tag and embeds input JSON as such. -func AppendEmbeddedJSON(dst, s []byte) []byte { - major := majorTypeTags - minor := additionalTypeEmbeddedJSON - - // Append the TAG to indicate this is Embedded JSON. - dst = append(dst, major|additionalTypeIntUint16) - dst = append(dst, byte(minor>>8)) - dst = append(dst, byte(minor&0xff)) - - // Append the JSON Object as Byte String. - major = majorTypeByteString - - l := len(s) - if l <= additionalMax { - lb := byte(l) - dst = append(dst, major|lb) - } else { - dst = appendCborTypePrefix(dst, major, uint64(l)) - } - return append(dst, s...) -} diff --git a/vendor/github.com/rs/zerolog/internal/cbor/time.go b/vendor/github.com/rs/zerolog/internal/cbor/time.go deleted file mode 100644 index d81fb12..0000000 --- a/vendor/github.com/rs/zerolog/internal/cbor/time.go +++ /dev/null @@ -1,93 +0,0 @@ -package cbor - -import ( - "time" -) - -func appendIntegerTimestamp(dst []byte, t time.Time) []byte { - major := majorTypeTags - minor := additionalTypeTimestamp - dst = append(dst, major|minor) - secs := t.Unix() - var val uint64 - if secs < 0 { - major = majorTypeNegativeInt - val = uint64(-secs - 1) - } else { - major = majorTypeUnsignedInt - val = uint64(secs) - } - dst = appendCborTypePrefix(dst, major, val) - return dst -} - -func (e Encoder) appendFloatTimestamp(dst []byte, t time.Time) []byte { - major := majorTypeTags - minor := additionalTypeTimestamp - dst = append(dst, major|minor) - secs := t.Unix() - nanos := t.Nanosecond() - var val float64 - val = float64(secs)*1.0 + float64(nanos)*1e-9 - return e.AppendFloat64(dst, val) -} - -// AppendTime encodes and adds a timestamp to the dst byte array. -func (e Encoder) AppendTime(dst []byte, t time.Time, unused string) []byte { - utc := t.UTC() - if utc.Nanosecond() == 0 { - return appendIntegerTimestamp(dst, utc) - } - return e.appendFloatTimestamp(dst, utc) -} - -// AppendTimes encodes and adds an array of timestamps to the dst byte array. -func (e Encoder) AppendTimes(dst []byte, vals []time.Time, unused string) []byte { - major := majorTypeArray - l := len(vals) - if l == 0 { - return e.AppendArrayEnd(e.AppendArrayStart(dst)) - } - if l <= additionalMax { - lb := byte(l) - dst = append(dst, major|lb) - } else { - dst = appendCborTypePrefix(dst, major, uint64(l)) - } - - for _, t := range vals { - dst = e.AppendTime(dst, t, unused) - } - return dst -} - -// AppendDuration encodes and adds a duration to the dst byte array. -// useInt field indicates whether to store the duration as seconds (integer) or -// as seconds+nanoseconds (float). -func (e Encoder) AppendDuration(dst []byte, d time.Duration, unit time.Duration, useInt bool) []byte { - if useInt { - return e.AppendInt64(dst, int64(d/unit)) - } - return e.AppendFloat64(dst, float64(d)/float64(unit)) -} - -// AppendDurations encodes and adds an array of durations to the dst byte array. -// useInt field indicates whether to store the duration as seconds (integer) or -// as seconds+nanoseconds (float). -func (e Encoder) AppendDurations(dst []byte, vals []time.Duration, unit time.Duration, useInt bool) []byte { - major := majorTypeArray - l := len(vals) - if l == 0 { - return e.AppendArrayEnd(e.AppendArrayStart(dst)) - } - if l <= additionalMax { - lb := byte(l) - dst = append(dst, major|lb) - } else { - dst = appendCborTypePrefix(dst, major, uint64(l)) - } - for _, d := range vals { - dst = e.AppendDuration(dst, d, unit, useInt) - } - return dst -} diff --git a/vendor/github.com/rs/zerolog/internal/cbor/types.go b/vendor/github.com/rs/zerolog/internal/cbor/types.go deleted file mode 100644 index 49316aa..0000000 --- a/vendor/github.com/rs/zerolog/internal/cbor/types.go +++ /dev/null @@ -1,477 +0,0 @@ -package cbor - -import ( - "fmt" - "math" - "net" -) - -// AppendNil inserts a 'Nil' object into the dst byte array. -func (Encoder) AppendNil(dst []byte) []byte { - return append(dst, majorTypeSimpleAndFloat|additionalTypeNull) -} - -// AppendBeginMarker inserts a map start into the dst byte array. -func (Encoder) AppendBeginMarker(dst []byte) []byte { - return append(dst, majorTypeMap|additionalTypeInfiniteCount) -} - -// AppendEndMarker inserts a map end into the dst byte array. -func (Encoder) AppendEndMarker(dst []byte) []byte { - return append(dst, majorTypeSimpleAndFloat|additionalTypeBreak) -} - -// AppendObjectData takes an object in form of a byte array and appends to dst. -func (Encoder) AppendObjectData(dst []byte, o []byte) []byte { - // BeginMarker is present in the dst, which - // should not be copied when appending to existing data. - return append(dst, o[1:]...) -} - -// AppendArrayStart adds markers to indicate the start of an array. -func (Encoder) AppendArrayStart(dst []byte) []byte { - return append(dst, majorTypeArray|additionalTypeInfiniteCount) -} - -// AppendArrayEnd adds markers to indicate the end of an array. -func (Encoder) AppendArrayEnd(dst []byte) []byte { - return append(dst, majorTypeSimpleAndFloat|additionalTypeBreak) -} - -// AppendArrayDelim adds markers to indicate end of a particular array element. -func (Encoder) AppendArrayDelim(dst []byte) []byte { - //No delimiters needed in cbor - return dst -} - -// AppendLineBreak is a noop that keep API compat with json encoder. -func (Encoder) AppendLineBreak(dst []byte) []byte { - // No line breaks needed in binary format. - return dst -} - -// AppendBool encodes and inserts a boolean value into the dst byte array. -func (Encoder) AppendBool(dst []byte, val bool) []byte { - b := additionalTypeBoolFalse - if val { - b = additionalTypeBoolTrue - } - return append(dst, majorTypeSimpleAndFloat|b) -} - -// AppendBools encodes and inserts an array of boolean values into the dst byte array. -func (e Encoder) AppendBools(dst []byte, vals []bool) []byte { - major := majorTypeArray - l := len(vals) - if l == 0 { - return e.AppendArrayEnd(e.AppendArrayStart(dst)) - } - if l <= additionalMax { - lb := byte(l) - dst = append(dst, major|lb) - } else { - dst = appendCborTypePrefix(dst, major, uint64(l)) - } - for _, v := range vals { - dst = e.AppendBool(dst, v) - } - return dst -} - -// AppendInt encodes and inserts an integer value into the dst byte array. -func (Encoder) AppendInt(dst []byte, val int) []byte { - major := majorTypeUnsignedInt - contentVal := val - if val < 0 { - major = majorTypeNegativeInt - contentVal = -val - 1 - } - if contentVal <= additionalMax { - lb := byte(contentVal) - dst = append(dst, major|lb) - } else { - dst = appendCborTypePrefix(dst, major, uint64(contentVal)) - } - return dst -} - -// AppendInts encodes and inserts an array of integer values into the dst byte array. -func (e Encoder) AppendInts(dst []byte, vals []int) []byte { - major := majorTypeArray - l := len(vals) - if l == 0 { - return e.AppendArrayEnd(e.AppendArrayStart(dst)) - } - if l <= additionalMax { - lb := byte(l) - dst = append(dst, major|lb) - } else { - dst = appendCborTypePrefix(dst, major, uint64(l)) - } - for _, v := range vals { - dst = e.AppendInt(dst, v) - } - return dst -} - -// AppendInt8 encodes and inserts an int8 value into the dst byte array. -func (e Encoder) AppendInt8(dst []byte, val int8) []byte { - return e.AppendInt(dst, int(val)) -} - -// AppendInts8 encodes and inserts an array of integer values into the dst byte array. -func (e Encoder) AppendInts8(dst []byte, vals []int8) []byte { - major := majorTypeArray - l := len(vals) - if l == 0 { - return e.AppendArrayEnd(e.AppendArrayStart(dst)) - } - if l <= additionalMax { - lb := byte(l) - dst = append(dst, major|lb) - } else { - dst = appendCborTypePrefix(dst, major, uint64(l)) - } - for _, v := range vals { - dst = e.AppendInt(dst, int(v)) - } - return dst -} - -// AppendInt16 encodes and inserts a int16 value into the dst byte array. -func (e Encoder) AppendInt16(dst []byte, val int16) []byte { - return e.AppendInt(dst, int(val)) -} - -// AppendInts16 encodes and inserts an array of int16 values into the dst byte array. -func (e Encoder) AppendInts16(dst []byte, vals []int16) []byte { - major := majorTypeArray - l := len(vals) - if l == 0 { - return e.AppendArrayEnd(e.AppendArrayStart(dst)) - } - if l <= additionalMax { - lb := byte(l) - dst = append(dst, major|lb) - } else { - dst = appendCborTypePrefix(dst, major, uint64(l)) - } - for _, v := range vals { - dst = e.AppendInt(dst, int(v)) - } - return dst -} - -// AppendInt32 encodes and inserts a int32 value into the dst byte array. -func (e Encoder) AppendInt32(dst []byte, val int32) []byte { - return e.AppendInt(dst, int(val)) -} - -// AppendInts32 encodes and inserts an array of int32 values into the dst byte array. -func (e Encoder) AppendInts32(dst []byte, vals []int32) []byte { - major := majorTypeArray - l := len(vals) - if l == 0 { - return e.AppendArrayEnd(e.AppendArrayStart(dst)) - } - if l <= additionalMax { - lb := byte(l) - dst = append(dst, major|lb) - } else { - dst = appendCborTypePrefix(dst, major, uint64(l)) - } - for _, v := range vals { - dst = e.AppendInt(dst, int(v)) - } - return dst -} - -// AppendInt64 encodes and inserts a int64 value into the dst byte array. -func (Encoder) AppendInt64(dst []byte, val int64) []byte { - major := majorTypeUnsignedInt - contentVal := val - if val < 0 { - major = majorTypeNegativeInt - contentVal = -val - 1 - } - if contentVal <= additionalMax { - lb := byte(contentVal) - dst = append(dst, major|lb) - } else { - dst = appendCborTypePrefix(dst, major, uint64(contentVal)) - } - return dst -} - -// AppendInts64 encodes and inserts an array of int64 values into the dst byte array. -func (e Encoder) AppendInts64(dst []byte, vals []int64) []byte { - major := majorTypeArray - l := len(vals) - if l == 0 { - return e.AppendArrayEnd(e.AppendArrayStart(dst)) - } - if l <= additionalMax { - lb := byte(l) - dst = append(dst, major|lb) - } else { - dst = appendCborTypePrefix(dst, major, uint64(l)) - } - for _, v := range vals { - dst = e.AppendInt64(dst, v) - } - return dst -} - -// AppendUint encodes and inserts an unsigned integer value into the dst byte array. -func (e Encoder) AppendUint(dst []byte, val uint) []byte { - return e.AppendInt64(dst, int64(val)) -} - -// AppendUints encodes and inserts an array of unsigned integer values into the dst byte array. -func (e Encoder) AppendUints(dst []byte, vals []uint) []byte { - major := majorTypeArray - l := len(vals) - if l == 0 { - return e.AppendArrayEnd(e.AppendArrayStart(dst)) - } - if l <= additionalMax { - lb := byte(l) - dst = append(dst, major|lb) - } else { - dst = appendCborTypePrefix(dst, major, uint64(l)) - } - for _, v := range vals { - dst = e.AppendUint(dst, v) - } - return dst -} - -// AppendUint8 encodes and inserts a unsigned int8 value into the dst byte array. -func (e Encoder) AppendUint8(dst []byte, val uint8) []byte { - return e.AppendUint(dst, uint(val)) -} - -// AppendUints8 encodes and inserts an array of uint8 values into the dst byte array. -func (e Encoder) AppendUints8(dst []byte, vals []uint8) []byte { - major := majorTypeArray - l := len(vals) - if l == 0 { - return e.AppendArrayEnd(e.AppendArrayStart(dst)) - } - if l <= additionalMax { - lb := byte(l) - dst = append(dst, major|lb) - } else { - dst = appendCborTypePrefix(dst, major, uint64(l)) - } - for _, v := range vals { - dst = e.AppendUint8(dst, v) - } - return dst -} - -// AppendUint16 encodes and inserts a uint16 value into the dst byte array. -func (e Encoder) AppendUint16(dst []byte, val uint16) []byte { - return e.AppendUint(dst, uint(val)) -} - -// AppendUints16 encodes and inserts an array of uint16 values into the dst byte array. -func (e Encoder) AppendUints16(dst []byte, vals []uint16) []byte { - major := majorTypeArray - l := len(vals) - if l == 0 { - return e.AppendArrayEnd(e.AppendArrayStart(dst)) - } - if l <= additionalMax { - lb := byte(l) - dst = append(dst, major|lb) - } else { - dst = appendCborTypePrefix(dst, major, uint64(l)) - } - for _, v := range vals { - dst = e.AppendUint16(dst, v) - } - return dst -} - -// AppendUint32 encodes and inserts a uint32 value into the dst byte array. -func (e Encoder) AppendUint32(dst []byte, val uint32) []byte { - return e.AppendUint(dst, uint(val)) -} - -// AppendUints32 encodes and inserts an array of uint32 values into the dst byte array. -func (e Encoder) AppendUints32(dst []byte, vals []uint32) []byte { - major := majorTypeArray - l := len(vals) - if l == 0 { - return e.AppendArrayEnd(e.AppendArrayStart(dst)) - } - if l <= additionalMax { - lb := byte(l) - dst = append(dst, major|lb) - } else { - dst = appendCborTypePrefix(dst, major, uint64(l)) - } - for _, v := range vals { - dst = e.AppendUint32(dst, v) - } - return dst -} - -// AppendUint64 encodes and inserts a uint64 value into the dst byte array. -func (Encoder) AppendUint64(dst []byte, val uint64) []byte { - major := majorTypeUnsignedInt - contentVal := val - if contentVal <= additionalMax { - lb := byte(contentVal) - dst = append(dst, major|lb) - } else { - dst = appendCborTypePrefix(dst, major, contentVal) - } - return dst -} - -// AppendUints64 encodes and inserts an array of uint64 values into the dst byte array. -func (e Encoder) AppendUints64(dst []byte, vals []uint64) []byte { - major := majorTypeArray - l := len(vals) - if l == 0 { - return e.AppendArrayEnd(e.AppendArrayStart(dst)) - } - if l <= additionalMax { - lb := byte(l) - dst = append(dst, major|lb) - } else { - dst = appendCborTypePrefix(dst, major, uint64(l)) - } - for _, v := range vals { - dst = e.AppendUint64(dst, v) - } - return dst -} - -// AppendFloat32 encodes and inserts a single precision float value into the dst byte array. -func (Encoder) AppendFloat32(dst []byte, val float32) []byte { - switch { - case math.IsNaN(float64(val)): - return append(dst, "\xfa\x7f\xc0\x00\x00"...) - case math.IsInf(float64(val), 1): - return append(dst, "\xfa\x7f\x80\x00\x00"...) - case math.IsInf(float64(val), -1): - return append(dst, "\xfa\xff\x80\x00\x00"...) - } - major := majorTypeSimpleAndFloat - subType := additionalTypeFloat32 - n := math.Float32bits(val) - var buf [4]byte - for i := uint(0); i < 4; i++ { - buf[i] = byte(n >> ((3 - i) * 8)) - } - return append(append(dst, major|subType), buf[0], buf[1], buf[2], buf[3]) -} - -// AppendFloats32 encodes and inserts an array of single precision float value into the dst byte array. -func (e Encoder) AppendFloats32(dst []byte, vals []float32) []byte { - major := majorTypeArray - l := len(vals) - if l == 0 { - return e.AppendArrayEnd(e.AppendArrayStart(dst)) - } - if l <= additionalMax { - lb := byte(l) - dst = append(dst, major|lb) - } else { - dst = appendCborTypePrefix(dst, major, uint64(l)) - } - for _, v := range vals { - dst = e.AppendFloat32(dst, v) - } - return dst -} - -// AppendFloat64 encodes and inserts a double precision float value into the dst byte array. -func (Encoder) AppendFloat64(dst []byte, val float64) []byte { - switch { - case math.IsNaN(val): - return append(dst, "\xfb\x7f\xf8\x00\x00\x00\x00\x00\x00"...) - case math.IsInf(val, 1): - return append(dst, "\xfb\x7f\xf0\x00\x00\x00\x00\x00\x00"...) - case math.IsInf(val, -1): - return append(dst, "\xfb\xff\xf0\x00\x00\x00\x00\x00\x00"...) - } - major := majorTypeSimpleAndFloat - subType := additionalTypeFloat64 - n := math.Float64bits(val) - dst = append(dst, major|subType) - for i := uint(1); i <= 8; i++ { - b := byte(n >> ((8 - i) * 8)) - dst = append(dst, b) - } - return dst -} - -// AppendFloats64 encodes and inserts an array of double precision float values into the dst byte array. -func (e Encoder) AppendFloats64(dst []byte, vals []float64) []byte { - major := majorTypeArray - l := len(vals) - if l == 0 { - return e.AppendArrayEnd(e.AppendArrayStart(dst)) - } - if l <= additionalMax { - lb := byte(l) - dst = append(dst, major|lb) - } else { - dst = appendCborTypePrefix(dst, major, uint64(l)) - } - for _, v := range vals { - dst = e.AppendFloat64(dst, v) - } - return dst -} - -// AppendInterface takes an arbitrary object and converts it to JSON and embeds it dst. -func (e Encoder) AppendInterface(dst []byte, i interface{}) []byte { - marshaled, err := JSONMarshalFunc(i) - if err != nil { - return e.AppendString(dst, fmt.Sprintf("marshaling error: %v", err)) - } - return AppendEmbeddedJSON(dst, marshaled) -} - -// AppendIPAddr encodes and inserts an IP Address (IPv4 or IPv6). -func (e Encoder) AppendIPAddr(dst []byte, ip net.IP) []byte { - dst = append(dst, majorTypeTags|additionalTypeIntUint16) - dst = append(dst, byte(additionalTypeTagNetworkAddr>>8)) - dst = append(dst, byte(additionalTypeTagNetworkAddr&0xff)) - return e.AppendBytes(dst, ip) -} - -// AppendIPPrefix encodes and inserts an IP Address Prefix (Address + Mask Length). -func (e Encoder) AppendIPPrefix(dst []byte, pfx net.IPNet) []byte { - dst = append(dst, majorTypeTags|additionalTypeIntUint16) - dst = append(dst, byte(additionalTypeTagNetworkPrefix>>8)) - dst = append(dst, byte(additionalTypeTagNetworkPrefix&0xff)) - - // Prefix is a tuple (aka MAP of 1 pair of elements) - - // first element is prefix, second is mask length. - dst = append(dst, majorTypeMap|0x1) - dst = e.AppendBytes(dst, pfx.IP) - maskLen, _ := pfx.Mask.Size() - return e.AppendUint8(dst, uint8(maskLen)) -} - -// AppendMACAddr encodes and inserts a Hardware (MAC) address. -func (e Encoder) AppendMACAddr(dst []byte, ha net.HardwareAddr) []byte { - dst = append(dst, majorTypeTags|additionalTypeIntUint16) - dst = append(dst, byte(additionalTypeTagNetworkAddr>>8)) - dst = append(dst, byte(additionalTypeTagNetworkAddr&0xff)) - return e.AppendBytes(dst, ha) -} - -// AppendHex adds a TAG and inserts a hex bytes as a string. -func (e Encoder) AppendHex(dst []byte, val []byte) []byte { - dst = append(dst, majorTypeTags|additionalTypeIntUint16) - dst = append(dst, byte(additionalTypeTagHexString>>8)) - dst = append(dst, byte(additionalTypeTagHexString&0xff)) - return e.AppendBytes(dst, val) -} diff --git a/vendor/github.com/rs/zerolog/internal/json/base.go b/vendor/github.com/rs/zerolog/internal/json/base.go deleted file mode 100644 index 09ec59f..0000000 --- a/vendor/github.com/rs/zerolog/internal/json/base.go +++ /dev/null @@ -1,19 +0,0 @@ -package json - -// JSONMarshalFunc is used to marshal interface to JSON encoded byte slice. -// Making it package level instead of embedded in Encoder brings -// some extra efforts at importing, but avoids value copy when the functions -// of Encoder being invoked. -// DO REMEMBER to set this variable at importing, or -// you might get a nil pointer dereference panic at runtime. -var JSONMarshalFunc func(v interface{}) ([]byte, error) - -type Encoder struct{} - -// AppendKey appends a new key to the output JSON. -func (e Encoder) AppendKey(dst []byte, key string) []byte { - if dst[len(dst)-1] != '{' { - dst = append(dst, ',') - } - return append(e.AppendString(dst, key), ':') -} diff --git a/vendor/github.com/rs/zerolog/internal/json/bytes.go b/vendor/github.com/rs/zerolog/internal/json/bytes.go deleted file mode 100644 index de64120..0000000 --- a/vendor/github.com/rs/zerolog/internal/json/bytes.go +++ /dev/null @@ -1,85 +0,0 @@ -package json - -import "unicode/utf8" - -// AppendBytes is a mirror of appendString with []byte arg -func (Encoder) AppendBytes(dst, s []byte) []byte { - dst = append(dst, '"') - for i := 0; i < len(s); i++ { - if !noEscapeTable[s[i]] { - dst = appendBytesComplex(dst, s, i) - return append(dst, '"') - } - } - dst = append(dst, s...) - return append(dst, '"') -} - -// AppendHex encodes the input bytes to a hex string and appends -// the encoded string to the input byte slice. -// -// The operation loops though each byte and encodes it as hex using -// the hex lookup table. -func (Encoder) AppendHex(dst, s []byte) []byte { - dst = append(dst, '"') - for _, v := range s { - dst = append(dst, hex[v>>4], hex[v&0x0f]) - } - return append(dst, '"') -} - -// appendBytesComplex is a mirror of the appendStringComplex -// with []byte arg -func appendBytesComplex(dst, s []byte, i int) []byte { - start := 0 - for i < len(s) { - b := s[i] - if b >= utf8.RuneSelf { - r, size := utf8.DecodeRune(s[i:]) - if r == utf8.RuneError && size == 1 { - if start < i { - dst = append(dst, s[start:i]...) - } - dst = append(dst, `\ufffd`...) - i += size - start = i - continue - } - i += size - continue - } - if noEscapeTable[b] { - i++ - continue - } - // We encountered a character that needs to be encoded. - // Let's append the previous simple characters to the byte slice - // and switch our operation to read and encode the remainder - // characters byte-by-byte. - if start < i { - dst = append(dst, s[start:i]...) - } - switch b { - case '"', '\\': - dst = append(dst, '\\', b) - case '\b': - dst = append(dst, '\\', 'b') - case '\f': - dst = append(dst, '\\', 'f') - case '\n': - dst = append(dst, '\\', 'n') - case '\r': - dst = append(dst, '\\', 'r') - case '\t': - dst = append(dst, '\\', 't') - default: - dst = append(dst, '\\', 'u', '0', '0', hex[b>>4], hex[b&0xF]) - } - i++ - start = i - } - if start < len(s) { - dst = append(dst, s[start:]...) - } - return dst -} diff --git a/vendor/github.com/rs/zerolog/internal/json/string.go b/vendor/github.com/rs/zerolog/internal/json/string.go deleted file mode 100644 index fd7770f..0000000 --- a/vendor/github.com/rs/zerolog/internal/json/string.go +++ /dev/null @@ -1,149 +0,0 @@ -package json - -import ( - "fmt" - "unicode/utf8" -) - -const hex = "0123456789abcdef" - -var noEscapeTable = [256]bool{} - -func init() { - for i := 0; i <= 0x7e; i++ { - noEscapeTable[i] = i >= 0x20 && i != '\\' && i != '"' - } -} - -// AppendStrings encodes the input strings to json and -// appends the encoded string list to the input byte slice. -func (e Encoder) AppendStrings(dst []byte, vals []string) []byte { - if len(vals) == 0 { - return append(dst, '[', ']') - } - dst = append(dst, '[') - dst = e.AppendString(dst, vals[0]) - if len(vals) > 1 { - for _, val := range vals[1:] { - dst = e.AppendString(append(dst, ','), val) - } - } - dst = append(dst, ']') - return dst -} - -// AppendString encodes the input string to json and appends -// the encoded string to the input byte slice. -// -// The operation loops though each byte in the string looking -// for characters that need json or utf8 encoding. If the string -// does not need encoding, then the string is appended in its -// entirety to the byte slice. -// If we encounter a byte that does need encoding, switch up -// the operation and perform a byte-by-byte read-encode-append. -func (Encoder) AppendString(dst []byte, s string) []byte { - // Start with a double quote. - dst = append(dst, '"') - // Loop through each character in the string. - for i := 0; i < len(s); i++ { - // Check if the character needs encoding. Control characters, slashes, - // and the double quote need json encoding. Bytes above the ascii - // boundary needs utf8 encoding. - if !noEscapeTable[s[i]] { - // We encountered a character that needs to be encoded. Switch - // to complex version of the algorithm. - dst = appendStringComplex(dst, s, i) - return append(dst, '"') - } - } - // The string has no need for encoding and therefore is directly - // appended to the byte slice. - dst = append(dst, s...) - // End with a double quote - return append(dst, '"') -} - -// AppendStringers encodes the provided Stringer list to json and -// appends the encoded Stringer list to the input byte slice. -func (e Encoder) AppendStringers(dst []byte, vals []fmt.Stringer) []byte { - if len(vals) == 0 { - return append(dst, '[', ']') - } - dst = append(dst, '[') - dst = e.AppendStringer(dst, vals[0]) - if len(vals) > 1 { - for _, val := range vals[1:] { - dst = e.AppendStringer(append(dst, ','), val) - } - } - return append(dst, ']') -} - -// AppendStringer encodes the input Stringer to json and appends the -// encoded Stringer value to the input byte slice. -func (e Encoder) AppendStringer(dst []byte, val fmt.Stringer) []byte { - if val == nil { - return e.AppendInterface(dst, nil) - } - return e.AppendString(dst, val.String()) -} - -//// appendStringComplex is used by appendString to take over an in -// progress JSON string encoding that encountered a character that needs -// to be encoded. -func appendStringComplex(dst []byte, s string, i int) []byte { - start := 0 - for i < len(s) { - b := s[i] - if b >= utf8.RuneSelf { - r, size := utf8.DecodeRuneInString(s[i:]) - if r == utf8.RuneError && size == 1 { - // In case of error, first append previous simple characters to - // the byte slice if any and append a replacement character code - // in place of the invalid sequence. - if start < i { - dst = append(dst, s[start:i]...) - } - dst = append(dst, `\ufffd`...) - i += size - start = i - continue - } - i += size - continue - } - if noEscapeTable[b] { - i++ - continue - } - // We encountered a character that needs to be encoded. - // Let's append the previous simple characters to the byte slice - // and switch our operation to read and encode the remainder - // characters byte-by-byte. - if start < i { - dst = append(dst, s[start:i]...) - } - switch b { - case '"', '\\': - dst = append(dst, '\\', b) - case '\b': - dst = append(dst, '\\', 'b') - case '\f': - dst = append(dst, '\\', 'f') - case '\n': - dst = append(dst, '\\', 'n') - case '\r': - dst = append(dst, '\\', 'r') - case '\t': - dst = append(dst, '\\', 't') - default: - dst = append(dst, '\\', 'u', '0', '0', hex[b>>4], hex[b&0xF]) - } - i++ - start = i - } - if start < len(s) { - dst = append(dst, s[start:]...) - } - return dst -} diff --git a/vendor/github.com/rs/zerolog/internal/json/time.go b/vendor/github.com/rs/zerolog/internal/json/time.go deleted file mode 100644 index 6a8dc91..0000000 --- a/vendor/github.com/rs/zerolog/internal/json/time.go +++ /dev/null @@ -1,113 +0,0 @@ -package json - -import ( - "strconv" - "time" -) - -const ( - // Import from zerolog/global.go - timeFormatUnix = "" - timeFormatUnixMs = "UNIXMS" - timeFormatUnixMicro = "UNIXMICRO" - timeFormatUnixNano = "UNIXNANO" -) - -// AppendTime formats the input time with the given format -// and appends the encoded string to the input byte slice. -func (e Encoder) AppendTime(dst []byte, t time.Time, format string) []byte { - switch format { - case timeFormatUnix: - return e.AppendInt64(dst, t.Unix()) - case timeFormatUnixMs: - return e.AppendInt64(dst, t.UnixNano()/1000000) - case timeFormatUnixMicro: - return e.AppendInt64(dst, t.UnixNano()/1000) - case timeFormatUnixNano: - return e.AppendInt64(dst, t.UnixNano()) - } - return append(t.AppendFormat(append(dst, '"'), format), '"') -} - -// AppendTimes converts the input times with the given format -// and appends the encoded string list to the input byte slice. -func (Encoder) AppendTimes(dst []byte, vals []time.Time, format string) []byte { - switch format { - case timeFormatUnix: - return appendUnixTimes(dst, vals) - case timeFormatUnixMs: - return appendUnixNanoTimes(dst, vals, 1000000) - case timeFormatUnixMicro: - return appendUnixNanoTimes(dst, vals, 1000) - case timeFormatUnixNano: - return appendUnixNanoTimes(dst, vals, 1) - } - if len(vals) == 0 { - return append(dst, '[', ']') - } - dst = append(dst, '[') - dst = append(vals[0].AppendFormat(append(dst, '"'), format), '"') - if len(vals) > 1 { - for _, t := range vals[1:] { - dst = append(t.AppendFormat(append(dst, ',', '"'), format), '"') - } - } - dst = append(dst, ']') - return dst -} - -func appendUnixTimes(dst []byte, vals []time.Time) []byte { - if len(vals) == 0 { - return append(dst, '[', ']') - } - dst = append(dst, '[') - dst = strconv.AppendInt(dst, vals[0].Unix(), 10) - if len(vals) > 1 { - for _, t := range vals[1:] { - dst = strconv.AppendInt(append(dst, ','), t.Unix(), 10) - } - } - dst = append(dst, ']') - return dst -} - -func appendUnixNanoTimes(dst []byte, vals []time.Time, div int64) []byte { - if len(vals) == 0 { - return append(dst, '[', ']') - } - dst = append(dst, '[') - dst = strconv.AppendInt(dst, vals[0].UnixNano()/div, 10) - if len(vals) > 1 { - for _, t := range vals[1:] { - dst = strconv.AppendInt(append(dst, ','), t.UnixNano()/div, 10) - } - } - dst = append(dst, ']') - return dst -} - -// AppendDuration formats the input duration with the given unit & format -// and appends the encoded string to the input byte slice. -func (e Encoder) AppendDuration(dst []byte, d time.Duration, unit time.Duration, useInt bool) []byte { - if useInt { - return strconv.AppendInt(dst, int64(d/unit), 10) - } - return e.AppendFloat64(dst, float64(d)/float64(unit)) -} - -// AppendDurations formats the input durations with the given unit & format -// and appends the encoded string list to the input byte slice. -func (e Encoder) AppendDurations(dst []byte, vals []time.Duration, unit time.Duration, useInt bool) []byte { - if len(vals) == 0 { - return append(dst, '[', ']') - } - dst = append(dst, '[') - dst = e.AppendDuration(dst, vals[0], unit, useInt) - if len(vals) > 1 { - for _, d := range vals[1:] { - dst = e.AppendDuration(append(dst, ','), d, unit, useInt) - } - } - dst = append(dst, ']') - return dst -} diff --git a/vendor/github.com/rs/zerolog/internal/json/types.go b/vendor/github.com/rs/zerolog/internal/json/types.go deleted file mode 100644 index ad7f7a8..0000000 --- a/vendor/github.com/rs/zerolog/internal/json/types.go +++ /dev/null @@ -1,405 +0,0 @@ -package json - -import ( - "fmt" - "math" - "net" - "strconv" -) - -// AppendNil inserts a 'Nil' object into the dst byte array. -func (Encoder) AppendNil(dst []byte) []byte { - return append(dst, "null"...) -} - -// AppendBeginMarker inserts a map start into the dst byte array. -func (Encoder) AppendBeginMarker(dst []byte) []byte { - return append(dst, '{') -} - -// AppendEndMarker inserts a map end into the dst byte array. -func (Encoder) AppendEndMarker(dst []byte) []byte { - return append(dst, '}') -} - -// AppendLineBreak appends a line break. -func (Encoder) AppendLineBreak(dst []byte) []byte { - return append(dst, '\n') -} - -// AppendArrayStart adds markers to indicate the start of an array. -func (Encoder) AppendArrayStart(dst []byte) []byte { - return append(dst, '[') -} - -// AppendArrayEnd adds markers to indicate the end of an array. -func (Encoder) AppendArrayEnd(dst []byte) []byte { - return append(dst, ']') -} - -// AppendArrayDelim adds markers to indicate end of a particular array element. -func (Encoder) AppendArrayDelim(dst []byte) []byte { - if len(dst) > 0 { - return append(dst, ',') - } - return dst -} - -// AppendBool converts the input bool to a string and -// appends the encoded string to the input byte slice. -func (Encoder) AppendBool(dst []byte, val bool) []byte { - return strconv.AppendBool(dst, val) -} - -// AppendBools encodes the input bools to json and -// appends the encoded string list to the input byte slice. -func (Encoder) AppendBools(dst []byte, vals []bool) []byte { - if len(vals) == 0 { - return append(dst, '[', ']') - } - dst = append(dst, '[') - dst = strconv.AppendBool(dst, vals[0]) - if len(vals) > 1 { - for _, val := range vals[1:] { - dst = strconv.AppendBool(append(dst, ','), val) - } - } - dst = append(dst, ']') - return dst -} - -// AppendInt converts the input int to a string and -// appends the encoded string to the input byte slice. -func (Encoder) AppendInt(dst []byte, val int) []byte { - return strconv.AppendInt(dst, int64(val), 10) -} - -// AppendInts encodes the input ints to json and -// appends the encoded string list to the input byte slice. -func (Encoder) AppendInts(dst []byte, vals []int) []byte { - if len(vals) == 0 { - return append(dst, '[', ']') - } - dst = append(dst, '[') - dst = strconv.AppendInt(dst, int64(vals[0]), 10) - if len(vals) > 1 { - for _, val := range vals[1:] { - dst = strconv.AppendInt(append(dst, ','), int64(val), 10) - } - } - dst = append(dst, ']') - return dst -} - -// AppendInt8 converts the input []int8 to a string and -// appends the encoded string to the input byte slice. -func (Encoder) AppendInt8(dst []byte, val int8) []byte { - return strconv.AppendInt(dst, int64(val), 10) -} - -// AppendInts8 encodes the input int8s to json and -// appends the encoded string list to the input byte slice. -func (Encoder) AppendInts8(dst []byte, vals []int8) []byte { - if len(vals) == 0 { - return append(dst, '[', ']') - } - dst = append(dst, '[') - dst = strconv.AppendInt(dst, int64(vals[0]), 10) - if len(vals) > 1 { - for _, val := range vals[1:] { - dst = strconv.AppendInt(append(dst, ','), int64(val), 10) - } - } - dst = append(dst, ']') - return dst -} - -// AppendInt16 converts the input int16 to a string and -// appends the encoded string to the input byte slice. -func (Encoder) AppendInt16(dst []byte, val int16) []byte { - return strconv.AppendInt(dst, int64(val), 10) -} - -// AppendInts16 encodes the input int16s to json and -// appends the encoded string list to the input byte slice. -func (Encoder) AppendInts16(dst []byte, vals []int16) []byte { - if len(vals) == 0 { - return append(dst, '[', ']') - } - dst = append(dst, '[') - dst = strconv.AppendInt(dst, int64(vals[0]), 10) - if len(vals) > 1 { - for _, val := range vals[1:] { - dst = strconv.AppendInt(append(dst, ','), int64(val), 10) - } - } - dst = append(dst, ']') - return dst -} - -// AppendInt32 converts the input int32 to a string and -// appends the encoded string to the input byte slice. -func (Encoder) AppendInt32(dst []byte, val int32) []byte { - return strconv.AppendInt(dst, int64(val), 10) -} - -// AppendInts32 encodes the input int32s to json and -// appends the encoded string list to the input byte slice. -func (Encoder) AppendInts32(dst []byte, vals []int32) []byte { - if len(vals) == 0 { - return append(dst, '[', ']') - } - dst = append(dst, '[') - dst = strconv.AppendInt(dst, int64(vals[0]), 10) - if len(vals) > 1 { - for _, val := range vals[1:] { - dst = strconv.AppendInt(append(dst, ','), int64(val), 10) - } - } - dst = append(dst, ']') - return dst -} - -// AppendInt64 converts the input int64 to a string and -// appends the encoded string to the input byte slice. -func (Encoder) AppendInt64(dst []byte, val int64) []byte { - return strconv.AppendInt(dst, val, 10) -} - -// AppendInts64 encodes the input int64s to json and -// appends the encoded string list to the input byte slice. -func (Encoder) AppendInts64(dst []byte, vals []int64) []byte { - if len(vals) == 0 { - return append(dst, '[', ']') - } - dst = append(dst, '[') - dst = strconv.AppendInt(dst, vals[0], 10) - if len(vals) > 1 { - for _, val := range vals[1:] { - dst = strconv.AppendInt(append(dst, ','), val, 10) - } - } - dst = append(dst, ']') - return dst -} - -// AppendUint converts the input uint to a string and -// appends the encoded string to the input byte slice. -func (Encoder) AppendUint(dst []byte, val uint) []byte { - return strconv.AppendUint(dst, uint64(val), 10) -} - -// AppendUints encodes the input uints to json and -// appends the encoded string list to the input byte slice. -func (Encoder) AppendUints(dst []byte, vals []uint) []byte { - if len(vals) == 0 { - return append(dst, '[', ']') - } - dst = append(dst, '[') - dst = strconv.AppendUint(dst, uint64(vals[0]), 10) - if len(vals) > 1 { - for _, val := range vals[1:] { - dst = strconv.AppendUint(append(dst, ','), uint64(val), 10) - } - } - dst = append(dst, ']') - return dst -} - -// AppendUint8 converts the input uint8 to a string and -// appends the encoded string to the input byte slice. -func (Encoder) AppendUint8(dst []byte, val uint8) []byte { - return strconv.AppendUint(dst, uint64(val), 10) -} - -// AppendUints8 encodes the input uint8s to json and -// appends the encoded string list to the input byte slice. -func (Encoder) AppendUints8(dst []byte, vals []uint8) []byte { - if len(vals) == 0 { - return append(dst, '[', ']') - } - dst = append(dst, '[') - dst = strconv.AppendUint(dst, uint64(vals[0]), 10) - if len(vals) > 1 { - for _, val := range vals[1:] { - dst = strconv.AppendUint(append(dst, ','), uint64(val), 10) - } - } - dst = append(dst, ']') - return dst -} - -// AppendUint16 converts the input uint16 to a string and -// appends the encoded string to the input byte slice. -func (Encoder) AppendUint16(dst []byte, val uint16) []byte { - return strconv.AppendUint(dst, uint64(val), 10) -} - -// AppendUints16 encodes the input uint16s to json and -// appends the encoded string list to the input byte slice. -func (Encoder) AppendUints16(dst []byte, vals []uint16) []byte { - if len(vals) == 0 { - return append(dst, '[', ']') - } - dst = append(dst, '[') - dst = strconv.AppendUint(dst, uint64(vals[0]), 10) - if len(vals) > 1 { - for _, val := range vals[1:] { - dst = strconv.AppendUint(append(dst, ','), uint64(val), 10) - } - } - dst = append(dst, ']') - return dst -} - -// AppendUint32 converts the input uint32 to a string and -// appends the encoded string to the input byte slice. -func (Encoder) AppendUint32(dst []byte, val uint32) []byte { - return strconv.AppendUint(dst, uint64(val), 10) -} - -// AppendUints32 encodes the input uint32s to json and -// appends the encoded string list to the input byte slice. -func (Encoder) AppendUints32(dst []byte, vals []uint32) []byte { - if len(vals) == 0 { - return append(dst, '[', ']') - } - dst = append(dst, '[') - dst = strconv.AppendUint(dst, uint64(vals[0]), 10) - if len(vals) > 1 { - for _, val := range vals[1:] { - dst = strconv.AppendUint(append(dst, ','), uint64(val), 10) - } - } - dst = append(dst, ']') - return dst -} - -// AppendUint64 converts the input uint64 to a string and -// appends the encoded string to the input byte slice. -func (Encoder) AppendUint64(dst []byte, val uint64) []byte { - return strconv.AppendUint(dst, val, 10) -} - -// AppendUints64 encodes the input uint64s to json and -// appends the encoded string list to the input byte slice. -func (Encoder) AppendUints64(dst []byte, vals []uint64) []byte { - if len(vals) == 0 { - return append(dst, '[', ']') - } - dst = append(dst, '[') - dst = strconv.AppendUint(dst, vals[0], 10) - if len(vals) > 1 { - for _, val := range vals[1:] { - dst = strconv.AppendUint(append(dst, ','), val, 10) - } - } - dst = append(dst, ']') - return dst -} - -func appendFloat(dst []byte, val float64, bitSize int) []byte { - // JSON does not permit NaN or Infinity. A typical JSON encoder would fail - // with an error, but a logging library wants the data to get through so we - // make a tradeoff and store those types as string. - switch { - case math.IsNaN(val): - return append(dst, `"NaN"`...) - case math.IsInf(val, 1): - return append(dst, `"+Inf"`...) - case math.IsInf(val, -1): - return append(dst, `"-Inf"`...) - } - return strconv.AppendFloat(dst, val, 'f', -1, bitSize) -} - -// AppendFloat32 converts the input float32 to a string and -// appends the encoded string to the input byte slice. -func (Encoder) AppendFloat32(dst []byte, val float32) []byte { - return appendFloat(dst, float64(val), 32) -} - -// AppendFloats32 encodes the input float32s to json and -// appends the encoded string list to the input byte slice. -func (Encoder) AppendFloats32(dst []byte, vals []float32) []byte { - if len(vals) == 0 { - return append(dst, '[', ']') - } - dst = append(dst, '[') - dst = appendFloat(dst, float64(vals[0]), 32) - if len(vals) > 1 { - for _, val := range vals[1:] { - dst = appendFloat(append(dst, ','), float64(val), 32) - } - } - dst = append(dst, ']') - return dst -} - -// AppendFloat64 converts the input float64 to a string and -// appends the encoded string to the input byte slice. -func (Encoder) AppendFloat64(dst []byte, val float64) []byte { - return appendFloat(dst, val, 64) -} - -// AppendFloats64 encodes the input float64s to json and -// appends the encoded string list to the input byte slice. -func (Encoder) AppendFloats64(dst []byte, vals []float64) []byte { - if len(vals) == 0 { - return append(dst, '[', ']') - } - dst = append(dst, '[') - dst = appendFloat(dst, vals[0], 64) - if len(vals) > 1 { - for _, val := range vals[1:] { - dst = appendFloat(append(dst, ','), val, 64) - } - } - dst = append(dst, ']') - return dst -} - -// AppendInterface marshals the input interface to a string and -// appends the encoded string to the input byte slice. -func (e Encoder) AppendInterface(dst []byte, i interface{}) []byte { - marshaled, err := JSONMarshalFunc(i) - if err != nil { - return e.AppendString(dst, fmt.Sprintf("marshaling error: %v", err)) - } - return append(dst, marshaled...) -} - -// AppendObjectData takes in an object that is already in a byte array -// and adds it to the dst. -func (Encoder) AppendObjectData(dst []byte, o []byte) []byte { - // Three conditions apply here: - // 1. new content starts with '{' - which should be dropped OR - // 2. new content starts with '{' - which should be replaced with ',' - // to separate with existing content OR - // 3. existing content has already other fields - if o[0] == '{' { - if len(dst) > 1 { - dst = append(dst, ',') - } - o = o[1:] - } else if len(dst) > 1 { - dst = append(dst, ',') - } - return append(dst, o...) -} - -// AppendIPAddr adds IPv4 or IPv6 address to dst. -func (e Encoder) AppendIPAddr(dst []byte, ip net.IP) []byte { - return e.AppendString(dst, ip.String()) -} - -// AppendIPPrefix adds IPv4 or IPv6 Prefix (address & mask) to dst. -func (e Encoder) AppendIPPrefix(dst []byte, pfx net.IPNet) []byte { - return e.AppendString(dst, pfx.String()) - -} - -// AppendMACAddr adds MAC address to dst. -func (e Encoder) AppendMACAddr(dst []byte, ha net.HardwareAddr) []byte { - return e.AppendString(dst, ha.String()) -} diff --git a/vendor/github.com/rs/zerolog/log.go b/vendor/github.com/rs/zerolog/log.go deleted file mode 100644 index efd2a33..0000000 --- a/vendor/github.com/rs/zerolog/log.go +++ /dev/null @@ -1,476 +0,0 @@ -// Package zerolog provides a lightweight logging library dedicated to JSON logging. -// -// A global Logger can be use for simple logging: -// -// import "github.com/rs/zerolog/log" -// -// log.Info().Msg("hello world") -// // Output: {"time":1494567715,"level":"info","message":"hello world"} -// -// NOTE: To import the global logger, import the "log" subpackage "github.com/rs/zerolog/log". -// -// Fields can be added to log messages: -// -// log.Info().Str("foo", "bar").Msg("hello world") -// // Output: {"time":1494567715,"level":"info","message":"hello world","foo":"bar"} -// -// Create logger instance to manage different outputs: -// -// logger := zerolog.New(os.Stderr).With().Timestamp().Logger() -// logger.Info(). -// Str("foo", "bar"). -// Msg("hello world") -// // Output: {"time":1494567715,"level":"info","message":"hello world","foo":"bar"} -// -// Sub-loggers let you chain loggers with additional context: -// -// sublogger := log.With().Str("component": "foo").Logger() -// sublogger.Info().Msg("hello world") -// // Output: {"time":1494567715,"level":"info","message":"hello world","component":"foo"} -// -// Level logging -// -// zerolog.SetGlobalLevel(zerolog.InfoLevel) -// -// log.Debug().Msg("filtered out message") -// log.Info().Msg("routed message") -// -// if e := log.Debug(); e.Enabled() { -// // Compute log output only if enabled. -// value := compute() -// e.Str("foo": value).Msg("some debug message") -// } -// // Output: {"level":"info","time":1494567715,"routed message"} -// -// Customize automatic field names: -// -// log.TimestampFieldName = "t" -// log.LevelFieldName = "p" -// log.MessageFieldName = "m" -// -// log.Info().Msg("hello world") -// // Output: {"t":1494567715,"p":"info","m":"hello world"} -// -// Log with no level and message: -// -// log.Log().Str("foo","bar").Msg("") -// // Output: {"time":1494567715,"foo":"bar"} -// -// Add contextual fields to global Logger: -// -// log.Logger = log.With().Str("foo", "bar").Logger() -// -// Sample logs: -// -// sampled := log.Sample(&zerolog.BasicSampler{N: 10}) -// sampled.Info().Msg("will be logged every 10 messages") -// -// Log with contextual hooks: -// -// // Create the hook: -// type SeverityHook struct{} -// -// func (h SeverityHook) Run(e *zerolog.Event, level zerolog.Level, msg string) { -// if level != zerolog.NoLevel { -// e.Str("severity", level.String()) -// } -// } -// -// // And use it: -// var h SeverityHook -// log := zerolog.New(os.Stdout).Hook(h) -// log.Warn().Msg("") -// // Output: {"level":"warn","severity":"warn"} -// -// -// Caveats -// -// There is no fields deduplication out-of-the-box. -// Using the same key multiple times creates new key in final JSON each time. -// -// logger := zerolog.New(os.Stderr).With().Timestamp().Logger() -// logger.Info(). -// Timestamp(). -// Msg("dup") -// // Output: {"level":"info","time":1494567715,"time":1494567715,"message":"dup"} -// -// In this case, many consumers will take the last value, -// but this is not guaranteed; check yours if in doubt. -package zerolog - -import ( - "errors" - "fmt" - "io" - "io/ioutil" - "os" - "strconv" -) - -// Level defines log levels. -type Level int8 - -const ( - // DebugLevel defines debug log level. - DebugLevel Level = iota - // InfoLevel defines info log level. - InfoLevel - // WarnLevel defines warn log level. - WarnLevel - // ErrorLevel defines error log level. - ErrorLevel - // FatalLevel defines fatal log level. - FatalLevel - // PanicLevel defines panic log level. - PanicLevel - // NoLevel defines an absent log level. - NoLevel - // Disabled disables the logger. - Disabled - - // TraceLevel defines trace log level. - TraceLevel Level = -1 - // Values less than TraceLevel are handled as numbers. -) - -func (l Level) String() string { - switch l { - case TraceLevel: - return LevelTraceValue - case DebugLevel: - return LevelDebugValue - case InfoLevel: - return LevelInfoValue - case WarnLevel: - return LevelWarnValue - case ErrorLevel: - return LevelErrorValue - case FatalLevel: - return LevelFatalValue - case PanicLevel: - return LevelPanicValue - case Disabled: - return "disabled" - case NoLevel: - return "" - } - return strconv.Itoa(int(l)) -} - -// ParseLevel converts a level string into a zerolog Level value. -// returns an error if the input string does not match known values. -func ParseLevel(levelStr string) (Level, error) { - switch levelStr { - case LevelFieldMarshalFunc(TraceLevel): - return TraceLevel, nil - case LevelFieldMarshalFunc(DebugLevel): - return DebugLevel, nil - case LevelFieldMarshalFunc(InfoLevel): - return InfoLevel, nil - case LevelFieldMarshalFunc(WarnLevel): - return WarnLevel, nil - case LevelFieldMarshalFunc(ErrorLevel): - return ErrorLevel, nil - case LevelFieldMarshalFunc(FatalLevel): - return FatalLevel, nil - case LevelFieldMarshalFunc(PanicLevel): - return PanicLevel, nil - case LevelFieldMarshalFunc(Disabled): - return Disabled, nil - case LevelFieldMarshalFunc(NoLevel): - return NoLevel, nil - } - i, err := strconv.Atoi(levelStr) - if err != nil { - return NoLevel, fmt.Errorf("Unknown Level String: '%s', defaulting to NoLevel", levelStr) - } - if i > 127 || i < -128 { - return NoLevel, fmt.Errorf("Out-Of-Bounds Level: '%d', defaulting to NoLevel", i) - } - return Level(i), nil -} - -// UnmarshalText implements encoding.TextUnmarshaler to allow for easy reading from toml/yaml/json formats -func (l *Level) UnmarshalText(text []byte) error { - if l == nil { - return errors.New("can't unmarshal a nil *Level") - } - var err error - *l, err = ParseLevel(string(text)) - return err -} - -// MarshalText implements encoding.TextMarshaler to allow for easy writing into toml/yaml/json formats -func (l Level) MarshalText() ([]byte, error) { - return []byte(LevelFieldMarshalFunc(l)), nil -} - -// A Logger represents an active logging object that generates lines -// of JSON output to an io.Writer. Each logging operation makes a single -// call to the Writer's Write method. There is no guarantee on access -// serialization to the Writer. If your Writer is not thread safe, -// you may consider a sync wrapper. -type Logger struct { - w LevelWriter - level Level - sampler Sampler - context []byte - hooks []Hook - stack bool -} - -// New creates a root logger with given output writer. If the output writer implements -// the LevelWriter interface, the WriteLevel method will be called instead of the Write -// one. -// -// Each logging operation makes a single call to the Writer's Write method. There is no -// guarantee on access serialization to the Writer. If your Writer is not thread safe, -// you may consider using sync wrapper. -func New(w io.Writer) Logger { - if w == nil { - w = ioutil.Discard - } - lw, ok := w.(LevelWriter) - if !ok { - lw = levelWriterAdapter{w} - } - return Logger{w: lw, level: TraceLevel} -} - -// Nop returns a disabled logger for which all operation are no-op. -func Nop() Logger { - return New(nil).Level(Disabled) -} - -// Output duplicates the current logger and sets w as its output. -func (l Logger) Output(w io.Writer) Logger { - l2 := New(w) - l2.level = l.level - l2.sampler = l.sampler - l2.stack = l.stack - if len(l.hooks) > 0 { - l2.hooks = append(l2.hooks, l.hooks...) - } - if l.context != nil { - l2.context = make([]byte, len(l.context), cap(l.context)) - copy(l2.context, l.context) - } - return l2 -} - -// With creates a child logger with the field added to its context. -func (l Logger) With() Context { - context := l.context - l.context = make([]byte, 0, 500) - if context != nil { - l.context = append(l.context, context...) - } else { - // This is needed for AppendKey to not check len of input - // thus making it inlinable - l.context = enc.AppendBeginMarker(l.context) - } - return Context{l} -} - -// UpdateContext updates the internal logger's context. -// -// Use this method with caution. If unsure, prefer the With method. -func (l *Logger) UpdateContext(update func(c Context) Context) { - if l == disabledLogger { - return - } - if cap(l.context) == 0 { - l.context = make([]byte, 0, 500) - } - if len(l.context) == 0 { - l.context = enc.AppendBeginMarker(l.context) - } - c := update(Context{*l}) - l.context = c.l.context -} - -// Level creates a child logger with the minimum accepted level set to level. -func (l Logger) Level(lvl Level) Logger { - l.level = lvl - return l -} - -// GetLevel returns the current Level of l. -func (l Logger) GetLevel() Level { - return l.level -} - -// Sample returns a logger with the s sampler. -func (l Logger) Sample(s Sampler) Logger { - l.sampler = s - return l -} - -// Hook returns a logger with the h Hook. -func (l Logger) Hook(h Hook) Logger { - l.hooks = append(l.hooks, h) - return l -} - -// Trace starts a new message with trace level. -// -// You must call Msg on the returned event in order to send the event. -func (l *Logger) Trace() *Event { - return l.newEvent(TraceLevel, nil) -} - -// Debug starts a new message with debug level. -// -// You must call Msg on the returned event in order to send the event. -func (l *Logger) Debug() *Event { - return l.newEvent(DebugLevel, nil) -} - -// Info starts a new message with info level. -// -// You must call Msg on the returned event in order to send the event. -func (l *Logger) Info() *Event { - return l.newEvent(InfoLevel, nil) -} - -// Warn starts a new message with warn level. -// -// You must call Msg on the returned event in order to send the event. -func (l *Logger) Warn() *Event { - return l.newEvent(WarnLevel, nil) -} - -// Error starts a new message with error level. -// -// You must call Msg on the returned event in order to send the event. -func (l *Logger) Error() *Event { - return l.newEvent(ErrorLevel, nil) -} - -// Err starts a new message with error level with err as a field if not nil or -// with info level if err is nil. -// -// You must call Msg on the returned event in order to send the event. -func (l *Logger) Err(err error) *Event { - if err != nil { - return l.Error().Err(err) - } - - return l.Info() -} - -// Fatal starts a new message with fatal level. The os.Exit(1) function -// is called by the Msg method, which terminates the program immediately. -// -// You must call Msg on the returned event in order to send the event. -func (l *Logger) Fatal() *Event { - return l.newEvent(FatalLevel, func(msg string) { os.Exit(1) }) -} - -// Panic starts a new message with panic level. The panic() function -// is called by the Msg method, which stops the ordinary flow of a goroutine. -// -// You must call Msg on the returned event in order to send the event. -func (l *Logger) Panic() *Event { - return l.newEvent(PanicLevel, func(msg string) { panic(msg) }) -} - -// WithLevel starts a new message with level. Unlike Fatal and Panic -// methods, WithLevel does not terminate the program or stop the ordinary -// flow of a goroutine when used with their respective levels. -// -// You must call Msg on the returned event in order to send the event. -func (l *Logger) WithLevel(level Level) *Event { - switch level { - case TraceLevel: - return l.Trace() - case DebugLevel: - return l.Debug() - case InfoLevel: - return l.Info() - case WarnLevel: - return l.Warn() - case ErrorLevel: - return l.Error() - case FatalLevel: - return l.newEvent(FatalLevel, nil) - case PanicLevel: - return l.newEvent(PanicLevel, nil) - case NoLevel: - return l.Log() - case Disabled: - return nil - default: - return l.newEvent(level, nil) - } -} - -// Log starts a new message with no level. Setting GlobalLevel to Disabled -// will still disable events produced by this method. -// -// You must call Msg on the returned event in order to send the event. -func (l *Logger) Log() *Event { - return l.newEvent(NoLevel, nil) -} - -// Print sends a log event using debug level and no extra field. -// Arguments are handled in the manner of fmt.Print. -func (l *Logger) Print(v ...interface{}) { - if e := l.Debug(); e.Enabled() { - e.CallerSkipFrame(1).Msg(fmt.Sprint(v...)) - } -} - -// Printf sends a log event using debug level and no extra field. -// Arguments are handled in the manner of fmt.Printf. -func (l *Logger) Printf(format string, v ...interface{}) { - if e := l.Debug(); e.Enabled() { - e.CallerSkipFrame(1).Msg(fmt.Sprintf(format, v...)) - } -} - -// Write implements the io.Writer interface. This is useful to set as a writer -// for the standard library log. -func (l Logger) Write(p []byte) (n int, err error) { - n = len(p) - if n > 0 && p[n-1] == '\n' { - // Trim CR added by stdlog. - p = p[0 : n-1] - } - l.Log().CallerSkipFrame(1).Msg(string(p)) - return -} - -func (l *Logger) newEvent(level Level, done func(string)) *Event { - enabled := l.should(level) - if !enabled { - if done != nil { - done("") - } - return nil - } - e := newEvent(l.w, level) - e.done = done - e.ch = l.hooks - if level != NoLevel && LevelFieldName != "" { - e.Str(LevelFieldName, LevelFieldMarshalFunc(level)) - } - if l.context != nil && len(l.context) > 1 { - e.buf = enc.AppendObjectData(e.buf, l.context) - } - if l.stack { - e.Stack() - } - return e -} - -// should returns true if the log event should be logged. -func (l *Logger) should(lvl Level) bool { - if lvl < l.level || lvl < GlobalLevel() { - return false - } - if l.sampler != nil && !samplingDisabled() { - return l.sampler.Sample(lvl) - } - return true -} diff --git a/vendor/github.com/rs/zerolog/not_go112.go b/vendor/github.com/rs/zerolog/not_go112.go deleted file mode 100644 index 4c43c9e..0000000 --- a/vendor/github.com/rs/zerolog/not_go112.go +++ /dev/null @@ -1,5 +0,0 @@ -// +build !go1.12 - -package zerolog - -const contextCallerSkipFrameCount = 3 diff --git a/vendor/github.com/rs/zerolog/pretty.png b/vendor/github.com/rs/zerolog/pretty.png deleted file mode 100644 index 242033686debf04c5b1756c166d05d09767594e3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 84064 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

8fq~0=I!v4AnE;d}cbadUlY^=u7 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 diff --git a/vendor/github.com/rs/zerolog/sampler.go b/vendor/github.com/rs/zerolog/sampler.go deleted file mode 100644 index 1be98c4..0000000 --- a/vendor/github.com/rs/zerolog/sampler.go +++ /dev/null @@ -1,134 +0,0 @@ -package zerolog - -import ( - "math/rand" - "sync/atomic" - "time" -) - -var ( - // Often samples log every ~ 10 events. - Often = RandomSampler(10) - // Sometimes samples log every ~ 100 events. - Sometimes = RandomSampler(100) - // Rarely samples log every ~ 1000 events. - Rarely = RandomSampler(1000) -) - -// Sampler defines an interface to a log sampler. -type Sampler interface { - // Sample returns true if the event should be part of the sample, false if - // the event should be dropped. - Sample(lvl Level) bool -} - -// RandomSampler use a PRNG to randomly sample an event out of N events, -// regardless of their level. -type RandomSampler uint32 - -// Sample implements the Sampler interface. -func (s RandomSampler) Sample(lvl Level) bool { - if s <= 0 { - return false - } - if rand.Intn(int(s)) != 0 { - return false - } - return true -} - -// BasicSampler is a sampler that will send every Nth events, regardless of -// their level. -type BasicSampler struct { - N uint32 - counter uint32 -} - -// Sample implements the Sampler interface. -func (s *BasicSampler) Sample(lvl Level) bool { - n := s.N - if n == 1 { - return true - } - c := atomic.AddUint32(&s.counter, 1) - return c%n == 1 -} - -// BurstSampler lets Burst events pass per Period then pass the decision to -// NextSampler. If Sampler is not set, all subsequent events are rejected. -type BurstSampler struct { - // Burst is the maximum number of event per period allowed before calling - // NextSampler. - Burst uint32 - // Period defines the burst period. If 0, NextSampler is always called. - Period time.Duration - // NextSampler is the sampler used after the burst is reached. If nil, - // events are always rejected after the burst. - NextSampler Sampler - - counter uint32 - resetAt int64 -} - -// Sample implements the Sampler interface. -func (s *BurstSampler) Sample(lvl Level) bool { - if s.Burst > 0 && s.Period > 0 { - if s.inc() <= s.Burst { - return true - } - } - if s.NextSampler == nil { - return false - } - return s.NextSampler.Sample(lvl) -} - -func (s *BurstSampler) inc() uint32 { - now := time.Now().UnixNano() - resetAt := atomic.LoadInt64(&s.resetAt) - var c uint32 - if now > resetAt { - c = 1 - atomic.StoreUint32(&s.counter, c) - newResetAt := now + s.Period.Nanoseconds() - reset := atomic.CompareAndSwapInt64(&s.resetAt, resetAt, newResetAt) - if !reset { - // Lost the race with another goroutine trying to reset. - c = atomic.AddUint32(&s.counter, 1) - } - } else { - c = atomic.AddUint32(&s.counter, 1) - } - return c -} - -// LevelSampler applies a different sampler for each level. -type LevelSampler struct { - TraceSampler, DebugSampler, InfoSampler, WarnSampler, ErrorSampler Sampler -} - -func (s LevelSampler) Sample(lvl Level) bool { - switch lvl { - case TraceLevel: - if s.TraceSampler != nil { - return s.TraceSampler.Sample(lvl) - } - case DebugLevel: - if s.DebugSampler != nil { - return s.DebugSampler.Sample(lvl) - } - case InfoLevel: - if s.InfoSampler != nil { - return s.InfoSampler.Sample(lvl) - } - case WarnLevel: - if s.WarnSampler != nil { - return s.WarnSampler.Sample(lvl) - } - case ErrorLevel: - if s.ErrorSampler != nil { - return s.ErrorSampler.Sample(lvl) - } - } - return true -} diff --git a/vendor/github.com/rs/zerolog/syslog.go b/vendor/github.com/rs/zerolog/syslog.go deleted file mode 100644 index c408283..0000000 --- a/vendor/github.com/rs/zerolog/syslog.go +++ /dev/null @@ -1,80 +0,0 @@ -// +build !windows -// +build !binary_log - -package zerolog - -import ( - "io" -) - -// See http://cee.mitre.org/language/1.0-beta1/clt.html#syslog -// or https://www.rsyslog.com/json-elasticsearch/ -const ceePrefix = "@cee:" - -// SyslogWriter is an interface matching a syslog.Writer struct. -type SyslogWriter interface { - io.Writer - Debug(m string) error - Info(m string) error - Warning(m string) error - Err(m string) error - Emerg(m string) error - Crit(m string) error -} - -type syslogWriter struct { - w SyslogWriter - prefix string -} - -// SyslogLevelWriter wraps a SyslogWriter and call the right syslog level -// method matching the zerolog level. -func SyslogLevelWriter(w SyslogWriter) LevelWriter { - return syslogWriter{w, ""} -} - -// SyslogCEEWriter wraps a SyslogWriter with a SyslogLevelWriter that adds a -// MITRE CEE prefix for JSON syslog entries, compatible with rsyslog -// and syslog-ng JSON logging support. -// See https://www.rsyslog.com/json-elasticsearch/ -func SyslogCEEWriter(w SyslogWriter) LevelWriter { - return syslogWriter{w, ceePrefix} -} - -func (sw syslogWriter) Write(p []byte) (n int, err error) { - var pn int - if sw.prefix != "" { - pn, err = sw.w.Write([]byte(sw.prefix)) - if err != nil { - return pn, err - } - } - n, err = sw.w.Write(p) - return pn + n, err -} - -// WriteLevel implements LevelWriter interface. -func (sw syslogWriter) WriteLevel(level Level, p []byte) (n int, err error) { - switch level { - case TraceLevel: - case DebugLevel: - err = sw.w.Debug(sw.prefix + string(p)) - case InfoLevel: - err = sw.w.Info(sw.prefix + string(p)) - case WarnLevel: - err = sw.w.Warning(sw.prefix + string(p)) - case ErrorLevel: - err = sw.w.Err(sw.prefix + string(p)) - case FatalLevel: - err = sw.w.Emerg(sw.prefix + string(p)) - case PanicLevel: - err = sw.w.Crit(sw.prefix + string(p)) - case NoLevel: - err = sw.w.Info(sw.prefix + string(p)) - default: - panic("invalid level") - } - // Any CEE prefix is not part of the message, so we don't include its length - n = len(p) - return -} diff --git a/vendor/github.com/rs/zerolog/writer.go b/vendor/github.com/rs/zerolog/writer.go deleted file mode 100644 index 26f5e63..0000000 --- a/vendor/github.com/rs/zerolog/writer.go +++ /dev/null @@ -1,154 +0,0 @@ -package zerolog - -import ( - "bytes" - "io" - "path" - "runtime" - "strconv" - "strings" - "sync" -) - -// LevelWriter defines as interface a writer may implement in order -// to receive level information with payload. -type LevelWriter interface { - io.Writer - WriteLevel(level Level, p []byte) (n int, err error) -} - -type levelWriterAdapter struct { - io.Writer -} - -func (lw levelWriterAdapter) WriteLevel(l Level, p []byte) (n int, err error) { - return lw.Write(p) -} - -type syncWriter struct { - mu sync.Mutex - lw LevelWriter -} - -// SyncWriter wraps w so that each call to Write is synchronized with a mutex. -// This syncer can be used to wrap the call to writer's Write method if it is -// not thread safe. Note that you do not need this wrapper for os.File Write -// operations on POSIX and Windows systems as they are already thread-safe. -func SyncWriter(w io.Writer) io.Writer { - if lw, ok := w.(LevelWriter); ok { - return &syncWriter{lw: lw} - } - return &syncWriter{lw: levelWriterAdapter{w}} -} - -// Write implements the io.Writer interface. -func (s *syncWriter) Write(p []byte) (n int, err error) { - s.mu.Lock() - defer s.mu.Unlock() - return s.lw.Write(p) -} - -// WriteLevel implements the LevelWriter interface. -func (s *syncWriter) WriteLevel(l Level, p []byte) (n int, err error) { - s.mu.Lock() - defer s.mu.Unlock() - return s.lw.WriteLevel(l, p) -} - -type multiLevelWriter struct { - writers []LevelWriter -} - -func (t multiLevelWriter) Write(p []byte) (n int, err error) { - for _, w := range t.writers { - if _n, _err := w.Write(p); err == nil { - n = _n - if _err != nil { - err = _err - } else if _n != len(p) { - err = io.ErrShortWrite - } - } - } - return n, err -} - -func (t multiLevelWriter) WriteLevel(l Level, p []byte) (n int, err error) { - for _, w := range t.writers { - if _n, _err := w.WriteLevel(l, p); err == nil { - n = _n - if _err != nil { - err = _err - } else if _n != len(p) { - err = io.ErrShortWrite - } - } - } - return n, err -} - -// MultiLevelWriter creates a writer that duplicates its writes to all the -// provided writers, similar to the Unix tee(1) command. If some writers -// implement LevelWriter, their WriteLevel method will be used instead of Write. -func MultiLevelWriter(writers ...io.Writer) LevelWriter { - lwriters := make([]LevelWriter, 0, len(writers)) - for _, w := range writers { - if lw, ok := w.(LevelWriter); ok { - lwriters = append(lwriters, lw) - } else { - lwriters = append(lwriters, levelWriterAdapter{w}) - } - } - return multiLevelWriter{lwriters} -} - -// TestingLog is the logging interface of testing.TB. -type TestingLog interface { - Log(args ...interface{}) - Logf(format string, args ...interface{}) - Helper() -} - -// TestWriter is a writer that writes to testing.TB. -type TestWriter struct { - T TestingLog - - // Frame skips caller frames to capture the original file and line numbers. - Frame int -} - -// NewTestWriter creates a writer that logs to the testing.TB. -func NewTestWriter(t TestingLog) TestWriter { - return TestWriter{T: t} -} - -// Write to testing.TB. -func (t TestWriter) Write(p []byte) (n int, err error) { - t.T.Helper() - - n = len(p) - - // Strip trailing newline because t.Log always adds one. - p = bytes.TrimRight(p, "\n") - - // Try to correct the log file and line number to the caller. - if t.Frame > 0 { - _, origFile, origLine, _ := runtime.Caller(1) - _, frameFile, frameLine, ok := runtime.Caller(1 + t.Frame) - if ok { - erase := strings.Repeat("\b", len(path.Base(origFile))+len(strconv.Itoa(origLine))+3) - t.T.Logf("%s%s:%d: %s", erase, path.Base(frameFile), frameLine, p) - return n, err - } - } - t.T.Log(string(p)) - - return n, err -} - -// ConsoleTestWriter creates an option that correctly sets the file frame depth for testing.TB log. -func ConsoleTestWriter(t TestingLog) func(w *ConsoleWriter) { - return func(w *ConsoleWriter) { - w.Out = TestWriter{T: t, Frame: 6} - } -} diff --git a/vendor/k8s.io/klog/v2/.gitignore b/vendor/k8s.io/klog/v2/.gitignore new file mode 100644 index 0000000..0aa2002 --- /dev/null +++ b/vendor/k8s.io/klog/v2/.gitignore @@ -0,0 +1,17 @@ +# OSX leaves these everywhere on SMB shares +._* + +# OSX trash +.DS_Store + +# Eclipse files +.classpath +.project +.settings/** + +# Files generated by JetBrains IDEs, e.g. IntelliJ IDEA +.idea/ +*.iml + +# Vscode files +.vscode diff --git a/vendor/k8s.io/klog/v2/CONTRIBUTING.md b/vendor/k8s.io/klog/v2/CONTRIBUTING.md new file mode 100644 index 0000000..2641b1f --- /dev/null +++ b/vendor/k8s.io/klog/v2/CONTRIBUTING.md @@ -0,0 +1,22 @@ +# Contributing Guidelines + +Welcome to Kubernetes. We are excited about the prospect of you joining our [community](https://github.com/kubernetes/community)! The Kubernetes community abides by the CNCF [code of conduct](code-of-conduct.md). Here is an excerpt: + +_As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities._ + +## Getting Started + +We have full documentation on how to get started contributing here: + +- [Contributor License Agreement](https://git.k8s.io/community/CLA.md) Kubernetes projects require that you sign a Contributor License Agreement (CLA) before we can accept your pull requests +- [Kubernetes Contributor Guide](http://git.k8s.io/community/contributors/guide) - Main contributor documentation, or you can just jump directly to the [contributing section](http://git.k8s.io/community/contributors/guide#contributing) +- [Contributor Cheat Sheet](https://git.k8s.io/community/contributors/guide/contributor-cheatsheet) - Common resources for existing developers + +## Mentorship + +- [Mentoring Initiatives](https://git.k8s.io/community/mentoring) - We have a diverse set of mentorship programs available that are always looking for volunteers! + +## Contact Information + +- [Slack](https://kubernetes.slack.com/messages/sig-architecture) +- [Mailing List](https://groups.google.com/forum/#!forum/kubernetes-sig-architecture) diff --git a/vendor/k8s.io/klog/v2/LICENSE b/vendor/k8s.io/klog/v2/LICENSE new file mode 100644 index 0000000..37ec93a --- /dev/null +++ b/vendor/k8s.io/klog/v2/LICENSE @@ -0,0 +1,191 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +"Object" form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of +this License; and +You must cause any modified files to carry prominent notices stating that You +changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "[]" replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a file or class name and description of purpose be included on +the same "printed page" as the copyright notice for easier identification within +third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/k8s.io/klog/v2/OWNERS b/vendor/k8s.io/klog/v2/OWNERS new file mode 100644 index 0000000..a2fe8f3 --- /dev/null +++ b/vendor/k8s.io/klog/v2/OWNERS @@ -0,0 +1,14 @@ +# See the OWNERS docs at https://go.k8s.io/owners +reviewers: + - harshanarayana + - pohly +approvers: + - dims + - thockin + - serathius +emeritus_approvers: + - brancz + - justinsb + - lavalamp + - piosz + - tallclair diff --git a/vendor/k8s.io/klog/v2/README.md b/vendor/k8s.io/klog/v2/README.md new file mode 100644 index 0000000..d45cbe1 --- /dev/null +++ b/vendor/k8s.io/klog/v2/README.md @@ -0,0 +1,118 @@ +klog +==== + +klog is a permanent fork of https://github.com/golang/glog. + +## Why was klog created? + +The decision to create klog was one that wasn't made lightly, but it was necessary due to some +drawbacks that are present in [glog](https://github.com/golang/glog). Ultimately, the fork was created due to glog not being under active development; this can be seen in the glog README: + +> The code in this repo [...] is not itself under development + +This makes us unable to solve many use cases without a fork. The factors that contributed to needing feature development are listed below: + + * `glog` [presents a lot "gotchas"](https://github.com/kubernetes/kubernetes/issues/61006) and introduces challenges in containerized environments, all of which aren't well documented. + * `glog` doesn't provide an easy way to test logs, which detracts from the stability of software using it + * A long term goal is to implement a logging interface that allows us to add context, change output format, etc. + +Historical context is available here: + + * https://github.com/kubernetes/kubernetes/issues/61006 + * https://github.com/kubernetes/kubernetes/issues/70264 + * https://groups.google.com/forum/#!msg/kubernetes-sig-architecture/wCWiWf3Juzs/hXRVBH90CgAJ + * https://groups.google.com/forum/#!msg/kubernetes-dev/7vnijOMhLS0/1oRiNtigBgAJ + +## Release versioning + +Semantic versioning is used in this repository. It contains several Go modules +with different levels of stability: +- `k8s.io/klog/v2` - stable API, `vX.Y.Z` tags +- `examples` - no stable API, no tags, no intention to ever stabilize + +Exempt from the API stability guarantee are items (packages, functions, etc.) +which are marked explicitly as `EXPERIMENTAL` in their docs comment. Those +may still change in incompatible ways or get removed entirely. This can only +be used for code that is used in tests to avoid situations where non-test +code from two different Kubernetes dependencies depends on incompatible +releases of klog because an experimental API was changed. + +---- + +How to use klog +=============== +- Replace imports for `"github.com/golang/glog"` with `"k8s.io/klog/v2"` +- Use `klog.InitFlags(nil)` explicitly for initializing global flags as we no longer use `init()` method to register the flags +- You can now use `log_file` instead of `log_dir` for logging to a single file (See `examples/log_file/usage_log_file.go`) +- If you want to redirect everything logged using klog somewhere else (say syslog!), you can use `klog.SetOutput()` method and supply a `io.Writer`. (See `examples/set_output/usage_set_output.go`) +- For more logging conventions (See [Logging Conventions](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/logging.md)) +- See our documentation on [pkg.go.dev/k8s.io](https://pkg.go.dev/k8s.io/klog). + +**NOTE**: please use the newer go versions that support semantic import versioning in modules, ideally go 1.11.4 or greater. + +### Coexisting with klog/v2 + +See [this example](examples/coexist_klog_v1_and_v2/) to see how to coexist with both klog/v1 and klog/v2. + +### Coexisting with glog +This package can be used side by side with glog. [This example](examples/coexist_glog/coexist_glog.go) shows how to initialize and synchronize flags from the global `flag.CommandLine` FlagSet. In addition, the example makes use of stderr as combined output by setting `alsologtostderr` (or `logtostderr`) to `true`. + +## Community, discussion, contribution, and support + +Learn how to engage with the Kubernetes community on the [community page](http://kubernetes.io/community/). + +You can reach the maintainers of this project at: + +- [Slack](https://kubernetes.slack.com/messages/klog) +- [Mailing List](https://groups.google.com/forum/#!forum/kubernetes-sig-architecture) + +### Code of conduct + +Participation in the Kubernetes community is governed by the [Kubernetes Code of Conduct](code-of-conduct.md). + +---- + +glog +==== + +Leveled execution logs for Go. + +This is an efficient pure Go implementation of leveled logs in the +manner of the open source C++ package + https://github.com/google/glog + +By binding methods to booleans it is possible to use the log package +without paying the expense of evaluating the arguments to the log. +Through the -vmodule flag, the package also provides fine-grained +control over logging at the file level. + +The comment from glog.go introduces the ideas: + + Package glog implements logging analogous to the Google-internal + C++ INFO/ERROR/V setup. It provides functions Info, Warning, + Error, Fatal, plus formatting variants such as Infof. It + also provides V-style logging controlled by the -v and + -vmodule=file=2 flags. + + Basic examples: + + glog.Info("Prepare to repel boarders") + + glog.Fatalf("Initialization failed: %s", err) + + See the documentation of the V function for an explanation + of these examples: + + if glog.V(2) { + glog.Info("Starting transaction...") + } + + glog.V(2).Infoln("Processed", nItems, "elements") + + +The repository contains an open source version of the log package +used inside Google. The master copy of the source lives inside +Google, not here. The code in this repo is for export only and is not itself +under development. Feature requests will be ignored. + +Send bug reports to golang-nuts@googlegroups.com. diff --git a/vendor/k8s.io/klog/v2/RELEASE.md b/vendor/k8s.io/klog/v2/RELEASE.md new file mode 100644 index 0000000..b53eb96 --- /dev/null +++ b/vendor/k8s.io/klog/v2/RELEASE.md @@ -0,0 +1,9 @@ +# Release Process + +The `klog` is released on an as-needed basis. The process is as follows: + +1. An issue is proposing a new release with a changelog since the last release +1. All [OWNERS](OWNERS) must LGTM this release +1. An OWNER runs `git tag -s $VERSION` and inserts the changelog and pushes the tag with `git push $VERSION` +1. The release issue is closed +1. An announcement email is sent to `kubernetes-dev@googlegroups.com` with the subject `[ANNOUNCE] kubernetes-template-project $VERSION is released` diff --git a/vendor/k8s.io/klog/v2/SECURITY.md b/vendor/k8s.io/klog/v2/SECURITY.md new file mode 100644 index 0000000..2083d44 --- /dev/null +++ b/vendor/k8s.io/klog/v2/SECURITY.md @@ -0,0 +1,22 @@ +# Security Policy + +## Security Announcements + +Join the [kubernetes-security-announce] group for security and vulnerability announcements. + +You can also subscribe to an RSS feed of the above using [this link][kubernetes-security-announce-rss]. + +## Reporting a Vulnerability + +Instructions for reporting a vulnerability can be found on the +[Kubernetes Security and Disclosure Information] page. + +## Supported Versions + +Information about supported Kubernetes versions can be found on the +[Kubernetes version and version skew support policy] page on the Kubernetes website. + +[kubernetes-security-announce]: https://groups.google.com/forum/#!forum/kubernetes-security-announce +[kubernetes-security-announce-rss]: https://groups.google.com/forum/feed/kubernetes-security-announce/msgs/rss_v2_0.xml?num=50 +[Kubernetes version and version skew support policy]: https://kubernetes.io/docs/setup/release/version-skew-policy/#supported-versions +[Kubernetes Security and Disclosure Information]: https://kubernetes.io/docs/reference/issues-security/security/#report-a-vulnerability diff --git a/vendor/k8s.io/klog/v2/SECURITY_CONTACTS b/vendor/k8s.io/klog/v2/SECURITY_CONTACTS new file mode 100644 index 0000000..6128a58 --- /dev/null +++ b/vendor/k8s.io/klog/v2/SECURITY_CONTACTS @@ -0,0 +1,20 @@ +# Defined below are the security contacts for this repo. +# +# They are the contact point for the Product Security Committee to reach out +# to for triaging and handling of incoming issues. +# +# The below names agree to abide by the +# [Embargo Policy](https://git.k8s.io/security/private-distributors-list.md#embargo-policy) +# and will be removed and replaced if they violate that agreement. +# +# DO NOT REPORT SECURITY VULNERABILITIES DIRECTLY TO THESE NAMES, FOLLOW THE +# INSTRUCTIONS AT https://kubernetes.io/security/ + +dims +thockin +justinsb +tallclair +piosz +brancz +DirectXMan12 +lavalamp diff --git a/vendor/k8s.io/klog/v2/code-of-conduct.md b/vendor/k8s.io/klog/v2/code-of-conduct.md new file mode 100644 index 0000000..0d15c00 --- /dev/null +++ b/vendor/k8s.io/klog/v2/code-of-conduct.md @@ -0,0 +1,3 @@ +# Kubernetes Community Code of Conduct + +Please refer to our [Kubernetes Community Code of Conduct](https://git.k8s.io/community/code-of-conduct.md) diff --git a/vendor/k8s.io/klog/v2/contextual.go b/vendor/k8s.io/klog/v2/contextual.go new file mode 100644 index 0000000..2428963 --- /dev/null +++ b/vendor/k8s.io/klog/v2/contextual.go @@ -0,0 +1,186 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package klog + +import ( + "context" + + "github.com/go-logr/logr" +) + +// This file provides the implementation of +// https://github.com/kubernetes/enhancements/tree/master/keps/sig-instrumentation/1602-structured-logging +// +// SetLogger and ClearLogger were originally added to klog.go and got moved +// here. Contextual logging adds a way to retrieve a Logger for direct logging +// without the logging calls in klog.go. +// +// The global variables are expected to be modified only during sequential +// parts of a program (init, serial tests) and therefore are not protected by +// mutex locking. + +var ( + // klogLogger is used as fallback for logging through the normal klog code + // when no Logger is set. + klogLogger logr.Logger = logr.New(&klogger{}) +) + +// SetLogger sets a Logger implementation that will be used as backing +// implementation of the traditional klog log calls. klog will do its own +// verbosity checks before calling logger.V().Info. logger.Error is always +// called, regardless of the klog verbosity settings. +// +// If set, all log lines will be suppressed from the regular output, and +// redirected to the logr implementation. +// Use as: +// +// ... +// klog.SetLogger(zapr.NewLogger(zapLog)) +// +// To remove a backing logr implemention, use ClearLogger. Setting an +// empty logger with SetLogger(logr.Logger{}) does not work. +// +// Modifying the logger is not thread-safe and should be done while no other +// goroutines invoke log calls, usually during program initialization. +func SetLogger(logger logr.Logger) { + SetLoggerWithOptions(logger) +} + +// SetLoggerWithOptions is a more flexible version of SetLogger. Without +// additional options, it behaves exactly like SetLogger. By passing +// ContextualLogger(true) as option, it can be used to set a logger that then +// will also get called directly by applications which retrieve it via +// FromContext, Background, or TODO. +// +// Supporting direct calls is recommended because it avoids the overhead of +// routing log entries through klogr into klog and then into the actual Logger +// backend. +func SetLoggerWithOptions(logger logr.Logger, opts ...LoggerOption) { + logging.logger = &logger + logging.loggerOptions = loggerOptions{} + for _, opt := range opts { + opt(&logging.loggerOptions) + } +} + +// ContextualLogger determines whether the logger passed to +// SetLoggerWithOptions may also get called directly. Such a logger cannot rely +// on verbosity checking in klog. +func ContextualLogger(enabled bool) LoggerOption { + return func(o *loggerOptions) { + o.contextualLogger = enabled + } +} + +// FlushLogger provides a callback for flushing data buffered by the logger. +func FlushLogger(flush func()) LoggerOption { + return func(o *loggerOptions) { + o.flush = flush + } +} + +// LoggerOption implements the functional parameter paradigm for +// SetLoggerWithOptions. +type LoggerOption func(o *loggerOptions) + +type loggerOptions struct { + contextualLogger bool + flush func() +} + +// ClearLogger removes a backing Logger implementation if one was set earlier +// with SetLogger. +// +// Modifying the logger is not thread-safe and should be done while no other +// goroutines invoke log calls, usually during program initialization. +func ClearLogger() { + logging.logger = nil + logging.loggerOptions = loggerOptions{} +} + +// EnableContextualLogging controls whether contextual logging is enabled. +// By default it is enabled. When disabled, FromContext avoids looking up +// the logger in the context and always returns the global logger. +// LoggerWithValues, LoggerWithName, and NewContext become no-ops +// and return their input logger respectively context. This may be useful +// to avoid the additional overhead for contextual logging. +// +// This must be called during initialization before goroutines are started. +func EnableContextualLogging(enabled bool) { + logging.contextualLoggingEnabled = enabled +} + +// FromContext retrieves a logger set by the caller or, if not set, +// falls back to the program's global logger (a Logger instance or klog +// itself). +func FromContext(ctx context.Context) Logger { + if logging.contextualLoggingEnabled { + if logger, err := logr.FromContext(ctx); err == nil { + return logger + } + } + + return Background() +} + +// TODO can be used as a last resort by code that has no means of +// receiving a logger from its caller. FromContext or an explicit logger +// parameter should be used instead. +func TODO() Logger { + return Background() +} + +// Background retrieves the fallback logger. It should not be called before +// that logger was initialized by the program and not by code that should +// better receive a logger via its parameters. TODO can be used as a temporary +// solution for such code. +func Background() Logger { + if logging.loggerOptions.contextualLogger { + // Is non-nil because logging.loggerOptions.contextualLogger is + // only true if a logger was set. + return *logging.logger + } + + return klogLogger +} + +// LoggerWithValues returns logger.WithValues(...kv) when +// contextual logging is enabled, otherwise the logger. +func LoggerWithValues(logger Logger, kv ...interface{}) Logger { + if logging.contextualLoggingEnabled { + return logger.WithValues(kv...) + } + return logger +} + +// LoggerWithName returns logger.WithName(name) when contextual logging is +// enabled, otherwise the logger. +func LoggerWithName(logger Logger, name string) Logger { + if logging.contextualLoggingEnabled { + return logger.WithName(name) + } + return logger +} + +// NewContext returns logr.NewContext(ctx, logger) when +// contextual logging is enabled, otherwise ctx. +func NewContext(ctx context.Context, logger Logger) context.Context { + if logging.contextualLoggingEnabled { + return logr.NewContext(ctx, logger) + } + return ctx +} diff --git a/vendor/k8s.io/klog/v2/exit.go b/vendor/k8s.io/klog/v2/exit.go new file mode 100644 index 0000000..320a147 --- /dev/null +++ b/vendor/k8s.io/klog/v2/exit.go @@ -0,0 +1,69 @@ +// Go support for leveled logs, analogous to https://code.google.com/p/google-glog/ +// +// Copyright 2013 Google Inc. All Rights Reserved. +// Copyright 2022 The Kubernetes Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package klog + +import ( + "fmt" + "os" + "time" +) + +var ( + + // ExitFlushTimeout is the timeout that klog has traditionally used during + // calls like Fatal or Exit when flushing log data right before exiting. + // Applications that replace those calls and do not have some specific + // requirements like "exit immediately" can use this value as parameter + // for FlushAndExit. + // + // Can be set for testing purpose or to change the application's + // default. + ExitFlushTimeout = 10 * time.Second + + // OsExit is the function called by FlushAndExit to terminate the program. + // + // Can be set for testing purpose or to change the application's + // default behavior. Note that the function should not simply return + // because callers of functions like Fatal will not expect that. + OsExit = os.Exit +) + +// FlushAndExit flushes log data for a certain amount of time and then calls +// os.Exit. Combined with some logging call it provides a replacement for +// traditional calls like Fatal or Exit. +func FlushAndExit(flushTimeout time.Duration, exitCode int) { + timeoutFlush(flushTimeout) + OsExit(exitCode) +} + +// timeoutFlush calls Flush and returns when it completes or after timeout +// elapses, whichever happens first. This is needed because the hooks invoked +// by Flush may deadlock when klog.Fatal is called from a hook that holds +// a lock. Flushing also might take too long. +func timeoutFlush(timeout time.Duration) { + done := make(chan bool, 1) + go func() { + Flush() // calls logging.lockAndFlushAll() + done <- true + }() + select { + case <-done: + case <-time.After(timeout): + fmt.Fprintln(os.Stderr, "klog: Flush took longer than", timeout) + } +} diff --git a/vendor/k8s.io/klog/v2/imports.go b/vendor/k8s.io/klog/v2/imports.go new file mode 100644 index 0000000..602c3ed --- /dev/null +++ b/vendor/k8s.io/klog/v2/imports.go @@ -0,0 +1,38 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package klog + +import ( + "github.com/go-logr/logr" +) + +// The reason for providing these aliases is to allow code to work with logr +// without directly importing it. + +// Logger in this package is exactly the same as logr.Logger. +type Logger = logr.Logger + +// LogSink in this package is exactly the same as logr.LogSink. +type LogSink = logr.LogSink + +// Runtimeinfo in this package is exactly the same as logr.RuntimeInfo. +type RuntimeInfo = logr.RuntimeInfo + +var ( + // New is an alias for logr.New. + New = logr.New +) diff --git a/vendor/k8s.io/klog/v2/internal/buffer/buffer.go b/vendor/k8s.io/klog/v2/internal/buffer/buffer.go new file mode 100644 index 0000000..ac88682 --- /dev/null +++ b/vendor/k8s.io/klog/v2/internal/buffer/buffer.go @@ -0,0 +1,159 @@ +// Copyright 2013 Google Inc. All Rights Reserved. +// Copyright 2022 The Kubernetes Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package buffer provides a cache for byte.Buffer instances that can be reused +// to avoid frequent allocation and deallocation. It also has utility code +// for log header formatting that use these buffers. +package buffer + +import ( + "bytes" + "os" + "sync" + "time" + + "k8s.io/klog/v2/internal/severity" +) + +var ( + // Pid is inserted into log headers. Can be overridden for tests. + Pid = os.Getpid() +) + +// Buffer holds a single byte.Buffer for reuse. The zero value is ready for +// use. It also provides some helper methods for output formatting. +type Buffer struct { + bytes.Buffer + Tmp [64]byte // temporary byte array for creating headers. + next *Buffer +} + +// Buffers manages the reuse of individual buffer instances. It is thread-safe. +type Buffers struct { + // mu protects the free list. It is separate from the main mutex + // so buffers can be grabbed and printed to without holding the main lock, + // for better parallelization. + mu sync.Mutex + + // freeList is a list of byte buffers, maintained under mu. + freeList *Buffer +} + +// GetBuffer returns a new, ready-to-use buffer. +func (bl *Buffers) GetBuffer() *Buffer { + bl.mu.Lock() + b := bl.freeList + if b != nil { + bl.freeList = b.next + } + bl.mu.Unlock() + if b == nil { + b = new(Buffer) + } else { + b.next = nil + b.Reset() + } + return b +} + +// PutBuffer returns a buffer to the free list. +func (bl *Buffers) PutBuffer(b *Buffer) { + if b.Len() >= 256 { + // Let big buffers die a natural death. + return + } + bl.mu.Lock() + b.next = bl.freeList + bl.freeList = b + bl.mu.Unlock() +} + +// Some custom tiny helper functions to print the log header efficiently. + +const digits = "0123456789" + +// twoDigits formats a zero-prefixed two-digit integer at buf.Tmp[i]. +func (buf *Buffer) twoDigits(i, d int) { + buf.Tmp[i+1] = digits[d%10] + d /= 10 + buf.Tmp[i] = digits[d%10] +} + +// nDigits formats an n-digit integer at buf.Tmp[i], +// padding with pad on the left. +// It assumes d >= 0. +func (buf *Buffer) nDigits(n, i, d int, pad byte) { + j := n - 1 + for ; j >= 0 && d > 0; j-- { + buf.Tmp[i+j] = digits[d%10] + d /= 10 + } + for ; j >= 0; j-- { + buf.Tmp[i+j] = pad + } +} + +// someDigits formats a zero-prefixed variable-width integer at buf.Tmp[i]. +func (buf *Buffer) someDigits(i, d int) int { + // Print into the top, then copy down. We know there's space for at least + // a 10-digit number. + j := len(buf.Tmp) + for { + j-- + buf.Tmp[j] = digits[d%10] + d /= 10 + if d == 0 { + break + } + } + return copy(buf.Tmp[i:], buf.Tmp[j:]) +} + +// FormatHeader formats a log header using the provided file name and line number. +func (buf *Buffer) FormatHeader(s severity.Severity, file string, line int, now time.Time) { + if line < 0 { + line = 0 // not a real line number, but acceptable to someDigits + } + if s > severity.FatalLog { + s = severity.InfoLog // for safety. + } + + // Avoid Fprintf, for speed. The format is so simple that we can do it quickly by hand. + // It's worth about 3X. Fprintf is hard. + _, month, day := now.Date() + hour, minute, second := now.Clock() + // Lmmdd hh:mm:ss.uuuuuu threadid file:line] + buf.Tmp[0] = severity.Char[s] + buf.twoDigits(1, int(month)) + buf.twoDigits(3, day) + buf.Tmp[5] = ' ' + buf.twoDigits(6, hour) + buf.Tmp[8] = ':' + buf.twoDigits(9, minute) + buf.Tmp[11] = ':' + buf.twoDigits(12, second) + buf.Tmp[14] = '.' + buf.nDigits(6, 15, now.Nanosecond()/1000, '0') + buf.Tmp[21] = ' ' + buf.nDigits(7, 22, Pid, ' ') // TODO: should be TID + buf.Tmp[29] = ' ' + buf.Write(buf.Tmp[:30]) + buf.WriteString(file) + buf.Tmp[0] = ':' + n := buf.someDigits(1, line) + buf.Tmp[n+1] = ']' + buf.Tmp[n+2] = ' ' + buf.Write(buf.Tmp[:n+3]) +} diff --git a/vendor/k8s.io/klog/v2/internal/clock/README.md b/vendor/k8s.io/klog/v2/internal/clock/README.md new file mode 100644 index 0000000..03d692c --- /dev/null +++ b/vendor/k8s.io/klog/v2/internal/clock/README.md @@ -0,0 +1,7 @@ +# Clock + +This package provides an interface for time-based operations. It allows +mocking time for testing. + +This is a copy of k8s.io/utils/clock. We have to copy it to avoid a circular +dependency (k8s.io/klog -> k8s.io/utils -> k8s.io/klog). diff --git a/vendor/k8s.io/klog/v2/internal/clock/clock.go b/vendor/k8s.io/klog/v2/internal/clock/clock.go new file mode 100644 index 0000000..b8b6af5 --- /dev/null +++ b/vendor/k8s.io/klog/v2/internal/clock/clock.go @@ -0,0 +1,178 @@ +/* +Copyright 2014 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package clock + +import "time" + +// PassiveClock allows for injecting fake or real clocks into code +// that needs to read the current time but does not support scheduling +// activity in the future. +type PassiveClock interface { + Now() time.Time + Since(time.Time) time.Duration +} + +// Clock allows for injecting fake or real clocks into code that +// needs to do arbitrary things based on time. +type Clock interface { + PassiveClock + // After returns the channel of a new Timer. + // This method does not allow to free/GC the backing timer before it fires. Use + // NewTimer instead. + After(d time.Duration) <-chan time.Time + // NewTimer returns a new Timer. + NewTimer(d time.Duration) Timer + // Sleep sleeps for the provided duration d. + // Consider making the sleep interruptible by using 'select' on a context channel and a timer channel. + Sleep(d time.Duration) + // Tick returns the channel of a new Ticker. + // This method does not allow to free/GC the backing ticker. Use + // NewTicker from WithTicker instead. + Tick(d time.Duration) <-chan time.Time +} + +// WithTicker allows for injecting fake or real clocks into code that +// needs to do arbitrary things based on time. +type WithTicker interface { + Clock + // NewTicker returns a new Ticker. + NewTicker(time.Duration) Ticker +} + +// WithDelayedExecution allows for injecting fake or real clocks into +// code that needs to make use of AfterFunc functionality. +type WithDelayedExecution interface { + Clock + // AfterFunc executes f in its own goroutine after waiting + // for d duration and returns a Timer whose channel can be + // closed by calling Stop() on the Timer. + AfterFunc(d time.Duration, f func()) Timer +} + +// WithTickerAndDelayedExecution allows for injecting fake or real clocks +// into code that needs Ticker and AfterFunc functionality +type WithTickerAndDelayedExecution interface { + WithTicker + // AfterFunc executes f in its own goroutine after waiting + // for d duration and returns a Timer whose channel can be + // closed by calling Stop() on the Timer. + AfterFunc(d time.Duration, f func()) Timer +} + +// Ticker defines the Ticker interface. +type Ticker interface { + C() <-chan time.Time + Stop() +} + +var _ = WithTicker(RealClock{}) + +// RealClock really calls time.Now() +type RealClock struct{} + +// Now returns the current time. +func (RealClock) Now() time.Time { + return time.Now() +} + +// Since returns time since the specified timestamp. +func (RealClock) Since(ts time.Time) time.Duration { + return time.Since(ts) +} + +// After is the same as time.After(d). +// This method does not allow to free/GC the backing timer before it fires. Use +// NewTimer instead. +func (RealClock) After(d time.Duration) <-chan time.Time { + return time.After(d) +} + +// NewTimer is the same as time.NewTimer(d) +func (RealClock) NewTimer(d time.Duration) Timer { + return &realTimer{ + timer: time.NewTimer(d), + } +} + +// AfterFunc is the same as time.AfterFunc(d, f). +func (RealClock) AfterFunc(d time.Duration, f func()) Timer { + return &realTimer{ + timer: time.AfterFunc(d, f), + } +} + +// Tick is the same as time.Tick(d) +// This method does not allow to free/GC the backing ticker. Use +// NewTicker instead. +func (RealClock) Tick(d time.Duration) <-chan time.Time { + return time.Tick(d) +} + +// NewTicker returns a new Ticker. +func (RealClock) NewTicker(d time.Duration) Ticker { + return &realTicker{ + ticker: time.NewTicker(d), + } +} + +// Sleep is the same as time.Sleep(d) +// Consider making the sleep interruptible by using 'select' on a context channel and a timer channel. +func (RealClock) Sleep(d time.Duration) { + time.Sleep(d) +} + +// Timer allows for injecting fake or real timers into code that +// needs to do arbitrary things based on time. +type Timer interface { + C() <-chan time.Time + Stop() bool + Reset(d time.Duration) bool +} + +var _ = Timer(&realTimer{}) + +// realTimer is backed by an actual time.Timer. +type realTimer struct { + timer *time.Timer +} + +// C returns the underlying timer's channel. +func (r *realTimer) C() <-chan time.Time { + return r.timer.C +} + +// Stop calls Stop() on the underlying timer. +func (r *realTimer) Stop() bool { + return r.timer.Stop() +} + +// Reset calls Reset() on the underlying timer. +func (r *realTimer) Reset(d time.Duration) bool { + return r.timer.Reset(d) +} + +type realTicker struct { + ticker *time.Ticker +} + +func (r *realTicker) C() <-chan time.Time { + return r.ticker.C +} + +func (r *realTicker) Stop() { + r.ticker.Stop() +} diff --git a/vendor/k8s.io/klog/v2/internal/dbg/dbg.go b/vendor/k8s.io/klog/v2/internal/dbg/dbg.go new file mode 100644 index 0000000..f27bd14 --- /dev/null +++ b/vendor/k8s.io/klog/v2/internal/dbg/dbg.go @@ -0,0 +1,42 @@ +// Go support for leveled logs, analogous to https://code.google.com/p/google-glog/ +// +// Copyright 2013 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package dbg provides some helper code for call traces. +package dbg + +import ( + "runtime" +) + +// Stacks is a wrapper for runtime.Stack that attempts to recover the data for +// all goroutines or the calling one. +func Stacks(all bool) []byte { + // We don't know how big the traces are, so grow a few times if they don't fit. Start large, though. + n := 10000 + if all { + n = 100000 + } + var trace []byte + for i := 0; i < 5; i++ { + trace = make([]byte, n) + nbytes := runtime.Stack(trace, all) + if nbytes < len(trace) { + return trace[:nbytes] + } + n *= 2 + } + return trace +} diff --git a/vendor/k8s.io/klog/v2/internal/serialize/keyvalues.go b/vendor/k8s.io/klog/v2/internal/serialize/keyvalues.go new file mode 100644 index 0000000..ad6bf11 --- /dev/null +++ b/vendor/k8s.io/klog/v2/internal/serialize/keyvalues.go @@ -0,0 +1,253 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package serialize + +import ( + "bytes" + "fmt" + "strconv" + + "github.com/go-logr/logr" +) + +// WithValues implements LogSink.WithValues. The old key/value pairs are +// assumed to be well-formed, the new ones are checked and padded if +// necessary. It returns a new slice. +func WithValues(oldKV, newKV []interface{}) []interface{} { + if len(newKV) == 0 { + return oldKV + } + newLen := len(oldKV) + len(newKV) + hasMissingValue := newLen%2 != 0 + if hasMissingValue { + newLen++ + } + // The new LogSink must have its own slice. + kv := make([]interface{}, 0, newLen) + kv = append(kv, oldKV...) + kv = append(kv, newKV...) + if hasMissingValue { + kv = append(kv, missingValue) + } + return kv +} + +// MergeKVs deduplicates elements provided in two key/value slices. +// +// Keys in each slice are expected to be unique, so duplicates can only occur +// when the first and second slice contain the same key. When that happens, the +// key/value pair from the second slice is used. The first slice must be well-formed +// (= even key/value pairs). The second one may have a missing value, in which +// case the special "missing value" is added to the result. +func MergeKVs(first, second []interface{}) []interface{} { + maxLength := len(first) + (len(second)+1)/2*2 + if maxLength == 0 { + // Nothing to do at all. + return nil + } + + if len(first) == 0 && len(second)%2 == 0 { + // Nothing to be overridden, second slice is well-formed + // and can be used directly. + return second + } + + // Determine which keys are in the second slice so that we can skip + // them when iterating over the first one. The code intentionally + // favors performance over completeness: we assume that keys are string + // constants and thus compare equal when the string values are equal. A + // string constant being overridden by, for example, a fmt.Stringer is + // not handled. + overrides := map[interface{}]bool{} + for i := 0; i < len(second); i += 2 { + overrides[second[i]] = true + } + merged := make([]interface{}, 0, maxLength) + for i := 0; i+1 < len(first); i += 2 { + key := first[i] + if overrides[key] { + continue + } + merged = append(merged, key, first[i+1]) + } + merged = append(merged, second...) + if len(merged)%2 != 0 { + merged = append(merged, missingValue) + } + return merged +} + +const missingValue = "(MISSING)" + +// KVListFormat serializes all key/value pairs into the provided buffer. +// A space gets inserted before the first pair and between each pair. +func KVListFormat(b *bytes.Buffer, keysAndValues ...interface{}) { + for i := 0; i < len(keysAndValues); i += 2 { + var v interface{} + k := keysAndValues[i] + if i+1 < len(keysAndValues) { + v = keysAndValues[i+1] + } else { + v = missingValue + } + b.WriteByte(' ') + // Keys are assumed to be well-formed according to + // https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/migration-to-structured-logging.md#name-arguments + // for the sake of performance. Keys with spaces, + // special characters, etc. will break parsing. + if sK, ok := k.(string); ok { + // Avoid one allocation when the key is a string, which + // normally it should be. + b.WriteString(sK) + } else { + b.WriteString(fmt.Sprintf("%s", k)) + } + + // The type checks are sorted so that more frequently used ones + // come first because that is then faster in the common + // cases. In Kubernetes, ObjectRef (a Stringer) is more common + // than plain strings + // (https://github.com/kubernetes/kubernetes/pull/106594#issuecomment-975526235). + switch v := v.(type) { + case fmt.Stringer: + writeStringValue(b, true, StringerToString(v)) + case string: + writeStringValue(b, true, v) + case error: + writeStringValue(b, true, ErrorToString(v)) + case logr.Marshaler: + value := MarshalerToValue(v) + // A marshaler that returns a string is useful for + // delayed formatting of complex values. We treat this + // case like a normal string. This is useful for + // multi-line support. + // + // We could do this by recursively formatting a value, + // but that comes with the risk of infinite recursion + // if a marshaler returns itself. Instead we call it + // only once and rely on it returning the intended + // value directly. + switch value := value.(type) { + case string: + writeStringValue(b, true, value) + default: + writeStringValue(b, false, fmt.Sprintf("%+v", value)) + } + case []byte: + // In https://github.com/kubernetes/klog/pull/237 it was decided + // to format byte slices with "%+q". The advantages of that are: + // - readable output if the bytes happen to be printable + // - non-printable bytes get represented as unicode escape + // sequences (\uxxxx) + // + // The downsides are that we cannot use the faster + // strconv.Quote here and that multi-line output is not + // supported. If developers know that a byte array is + // printable and they want multi-line output, they can + // convert the value to string before logging it. + b.WriteByte('=') + b.WriteString(fmt.Sprintf("%+q", v)) + default: + writeStringValue(b, false, fmt.Sprintf("%+v", v)) + } + } +} + +// StringerToString converts a Stringer to a string, +// handling panics if they occur. +func StringerToString(s fmt.Stringer) (ret string) { + defer func() { + if err := recover(); err != nil { + ret = fmt.Sprintf("", err) + } + }() + ret = s.String() + return +} + +// MarshalerToValue invokes a marshaler and catches +// panics. +func MarshalerToValue(m logr.Marshaler) (ret interface{}) { + defer func() { + if err := recover(); err != nil { + ret = fmt.Sprintf("", err) + } + }() + ret = m.MarshalLog() + return +} + +// ErrorToString converts an error to a string, +// handling panics if they occur. +func ErrorToString(err error) (ret string) { + defer func() { + if err := recover(); err != nil { + ret = fmt.Sprintf("", err) + } + }() + ret = err.Error() + return +} + +func writeStringValue(b *bytes.Buffer, quote bool, v string) { + data := []byte(v) + index := bytes.IndexByte(data, '\n') + if index == -1 { + b.WriteByte('=') + if quote { + // Simple string, quote quotation marks and non-printable characters. + b.WriteString(strconv.Quote(v)) + return + } + // Non-string with no line breaks. + b.WriteString(v) + return + } + + // Complex multi-line string, show as-is with indention like this: + // I... "hello world" key=< + // line 1 + // line 2 + // > + // + // Tabs indent the lines of the value while the end of string delimiter + // is indented with a space. That has two purposes: + // - visual difference between the two for a human reader because indention + // will be different + // - no ambiguity when some value line starts with the end delimiter + // + // One downside is that the output cannot distinguish between strings that + // end with a line break and those that don't because the end delimiter + // will always be on the next line. + b.WriteString("=<\n") + for index != -1 { + b.WriteByte('\t') + b.Write(data[0 : index+1]) + data = data[index+1:] + index = bytes.IndexByte(data, '\n') + } + if len(data) == 0 { + // String ended with line break, don't add another. + b.WriteString(" >") + } else { + // No line break at end of last line, write rest of string and + // add one. + b.WriteByte('\t') + b.Write(data) + b.WriteString("\n >") + } +} diff --git a/vendor/k8s.io/klog/v2/internal/severity/severity.go b/vendor/k8s.io/klog/v2/internal/severity/severity.go new file mode 100644 index 0000000..30fa183 --- /dev/null +++ b/vendor/k8s.io/klog/v2/internal/severity/severity.go @@ -0,0 +1,58 @@ +// Copyright 2013 Google Inc. All Rights Reserved. +// Copyright 2022 The Kubernetes Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package severity provides definitions for klog severity (info, warning, ...) +package severity + +import ( + "strings" +) + +// severity identifies the sort of log: info, warning etc. The binding to flag.Value +// is handled in klog.go +type Severity int32 // sync/atomic int32 + +// These constants identify the log levels in order of increasing severity. +// A message written to a high-severity log file is also written to each +// lower-severity log file. +const ( + InfoLog Severity = iota + WarningLog + ErrorLog + FatalLog + NumSeverity = 4 +) + +// Char contains one shortcut letter per severity level. +const Char = "IWEF" + +// Name contains one name per severity level. +var Name = []string{ + InfoLog: "INFO", + WarningLog: "WARNING", + ErrorLog: "ERROR", + FatalLog: "FATAL", +} + +// ByName looks up a severity level by name. +func ByName(s string) (Severity, bool) { + s = strings.ToUpper(s) + for i, name := range Name { + if name == s { + return Severity(i), true + } + } + return 0, false +} diff --git a/vendor/k8s.io/klog/v2/k8s_references.go b/vendor/k8s.io/klog/v2/k8s_references.go new file mode 100644 index 0000000..2c218f6 --- /dev/null +++ b/vendor/k8s.io/klog/v2/k8s_references.go @@ -0,0 +1,158 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package klog + +import ( + "fmt" + "reflect" + + "github.com/go-logr/logr" +) + +// ObjectRef references a kubernetes object +type ObjectRef struct { + Name string `json:"name"` + Namespace string `json:"namespace,omitempty"` +} + +func (ref ObjectRef) String() string { + if ref.Namespace != "" { + return fmt.Sprintf("%s/%s", ref.Namespace, ref.Name) + } + return ref.Name +} + +// MarshalLog ensures that loggers with support for structured output will log +// as a struct by removing the String method via a custom type. +func (ref ObjectRef) MarshalLog() interface{} { + type or ObjectRef + return or(ref) +} + +var _ logr.Marshaler = ObjectRef{} + +// KMetadata is a subset of the kubernetes k8s.io/apimachinery/pkg/apis/meta/v1.Object interface +// this interface may expand in the future, but will always be a subset of the +// kubernetes k8s.io/apimachinery/pkg/apis/meta/v1.Object interface +type KMetadata interface { + GetName() string + GetNamespace() string +} + +// KObj returns ObjectRef from ObjectMeta +func KObj(obj KMetadata) ObjectRef { + if obj == nil { + return ObjectRef{} + } + if val := reflect.ValueOf(obj); val.Kind() == reflect.Ptr && val.IsNil() { + return ObjectRef{} + } + + return ObjectRef{ + Name: obj.GetName(), + Namespace: obj.GetNamespace(), + } +} + +// KRef returns ObjectRef from name and namespace +func KRef(namespace, name string) ObjectRef { + return ObjectRef{ + Name: name, + Namespace: namespace, + } +} + +// KObjs returns slice of ObjectRef from an slice of ObjectMeta +// +// DEPRECATED: Use KObjSlice instead, it has better performance. +func KObjs(arg interface{}) []ObjectRef { + s := reflect.ValueOf(arg) + if s.Kind() != reflect.Slice { + return nil + } + objectRefs := make([]ObjectRef, 0, s.Len()) + for i := 0; i < s.Len(); i++ { + if v, ok := s.Index(i).Interface().(KMetadata); ok { + objectRefs = append(objectRefs, KObj(v)) + } else { + return nil + } + } + return objectRefs +} + +// KObjSlice takes a slice of objects that implement the KMetadata interface +// and returns an object that gets logged as a slice of ObjectRef values or a +// string containing those values, depending on whether the logger prefers text +// output or structured output. +// +// An error string is logged when KObjSlice is not passed a suitable slice. +// +// Processing of the argument is delayed until the value actually gets logged, +// in contrast to KObjs where that overhead is incurred regardless of whether +// the result is needed. +func KObjSlice(arg interface{}) interface{} { + return kobjSlice{arg: arg} +} + +type kobjSlice struct { + arg interface{} +} + +var _ fmt.Stringer = kobjSlice{} +var _ logr.Marshaler = kobjSlice{} + +func (ks kobjSlice) String() string { + objectRefs, err := ks.process() + if err != nil { + return err.Error() + } + return fmt.Sprintf("%v", objectRefs) +} + +func (ks kobjSlice) MarshalLog() interface{} { + objectRefs, err := ks.process() + if err != nil { + return err.Error() + } + return objectRefs +} + +func (ks kobjSlice) process() ([]interface{}, error) { + s := reflect.ValueOf(ks.arg) + switch s.Kind() { + case reflect.Invalid: + // nil parameter, print as nil. + return nil, nil + case reflect.Slice: + // Okay, handle below. + default: + return nil, fmt.Errorf("", ks.arg) + } + objectRefs := make([]interface{}, 0, s.Len()) + for i := 0; i < s.Len(); i++ { + item := s.Index(i).Interface() + if item == nil { + objectRefs = append(objectRefs, nil) + } else if v, ok := item.(KMetadata); ok { + objectRefs = append(objectRefs, KObj(v)) + } else { + return nil, fmt.Errorf("", item) + } + } + return objectRefs, nil +} diff --git a/vendor/k8s.io/klog/v2/klog.go b/vendor/k8s.io/klog/v2/klog.go new file mode 100644 index 0000000..1bd11b6 --- /dev/null +++ b/vendor/k8s.io/klog/v2/klog.go @@ -0,0 +1,1689 @@ +// Go support for leveled logs, analogous to https://code.google.com/p/google-glog/ +// +// Copyright 2013 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package klog implements logging analogous to the Google-internal C++ INFO/ERROR/V setup. +// It provides functions Info, Warning, Error, Fatal, plus formatting variants such as +// Infof. It also provides V-style logging controlled by the -v and -vmodule=file=2 flags. +// +// Basic examples: +// +// klog.Info("Prepare to repel boarders") +// +// klog.Fatalf("Initialization failed: %s", err) +// +// See the documentation for the V function for an explanation of these examples: +// +// if klog.V(2) { +// klog.Info("Starting transaction...") +// } +// +// klog.V(2).Infoln("Processed", nItems, "elements") +// +// Log output is buffered and written periodically using Flush. Programs +// should call Flush before exiting to guarantee all log output is written. +// +// By default, all log statements write to standard error. +// This package provides several flags that modify this behavior. +// As a result, flag.Parse must be called before any logging is done. +// +// -logtostderr=true +// Logs are written to standard error instead of to files. +// This shortcuts most of the usual output routing: +// -alsologtostderr, -stderrthreshold and -log_dir have no +// effect and output redirection at runtime with SetOutput is +// ignored. +// -alsologtostderr=false +// Logs are written to standard error as well as to files. +// -stderrthreshold=ERROR +// Log events at or above this severity are logged to standard +// error as well as to files. +// -log_dir="" +// Log files will be written to this directory instead of the +// default temporary directory. +// +// Other flags provide aids to debugging. +// +// -log_backtrace_at="" +// When set to a file and line number holding a logging statement, +// such as +// -log_backtrace_at=gopherflakes.go:234 +// a stack trace will be written to the Info log whenever execution +// hits that statement. (Unlike with -vmodule, the ".go" must be +// present.) +// -v=0 +// Enable V-leveled logging at the specified level. +// -vmodule="" +// The syntax of the argument is a comma-separated list of pattern=N, +// where pattern is a literal file name (minus the ".go" suffix) or +// "glob" pattern and N is a V level. For instance, +// -vmodule=gopher*=3 +// sets the V level to 3 in all Go files whose names begin "gopher". +package klog + +import ( + "bufio" + "bytes" + "errors" + "flag" + "fmt" + "io" + stdLog "log" + "math" + "os" + "path/filepath" + "runtime" + "strconv" + "strings" + "sync" + "sync/atomic" + "time" + + "github.com/go-logr/logr" + + "k8s.io/klog/v2/internal/buffer" + "k8s.io/klog/v2/internal/clock" + "k8s.io/klog/v2/internal/dbg" + "k8s.io/klog/v2/internal/serialize" + "k8s.io/klog/v2/internal/severity" +) + +// severityValue identifies the sort of log: info, warning etc. It also implements +// the flag.Value interface. The -stderrthreshold flag is of type severity and +// should be modified only through the flag.Value interface. The values match +// the corresponding constants in C++. +type severityValue struct { + severity.Severity +} + +// get returns the value of the severity. +func (s *severityValue) get() severity.Severity { + return severity.Severity(atomic.LoadInt32((*int32)(&s.Severity))) +} + +// set sets the value of the severity. +func (s *severityValue) set(val severity.Severity) { + atomic.StoreInt32((*int32)(&s.Severity), int32(val)) +} + +// String is part of the flag.Value interface. +func (s *severityValue) String() string { + return strconv.FormatInt(int64(s.Severity), 10) +} + +// Get is part of the flag.Getter interface. +func (s *severityValue) Get() interface{} { + return s.Severity +} + +// Set is part of the flag.Value interface. +func (s *severityValue) Set(value string) error { + var threshold severity.Severity + // Is it a known name? + if v, ok := severity.ByName(value); ok { + threshold = v + } else { + v, err := strconv.ParseInt(value, 10, 32) + if err != nil { + return err + } + threshold = severity.Severity(v) + } + logging.stderrThreshold.set(threshold) + return nil +} + +// OutputStats tracks the number of output lines and bytes written. +type OutputStats struct { + lines int64 + bytes int64 +} + +// Lines returns the number of lines written. +func (s *OutputStats) Lines() int64 { + return atomic.LoadInt64(&s.lines) +} + +// Bytes returns the number of bytes written. +func (s *OutputStats) Bytes() int64 { + return atomic.LoadInt64(&s.bytes) +} + +// Stats tracks the number of lines of output and number of bytes +// per severity level. Values must be read with atomic.LoadInt64. +var Stats struct { + Info, Warning, Error OutputStats +} + +var severityStats = [severity.NumSeverity]*OutputStats{ + severity.InfoLog: &Stats.Info, + severity.WarningLog: &Stats.Warning, + severity.ErrorLog: &Stats.Error, +} + +// Level is exported because it appears in the arguments to V and is +// the type of the v flag, which can be set programmatically. +// It's a distinct type because we want to discriminate it from logType. +// Variables of type level are only changed under logging.mu. +// The -v flag is read only with atomic ops, so the state of the logging +// module is consistent. + +// Level is treated as a sync/atomic int32. + +// Level specifies a level of verbosity for V logs. *Level implements +// flag.Value; the -v flag is of type Level and should be modified +// only through the flag.Value interface. +type Level int32 + +// get returns the value of the Level. +func (l *Level) get() Level { + return Level(atomic.LoadInt32((*int32)(l))) +} + +// set sets the value of the Level. +func (l *Level) set(val Level) { + atomic.StoreInt32((*int32)(l), int32(val)) +} + +// String is part of the flag.Value interface. +func (l *Level) String() string { + return strconv.FormatInt(int64(*l), 10) +} + +// Get is part of the flag.Getter interface. +func (l *Level) Get() interface{} { + return *l +} + +// Set is part of the flag.Value interface. +func (l *Level) Set(value string) error { + v, err := strconv.ParseInt(value, 10, 32) + if err != nil { + return err + } + logging.mu.Lock() + defer logging.mu.Unlock() + logging.setVState(Level(v), logging.vmodule.filter, false) + return nil +} + +// moduleSpec represents the setting of the -vmodule flag. +type moduleSpec struct { + filter []modulePat +} + +// modulePat contains a filter for the -vmodule flag. +// It holds a verbosity level and a file pattern to match. +type modulePat struct { + pattern string + literal bool // The pattern is a literal string + level Level +} + +// match reports whether the file matches the pattern. It uses a string +// comparison if the pattern contains no metacharacters. +func (m *modulePat) match(file string) bool { + if m.literal { + return file == m.pattern + } + match, _ := filepath.Match(m.pattern, file) + return match +} + +func (m *moduleSpec) String() string { + // Lock because the type is not atomic. TODO: clean this up. + logging.mu.Lock() + defer logging.mu.Unlock() + return m.serialize() +} + +func (m *moduleSpec) serialize() string { + var b bytes.Buffer + for i, f := range m.filter { + if i > 0 { + b.WriteRune(',') + } + fmt.Fprintf(&b, "%s=%d", f.pattern, f.level) + } + return b.String() +} + +// Get is part of the (Go 1.2) flag.Getter interface. It always returns nil for this flag type since the +// struct is not exported. +func (m *moduleSpec) Get() interface{} { + return nil +} + +var errVmoduleSyntax = errors.New("syntax error: expect comma-separated list of filename=N") + +// Set will sets module value +// Syntax: -vmodule=recordio=2,file=1,gfs*=3 +func (m *moduleSpec) Set(value string) error { + filter, err := parseModuleSpec(value) + if err != nil { + return err + } + logging.mu.Lock() + defer logging.mu.Unlock() + logging.setVState(logging.verbosity, filter, true) + return nil +} + +func parseModuleSpec(value string) ([]modulePat, error) { + var filter []modulePat + for _, pat := range strings.Split(value, ",") { + if len(pat) == 0 { + // Empty strings such as from a trailing comma can be ignored. + continue + } + patLev := strings.Split(pat, "=") + if len(patLev) != 2 || len(patLev[0]) == 0 || len(patLev[1]) == 0 { + return nil, errVmoduleSyntax + } + pattern := patLev[0] + v, err := strconv.ParseInt(patLev[1], 10, 32) + if err != nil { + return nil, errors.New("syntax error: expect comma-separated list of filename=N") + } + if v < 0 { + return nil, errors.New("negative value for vmodule level") + } + if v == 0 { + continue // Ignore. It's harmless but no point in paying the overhead. + } + // TODO: check syntax of filter? + filter = append(filter, modulePat{pattern, isLiteral(pattern), Level(v)}) + } + return filter, nil +} + +// isLiteral reports whether the pattern is a literal string, that is, has no metacharacters +// that require filepath.Match to be called to match the pattern. +func isLiteral(pattern string) bool { + return !strings.ContainsAny(pattern, `\*?[]`) +} + +// traceLocation represents the setting of the -log_backtrace_at flag. +type traceLocation struct { + file string + line int +} + +// isSet reports whether the trace location has been specified. +// logging.mu is held. +func (t *traceLocation) isSet() bool { + return t.line > 0 +} + +// match reports whether the specified file and line matches the trace location. +// The argument file name is the full path, not the basename specified in the flag. +// logging.mu is held. +func (t *traceLocation) match(file string, line int) bool { + if t.line != line { + return false + } + if i := strings.LastIndex(file, "/"); i >= 0 { + file = file[i+1:] + } + return t.file == file +} + +func (t *traceLocation) String() string { + // Lock because the type is not atomic. TODO: clean this up. + logging.mu.Lock() + defer logging.mu.Unlock() + return fmt.Sprintf("%s:%d", t.file, t.line) +} + +// Get is part of the (Go 1.2) flag.Getter interface. It always returns nil for this flag type since the +// struct is not exported +func (t *traceLocation) Get() interface{} { + return nil +} + +var errTraceSyntax = errors.New("syntax error: expect file.go:234") + +// Set will sets backtrace value +// Syntax: -log_backtrace_at=gopherflakes.go:234 +// Note that unlike vmodule the file extension is included here. +func (t *traceLocation) Set(value string) error { + if value == "" { + // Unset. + logging.mu.Lock() + defer logging.mu.Unlock() + t.line = 0 + t.file = "" + return nil + } + fields := strings.Split(value, ":") + if len(fields) != 2 { + return errTraceSyntax + } + file, line := fields[0], fields[1] + if !strings.Contains(file, ".") { + return errTraceSyntax + } + v, err := strconv.Atoi(line) + if err != nil { + return errTraceSyntax + } + if v <= 0 { + return errors.New("negative or zero value for level") + } + logging.mu.Lock() + defer logging.mu.Unlock() + t.line = v + t.file = file + return nil +} + +// flushSyncWriter is the interface satisfied by logging destinations. +type flushSyncWriter interface { + Flush() error + Sync() error + io.Writer +} + +var logging loggingT +var commandLine flag.FlagSet + +// init sets up the defaults and creates command line flags. +func init() { + commandLine.StringVar(&logging.logDir, "log_dir", "", "If non-empty, write log files in this directory (no effect when -logtostderr=true)") + commandLine.StringVar(&logging.logFile, "log_file", "", "If non-empty, use this log file (no effect when -logtostderr=true)") + commandLine.Uint64Var(&logging.logFileMaxSizeMB, "log_file_max_size", 1800, + "Defines the maximum size a log file can grow to (no effect when -logtostderr=true). Unit is megabytes. "+ + "If the value is 0, the maximum file size is unlimited.") + commandLine.BoolVar(&logging.toStderr, "logtostderr", true, "log to standard error instead of files") + commandLine.BoolVar(&logging.alsoToStderr, "alsologtostderr", false, "log to standard error as well as files (no effect when -logtostderr=true)") + logging.setVState(0, nil, false) + commandLine.Var(&logging.verbosity, "v", "number for the log level verbosity") + commandLine.BoolVar(&logging.addDirHeader, "add_dir_header", false, "If true, adds the file directory to the header of the log messages") + commandLine.BoolVar(&logging.skipHeaders, "skip_headers", false, "If true, avoid header prefixes in the log messages") + commandLine.BoolVar(&logging.oneOutput, "one_output", false, "If true, only write logs to their native severity level (vs also writing to each lower severity level; no effect when -logtostderr=true)") + commandLine.BoolVar(&logging.skipLogHeaders, "skip_log_headers", false, "If true, avoid headers when opening log files (no effect when -logtostderr=true)") + logging.stderrThreshold = severityValue{ + Severity: severity.ErrorLog, // Default stderrThreshold is ERROR. + } + commandLine.Var(&logging.stderrThreshold, "stderrthreshold", "logs at or above this threshold go to stderr when writing to files and stderr (no effect when -logtostderr=true or -alsologtostderr=false)") + commandLine.Var(&logging.vmodule, "vmodule", "comma-separated list of pattern=N settings for file-filtered logging") + commandLine.Var(&logging.traceLocation, "log_backtrace_at", "when logging hits line file:N, emit a stack trace") + + logging.settings.contextualLoggingEnabled = true + logging.flushD = newFlushDaemon(logging.lockAndFlushAll, nil) +} + +// InitFlags is for explicitly initializing the flags. +// It may get called repeatedly for different flagsets, but not +// twice for the same one. May get called concurrently +// to other goroutines using klog. However, only some flags +// may get set concurrently (see implementation). +func InitFlags(flagset *flag.FlagSet) { + if flagset == nil { + flagset = flag.CommandLine + } + + commandLine.VisitAll(func(f *flag.Flag) { + flagset.Var(f.Value, f.Name, f.Usage) + }) +} + +// Flush flushes all pending log I/O. +func Flush() { + logging.lockAndFlushAll() +} + +// settings collects global settings. +type settings struct { + // contextualLoggingEnabled controls whether contextual logging is + // active. Disabling it may have some small performance benefit. + contextualLoggingEnabled bool + + // logger is the global Logger chosen by users of klog, nil if + // none is available. + logger *Logger + + // loggerOptions contains the options that were supplied for + // globalLogger. + loggerOptions loggerOptions + + // Boolean flags. Not handled atomically because the flag.Value interface + // does not let us avoid the =true, and that shorthand is necessary for + // compatibility. TODO: does this matter enough to fix? Seems unlikely. + toStderr bool // The -logtostderr flag. + alsoToStderr bool // The -alsologtostderr flag. + + // Level flag. Handled atomically. + stderrThreshold severityValue // The -stderrthreshold flag. + + // Access to all of the following fields must be protected via a mutex. + + // file holds writer for each of the log types. + file [severity.NumSeverity]flushSyncWriter + // flushInterval is the interval for periodic flushing. If zero, + // the global default will be used. + flushInterval time.Duration + + // filterLength stores the length of the vmodule filter chain. If greater + // than zero, it means vmodule is enabled. It may be read safely + // using sync.LoadInt32, but is only modified under mu. + filterLength int32 + // traceLocation is the state of the -log_backtrace_at flag. + traceLocation traceLocation + // These flags are modified only under lock, although verbosity may be fetched + // safely using atomic.LoadInt32. + vmodule moduleSpec // The state of the -vmodule flag. + verbosity Level // V logging level, the value of the -v flag/ + + // If non-empty, overrides the choice of directory in which to write logs. + // See createLogDirs for the full list of possible destinations. + logDir string + + // If non-empty, specifies the path of the file to write logs. mutually exclusive + // with the log_dir option. + logFile string + + // When logFile is specified, this limiter makes sure the logFile won't exceeds a certain size. When exceeds, the + // logFile will be cleaned up. If this value is 0, no size limitation will be applied to logFile. + logFileMaxSizeMB uint64 + + // If true, do not add the prefix headers, useful when used with SetOutput + skipHeaders bool + + // If true, do not add the headers to log files + skipLogHeaders bool + + // If true, add the file directory to the header + addDirHeader bool + + // If true, messages will not be propagated to lower severity log levels + oneOutput bool + + // If set, all output will be filtered through the filter. + filter LogFilter +} + +// deepCopy creates a copy that doesn't share anything with the original +// instance. +func (s settings) deepCopy() settings { + // vmodule is a slice and would be shared, so we have copy it. + filter := make([]modulePat, len(s.vmodule.filter)) + for i := range s.vmodule.filter { + filter[i] = s.vmodule.filter[i] + } + s.vmodule.filter = filter + + return s +} + +// loggingT collects all the global state of the logging setup. +type loggingT struct { + settings + + // bufferCache maintains the free list. It uses its own mutex + // so buffers can be grabbed and printed to without holding the main lock, + // for better parallelization. + bufferCache buffer.Buffers + + // flushD holds a flushDaemon that frequently flushes log file buffers. + // Uses its own mutex. + flushD *flushDaemon + + // mu protects the remaining elements of this structure and the fields + // in settingsT which need a mutex lock. + mu sync.Mutex + + // pcs is used in V to avoid an allocation when computing the caller's PC. + pcs [1]uintptr + // vmap is a cache of the V Level for each V() call site, identified by PC. + // It is wiped whenever the vmodule flag changes state. + vmap map[uintptr]Level +} + +// setVState sets a consistent state for V logging. +// l.mu is held. +func (l *loggingT) setVState(verbosity Level, filter []modulePat, setFilter bool) { + // Turn verbosity off so V will not fire while we are in transition. + l.verbosity.set(0) + // Ditto for filter length. + atomic.StoreInt32(&l.filterLength, 0) + + // Set the new filters and wipe the pc->Level map if the filter has changed. + if setFilter { + l.vmodule.filter = filter + l.vmap = make(map[uintptr]Level) + } + + // Things are consistent now, so enable filtering and verbosity. + // They are enabled in order opposite to that in V. + atomic.StoreInt32(&l.filterLength, int32(len(filter))) + l.verbosity.set(verbosity) +} + +var timeNow = time.Now // Stubbed out for testing. + +// CaptureState gathers information about all current klog settings. +// The result can be used to restore those settings. +func CaptureState() State { + logging.mu.Lock() + defer logging.mu.Unlock() + return &state{ + settings: logging.settings.deepCopy(), + flushDRunning: logging.flushD.isRunning(), + maxSize: MaxSize, + } +} + +// State stores a snapshot of klog settings. It gets created with CaptureState +// and can be used to restore the entire state. Modifying individual settings +// is supported via the command line flags. +type State interface { + // Restore restore the entire state. It may get called more than once. + Restore() +} + +type state struct { + settings + + flushDRunning bool + maxSize uint64 +} + +func (s *state) Restore() { + // This needs to be done before mutex locking. + if s.flushDRunning && !logging.flushD.isRunning() { + // This is not quite accurate: StartFlushDaemon might + // have been called with some different interval. + interval := s.flushInterval + if interval == 0 { + interval = flushInterval + } + logging.flushD.run(interval) + } else if !s.flushDRunning && logging.flushD.isRunning() { + logging.flushD.stop() + } + + logging.mu.Lock() + defer logging.mu.Unlock() + + logging.settings = s.settings + logging.setVState(s.verbosity, s.vmodule.filter, true) + MaxSize = s.maxSize +} + +/* +header formats a log header as defined by the C++ implementation. +It returns a buffer containing the formatted header and the user's file and line number. +The depth specifies how many stack frames above lives the source line to be identified in the log message. + +Log lines have this form: + + Lmmdd hh:mm:ss.uuuuuu threadid file:line] msg... + +where the fields are defined as follows: + + L A single character, representing the log level (eg 'I' for INFO) + mm The month (zero padded; ie May is '05') + dd The day (zero padded) + hh:mm:ss.uuuuuu Time in hours, minutes and fractional seconds + threadid The space-padded thread ID as returned by GetTID() + file The file name + line The line number + msg The user-supplied message +*/ +func (l *loggingT) header(s severity.Severity, depth int) (*buffer.Buffer, string, int) { + _, file, line, ok := runtime.Caller(3 + depth) + if !ok { + file = "???" + line = 1 + } else { + if slash := strings.LastIndex(file, "/"); slash >= 0 { + path := file + file = path[slash+1:] + if l.addDirHeader { + if dirsep := strings.LastIndex(path[:slash], "/"); dirsep >= 0 { + file = path[dirsep+1:] + } + } + } + } + return l.formatHeader(s, file, line), file, line +} + +// formatHeader formats a log header using the provided file name and line number. +func (l *loggingT) formatHeader(s severity.Severity, file string, line int) *buffer.Buffer { + buf := l.bufferCache.GetBuffer() + if l.skipHeaders { + return buf + } + now := timeNow() + buf.FormatHeader(s, file, line, now) + return buf +} + +func (l *loggingT) println(s severity.Severity, logger *logr.Logger, filter LogFilter, args ...interface{}) { + l.printlnDepth(s, logger, filter, 1, args...) +} + +func (l *loggingT) printlnDepth(s severity.Severity, logger *logr.Logger, filter LogFilter, depth int, args ...interface{}) { + buf, file, line := l.header(s, depth) + // if logger is set, we clear the generated header as we rely on the backing + // logger implementation to print headers + if logger != nil { + l.bufferCache.PutBuffer(buf) + buf = l.bufferCache.GetBuffer() + } + if filter != nil { + args = filter.Filter(args) + } + fmt.Fprintln(buf, args...) + l.output(s, logger, buf, depth, file, line, false) +} + +func (l *loggingT) print(s severity.Severity, logger *logr.Logger, filter LogFilter, args ...interface{}) { + l.printDepth(s, logger, filter, 1, args...) +} + +func (l *loggingT) printDepth(s severity.Severity, logger *logr.Logger, filter LogFilter, depth int, args ...interface{}) { + buf, file, line := l.header(s, depth) + // if logr is set, we clear the generated header as we rely on the backing + // logr implementation to print headers + if logger != nil { + l.bufferCache.PutBuffer(buf) + buf = l.bufferCache.GetBuffer() + } + if filter != nil { + args = filter.Filter(args) + } + fmt.Fprint(buf, args...) + if buf.Len() == 0 || buf.Bytes()[buf.Len()-1] != '\n' { + buf.WriteByte('\n') + } + l.output(s, logger, buf, depth, file, line, false) +} + +func (l *loggingT) printf(s severity.Severity, logger *logr.Logger, filter LogFilter, format string, args ...interface{}) { + l.printfDepth(s, logger, filter, 1, format, args...) +} + +func (l *loggingT) printfDepth(s severity.Severity, logger *logr.Logger, filter LogFilter, depth int, format string, args ...interface{}) { + buf, file, line := l.header(s, depth) + // if logr is set, we clear the generated header as we rely on the backing + // logr implementation to print headers + if logger != nil { + l.bufferCache.PutBuffer(buf) + buf = l.bufferCache.GetBuffer() + } + if filter != nil { + format, args = filter.FilterF(format, args) + } + fmt.Fprintf(buf, format, args...) + if buf.Bytes()[buf.Len()-1] != '\n' { + buf.WriteByte('\n') + } + l.output(s, logger, buf, depth, file, line, false) +} + +// printWithFileLine behaves like print but uses the provided file and line number. If +// alsoLogToStderr is true, the log message always appears on standard error; it +// will also appear in the log file unless --logtostderr is set. +func (l *loggingT) printWithFileLine(s severity.Severity, logger *logr.Logger, filter LogFilter, file string, line int, alsoToStderr bool, args ...interface{}) { + buf := l.formatHeader(s, file, line) + // if logr is set, we clear the generated header as we rely on the backing + // logr implementation to print headers + if logger != nil { + l.bufferCache.PutBuffer(buf) + buf = l.bufferCache.GetBuffer() + } + if filter != nil { + args = filter.Filter(args) + } + fmt.Fprint(buf, args...) + if buf.Bytes()[buf.Len()-1] != '\n' { + buf.WriteByte('\n') + } + l.output(s, logger, buf, 2 /* depth */, file, line, alsoToStderr) +} + +// if loggr is specified, will call loggr.Error, otherwise output with logging module. +func (l *loggingT) errorS(err error, logger *logr.Logger, filter LogFilter, depth int, msg string, keysAndValues ...interface{}) { + if filter != nil { + msg, keysAndValues = filter.FilterS(msg, keysAndValues) + } + if logger != nil { + logger.WithCallDepth(depth+2).Error(err, msg, keysAndValues...) + return + } + l.printS(err, severity.ErrorLog, depth+1, msg, keysAndValues...) +} + +// if loggr is specified, will call loggr.Info, otherwise output with logging module. +func (l *loggingT) infoS(logger *logr.Logger, filter LogFilter, depth int, msg string, keysAndValues ...interface{}) { + if filter != nil { + msg, keysAndValues = filter.FilterS(msg, keysAndValues) + } + if logger != nil { + logger.WithCallDepth(depth+2).Info(msg, keysAndValues...) + return + } + l.printS(nil, severity.InfoLog, depth+1, msg, keysAndValues...) +} + +// printS is called from infoS and errorS if loggr is not specified. +// set log severity by s +func (l *loggingT) printS(err error, s severity.Severity, depth int, msg string, keysAndValues ...interface{}) { + // Only create a new buffer if we don't have one cached. + b := l.bufferCache.GetBuffer() + // The message is always quoted, even if it contains line breaks. + // If developers want multi-line output, they should use a small, fixed + // message and put the multi-line output into a value. + b.WriteString(strconv.Quote(msg)) + if err != nil { + serialize.KVListFormat(&b.Buffer, "err", err) + } + serialize.KVListFormat(&b.Buffer, keysAndValues...) + l.printDepth(s, logging.logger, nil, depth+1, &b.Buffer) + // Make the buffer available for reuse. + l.bufferCache.PutBuffer(b) +} + +// redirectBuffer is used to set an alternate destination for the logs +type redirectBuffer struct { + w io.Writer +} + +func (rb *redirectBuffer) Sync() error { + return nil +} + +func (rb *redirectBuffer) Flush() error { + return nil +} + +func (rb *redirectBuffer) Write(bytes []byte) (n int, err error) { + return rb.w.Write(bytes) +} + +// SetOutput sets the output destination for all severities +func SetOutput(w io.Writer) { + logging.mu.Lock() + defer logging.mu.Unlock() + for s := severity.FatalLog; s >= severity.InfoLog; s-- { + rb := &redirectBuffer{ + w: w, + } + logging.file[s] = rb + } +} + +// SetOutputBySeverity sets the output destination for specific severity +func SetOutputBySeverity(name string, w io.Writer) { + logging.mu.Lock() + defer logging.mu.Unlock() + sev, ok := severity.ByName(name) + if !ok { + panic(fmt.Sprintf("SetOutputBySeverity(%q): unrecognized severity name", name)) + } + rb := &redirectBuffer{ + w: w, + } + logging.file[sev] = rb +} + +// LogToStderr sets whether to log exclusively to stderr, bypassing outputs +func LogToStderr(stderr bool) { + logging.mu.Lock() + defer logging.mu.Unlock() + + logging.toStderr = stderr +} + +// output writes the data to the log files and releases the buffer. +func (l *loggingT) output(s severity.Severity, log *logr.Logger, buf *buffer.Buffer, depth int, file string, line int, alsoToStderr bool) { + var isLocked = true + l.mu.Lock() + defer func() { + if isLocked { + // Unlock before returning in case that it wasn't done already. + l.mu.Unlock() + } + }() + + if l.traceLocation.isSet() { + if l.traceLocation.match(file, line) { + buf.Write(dbg.Stacks(false)) + } + } + data := buf.Bytes() + if log != nil { + // TODO: set 'severity' and caller information as structured log info + // keysAndValues := []interface{}{"severity", severityName[s], "file", file, "line", line} + if s == severity.ErrorLog { + logging.logger.WithCallDepth(depth+3).Error(nil, string(data)) + } else { + log.WithCallDepth(depth + 3).Info(string(data)) + } + } else if l.toStderr { + os.Stderr.Write(data) + } else { + if alsoToStderr || l.alsoToStderr || s >= l.stderrThreshold.get() { + os.Stderr.Write(data) + } + + if logging.logFile != "" { + // Since we are using a single log file, all of the items in l.file array + // will point to the same file, so just use one of them to write data. + if l.file[severity.InfoLog] == nil { + if err := l.createFiles(severity.InfoLog); err != nil { + os.Stderr.Write(data) // Make sure the message appears somewhere. + l.exit(err) + } + } + l.file[severity.InfoLog].Write(data) + } else { + if l.file[s] == nil { + if err := l.createFiles(s); err != nil { + os.Stderr.Write(data) // Make sure the message appears somewhere. + l.exit(err) + } + } + + if l.oneOutput { + l.file[s].Write(data) + } else { + switch s { + case severity.FatalLog: + l.file[severity.FatalLog].Write(data) + fallthrough + case severity.ErrorLog: + l.file[severity.ErrorLog].Write(data) + fallthrough + case severity.WarningLog: + l.file[severity.WarningLog].Write(data) + fallthrough + case severity.InfoLog: + l.file[severity.InfoLog].Write(data) + } + } + } + } + if s == severity.FatalLog { + // If we got here via Exit rather than Fatal, print no stacks. + if atomic.LoadUint32(&fatalNoStacks) > 0 { + l.mu.Unlock() + isLocked = false + timeoutFlush(ExitFlushTimeout) + OsExit(1) + } + // Dump all goroutine stacks before exiting. + // First, make sure we see the trace for the current goroutine on standard error. + // If -logtostderr has been specified, the loop below will do that anyway + // as the first stack in the full dump. + if !l.toStderr { + os.Stderr.Write(dbg.Stacks(false)) + } + + // Write the stack trace for all goroutines to the files. + trace := dbg.Stacks(true) + logExitFunc = func(error) {} // If we get a write error, we'll still exit below. + for log := severity.FatalLog; log >= severity.InfoLog; log-- { + if f := l.file[log]; f != nil { // Can be nil if -logtostderr is set. + f.Write(trace) + } + } + l.mu.Unlock() + isLocked = false + timeoutFlush(ExitFlushTimeout) + OsExit(255) // C++ uses -1, which is silly because it's anded with 255 anyway. + } + l.bufferCache.PutBuffer(buf) + + if stats := severityStats[s]; stats != nil { + atomic.AddInt64(&stats.lines, 1) + atomic.AddInt64(&stats.bytes, int64(len(data))) + } +} + +// logExitFunc provides a simple mechanism to override the default behavior +// of exiting on error. Used in testing and to guarantee we reach a required exit +// for fatal logs. Instead, exit could be a function rather than a method but that +// would make its use clumsier. +var logExitFunc func(error) + +// exit is called if there is trouble creating or writing log files. +// It flushes the logs and exits the program; there's no point in hanging around. +// l.mu is held. +func (l *loggingT) exit(err error) { + fmt.Fprintf(os.Stderr, "log: exiting because of error: %s\n", err) + // If logExitFunc is set, we do that instead of exiting. + if logExitFunc != nil { + logExitFunc(err) + return + } + l.flushAll() + OsExit(2) +} + +// syncBuffer joins a bufio.Writer to its underlying file, providing access to the +// file's Sync method and providing a wrapper for the Write method that provides log +// file rotation. There are conflicting methods, so the file cannot be embedded. +// l.mu is held for all its methods. +type syncBuffer struct { + logger *loggingT + *bufio.Writer + file *os.File + sev severity.Severity + nbytes uint64 // The number of bytes written to this file + maxbytes uint64 // The max number of bytes this syncBuffer.file can hold before cleaning up. +} + +func (sb *syncBuffer) Sync() error { + return sb.file.Sync() +} + +// CalculateMaxSize returns the real max size in bytes after considering the default max size and the flag options. +func CalculateMaxSize() uint64 { + if logging.logFile != "" { + if logging.logFileMaxSizeMB == 0 { + // If logFileMaxSizeMB is zero, we don't have limitations on the log size. + return math.MaxUint64 + } + // Flag logFileMaxSizeMB is in MB for user convenience. + return logging.logFileMaxSizeMB * 1024 * 1024 + } + // If "log_file" flag is not specified, the target file (sb.file) will be cleaned up when reaches a fixed size. + return MaxSize +} + +func (sb *syncBuffer) Write(p []byte) (n int, err error) { + if sb.nbytes+uint64(len(p)) >= sb.maxbytes { + if err := sb.rotateFile(time.Now(), false); err != nil { + sb.logger.exit(err) + } + } + n, err = sb.Writer.Write(p) + sb.nbytes += uint64(n) + if err != nil { + sb.logger.exit(err) + } + return +} + +// rotateFile closes the syncBuffer's file and starts a new one. +// The startup argument indicates whether this is the initial startup of klog. +// If startup is true, existing files are opened for appending instead of truncated. +func (sb *syncBuffer) rotateFile(now time.Time, startup bool) error { + if sb.file != nil { + sb.Flush() + sb.file.Close() + } + var err error + sb.file, _, err = create(severity.Name[sb.sev], now, startup) + if err != nil { + return err + } + if startup { + fileInfo, err := sb.file.Stat() + if err != nil { + return fmt.Errorf("file stat could not get fileinfo: %v", err) + } + // init file size + sb.nbytes = uint64(fileInfo.Size()) + } else { + sb.nbytes = 0 + } + sb.Writer = bufio.NewWriterSize(sb.file, bufferSize) + + if sb.logger.skipLogHeaders { + return nil + } + + // Write header. + var buf bytes.Buffer + fmt.Fprintf(&buf, "Log file created at: %s\n", now.Format("2006/01/02 15:04:05")) + fmt.Fprintf(&buf, "Running on machine: %s\n", host) + fmt.Fprintf(&buf, "Binary: Built with %s %s for %s/%s\n", runtime.Compiler, runtime.Version(), runtime.GOOS, runtime.GOARCH) + fmt.Fprintf(&buf, "Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg\n") + n, err := sb.file.Write(buf.Bytes()) + sb.nbytes += uint64(n) + return err +} + +// bufferSize sizes the buffer associated with each log file. It's large +// so that log records can accumulate without the logging thread blocking +// on disk I/O. The flushDaemon will block instead. +const bufferSize = 256 * 1024 + +// createFiles creates all the log files for severity from sev down to infoLog. +// l.mu is held. +func (l *loggingT) createFiles(sev severity.Severity) error { + interval := l.flushInterval + if interval == 0 { + interval = flushInterval + } + l.flushD.run(interval) + now := time.Now() + // Files are created in decreasing severity order, so as soon as we find one + // has already been created, we can stop. + for s := sev; s >= severity.InfoLog && l.file[s] == nil; s-- { + sb := &syncBuffer{ + logger: l, + sev: s, + maxbytes: CalculateMaxSize(), + } + if err := sb.rotateFile(now, true); err != nil { + return err + } + l.file[s] = sb + } + return nil +} + +const flushInterval = 5 * time.Second + +// flushDaemon periodically flushes the log file buffers. +type flushDaemon struct { + mu sync.Mutex + clock clock.WithTicker + flush func() + stopC chan struct{} + stopDone chan struct{} +} + +// newFlushDaemon returns a new flushDaemon. If the passed clock is nil, a +// clock.RealClock is used. +func newFlushDaemon(flush func(), tickClock clock.WithTicker) *flushDaemon { + if tickClock == nil { + tickClock = clock.RealClock{} + } + return &flushDaemon{ + flush: flush, + clock: tickClock, + } +} + +// run starts a goroutine that periodically calls the daemons flush function. +// Calling run on an already running daemon will have no effect. +func (f *flushDaemon) run(interval time.Duration) { + f.mu.Lock() + defer f.mu.Unlock() + + if f.stopC != nil { // daemon already running + return + } + + f.stopC = make(chan struct{}, 1) + f.stopDone = make(chan struct{}, 1) + + ticker := f.clock.NewTicker(interval) + go func() { + defer ticker.Stop() + defer func() { f.stopDone <- struct{}{} }() + for { + select { + case <-ticker.C(): + f.flush() + case <-f.stopC: + f.flush() + return + } + } + }() +} + +// stop stops the running flushDaemon and waits until the daemon has shut down. +// Calling stop on a daemon that isn't running will have no effect. +func (f *flushDaemon) stop() { + f.mu.Lock() + defer f.mu.Unlock() + + if f.stopC == nil { // daemon not running + return + } + + f.stopC <- struct{}{} + <-f.stopDone + + f.stopC = nil + f.stopDone = nil +} + +// isRunning returns true if the flush daemon is running. +func (f *flushDaemon) isRunning() bool { + f.mu.Lock() + defer f.mu.Unlock() + return f.stopC != nil +} + +// StopFlushDaemon stops the flush daemon, if running, and flushes once. +// This prevents klog from leaking goroutines on shutdown. After stopping +// the daemon, you can still manually flush buffers again by calling Flush(). +func StopFlushDaemon() { + logging.flushD.stop() +} + +// StartFlushDaemon ensures that the flush daemon runs with the given delay +// between flush calls. If it is already running, it gets restarted. +func StartFlushDaemon(interval time.Duration) { + StopFlushDaemon() + logging.flushD.run(interval) +} + +// lockAndFlushAll is like flushAll but locks l.mu first. +func (l *loggingT) lockAndFlushAll() { + l.mu.Lock() + l.flushAll() + l.mu.Unlock() +} + +// flushAll flushes all the logs and attempts to "sync" their data to disk. +// l.mu is held. +func (l *loggingT) flushAll() { + // Flush from fatal down, in case there's trouble flushing. + for s := severity.FatalLog; s >= severity.InfoLog; s-- { + file := l.file[s] + if file != nil { + file.Flush() // ignore error + file.Sync() // ignore error + } + } + if logging.loggerOptions.flush != nil { + logging.loggerOptions.flush() + } +} + +// CopyStandardLogTo arranges for messages written to the Go "log" package's +// default logs to also appear in the Google logs for the named and lower +// severities. Subsequent changes to the standard log's default output location +// or format may break this behavior. +// +// Valid names are "INFO", "WARNING", "ERROR", and "FATAL". If the name is not +// recognized, CopyStandardLogTo panics. +func CopyStandardLogTo(name string) { + sev, ok := severity.ByName(name) + if !ok { + panic(fmt.Sprintf("log.CopyStandardLogTo(%q): unrecognized severity name", name)) + } + // Set a log format that captures the user's file and line: + // d.go:23: message + stdLog.SetFlags(stdLog.Lshortfile) + stdLog.SetOutput(logBridge(sev)) +} + +// logBridge provides the Write method that enables CopyStandardLogTo to connect +// Go's standard logs to the logs provided by this package. +type logBridge severity.Severity + +// Write parses the standard logging line and passes its components to the +// logger for severity(lb). +func (lb logBridge) Write(b []byte) (n int, err error) { + var ( + file = "???" + line = 1 + text string + ) + // Split "d.go:23: message" into "d.go", "23", and "message". + if parts := bytes.SplitN(b, []byte{':'}, 3); len(parts) != 3 || len(parts[0]) < 1 || len(parts[2]) < 1 { + text = fmt.Sprintf("bad log format: %s", b) + } else { + file = string(parts[0]) + text = string(parts[2][1:]) // skip leading space + line, err = strconv.Atoi(string(parts[1])) + if err != nil { + text = fmt.Sprintf("bad line number: %s", b) + line = 1 + } + } + // printWithFileLine with alsoToStderr=true, so standard log messages + // always appear on standard error. + logging.printWithFileLine(severity.Severity(lb), logging.logger, logging.filter, file, line, true, text) + return len(b), nil +} + +// setV computes and remembers the V level for a given PC +// when vmodule is enabled. +// File pattern matching takes the basename of the file, stripped +// of its .go suffix, and uses filepath.Match, which is a little more +// general than the *? matching used in C++. +// l.mu is held. +func (l *loggingT) setV(pc uintptr) Level { + fn := runtime.FuncForPC(pc) + file, _ := fn.FileLine(pc) + // The file is something like /a/b/c/d.go. We want just the d. + if strings.HasSuffix(file, ".go") { + file = file[:len(file)-3] + } + if slash := strings.LastIndex(file, "/"); slash >= 0 { + file = file[slash+1:] + } + for _, filter := range l.vmodule.filter { + if filter.match(file) { + l.vmap[pc] = filter.level + return filter.level + } + } + l.vmap[pc] = 0 + return 0 +} + +// Verbose is a boolean type that implements Infof (like Printf) etc. +// See the documentation of V for more information. +type Verbose struct { + enabled bool + logr *logr.Logger +} + +func newVerbose(level Level, b bool) Verbose { + if logging.logger == nil { + return Verbose{b, nil} + } + v := logging.logger.V(int(level)) + return Verbose{b, &v} +} + +// V reports whether verbosity at the call site is at least the requested level. +// The returned value is a struct of type Verbose, which implements Info, Infoln +// and Infof. These methods will write to the Info log if called. +// Thus, one may write either +// +// if klog.V(2).Enabled() { klog.Info("log this") } +// +// or +// +// klog.V(2).Info("log this") +// +// The second form is shorter but the first is cheaper if logging is off because it does +// not evaluate its arguments. +// +// Whether an individual call to V generates a log record depends on the setting of +// the -v and -vmodule flags; both are off by default. The V call will log if its level +// is less than or equal to the value of the -v flag, or alternatively if its level is +// less than or equal to the value of the -vmodule pattern matching the source file +// containing the call. +func V(level Level) Verbose { + // This function tries hard to be cheap unless there's work to do. + // The fast path is two atomic loads and compares. + + // Here is a cheap but safe test to see if V logging is enabled globally. + if logging.verbosity.get() >= level { + return newVerbose(level, true) + } + + // It's off globally but vmodule may still be set. + // Here is another cheap but safe test to see if vmodule is enabled. + if atomic.LoadInt32(&logging.filterLength) > 0 { + // Now we need a proper lock to use the logging structure. The pcs field + // is shared so we must lock before accessing it. This is fairly expensive, + // but if V logging is enabled we're slow anyway. + logging.mu.Lock() + defer logging.mu.Unlock() + if runtime.Callers(2, logging.pcs[:]) == 0 { + return newVerbose(level, false) + } + // runtime.Callers returns "return PCs", but we want + // to look up the symbolic information for the call, + // so subtract 1 from the PC. runtime.CallersFrames + // would be cleaner, but allocates. + pc := logging.pcs[0] - 1 + v, ok := logging.vmap[pc] + if !ok { + v = logging.setV(pc) + } + return newVerbose(level, v >= level) + } + return newVerbose(level, false) +} + +// Enabled will return true if this log level is enabled, guarded by the value +// of v. +// See the documentation of V for usage. +func (v Verbose) Enabled() bool { + return v.enabled +} + +// Info is equivalent to the global Info function, guarded by the value of v. +// See the documentation of V for usage. +func (v Verbose) Info(args ...interface{}) { + if v.enabled { + logging.print(severity.InfoLog, v.logr, logging.filter, args...) + } +} + +// InfoDepth is equivalent to the global InfoDepth function, guarded by the value of v. +// See the documentation of V for usage. +func (v Verbose) InfoDepth(depth int, args ...interface{}) { + if v.enabled { + logging.printDepth(severity.InfoLog, v.logr, logging.filter, depth, args...) + } +} + +// Infoln is equivalent to the global Infoln function, guarded by the value of v. +// See the documentation of V for usage. +func (v Verbose) Infoln(args ...interface{}) { + if v.enabled { + logging.println(severity.InfoLog, v.logr, logging.filter, args...) + } +} + +// InfolnDepth is equivalent to the global InfolnDepth function, guarded by the value of v. +// See the documentation of V for usage. +func (v Verbose) InfolnDepth(depth int, args ...interface{}) { + if v.enabled { + logging.printlnDepth(severity.InfoLog, v.logr, logging.filter, depth, args...) + } +} + +// Infof is equivalent to the global Infof function, guarded by the value of v. +// See the documentation of V for usage. +func (v Verbose) Infof(format string, args ...interface{}) { + if v.enabled { + logging.printf(severity.InfoLog, v.logr, logging.filter, format, args...) + } +} + +// InfofDepth is equivalent to the global InfofDepth function, guarded by the value of v. +// See the documentation of V for usage. +func (v Verbose) InfofDepth(depth int, format string, args ...interface{}) { + if v.enabled { + logging.printfDepth(severity.InfoLog, v.logr, logging.filter, depth, format, args...) + } +} + +// InfoS is equivalent to the global InfoS function, guarded by the value of v. +// See the documentation of V for usage. +func (v Verbose) InfoS(msg string, keysAndValues ...interface{}) { + if v.enabled { + logging.infoS(v.logr, logging.filter, 0, msg, keysAndValues...) + } +} + +// InfoSDepth acts as InfoS but uses depth to determine which call frame to log. +// InfoSDepth(0, "msg") is the same as InfoS("msg"). +func InfoSDepth(depth int, msg string, keysAndValues ...interface{}) { + logging.infoS(logging.logger, logging.filter, depth, msg, keysAndValues...) +} + +// InfoSDepth is equivalent to the global InfoSDepth function, guarded by the value of v. +// See the documentation of V for usage. +func (v Verbose) InfoSDepth(depth int, msg string, keysAndValues ...interface{}) { + if v.enabled { + logging.infoS(v.logr, logging.filter, depth, msg, keysAndValues...) + } +} + +// Deprecated: Use ErrorS instead. +func (v Verbose) Error(err error, msg string, args ...interface{}) { + if v.enabled { + logging.errorS(err, v.logr, logging.filter, 0, msg, args...) + } +} + +// ErrorS is equivalent to the global Error function, guarded by the value of v. +// See the documentation of V for usage. +func (v Verbose) ErrorS(err error, msg string, keysAndValues ...interface{}) { + if v.enabled { + logging.errorS(err, v.logr, logging.filter, 0, msg, keysAndValues...) + } +} + +// Info logs to the INFO log. +// Arguments are handled in the manner of fmt.Print; a newline is appended if missing. +func Info(args ...interface{}) { + logging.print(severity.InfoLog, logging.logger, logging.filter, args...) +} + +// InfoDepth acts as Info but uses depth to determine which call frame to log. +// InfoDepth(0, "msg") is the same as Info("msg"). +func InfoDepth(depth int, args ...interface{}) { + logging.printDepth(severity.InfoLog, logging.logger, logging.filter, depth, args...) +} + +// Infoln logs to the INFO log. +// Arguments are handled in the manner of fmt.Println; a newline is always appended. +func Infoln(args ...interface{}) { + logging.println(severity.InfoLog, logging.logger, logging.filter, args...) +} + +// InfolnDepth acts as Infoln but uses depth to determine which call frame to log. +// InfolnDepth(0, "msg") is the same as Infoln("msg"). +func InfolnDepth(depth int, args ...interface{}) { + logging.printlnDepth(severity.InfoLog, logging.logger, logging.filter, depth, args...) +} + +// Infof logs to the INFO log. +// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing. +func Infof(format string, args ...interface{}) { + logging.printf(severity.InfoLog, logging.logger, logging.filter, format, args...) +} + +// InfofDepth acts as Infof but uses depth to determine which call frame to log. +// InfofDepth(0, "msg", args...) is the same as Infof("msg", args...). +func InfofDepth(depth int, format string, args ...interface{}) { + logging.printfDepth(severity.InfoLog, logging.logger, logging.filter, depth, format, args...) +} + +// InfoS structured logs to the INFO log. +// The msg argument used to add constant description to the log line. +// The key/value pairs would be join by "=" ; a newline is always appended. +// +// Basic examples: +// >> klog.InfoS("Pod status updated", "pod", "kubedns", "status", "ready") +// output: +// >> I1025 00:15:15.525108 1 controller_utils.go:116] "Pod status updated" pod="kubedns" status="ready" +func InfoS(msg string, keysAndValues ...interface{}) { + logging.infoS(logging.logger, logging.filter, 0, msg, keysAndValues...) +} + +// Warning logs to the WARNING and INFO logs. +// Arguments are handled in the manner of fmt.Print; a newline is appended if missing. +func Warning(args ...interface{}) { + logging.print(severity.WarningLog, logging.logger, logging.filter, args...) +} + +// WarningDepth acts as Warning but uses depth to determine which call frame to log. +// WarningDepth(0, "msg") is the same as Warning("msg"). +func WarningDepth(depth int, args ...interface{}) { + logging.printDepth(severity.WarningLog, logging.logger, logging.filter, depth, args...) +} + +// Warningln logs to the WARNING and INFO logs. +// Arguments are handled in the manner of fmt.Println; a newline is always appended. +func Warningln(args ...interface{}) { + logging.println(severity.WarningLog, logging.logger, logging.filter, args...) +} + +// WarninglnDepth acts as Warningln but uses depth to determine which call frame to log. +// WarninglnDepth(0, "msg") is the same as Warningln("msg"). +func WarninglnDepth(depth int, args ...interface{}) { + logging.printlnDepth(severity.WarningLog, logging.logger, logging.filter, depth, args...) +} + +// Warningf logs to the WARNING and INFO logs. +// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing. +func Warningf(format string, args ...interface{}) { + logging.printf(severity.WarningLog, logging.logger, logging.filter, format, args...) +} + +// WarningfDepth acts as Warningf but uses depth to determine which call frame to log. +// WarningfDepth(0, "msg", args...) is the same as Warningf("msg", args...). +func WarningfDepth(depth int, format string, args ...interface{}) { + logging.printfDepth(severity.WarningLog, logging.logger, logging.filter, depth, format, args...) +} + +// Error logs to the ERROR, WARNING, and INFO logs. +// Arguments are handled in the manner of fmt.Print; a newline is appended if missing. +func Error(args ...interface{}) { + logging.print(severity.ErrorLog, logging.logger, logging.filter, args...) +} + +// ErrorDepth acts as Error but uses depth to determine which call frame to log. +// ErrorDepth(0, "msg") is the same as Error("msg"). +func ErrorDepth(depth int, args ...interface{}) { + logging.printDepth(severity.ErrorLog, logging.logger, logging.filter, depth, args...) +} + +// Errorln logs to the ERROR, WARNING, and INFO logs. +// Arguments are handled in the manner of fmt.Println; a newline is always appended. +func Errorln(args ...interface{}) { + logging.println(severity.ErrorLog, logging.logger, logging.filter, args...) +} + +// ErrorlnDepth acts as Errorln but uses depth to determine which call frame to log. +// ErrorlnDepth(0, "msg") is the same as Errorln("msg"). +func ErrorlnDepth(depth int, args ...interface{}) { + logging.printlnDepth(severity.ErrorLog, logging.logger, logging.filter, depth, args...) +} + +// Errorf logs to the ERROR, WARNING, and INFO logs. +// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing. +func Errorf(format string, args ...interface{}) { + logging.printf(severity.ErrorLog, logging.logger, logging.filter, format, args...) +} + +// ErrorfDepth acts as Errorf but uses depth to determine which call frame to log. +// ErrorfDepth(0, "msg", args...) is the same as Errorf("msg", args...). +func ErrorfDepth(depth int, format string, args ...interface{}) { + logging.printfDepth(severity.ErrorLog, logging.logger, logging.filter, depth, format, args...) +} + +// ErrorS structured logs to the ERROR, WARNING, and INFO logs. +// the err argument used as "err" field of log line. +// The msg argument used to add constant description to the log line. +// The key/value pairs would be join by "=" ; a newline is always appended. +// +// Basic examples: +// >> klog.ErrorS(err, "Failed to update pod status") +// output: +// >> E1025 00:15:15.525108 1 controller_utils.go:114] "Failed to update pod status" err="timeout" +func ErrorS(err error, msg string, keysAndValues ...interface{}) { + logging.errorS(err, logging.logger, logging.filter, 0, msg, keysAndValues...) +} + +// ErrorSDepth acts as ErrorS but uses depth to determine which call frame to log. +// ErrorSDepth(0, "msg") is the same as ErrorS("msg"). +func ErrorSDepth(depth int, err error, msg string, keysAndValues ...interface{}) { + logging.errorS(err, logging.logger, logging.filter, depth, msg, keysAndValues...) +} + +// Fatal logs to the FATAL, ERROR, WARNING, and INFO logs, +// prints stack trace(s), then calls OsExit(255). +// +// Stderr only receives a dump of the current goroutine's stack trace. Log files, +// if there are any, receive a dump of the stack traces in all goroutines. +// +// Callers who want more control over handling of fatal events may instead use a +// combination of different functions: +// - some info or error logging function, optionally with a stack trace +// value generated by github.com/go-logr/lib/dbg.Backtrace +// - Flush to flush pending log data +// - panic, os.Exit or returning to the caller with an error +// +// Arguments are handled in the manner of fmt.Print; a newline is appended if missing. +func Fatal(args ...interface{}) { + logging.print(severity.FatalLog, logging.logger, logging.filter, args...) +} + +// FatalDepth acts as Fatal but uses depth to determine which call frame to log. +// FatalDepth(0, "msg") is the same as Fatal("msg"). +func FatalDepth(depth int, args ...interface{}) { + logging.printDepth(severity.FatalLog, logging.logger, logging.filter, depth, args...) +} + +// Fatalln logs to the FATAL, ERROR, WARNING, and INFO logs, +// including a stack trace of all running goroutines, then calls OsExit(255). +// Arguments are handled in the manner of fmt.Println; a newline is always appended. +func Fatalln(args ...interface{}) { + logging.println(severity.FatalLog, logging.logger, logging.filter, args...) +} + +// FatallnDepth acts as Fatalln but uses depth to determine which call frame to log. +// FatallnDepth(0, "msg") is the same as Fatalln("msg"). +func FatallnDepth(depth int, args ...interface{}) { + logging.printlnDepth(severity.FatalLog, logging.logger, logging.filter, depth, args...) +} + +// Fatalf logs to the FATAL, ERROR, WARNING, and INFO logs, +// including a stack trace of all running goroutines, then calls OsExit(255). +// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing. +func Fatalf(format string, args ...interface{}) { + logging.printf(severity.FatalLog, logging.logger, logging.filter, format, args...) +} + +// FatalfDepth acts as Fatalf but uses depth to determine which call frame to log. +// FatalfDepth(0, "msg", args...) is the same as Fatalf("msg", args...). +func FatalfDepth(depth int, format string, args ...interface{}) { + logging.printfDepth(severity.FatalLog, logging.logger, logging.filter, depth, format, args...) +} + +// fatalNoStacks is non-zero if we are to exit without dumping goroutine stacks. +// It allows Exit and relatives to use the Fatal logs. +var fatalNoStacks uint32 + +// Exit logs to the FATAL, ERROR, WARNING, and INFO logs, then calls OsExit(1). +// Arguments are handled in the manner of fmt.Print; a newline is appended if missing. +func Exit(args ...interface{}) { + atomic.StoreUint32(&fatalNoStacks, 1) + logging.print(severity.FatalLog, logging.logger, logging.filter, args...) +} + +// ExitDepth acts as Exit but uses depth to determine which call frame to log. +// ExitDepth(0, "msg") is the same as Exit("msg"). +func ExitDepth(depth int, args ...interface{}) { + atomic.StoreUint32(&fatalNoStacks, 1) + logging.printDepth(severity.FatalLog, logging.logger, logging.filter, depth, args...) +} + +// Exitln logs to the FATAL, ERROR, WARNING, and INFO logs, then calls OsExit(1). +func Exitln(args ...interface{}) { + atomic.StoreUint32(&fatalNoStacks, 1) + logging.println(severity.FatalLog, logging.logger, logging.filter, args...) +} + +// ExitlnDepth acts as Exitln but uses depth to determine which call frame to log. +// ExitlnDepth(0, "msg") is the same as Exitln("msg"). +func ExitlnDepth(depth int, args ...interface{}) { + atomic.StoreUint32(&fatalNoStacks, 1) + logging.printlnDepth(severity.FatalLog, logging.logger, logging.filter, depth, args...) +} + +// Exitf logs to the FATAL, ERROR, WARNING, and INFO logs, then calls OsExit(1). +// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing. +func Exitf(format string, args ...interface{}) { + atomic.StoreUint32(&fatalNoStacks, 1) + logging.printf(severity.FatalLog, logging.logger, logging.filter, format, args...) +} + +// ExitfDepth acts as Exitf but uses depth to determine which call frame to log. +// ExitfDepth(0, "msg", args...) is the same as Exitf("msg", args...). +func ExitfDepth(depth int, format string, args ...interface{}) { + atomic.StoreUint32(&fatalNoStacks, 1) + logging.printfDepth(severity.FatalLog, logging.logger, logging.filter, depth, format, args...) +} + +// LogFilter is a collection of functions that can filter all logging calls, +// e.g. for sanitization of arguments and prevent accidental leaking of secrets. +type LogFilter interface { + Filter(args []interface{}) []interface{} + FilterF(format string, args []interface{}) (string, []interface{}) + FilterS(msg string, keysAndValues []interface{}) (string, []interface{}) +} + +// SetLogFilter installs a filter that is used for all log calls. +// +// Modifying the filter is not thread-safe and should be done while no other +// goroutines invoke log calls, usually during program initialization. +func SetLogFilter(filter LogFilter) { + logging.filter = filter +} diff --git a/vendor/k8s.io/klog/v2/klog_file.go b/vendor/k8s.io/klog/v2/klog_file.go new file mode 100644 index 0000000..1025d64 --- /dev/null +++ b/vendor/k8s.io/klog/v2/klog_file.go @@ -0,0 +1,130 @@ +// Go support for leveled logs, analogous to https://code.google.com/p/google-glog/ +// +// Copyright 2013 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// File I/O for logs. + +package klog + +import ( + "errors" + "fmt" + "os" + "path/filepath" + "strings" + "sync" + "time" +) + +// MaxSize is the maximum size of a log file in bytes. +var MaxSize uint64 = 1024 * 1024 * 1800 + +// logDirs lists the candidate directories for new log files. +var logDirs []string + +func createLogDirs() { + if logging.logDir != "" { + logDirs = append(logDirs, logging.logDir) + } + logDirs = append(logDirs, os.TempDir()) +} + +var ( + pid = os.Getpid() + program = filepath.Base(os.Args[0]) + host = "unknownhost" + userName = "unknownuser" + userNameOnce sync.Once +) + +func init() { + if h, err := os.Hostname(); err == nil { + host = shortHostname(h) + } +} + +// shortHostname returns its argument, truncating at the first period. +// For instance, given "www.google.com" it returns "www". +func shortHostname(hostname string) string { + if i := strings.Index(hostname, "."); i >= 0 { + return hostname[:i] + } + return hostname +} + +// logName returns a new log file name containing tag, with start time t, and +// the name for the symlink for tag. +func logName(tag string, t time.Time) (name, link string) { + name = fmt.Sprintf("%s.%s.%s.log.%s.%04d%02d%02d-%02d%02d%02d.%d", + program, + host, + getUserName(), + tag, + t.Year(), + t.Month(), + t.Day(), + t.Hour(), + t.Minute(), + t.Second(), + pid) + return name, program + "." + tag +} + +var onceLogDirs sync.Once + +// create creates a new log file and returns the file and its filename, which +// contains tag ("INFO", "FATAL", etc.) and t. If the file is created +// successfully, create also attempts to update the symlink for that tag, ignoring +// errors. +// The startup argument indicates whether this is the initial startup of klog. +// If startup is true, existing files are opened for appending instead of truncated. +func create(tag string, t time.Time, startup bool) (f *os.File, filename string, err error) { + if logging.logFile != "" { + f, err := openOrCreate(logging.logFile, startup) + if err == nil { + return f, logging.logFile, nil + } + return nil, "", fmt.Errorf("log: unable to create log: %v", err) + } + onceLogDirs.Do(createLogDirs) + if len(logDirs) == 0 { + return nil, "", errors.New("log: no log dirs") + } + name, link := logName(tag, t) + var lastErr error + for _, dir := range logDirs { + fname := filepath.Join(dir, name) + f, err := openOrCreate(fname, startup) + if err == nil { + symlink := filepath.Join(dir, link) + os.Remove(symlink) // ignore err + os.Symlink(name, symlink) // ignore err + return f, fname, nil + } + lastErr = err + } + return nil, "", fmt.Errorf("log: cannot create log: %v", lastErr) +} + +// The startup argument indicates whether this is the initial startup of klog. +// If startup is true, existing files are opened for appending instead of truncated. +func openOrCreate(name string, startup bool) (*os.File, error) { + if startup { + f, err := os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) + return f, err + } + f, err := os.Create(name) + return f, err +} diff --git a/vendor/k8s.io/klog/v2/klog_file_others.go b/vendor/k8s.io/klog/v2/klog_file_others.go new file mode 100644 index 0000000..aa46726 --- /dev/null +++ b/vendor/k8s.io/klog/v2/klog_file_others.go @@ -0,0 +1,19 @@ +//go:build !windows +// +build !windows + +package klog + +import ( + "os/user" +) + +func getUserName() string { + userNameOnce.Do(func() { + current, err := user.Current() + if err == nil { + userName = current.Username + } + }) + + return userName +} diff --git a/vendor/k8s.io/klog/v2/klog_file_windows.go b/vendor/k8s.io/klog/v2/klog_file_windows.go new file mode 100644 index 0000000..2517f9c --- /dev/null +++ b/vendor/k8s.io/klog/v2/klog_file_windows.go @@ -0,0 +1,34 @@ +//go:build windows +// +build windows + +package klog + +import ( + "os" + "strings" +) + +func getUserName() string { + userNameOnce.Do(func() { + // On Windows, the Go 'user' package requires netapi32.dll. + // This affects Windows Nano Server: + // https://github.com/golang/go/issues/21867 + // Fallback to using environment variables. + u := os.Getenv("USERNAME") + if len(u) == 0 { + return + } + // Sanitize the USERNAME since it may contain filepath separators. + u = strings.Replace(u, `\`, "_", -1) + + // user.Current().Username normally produces something like 'USERDOMAIN\USERNAME' + d := os.Getenv("USERDOMAIN") + if len(d) != 0 { + userName = d + "_" + u + } else { + userName = u + } + }) + + return userName +} diff --git a/vendor/k8s.io/klog/v2/klogr.go b/vendor/k8s.io/klog/v2/klogr.go new file mode 100644 index 0000000..027a401 --- /dev/null +++ b/vendor/k8s.io/klog/v2/klogr.go @@ -0,0 +1,87 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package klog + +import ( + "github.com/go-logr/logr" + + "k8s.io/klog/v2/internal/serialize" +) + +// NewKlogr returns a logger that is functionally identical to +// klogr.NewWithOptions(klogr.FormatKlog), i.e. it passes through to klog. The +// difference is that it uses a simpler implementation. +func NewKlogr() Logger { + return New(&klogger{}) +} + +// klogger is a subset of klogr/klogr.go. It had to be copied to break an +// import cycle (klogr wants to use klog, and klog wants to use klogr). +type klogger struct { + level int + callDepth int + prefix string + values []interface{} +} + +func (l *klogger) Init(info logr.RuntimeInfo) { + l.callDepth += info.CallDepth +} + +func (l klogger) Info(level int, msg string, kvList ...interface{}) { + merged := serialize.MergeKVs(l.values, kvList) + if l.prefix != "" { + msg = l.prefix + ": " + msg + } + V(Level(level)).InfoSDepth(l.callDepth+1, msg, merged...) +} + +func (l klogger) Enabled(level int) bool { + return V(Level(level)).Enabled() +} + +func (l klogger) Error(err error, msg string, kvList ...interface{}) { + merged := serialize.MergeKVs(l.values, kvList) + if l.prefix != "" { + msg = l.prefix + ": " + msg + } + ErrorSDepth(l.callDepth+1, err, msg, merged...) +} + +// WithName returns a new logr.Logger with the specified name appended. klogr +// uses '/' characters to separate name elements. Callers should not pass '/' +// in the provided name string, but this library does not actually enforce that. +func (l klogger) WithName(name string) logr.LogSink { + if len(l.prefix) > 0 { + l.prefix = l.prefix + "/" + } + l.prefix += name + return &l +} + +func (l klogger) WithValues(kvList ...interface{}) logr.LogSink { + l.values = serialize.WithValues(l.values, kvList) + return &l +} + +func (l klogger) WithCallDepth(depth int) logr.LogSink { + l.callDepth += depth + return &l +} + +var _ logr.LogSink = &klogger{} +var _ logr.CallDepthLogSink = &klogger{} diff --git a/vendor/k8s.io/klog/v2/klogr/README.md b/vendor/k8s.io/klog/v2/klogr/README.md new file mode 100644 index 0000000..c43fa81 --- /dev/null +++ b/vendor/k8s.io/klog/v2/klogr/README.md @@ -0,0 +1,19 @@ +# Minimal Go logging using klog + +This package implements the [logr interface](https://github.com/go-logr/logr) +in terms of Kubernetes' [klog](https://github.com/kubernetes/klog). This +provides a relatively minimalist API to logging in Go, backed by a well-proven +implementation. + +Because klogr was implemented before klog itself added supported for +structured logging, the default in klogr is to serialize key/value +pairs with JSON and log the result as text messages via klog. This +does not work well when klog itself forwards output to a structured +logger. + +Therefore the recommended approach is to let klogr pass all log +messages through to klog and deal with structured logging there. Just +beware that the output of klog without a structured logger is meant to +be human-readable, in contrast to the JSON-based traditional format. + +This is a BETA grade implementation. diff --git a/vendor/k8s.io/klog/v2/klogr/klogr.go b/vendor/k8s.io/klog/v2/klogr/klogr.go new file mode 100644 index 0000000..c94e551 --- /dev/null +++ b/vendor/k8s.io/klog/v2/klogr/klogr.go @@ -0,0 +1,185 @@ +// Package klogr implements github.com/go-logr/logr.Logger in terms of +// k8s.io/klog. +package klogr + +import ( + "bytes" + "encoding/json" + "fmt" + "sort" + "strings" + + "github.com/go-logr/logr" + + "k8s.io/klog/v2" + "k8s.io/klog/v2/internal/serialize" +) + +// Option is a functional option that reconfigures the logger created with New. +type Option func(*klogger) + +// Format defines how log output is produced. +type Format string + +const ( + // FormatSerialize tells klogr to turn key/value pairs into text itself + // before invoking klog. + FormatSerialize Format = "Serialize" + + // FormatKlog tells klogr to pass all text messages and key/value pairs + // directly to klog. Klog itself then serializes in a human-readable + // format and optionally passes on to a structure logging backend. + FormatKlog Format = "Klog" +) + +// WithFormat selects the output format. +func WithFormat(format Format) Option { + return func(l *klogger) { + l.format = format + } +} + +// New returns a logr.Logger which serializes output itself +// and writes it via klog. +func New() logr.Logger { + return NewWithOptions(WithFormat(FormatSerialize)) +} + +// NewWithOptions returns a logr.Logger which serializes as determined +// by the WithFormat option and writes via klog. The default is +// FormatKlog. +func NewWithOptions(options ...Option) logr.Logger { + l := klogger{ + level: 0, + prefix: "", + values: nil, + format: FormatKlog, + } + for _, option := range options { + option(&l) + } + return logr.New(&l) +} + +type klogger struct { + level int + callDepth int + prefix string + values []interface{} + format Format +} + +func (l *klogger) Init(info logr.RuntimeInfo) { + l.callDepth += info.CallDepth +} + +func flatten(kvList ...interface{}) string { + keys := make([]string, 0, len(kvList)) + vals := make(map[string]interface{}, len(kvList)) + for i := 0; i < len(kvList); i += 2 { + k, ok := kvList[i].(string) + if !ok { + panic(fmt.Sprintf("key is not a string: %s", pretty(kvList[i]))) + } + var v interface{} + if i+1 < len(kvList) { + v = kvList[i+1] + } + // Only print each key once... + if _, seen := vals[k]; !seen { + keys = append(keys, k) + } + // ... with the latest value. + vals[k] = v + } + sort.Strings(keys) + buf := bytes.Buffer{} + for i, k := range keys { + v := vals[k] + if i > 0 { + buf.WriteRune(' ') + } + buf.WriteString(pretty(k)) + buf.WriteString("=") + buf.WriteString(pretty(v)) + } + return buf.String() +} + +func pretty(value interface{}) string { + if err, ok := value.(error); ok { + if _, ok := value.(json.Marshaler); !ok { + value = err.Error() + } + } + buffer := &bytes.Buffer{} + encoder := json.NewEncoder(buffer) + encoder.SetEscapeHTML(false) + encoder.Encode(value) + return strings.TrimSpace(string(buffer.Bytes())) +} + +func (l klogger) Info(level int, msg string, kvList ...interface{}) { + switch l.format { + case FormatSerialize: + msgStr := flatten("msg", msg) + merged := serialize.MergeKVs(l.values, kvList) + kvStr := flatten(merged...) + klog.V(klog.Level(level)).InfoDepth(l.callDepth+1, l.prefix, " ", msgStr, " ", kvStr) + case FormatKlog: + merged := serialize.MergeKVs(l.values, kvList) + if l.prefix != "" { + msg = l.prefix + ": " + msg + } + klog.V(klog.Level(level)).InfoSDepth(l.callDepth+1, msg, merged...) + } +} + +func (l klogger) Enabled(level int) bool { + return klog.V(klog.Level(level)).Enabled() +} + +func (l klogger) Error(err error, msg string, kvList ...interface{}) { + msgStr := flatten("msg", msg) + var loggableErr interface{} + if err != nil { + loggableErr = serialize.ErrorToString(err) + } + switch l.format { + case FormatSerialize: + errStr := flatten("error", loggableErr) + merged := serialize.MergeKVs(l.values, kvList) + kvStr := flatten(merged...) + klog.ErrorDepth(l.callDepth+1, l.prefix, " ", msgStr, " ", errStr, " ", kvStr) + case FormatKlog: + merged := serialize.MergeKVs(l.values, kvList) + if l.prefix != "" { + msg = l.prefix + ": " + msg + } + klog.ErrorSDepth(l.callDepth+1, err, msg, merged...) + } +} + +// WithName returns a new logr.Logger with the specified name appended. klogr +// uses '/' characters to separate name elements. Callers should not pass '/' +// in the provided name string, but this library does not actually enforce that. +func (l klogger) WithName(name string) logr.LogSink { + if len(l.prefix) > 0 { + l.prefix = l.prefix + "/" + } + l.prefix += name + return &l +} + +func (l klogger) WithValues(kvList ...interface{}) logr.LogSink { + l.values = serialize.WithValues(l.values, kvList) + return &l +} + +func (l klogger) WithCallDepth(depth int) logr.LogSink { + l.callDepth += depth + return &l +} + +var _ logr.LogSink = &klogger{} +var _ logr.CallDepthLogSink = &klogger{} diff --git a/vendor/modules.txt b/vendor/modules.txt index 9492f1c..fc70c4d 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -100,9 +100,6 @@ github.com/glycerine/go-unsnap-stream # github.com/go-logr/logr v1.2.3 ## explicit; go 1.16 github.com/go-logr/logr -# github.com/go-logr/zerologr v1.2.2 -## explicit; go 1.17 -github.com/go-logr/zerologr # github.com/golang/protobuf v1.4.3 ## explicit; go 1.9 github.com/golang/protobuf/proto @@ -112,12 +109,6 @@ github.com/golang/snappy # github.com/gorilla/mux v1.8.0 ## explicit; go 1.12 github.com/gorilla/mux -# github.com/mattn/go-colorable v0.1.12 -## explicit; go 1.13 -github.com/mattn/go-colorable -# github.com/mattn/go-isatty v0.0.14 -## explicit; go 1.12 -github.com/mattn/go-isatty # github.com/mschoch/smat v0.2.0 ## explicit; go 1.13 github.com/mschoch/smat @@ -129,11 +120,6 @@ github.com/philhofer/fwd github.com/pquerna/otp github.com/pquerna/otp/hotp github.com/pquerna/otp/totp -# github.com/rs/zerolog v1.28.0 -## explicit; go 1.15 -github.com/rs/zerolog -github.com/rs/zerolog/internal/cbor -github.com/rs/zerolog/internal/json # github.com/russross/blackfriday/v2 v2.1.0 ## explicit github.com/russross/blackfriday/v2 @@ -193,3 +179,12 @@ google.golang.org/protobuf/reflect/protoreflect google.golang.org/protobuf/reflect/protoregistry google.golang.org/protobuf/runtime/protoiface google.golang.org/protobuf/runtime/protoimpl +# k8s.io/klog/v2 v2.80.1 +## explicit; go 1.13 +k8s.io/klog/v2 +k8s.io/klog/v2/internal/buffer +k8s.io/klog/v2/internal/clock +k8s.io/klog/v2/internal/dbg +k8s.io/klog/v2/internal/serialize +k8s.io/klog/v2/internal/severity +k8s.io/klog/v2/klogr