diff --git a/Dockerfile b/Dockerfile index 07e7634..e22aae2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM --platform=$BUILDPLATFORM golang:1.22.5 AS builder +FROM --platform=$BUILDPLATFORM golang:1.23.2 AS builder WORKDIR /app COPY . /app diff --git a/README.md b/README.md index 0844ee6..82a1f18 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ Binaries are available for download [here](https://github.com/automixer/gtexport The mandatory argument is a config file: ```gtexporter-- -config ```. ### Build from sources -Requires ```go 1.22.5``` or higher and ```make```. +Requires ```go 1.23.2``` or higher and ```make```. ``` git clone https://github.com/automixer/gtexporter.git cd gtexporter diff --git a/config-keys.yaml b/config-keys.yaml index ed61e15..38164b7 100644 --- a/config-keys.yaml +++ b/config-keys.yaml @@ -5,8 +5,12 @@ global: # It must satisfy the regex ^[a-zA-Z0-9_]*$ listen_address: 0.0.0.0 # Prometheus exporter listen address. Defaults to 0.0.0.0 listen_port: 9456 # Prometheus exporter listen port. Defaults to 9456 + listen_path: /metrics # Http endpoint for Prometheus scraping. scrape_interval: 1m # The scrape interval configured on Prometheus server. No less than 1 second. - + static_labels: # User defined labels/values to be added to all metrics. Can be null. + label1: value1 + label2: value2 + # etc... # These keys are shared among all device configurations and are overridden by the device section keys. device_template: diff --git a/go.mod b/go.mod index 3ccd430..943ebed 100644 --- a/go.mod +++ b/go.mod @@ -1,12 +1,12 @@ module github.com/automixer/gtexporter -go 1.22.5 +go 1.23.2 require ( github.com/golang/glog v1.2.2 github.com/openconfig/gnmi v0.11.0 github.com/openconfig/ygot v0.29.20 - github.com/prometheus/client_golang v1.19.1 + github.com/prometheus/client_golang v1.20.5 google.golang.org/grpc v1.65.0 gopkg.in/yaml.v2 v2.4.0 ) @@ -15,15 +15,17 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/google/go-cmp v0.6.0 // indirect + github.com/klauspost/compress v1.17.9 // indirect github.com/kylelemons/godebug v1.1.0 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/openconfig/goyang v1.4.5 // indirect - github.com/prometheus/client_model v0.5.0 // indirect - github.com/prometheus/common v0.48.0 // indirect - github.com/prometheus/procfs v0.12.0 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b // indirect - golang.org/x/net v0.25.0 // indirect - golang.org/x/sys v0.20.0 // indirect - golang.org/x/text v0.15.0 // indirect + golang.org/x/net v0.26.0 // indirect + golang.org/x/sys v0.22.0 // indirect + golang.org/x/text v0.16.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect - google.golang.org/protobuf v1.34.1 // indirect + google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/go.sum b/go.sum index 5cc3f80..77600d6 100644 --- a/go.sum +++ b/go.sum @@ -15,8 +15,6 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= 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/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -52,6 +50,8 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -59,6 +59,8 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/openconfig/gnmi v0.10.0/go.mod h1:Y9os75GmSkhHw2wX8sMsxfI7qRGAEcDh8NTa5a8vj6E= github.com/openconfig/gnmi v0.11.0 h1:H7pLIb/o3xObu3+x0Fv9DCK7TH3FUh7mNwbYe+34hFw= github.com/openconfig/gnmi v0.11.0/go.mod h1:9oJSQPPCpNvfMRj8e4ZoLVAw4wL8HyxXbiDlyuexCGU= @@ -72,15 +74,15 @@ github.com/openconfig/ygot v0.29.20/go.mod h1:K8HbrPm/v8/emtGQ9+RsJXx6UPKC5JzS/F github.com/pborman/getopt v1.1.0/go.mod h1:FxXoW1Re00sQG/+KIkuSqRL/LwQgSkv7uyac+STFsbk= 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/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= -github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= +github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= +github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= -github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= -github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE= -github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= -github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= -github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= +github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= +github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/protocolbuffers/txtpbfmt v0.0.0-20220608084003-fc78c767cd6a/go.mod h1:KjY0wibdYKc4DYkerHSbguaf3JeIPGhNJBp2BNiFH78= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= @@ -112,8 +114,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -130,16 +132,16 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -185,8 +187,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/pkg/core/confmgmt.go b/pkg/core/confmgmt.go index 668096d..b2f710a 100644 --- a/pkg/core/confmgmt.go +++ b/pkg/core/confmgmt.go @@ -20,6 +20,16 @@ const ( minSessionTTL = 10 * time.Minute ) +type yamlGlobalConfig struct { + InstanceName string `yaml:"instance_name"` + MetricPrefix string `yaml:"metric_prefix"` + ListenAddress string `yaml:"listen_address"` + ListenPort string `yaml:"listen_port"` + ListenPath string `yaml:"listen_path"` + ScrapeInterval string `yaml:"scrape_interval"` + StaticLabels map[string]string `yaml:"static_labels"` +} + type yamlDevConfig struct { Keys map[string]string `yaml:"devices,inline"` Plugins []string `yaml:"plugins"` @@ -27,8 +37,8 @@ type yamlDevConfig struct { } type yamlConfig struct { - Global map[string]string `yaml:"global"` - Templates yamlDevConfig `yaml:"device_template"` + Global yamlGlobalConfig `yaml:"global"` + Templates yamlDevConfig `yaml:"device_template"` Devices []yamlDevConfig } @@ -97,26 +107,35 @@ func (c *Core) parseAppConfig(yCfg *yamlConfig) error { // validateGlobalConfig validates the global configuration section in the configuration file. func (c *Core) validateGlobalConfig(yCfg *yamlConfig) error { // Global section - if yCfg.Global["instance_name"] == "" { - yCfg.Global["instance_name"] = "default" + if yCfg.Global.InstanceName == "" { + yCfg.Global.InstanceName = "default" } - if yCfg.Global["listen_address"] == "" { - yCfg.Global["listen_address"] = "0.0.0.0" + if yCfg.Global.ListenAddress == "" { + yCfg.Global.ListenAddress = "0.0.0.0" } - if yCfg.Global["listen_port"] == "" { - yCfg.Global["listen_port"] = "9456" + if yCfg.Global.ListenPort == "" { + yCfg.Global.ListenPort = "9456" } - if yCfg.Global["listen_path"] == "" { - yCfg.Global["listen_path"] = "/metrics" + if yCfg.Global.ListenPath == "" { + yCfg.Global.ListenPath = "/metrics" } rx := regexp.MustCompile("^[a-zA-Z0-9_]*$") - if !rx.MatchString(yCfg.Global["metric_prefix"]) { - return fmt.Errorf("%s is not a valid Prometheus metric name", yCfg.Global["metric_prefix"]) + if !rx.MatchString(yCfg.Global.MetricPrefix) { + return fmt.Errorf("%s is not a valid Prometheus metric name", yCfg.Global.MetricPrefix) } - sInt, _ := time.ParseDuration(yCfg.Global["scrape_interval"]) + sInt, _ := time.ParseDuration(yCfg.Global.ScrapeInterval) if sInt < minScrapeInterval { return fmt.Errorf("scrape interval must be greater than or equal to %s", minScrapeInterval) } + if yCfg.Global.StaticLabels == nil { + yCfg.Global.StaticLabels = make(map[string]string) + } else { + for k := range yCfg.Global.StaticLabels { + if !rx.MatchString(k) { + return fmt.Errorf("%s is not a valid Prometheus static_label name", k) + } + } + } return nil } @@ -137,11 +156,14 @@ func (c *Core) validateDeviceConfig(yCfg *yamlDevConfig) error { // buildExporterCfg builds the exporter configuration struct based on the provided yamlConfig object. func (c *Core) buildExporterCfg(yCfg *yamlConfig) { c.exporterCfg = exporter.Config{ - ListenAddress: yCfg.Global["listen_address"], - ListenPort: yCfg.Global["listen_port"], - ListenPath: yCfg.Global["listen_path"], - InstanceName: yCfg.Global["instance_name"], - MetricPrefix: yCfg.Global["metric_prefix"], + ListenAddress: yCfg.Global.ListenAddress, + ListenPort: yCfg.Global.ListenPort, + ListenPath: yCfg.Global.ListenPath, + InstanceName: yCfg.Global.InstanceName, + MetricPrefix: yCfg.Global.MetricPrefix, + } + for k, v := range yCfg.Global.StaticLabels { + c.exporterCfg.StaticLabels = append(c.exporterCfg.StaticLabels, exporter.StaticLabel{Key: k, Value: v}) } } @@ -175,7 +197,7 @@ func (c *Core) buildGnmiClientCfg(yCfg *yamlConfig, index int) { // Int values newDev.OverSampling, _ = strconv.ParseInt(src.Keys["oversampling"], 10, 64) // Duration values - scrapeInterval, _ := time.ParseDuration(yCfg.Global["scrape_interval"]) + scrapeInterval, _ := time.ParseDuration(yCfg.Global.ScrapeInterval) newDev.ScrapeInterval = scrapeInterval maxLife, err := time.ParseDuration(src.Keys["max_life"]) if err == nil && maxLife < minSessionTTL { @@ -220,7 +242,7 @@ func (c *Core) buildPluginCfg(yCfg *yamlConfig, index int) { newPlug.CacheData = true } // Duration values - scrapeInterval, _ := time.ParseDuration(yCfg.Global["scrape_interval"]) + scrapeInterval, _ := time.ParseDuration(yCfg.Global.ScrapeInterval) newPlug.ScrapeInterval = scrapeInterval c.plugCfg[src.Keys["name"]] = append(c.plugCfg[src.Keys["name"]], newPlug) // Plugin options diff --git a/pkg/exporter/exporter.go b/pkg/exporter/exporter.go index 3a19b54..37548b9 100644 --- a/pkg/exporter/exporter.go +++ b/pkg/exporter/exporter.go @@ -19,12 +19,18 @@ type GMetricSource interface { GetMetrics(ch chan<- GMetric) } +type StaticLabel struct { + Key string + Value string +} + type Config struct { ListenAddress string ListenPort string ListenPath string InstanceName string MetricPrefix string + StaticLabels []StaticLabel } type promExporter struct { @@ -51,6 +57,9 @@ func New(cfg Config) (*promExporter, error) { func (p *promExporter) Start() error { lAddr := p.config.ListenAddress + ":" + p.config.ListenPort if err := prometheus.Register(p); err != nil { + log.Errorf( + "cannot register Prometheus metric descriptors. " + + "please check configured static labels against plugins labels. ") return err } http.Handle(p.config.ListenPath, promhttp.Handler()) @@ -110,6 +119,9 @@ func (p *promExporter) Collect(ch chan<- prometheus.Metric) { } // Prepare labels lv := []string{p.config.InstanceName, commons.Device} + for _, slv := range p.config.StaticLabels { + lv = append(lv, slv.Value) + } lv = append(lv, getLabelValues(gMetric)...) // Send metric to Prom pMetric, err := prometheus.NewConstMetric(desc, commons.Type, commons.Value, lv...) @@ -170,6 +182,9 @@ func (p *promExporter) registerSource(src GMetricSource, metrics []GMetric) erro continue } labelKeys := []string{"instance_name", "device"} + for _, lk := range p.config.StaticLabels { + labelKeys = append(labelKeys, lk.Key) + } labelKeys = append(labelKeys, getLabelKeys(m)...) p.descriptors[fqName] = prometheus.NewDesc(fqName, commons.Help, labelKeys, nil) }