From 76552e7cadc1f76b4e28b5c872412db4a091aca0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Otto=20Kr=C3=B6pke?= Date: Sat, 15 Jul 2023 14:18:11 +0200 Subject: [PATCH] Implement structured logging (#331) Co-authored-by: Martin Helmich --- Dockerfile | 5 +- go.mod | 37 ++++++----- go.sum | 92 +++++++++++++++----------- log/main.go | 115 +++++++++++++++++++++++++++++++++ main.go | 94 +++++++++++++++------------ pkg/config/loader.go | 10 +-- pkg/config/loader_hcl.go | 3 +- pkg/config/loader_test.go | 13 ++-- pkg/config/loader_yaml.go | 5 +- pkg/config/struct_namespace.go | 11 ++-- pkg/config/structs.go | 3 + pkg/tail/tailer.go | 12 +++- 12 files changed, 279 insertions(+), 121 deletions(-) create mode 100644 log/main.go diff --git a/Dockerfile b/Dockerfile index b0d91fd..337e933 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,12 +1,13 @@ -FROM golang:1.18 +FROM golang:1.20 COPY . /work WORKDIR /work -RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o prometheus-nginxlog-exporter +RUN CGO_ENABLED=0 GOOS=linux go build -ldflags '-w -s' -a -installsuffix cgo -o prometheus-nginxlog-exporter FROM scratch COPY --from=0 /work/prometheus-nginxlog-exporter /prometheus-nginxlog-exporter EXPOSE 4040 +USER 65532 ENTRYPOINT ["/prometheus-nginxlog-exporter"] diff --git a/go.mod b/go.mod index 6e44e07..1fdba62 100644 --- a/go.mod +++ b/go.mod @@ -1,45 +1,48 @@ module github.com/martin-helmich/prometheus-nginxlog-exporter +go 1.20 + require ( - github.com/hashicorp/consul/api v1.20.0 + github.com/hashicorp/consul/api v1.22.0 github.com/hashicorp/hcl v1.0.0 - github.com/mitchellh/mapstructure v1.4.1 // indirect github.com/nxadm/tail v1.4.8 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.16.0 github.com/prometheus/common v0.44.0 - github.com/satyrius/gonx v1.3.1-0.20180709120835-47c52b995fe5 + github.com/satyrius/gonx v1.4.0 github.com/stretchr/testify v1.8.4 + go.uber.org/zap v1.24.0 gopkg.in/mcuadros/go-syslog.v2 v2.3.0 - gopkg.in/yaml.v2 v2.4.0 + gopkg.in/yaml.v3 v3.0.1 ) require ( - github.com/armon/go-metrics v0.3.10 // indirect + github.com/armon/go-metrics v0.4.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/fatih/color v1.9.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/fatih/color v1.14.1 // indirect github.com/fsnotify/fsnotify v1.4.9 // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/hashicorp/go-cleanhttp v0.5.1 // indirect - github.com/hashicorp/go-hclog v0.14.1 // indirect - github.com/hashicorp/go-immutable-radix v1.3.0 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-hclog v1.5.0 // indirect + github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-rootcerts v1.0.2 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/serf v0.10.1 // indirect - github.com/mattn/go-colorable v0.1.6 // indirect - github.com/mattn/go-isatty v0.0.12 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.17 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_model v0.4.0 // indirect github.com/prometheus/procfs v0.10.1 // indirect - github.com/smartystreets/goconvey v1.7.2 // indirect + github.com/smartystreets/goconvey v1.8.1 // indirect + go.uber.org/atomic v1.7.0 // indirect + go.uber.org/multierr v1.6.0 // indirect + golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect golang.org/x/sys v0.8.0 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect ) - -go 1.18 diff --git a/go.sum b/go.sum index c47de06..119f816 100644 --- a/go.sum +++ b/go.sum @@ -5,10 +5,11 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-metrics v0.3.10 h1:FR+drcQStOe+32sYyJYyZ7FIdgoGGBnwLl+flodp8Uo= -github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= +github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= +github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -20,11 +21,14 @@ github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w= +github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= @@ -39,33 +43,32 @@ github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/hashicorp/consul/api v1.20.0 h1:9IHTjNVSZ7MIwjlW3N3a7iGiykCMDpxZu8jsxFJh0yc= -github.com/hashicorp/consul/api v1.20.0/go.mod h1:nR64eD44KQ59Of/ECwt2vUmIK2DKsDzAwTmwmLl8Wpo= -github.com/hashicorp/consul/sdk v0.13.1 h1:EygWVWWMczTzXGpO93awkHFzfUka6hLYJ0qhETd+6lY= -github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g= +github.com/hashicorp/consul/api v1.22.0 h1:ydEvDooB/A0c/xpsBd8GSt7P2/zYPBui4KrNip0xGjE= +github.com/hashicorp/consul/api v1.22.0/go.mod h1:zHpYgZ7TeYqS6zaszjwSt128OwESRpnhU9aGa6ue3Eg= +github.com/hashicorp/consul/sdk v0.14.0 h1:Hly+BMNMssVzoWddbBnBFi3W+Fzytvm0haSkihhj3GU= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-hclog v0.14.1 h1:nQcJDQwIAGnmoUWp8ubocEX40cCml/17YkF6csQLReU= -github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= +github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-immutable-radix v1.3.0 h1:8exGP7ego3OmkfksihtSouGMZ+hQrhxx+FVELeXpVPE= -github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4= +github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= +github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= @@ -74,7 +77,7 @@ github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0S github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= +github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= @@ -90,7 +93,6 @@ github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfE github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= @@ -101,14 +103,19 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= @@ -119,8 +126,8 @@ github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXx github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= -github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= @@ -135,8 +142,9 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 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/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -160,30 +168,38 @@ github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+Pymzi github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/satyrius/gonx v1.3.1-0.20180709120835-47c52b995fe5 h1:nIAK+9DnhpSebWeiIqvPr0rqSDC3j9r1I2bp0OJAYVE= -github.com/satyrius/gonx v1.3.1-0.20180709120835-47c52b995fe5/go.mod h1:+r8KNe5d2tjkZU+DfhERo0G6KxkGih+1qYF6tqLHwvk= +github.com/satyrius/gonx v1.4.0 h1:F3uxif5Yx6FBzdQAh79bHQK6CTJugOcN0w0Z8azQuQg= +github.com/satyrius/gonx v1.4.0/go.mod h1:+r8KNe5d2tjkZU+DfhERo0G6KxkGih+1qYF6tqLHwvk= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= -github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= -github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= -github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= +github.com/smarty/assertions v1.15.0 h1:cR//PqUBUiQRakZWqBiFFQ9wb8emQGDb0HeGdqGByCY= +github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY= +github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= +go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -205,7 +221,6 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -213,7 +228,11 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/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-20220503163025-988cb79eb6c6/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-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -222,7 +241,6 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -242,7 +260,5 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/log/main.go b/log/main.go new file mode 100644 index 0000000..ce0de2c --- /dev/null +++ b/log/main.go @@ -0,0 +1,115 @@ +package log + +import ( + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +type Logger struct { + zap *zap.SugaredLogger +} + +func New(logLevel, logFormat string) (*Logger, error) { + level, err := zap.ParseAtomicLevel(logLevel) + if err != nil { + return nil, err + } + + config := zap.NewProductionConfig() + config.Level = level + config.Encoding = logFormat + config.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder + + // build logger + log, err := config.Build(zap.AddCallerSkip(1)) + if err != nil { + return nil, err + } + + return &Logger{ + zap: log.Sugar(), + }, nil +} + +func (log *Logger) Print(args ...interface{}) { + log.zap.Info(args...) +} + +func (log *Logger) Debug(msg string, fields ...zap.Field) { + log.zap.Debug(msg, fields) +} + +func (log *Logger) Info(msg string, fields ...zap.Field) { + log.zap.Info(msg, fields) +} + +func (log *Logger) Warn(msg string, fields ...zap.Field) { + log.zap.Warn(msg, fields) +} + +func (log *Logger) Error(msg string, fields ...zap.Field) { + log.zap.Error(msg, fields) +} + +func (log *Logger) Fatal(args ...interface{}) { + log.zap.Fatal(args...) +} + +func (log *Logger) Panic(args ...interface{}) { + log.zap.Panic(args...) +} + +func (log *Logger) Printf(template string, args ...interface{}) { + log.zap.Infof(template, args...) +} + +func (log *Logger) Debugf(template string, args ...interface{}) { + log.zap.Debugf(template, args...) +} +func (log *Logger) Infof(template string, args ...interface{}) { + log.zap.Infof(template, args...) +} + +func (log *Logger) Warnf(template string, args ...interface{}) { + log.zap.Warnf(template, args...) +} + +func (log *Logger) Errorf(template string, args ...interface{}) { + log.zap.Errorf(template, args...) +} + +func (log *Logger) Fatalf(template string, args ...interface{}) { + log.zap.Fatalf(template, args...) +} + +func (log *Logger) Panicf(template string, args ...interface{}) { + log.zap.Panicf(template, args...) +} + +func (log *Logger) Println(args ...interface{}) { + log.zap.Infoln(args...) +} + +func (log *Logger) Debugln(args ...interface{}) { + log.zap.Debugln(args...) +} + +func (log *Logger) Infoln(args ...interface{}) { + log.zap.Infoln(args...) +} + +func (log *Logger) Warnln(args ...interface{}) { + log.zap.Warnln(args...) +} + +func (log *Logger) Errorln(args ...interface{}) { + log.zap.Errorln(args...) +} + +func (log *Logger) Fatalln(args ...interface{}) { + log.zap.Fatalln(args...) +} + +func (log *Logger) Panicln(args ...interface{}) { + log.zap.Panicln(args...) +} diff --git a/main.go b/main.go index 9f3247f..0ec971f 100644 --- a/main.go +++ b/main.go @@ -27,6 +27,7 @@ import ( "sync" "syscall" + "github.com/martin-helmich/prometheus-nginxlog-exporter/log" "github.com/martin-helmich/prometheus-nginxlog-exporter/pkg/config" "github.com/martin-helmich/prometheus-nginxlog-exporter/pkg/discovery" "github.com/martin-helmich/prometheus-nginxlog-exporter/pkg/metrics" @@ -36,7 +37,6 @@ import ( "github.com/martin-helmich/prometheus-nginxlog-exporter/pkg/syslog" "github.com/martin-helmich/prometheus-nginxlog-exporter/pkg/tail" "github.com/pkg/errors" - "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/prometheus/common/version" @@ -69,6 +69,8 @@ func main() { flag.StringVar(&opts.CPUProfile, "cpuprofile", "", "write cpu profile to `file`") flag.StringVar(&opts.MemProfile, "memprofile", "", "write memory profile to `file`") flag.StringVar(&opts.MetricsEndpoint, "metrics-endpoint", cfg.Listen.MetricsEndpoint, "URL path at which to serve metrics") + flag.StringVar(&opts.LogLevel, "log-level", "info", "level of logs. Allowed values: error, warning, info, debug") + flag.StringVar(&opts.LogFormat, "log-format", "console", "Define log format. Allowed values: console, json") flag.BoolVar(&opts.VerifyConfig, "verify-config", false, "Enable this flag to check config file loads, then exit") flag.BoolVar(&opts.Version, "version", false, "set to print version information") flag.Parse() @@ -78,6 +80,12 @@ func main() { os.Exit(0) } + logger, err := log.New(opts.LogLevel, opts.LogFormat) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + opts.Filenames = flag.Args() sigChan := make(chan os.Signal, 1) @@ -90,7 +98,7 @@ func main() { go func() { sig := <-sigChan - fmt.Printf("caught term %s. exiting\n", sig) + logger.Infof("caught term %s. exiting", sig) close(stopChan) stopHandlers.Wait() @@ -106,19 +114,20 @@ func main() { prof.SetupCPUProfiling(opts.CPUProfile, stopChan, &stopHandlers) prof.SetupMemoryProfiling(opts.MemProfile, stopChan, &stopHandlers) - loadConfig(&opts, &cfg) + loadConfig(logger, &opts, &cfg) - fmt.Printf("using configuration %+v\n", cfg) + logger.Debugf("using configuration %+v", cfg) if stabilityError := cfg.StabilityWarnings(); stabilityError != nil && !opts.EnableExperimentalFeatures { - fmt.Fprintf(os.Stderr, "Your configuration file contains an option that is explicitly labeled as experimental feature:\n\n %s\n\n", stabilityError.Error()) - fmt.Fprintln(os.Stderr, "Use the -enable-experimental flag or the enable_experimental option to enable these features. Use them at your own peril.") + logger.Error("Your configuration file contains an option that is explicitly labeled as experimental feature") + logger.Error(stabilityError.Error()) + logger.Error("Use the -enable-experimental flag or the enable_experimental option to enable these features. Use them at your own peril.") os.Exit(1) } if cfg.Consul.Enable { - setupConsul(&cfg, stopChan, &stopHandlers) + setupConsul(logger, &cfg, stopChan, &stopHandlers) } for i := range cfg.Namespaces { @@ -127,16 +136,16 @@ func main() { nsMetrics := metrics.NewForNamespace(namespace) gatherers = append(gatherers, nsMetrics.Gatherer()) - fmt.Printf("starting listener for namespace %s\n", namespace.Name) + logger.Infof("starting listener for namespace %s", namespace.Name) go func(ns *config.NamespaceConfig) { - processNamespace(ns, &(nsMetrics.Collection), stopChan, &stopHandlers) + processNamespace(logger, ns, &(nsMetrics.Collection), stopChan, &stopHandlers) }(namespace) } listenAddr := fmt.Sprintf("%s:%d", cfg.Listen.Address, cfg.Listen.Port) endpoint := cfg.Listen.MetricsEndpointOrDefault() - fmt.Printf("running HTTP server on address %s, serving metrics at %s\n", listenAddr, endpoint) + logger.Infof("running HTTP server on address %s, serving metrics at %s", listenAddr, endpoint) nsHandler := promhttp.InstrumentMetricHandler( prometheus.DefaultRegisterer, @@ -145,43 +154,42 @@ func main() { http.Handle(endpoint, nsHandler) - if err := http.ListenAndServe(listenAddr, nil); err != nil { - fmt.Printf("error while starting HTTP server: %s", err.Error()) - } + logger.Fatal(http.ListenAndServe(listenAddr, nil)) } -func loadConfig(opts *config.StartupFlags, cfg *config.Config) { +func loadConfig(logger *log.Logger, opts *config.StartupFlags, cfg *config.Config) { if opts.ConfigFile != "" { - fmt.Printf("loading configuration file %s\n", opts.ConfigFile) - if err := config.LoadConfigFromFile(cfg, opts.ConfigFile); err != nil { - panic(err) + logger.Infof("loading configuration file %s", opts.ConfigFile) + if err := config.LoadConfigFromFile(logger, cfg, opts.ConfigFile); err != nil { + logger.Fatal(err) } } else if err := config.LoadConfigFromFlags(cfg, opts); err != nil { - panic(err) + logger.Fatal(err) } + if opts.VerifyConfig { fmt.Printf("Configuration is valid") os.Exit(0) } } -func setupConsul(cfg *config.Config, stopChan <-chan bool, stopHandlers *sync.WaitGroup) { +func setupConsul(logger *log.Logger, cfg *config.Config, stopChan <-chan bool, stopHandlers *sync.WaitGroup) { registrator, err := discovery.NewConsulRegistrator(cfg) if err != nil { - panic(err) + logger.Fatal(err) } - fmt.Printf("registering service in Consul\n") - if err := registrator.RegisterConsul(); err != nil { - panic(err) + logger.Info("registering service in Consul") + if err = registrator.RegisterConsul(); err != nil { + logger.Fatal(err) } go func() { <-stopChan - fmt.Printf("unregistering service in Consul\n") + logger.Info("unregistering service in Consul") if err := registrator.UnregisterConsul(); err != nil { - fmt.Printf("error while unregistering from consul: %s\n", err.Error()) + logger.Errorf("error while unregistering from consul: %s", err.Error()) } stopHandlers.Done() @@ -190,19 +198,19 @@ func setupConsul(cfg *config.Config, stopChan <-chan bool, stopHandlers *sync.Wa stopHandlers.Add(1) } -func processNamespace(nsCfg *config.NamespaceConfig, metrics *metrics.Collection, stopChan <-chan bool, stopHandlers *sync.WaitGroup) error { +func processNamespace(logger *log.Logger, nsCfg *config.NamespaceConfig, metrics *metrics.Collection, stopChan <-chan bool, stopHandlers *sync.WaitGroup) error { var followers []tail.Follower - parser := parser.NewParser(nsCfg) + logParser := parser.NewParser(nsCfg) for _, f := range nsCfg.SourceData.Files { - t, err := tail.NewFileFollower(f) + t, err := tail.NewFileFollower(logger, f) if err != nil { - panic(err) + logger.Fatal(err) } t.OnError(func(err error) { - panic(err) + logger.Fatal(err) }) followers = append(followers, t) @@ -211,7 +219,7 @@ func processNamespace(nsCfg *config.NamespaceConfig, metrics *metrics.Collection if nsCfg.SourceData.Syslog != nil { slCfg := nsCfg.SourceData.Syslog - fmt.Printf("running Syslog server on address %s\n", slCfg.ListenAddress) + logger.Infof("running Syslog server on address %s", slCfg.ListenAddress) channel, server, closeServer, err := syslog.Listen(slCfg.ListenAddress, slCfg.Format) if err != nil { panic(err) @@ -232,11 +240,11 @@ func processNamespace(nsCfg *config.NamespaceConfig, metrics *metrics.Collection for _, f := range slCfg.Tags { t, err := tail.NewSyslogFollower(f, server, channel) if err != nil { - panic(err) + logger.Fatal(err) } t.OnError(func(err error) { - panic(err) + logger.Fatal(err) }) followers = append(followers, t) @@ -257,7 +265,7 @@ func processNamespace(nsCfg *config.NamespaceConfig, metrics *metrics.Collection for _, follower := range followers { go func(f tail.Follower) { - if err := processSource(nsCfg, f, parser, metrics, hasCounterOnlyLabels); err != nil { + if err := processSource(logger, nsCfg, f, logParser, metrics, hasCounterOnlyLabels); err != nil { errs <- err } }(follower) @@ -266,7 +274,7 @@ func processNamespace(nsCfg *config.NamespaceConfig, metrics *metrics.Collection return <-errs } -func processSource(nsCfg *config.NamespaceConfig, t tail.Follower, parser parser.Parser, metrics *metrics.Collection, hasCounterOnlyLabels bool) error { +func processSource(logger *log.Logger, nsCfg *config.NamespaceConfig, t tail.Follower, parser parser.Parser, metrics *metrics.Collection, hasCounterOnlyLabels bool) error { relabelings := relabeling.NewRelabelings(nsCfg.RelabelConfigs) relabelings = append(relabelings, relabeling.DefaultRelabelings...) relabelings = relabeling.UniqueRelabelings(relabelings) @@ -291,7 +299,7 @@ func processSource(nsCfg *config.NamespaceConfig, t tail.Follower, parser parser fields, err := parser.ParseString(line) if err != nil { - fmt.Printf("error while parsing line '%s': %s\n", line, err) + logger.Errorf("error while parsing line '%s': %s", line, err) metrics.ParseErrorsTotal.Inc() continue } @@ -314,25 +322,25 @@ func processSource(nsCfg *config.NamespaceConfig, t tail.Follower, parser parser metrics.CountTotal.WithLabelValues(labelValues...).Inc() - if v, ok := observeMetrics(fields, "body_bytes_sent", floatFromFields, metrics.ParseErrorsTotal); ok { + if v, ok := observeMetrics(logger, fields, "body_bytes_sent", floatFromFields, metrics.ParseErrorsTotal); ok { metrics.ResponseBytesTotal.WithLabelValues(notCounterValues...).Add(v) } - if v, ok := observeMetrics(fields, "request_length", floatFromFields, metrics.ParseErrorsTotal); ok { + if v, ok := observeMetrics(logger, fields, "request_length", floatFromFields, metrics.ParseErrorsTotal); ok { metrics.RequestBytesTotal.WithLabelValues(notCounterValues...).Add(v) } - if v, ok := observeMetrics(fields, "upstream_response_time", floatFromFieldsMulti, metrics.ParseErrorsTotal); ok { + if v, ok := observeMetrics(logger, fields, "upstream_response_time", floatFromFieldsMulti, metrics.ParseErrorsTotal); ok { metrics.UpstreamSeconds.WithLabelValues(notCounterValues...).Observe(v) metrics.UpstreamSecondsHist.WithLabelValues(notCounterValues...).Observe(v) } - if v, ok := observeMetrics(fields, "upstream_connect_time", floatFromFieldsMulti, metrics.ParseErrorsTotal); ok { + if v, ok := observeMetrics(logger, fields, "upstream_connect_time", floatFromFieldsMulti, metrics.ParseErrorsTotal); ok { metrics.UpstreamConnectSeconds.WithLabelValues(notCounterValues...).Observe(v) metrics.UpstreamConnectSecondsHist.WithLabelValues(notCounterValues...).Observe(v) } - if v, ok := observeMetrics(fields, "request_time", floatFromFields, metrics.ParseErrorsTotal); ok { + if v, ok := observeMetrics(logger, fields, "request_time", floatFromFields, metrics.ParseErrorsTotal); ok { metrics.ResponseSeconds.WithLabelValues(notCounterValues...).Observe(v) metrics.ResponseSecondsHist.WithLabelValues(notCounterValues...).Observe(v) } @@ -341,11 +349,11 @@ func processSource(nsCfg *config.NamespaceConfig, t tail.Follower, parser parser return nil } -func observeMetrics(fields map[string]string, name string, extractor func(map[string]string, string) (float64, bool, error), parseErrors prometheus.Counter) (float64, bool) { +func observeMetrics(logger *log.Logger, fields map[string]string, name string, extractor func(map[string]string, string) (float64, bool, error), parseErrors prometheus.Counter) (float64, bool) { if observation, ok, err := extractor(fields, name); ok { return observation, true } else if err != nil { - fmt.Printf("error while parsing $%s: %v\n", name, err) + logger.Errorf("error while parsing $%s: %v", name, err) parseErrors.Inc() } diff --git a/pkg/config/loader.go b/pkg/config/loader.go index ce35432..2f12d5b 100644 --- a/pkg/config/loader.go +++ b/pkg/config/loader.go @@ -5,6 +5,8 @@ import ( "io" "os" "strings" + + "github.com/martin-helmich/prometheus-nginxlog-exporter/log" ) // FileFormat describes which kind of configuration file the exporter was started with @@ -20,7 +22,7 @@ const ( // LoadConfigFromFile fills a configuration object (passed as parameter) with // values read from a configuration file (pass as parameter by filename). The // configuration file needs to be in HCL format. -func LoadConfigFromFile(config *Config, filename string) error { +func LoadConfigFromFile(logger *log.Logger, config *Config, filename string) error { var typ FileFormat reader, err := os.Open(filename) @@ -38,12 +40,12 @@ func LoadConfigFromFile(config *Config, filename string) error { return fmt.Errorf("config file '%s' has unsupported file type", filename) } - return LoadConfigFromStream(config, reader, typ) + return LoadConfigFromStream(logger, config, reader, typ) } // LoadConfigFromStream fills a configuration object (passed as parameter) with // values read from a Reader interface (passed as parameter). -func LoadConfigFromStream(config *Config, stream io.Reader, typ FileFormat) error { +func LoadConfigFromStream(logger *log.Logger, config *Config, stream io.Reader, typ FileFormat) error { switch typ { case TypeHCL: if err := loadConfigFromHCLStream(config, stream); err != nil { @@ -60,7 +62,7 @@ func LoadConfigFromStream(config *Config, stream io.Reader, typ FileFormat) erro for i := range config.Namespaces { config.Namespaces[i].ResolveDeprecations() - if err := config.Namespaces[i].ResolveGlobs(); err != nil { + if err := config.Namespaces[i].ResolveGlobs(logger); err != nil { return err } } diff --git a/pkg/config/loader_hcl.go b/pkg/config/loader_hcl.go index b6a6ac5..73c1cae 100644 --- a/pkg/config/loader_hcl.go +++ b/pkg/config/loader_hcl.go @@ -2,13 +2,12 @@ package config import ( "io" - "io/ioutil" "github.com/hashicorp/hcl" ) func loadConfigFromHCLStream(config *Config, file io.Reader) error { - buf, err := ioutil.ReadAll(file) + buf, err := io.ReadAll(file) if err != nil { return err } diff --git a/pkg/config/loader_test.go b/pkg/config/loader_test.go index db094b6..4cef354 100644 --- a/pkg/config/loader_test.go +++ b/pkg/config/loader_test.go @@ -4,6 +4,7 @@ import ( "bytes" "testing" + "github.com/martin-helmich/prometheus-nginxlog-exporter/log" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -146,7 +147,8 @@ func TestLoadsHCLConfigFile(t *testing.T) { buf := bytes.NewBufferString(HCLInput) cfg := Config{} - err := LoadConfigFromStream(&cfg, buf, TypeHCL) + logger, _ := log.New("panic", "console") + err := LoadConfigFromStream(logger, &cfg, buf, TypeHCL) assert.Nil(t, err, "unexpected error: %v", err) assertConfigContents(t, cfg) } @@ -157,7 +159,8 @@ func TestLoadsYAMLConfigFile(t *testing.T) { buf := bytes.NewBufferString(YAMLInput) cfg := Config{} - err := LoadConfigFromStream(&cfg, buf, TypeYAML) + logger, _ := log.New("panic", "console") + err := LoadConfigFromStream(logger, &cfg, buf, TypeYAML) assert.Nil(t, err, "unexpected error: %v", err) assertConfigContents(t, cfg) } @@ -263,7 +266,8 @@ func TestLoadsNSLabeledHCLConfigFile(t *testing.T) { buf := bytes.NewBufferString(HCLLabeledInput) cfg := Config{} - err := LoadConfigFromStream(&cfg, buf, TypeHCL) + logger, _ := log.New("panic", "console") + err := LoadConfigFromStream(logger, &cfg, buf, TypeHCL) assert.Nil(t, err, "unexpected error: %v", err) assertLabeledConfigContents(t, cfg) } @@ -274,7 +278,8 @@ func TestLoadsNSLabeledYAMLConfigFile(t *testing.T) { buf := bytes.NewBufferString(YAMLLabeledInput) cfg := Config{} - err := LoadConfigFromStream(&cfg, buf, TypeYAML) + logger, _ := log.New("panic", "console") + err := LoadConfigFromStream(logger, &cfg, buf, TypeYAML) assert.Nil(t, err, "unexpected error: %v", err) assertLabeledConfigContents(t, cfg) } diff --git a/pkg/config/loader_yaml.go b/pkg/config/loader_yaml.go index b3c4309..7479d49 100644 --- a/pkg/config/loader_yaml.go +++ b/pkg/config/loader_yaml.go @@ -2,13 +2,12 @@ package config import ( "io" - "io/ioutil" - "gopkg.in/yaml.v2" + "gopkg.in/yaml.v3" ) func loadConfigFromYAMLStream(config *Config, file io.Reader) error { - buf, err := ioutil.ReadAll(file) + buf, err := io.ReadAll(file) if err != nil { return err } diff --git a/pkg/config/struct_namespace.go b/pkg/config/struct_namespace.go index 7c32d49..c9e019d 100644 --- a/pkg/config/struct_namespace.go +++ b/pkg/config/struct_namespace.go @@ -2,10 +2,11 @@ package config import ( "errors" - "fmt" "path/filepath" "sort" "strings" + + "github.com/martin-helmich/prometheus-nginxlog-exporter/log" ) // NamespaceConfig is a struct describing single metric namespaces @@ -82,7 +83,7 @@ func (c *NamespaceConfig) ResolveDeprecations() { // ResolveGlobs finds globs in file sources and expand them to the actual // list of files -func (c *NamespaceConfig) ResolveGlobs() error { +func (c *NamespaceConfig) ResolveGlobs(logger *log.Logger) error { if len(c.SourceData.Files) > 0 { resolvedFiles := make([]string, 0) for _, sf := range c.SourceData.Files { @@ -91,10 +92,10 @@ func (c *NamespaceConfig) ResolveGlobs() error { if err != nil { return err } - fmt.Printf("Resolved globs %v to %v\n", sf, matches) + logger.Infof("Resolved globs %v to %v", sf, matches) resolvedFiles = append(resolvedFiles, matches...) } else { - fmt.Printf("No globs for %v\n", sf) + logger.Warnf("No globs for %v", sf) resolvedFiles = append(resolvedFiles, sf) } } @@ -111,7 +112,7 @@ func (c *NamespaceConfig) ResolveGlobs() error { func (c *NamespaceConfig) Compile() error { for i := range c.RelabelConfigs { if err := c.RelabelConfigs[i].Compile(); err != nil { - return nil + return err } } if c.NamespaceLabelName != "" { diff --git a/pkg/config/structs.go b/pkg/config/structs.go index 26e7a1f..84b965a 100644 --- a/pkg/config/structs.go +++ b/pkg/config/structs.go @@ -15,6 +15,9 @@ type StartupFlags struct { VerifyConfig bool Version bool + LogLevel string + LogFormat string + CPUProfile string MemProfile string } diff --git a/pkg/tail/tailer.go b/pkg/tail/tailer.go index 7ae523e..ee999b0 100644 --- a/pkg/tail/tailer.go +++ b/pkg/tail/tailer.go @@ -1,22 +1,27 @@ package tail import ( + "io" "os" + "github.com/martin-helmich/prometheus-nginxlog-exporter/log" "github.com/nxadm/tail" ) type followerImpl struct { + logger *log.Logger + filename string t *tail.Tail line chan string } -// NewFollower creates a new Follower instance for a given file (given by name) -func NewFileFollower(filename string) (Follower, error) { +// NewFileFollower creates a new Follower instance for a given file (given by name) +func NewFileFollower(logger *log.Logger, filename string) (Follower, error) { f := &followerImpl{ filename: filename, line: make(chan string), + logger: logger, } if err := f.start(); err != nil { @@ -35,7 +40,7 @@ func (f *followerImpl) start() error { return err } } else { - seekInfo = &tail.SeekInfo{Offset: 0, Whence: os.SEEK_END} + seekInfo = &tail.SeekInfo{Offset: 0, Whence: io.SeekEnd} } t, err := tail.TailFile(f.filename, tail.Config{ @@ -43,6 +48,7 @@ func (f *followerImpl) start() error { ReOpen: true, Poll: true, Location: seekInfo, + Logger: f.logger, }) if err != nil {