From 929e27ba5e4d0aaa61a313770e4bdafd4e83259f Mon Sep 17 00:00:00 2001 From: Yannig Date: Wed, 22 Nov 2023 07:32:16 +0100 Subject: [PATCH] :construction_worker: Merge docker build + push step (#380) * :construction_worker: Merge docker build + push step * :pencil2: Fix ide warning * :bookmark: Bump to 0.5.2 * :construction_worker: Handle build with podman * :rotating_light: Fix linter warning --- .github/workflows/pull-request.yml | 14 +++----- .github/workflows/release.yml | 15 +++------ Makefile | 54 ++++++++++++++++++------------ README.md | 46 ++++++++++++------------- collector/collector.go | 31 ++++++++--------- main.go | 37 +++++++++++++++----- 6 files changed, 108 insertions(+), 89 deletions(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 739a37b9..997cdc04 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -191,6 +191,10 @@ jobs: with: ref: ${{ env.PULL_REQUEST_HEAD }} + - name: Log in to registry + if: ${{ env.FORKED == 'false' }} + run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ${{ env.REGISTRY }} -u $ --password-stdin + - name: Build image id: docker-meta env: @@ -200,16 +204,6 @@ jobs: TAG_SUFFIX=$(echo "-${{ matrix.name }}" | sed s/-ubuntu//) echo "image-id=$IMAGE_NAME" >> $GITHUB_OUTPUT echo "image-version=${VERSION}${TAG_SUFFIX}" >> $GITHUB_OUTPUT - - - name: Log in to registry - if: ${{ env.FORKED == 'false' }} - run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ${{ env.REGISTRY }} -u $ --password-stdin - - - name: Push image - if: ${{ env.FORKED == 'false' }} - env: - VERSION: "${{ needs.release.outputs.version }}" - run: | make push-${{ matrix.name }}-image - name: Format current time diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 761a89db..2e3e22db 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -131,7 +131,7 @@ jobs: - name: Checkout uses: actions/checkout@v3 - - name: Set releasw version + - name: Set release version id: version run: echo "version=${{ needs.build.outputs.version }}" >> $GITHUB_OUTPUT @@ -173,6 +173,9 @@ jobs: - name: Checkout uses: actions/checkout@v3 + - name: Log in to registry + run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ${{ env.REGISTRY }} -u $ --password-stdin + - name: Build image id: docker-meta env: @@ -182,14 +185,6 @@ jobs: TAG_SUFFIX=$(echo "-${{ matrix.name }}" | sed s/-ubuntu//) echo "image-id=$IMAGE_NAME" >> $GITHUB_OUTPUT echo "image-version=${VERSION}${TAG_SUFFIX}" >> $GITHUB_OUTPUT - - - name: Log in to registry - run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ${{ env.REGISTRY }} -u $ --password-stdin - - - name: Push image - env: - VERSION: "${{ needs.release.outputs.version }}" - run: | make push-${{ matrix.name }}-image - name: Setup cosign @@ -210,7 +205,7 @@ jobs: run: make sign-${{ matrix.name }}-image - name: Container scan - uses: aquasecurity/trivy-action@0.8.0 + uses: aquasecurity/trivy-action@0.14.0 env: image-ref: "${{ steps.docker-meta.outputs.image-id }}:${{ steps.docker-meta.outputs.image-version }}" with: diff --git a/Makefile b/Makefile index 8911d38d..6e4ebec3 100644 --- a/Makefile +++ b/Makefile @@ -3,12 +3,20 @@ OS_TYPE ?= $(shell uname -s | tr '[:upper:]' '[:lower:]') ARCH_TYPE ?= $(subst x86_64,amd64,$(patsubst i%86,386,$(ARCH))) GOOS ?= $(shell go env GOOS) GOARCH ?= $(shell go env GOARCH) -VERSION ?= 0.5.1 +VERSION ?= 0.5.2 LDFLAGS := -X main.Version=$(VERSION) GOFLAGS := -ldflags "$(LDFLAGS) -s -w" BUILD_ARGS = --build-arg VERSION=$(VERSION) LEGACY_TABLESPACE = --build-arg LEGACY_TABLESPACE=.legacy-tablespace OUTDIR = ./dist +LINTER_VERSION ?= v1.55.2 +LINTER_IMAGE ?= docker.io/golangci/golangci-lint:$(LINTER_VERSION) + +ifeq ($(shell command -v podman 2> /dev/null),) + DOCKER_CMD = docker +else + DOCKER_CMD = podman +endif IMAGE_NAME ?= iamseth/oracledb_exporter IMAGE_ID ?= $(IMAGE_NAME):$(VERSION) @@ -64,7 +72,9 @@ go-build-windows-x86: go-lint: @echo "Linting codebase" - docker run --rm -v $(shell pwd):/app -v ~/.cache/golangci-lint/v1.50.1:/root/.cache -w /app golangci/golangci-lint:v1.50.1 golangci-lint run -v + mkdir -p ~/.cache/golangci-lint/$(LINTER_VERSION) + $(DOCKER_CMD) run --rm -v $$PWD:/app -v ~/.cache/golangci-lint/$(LINTER_VERSION):/root/.cache -w /app \ + $(LINTER_IMAGE) golangci-lint run -v local-build: go-build @true @@ -90,19 +100,19 @@ push-images: @make --no-print-directory push-alpine-image oraclelinux-image: - if DOCKER_CLI_EXPERIMENTAL=enabled docker manifest inspect "$(IMAGE_ID)-oraclelinux" > /dev/null; then \ + if DOCKER_CLI_EXPERIMENTAL=enabled $(DOCKER_CMD) manifest inspect "$(IMAGE_ID)-oraclelinux" > /dev/null; then \ echo "Image \"$(IMAGE_ID)-oraclelinux\" already exists on ghcr.io"; \ else \ - docker build --progress=plain $(BUILD_ARGS) -t "$(IMAGE_ID)-oraclelinux" --build-arg BASE_IMAGE=$(ORACLE_LINUX_BASE_IMAGE) . && \ - docker build --progress=plain $(BUILD_ARGS) $(LEGACY_TABLESPACE) -t "$(IMAGE_ID)-oraclelinux_legacy-tablespace" --build-arg BASE_IMAGE=$(ORACLE_LINUX_BASE_IMAGE) . && \ - docker tag "$(IMAGE_ID)-oraclelinux" "$(IMAGE_NAME):oraclelinux"; \ + $(DOCKER_CMD) build --progress=plain $(BUILD_ARGS) -t "$(IMAGE_ID)-oraclelinux" --build-arg BASE_IMAGE=$(ORACLE_LINUX_BASE_IMAGE) . && \ + $(DOCKER_CMD) build --progress=plain $(BUILD_ARGS) $(LEGACY_TABLESPACE) -t "$(IMAGE_ID)-oraclelinux_legacy-tablespace" --build-arg BASE_IMAGE=$(ORACLE_LINUX_BASE_IMAGE) . && \ + $(DOCKER_CMD) tag "$(IMAGE_ID)-oraclelinux" "$(IMAGE_NAME):oraclelinux"; \ fi push-oraclelinux-image: - docker push $(IMAGE_ID)-oraclelinux + $(DOCKER_CMD) push $(IMAGE_ID)-oraclelinux ifeq ("$(RELEASE)", "true") - docker push "$(IMAGE_NAME):oraclelinux" - docker push "$(IMAGE_ID)-oraclelinux_legacy-tablespace" + $(DOCKER_CMD) push "$(IMAGE_NAME):oraclelinux" + $(DOCKER_CMD) push "$(IMAGE_ID)-oraclelinux_legacy-tablespace" endif sign-oraclelinux-image: @@ -113,19 +123,19 @@ else endif ubuntu-image: - if DOCKER_CLI_EXPERIMENTAL=enabled docker manifest inspect "$(IMAGE_ID)" > /dev/null; then \ + if DOCKER_CLI_EXPERIMENTAL=enabled $(DOCKER_CMD) manifest inspect "$(IMAGE_ID)" > /dev/null; then \ echo "Image \"$(IMAGE_ID)\" already exists on ghcr.io"; \ else \ - docker build --progress=plain $(BUILD_ARGS) --build-arg BASE_IMAGE=$(UBUNTU_BASE_IMAGE) -t "$(IMAGE_ID)" . && \ - docker build --progress=plain $(BUILD_ARGS) --build-arg BASE_IMAGE=$(UBUNTU_BASE_IMAGE) $(LEGACY_TABLESPACE) -t "$(IMAGE_ID)_legacy-tablespace" . && \ - docker tag "$(IMAGE_ID)" "$(IMAGE_ID_LATEST)"; \ + $(DOCKER_CMD) build --progress=plain $(BUILD_ARGS) --build-arg BASE_IMAGE=$(UBUNTU_BASE_IMAGE) -t "$(IMAGE_ID)" . && \ + $(DOCKER_CMD) build --progress=plain $(BUILD_ARGS) --build-arg BASE_IMAGE=$(UBUNTU_BASE_IMAGE) $(LEGACY_TABLESPACE) -t "$(IMAGE_ID)_legacy-tablespace" . && \ + $(DOCKER_CMD) tag "$(IMAGE_ID)" "$(IMAGE_ID_LATEST)"; \ fi push-ubuntu-image: - docker push $(IMAGE_ID) + $(DOCKER_CMD) push $(IMAGE_ID) ifeq ("$(RELEASE)", "true") - docker push "$(IMAGE_ID_LATEST)" - docker push "$(IMAGE_ID)_legacy-tablespace" + $(DOCKER_CMD) push "$(IMAGE_ID_LATEST)" + $(DOCKER_CMD) push "$(IMAGE_ID)_legacy-tablespace" endif sign-ubuntu-image: @@ -137,18 +147,18 @@ else endif alpine-image: - if DOCKER_CLI_EXPERIMENTAL=enabled docker manifest inspect "$(IMAGE_ID)-alpine" > /dev/null; then \ + if DOCKER_CLI_EXPERIMENTAL=enabled $(DOCKER_CMD) manifest inspect "$(IMAGE_ID)-alpine" > /dev/null; then \ echo "Image \"$(IMAGE_ID)-alpine\" already exists on ghcr.io"; \ else \ - docker build --progress=plain $(BUILD_ARGS) -t "$(IMAGE_ID)-alpine" --build-arg BASE_IMAGE=$(ALPINE_BASE_IMAGE) . && \ - docker build --progress=plain $(BUILD_ARGS) $(LEGACY_TABLESPACE) --build-arg BASE_IMAGE=$(ALPINE_BASE_IMAGE) -t "$(IMAGE_ID)-alpine_legacy-tablespace" . && \ - docker tag "$(IMAGE_ID)-alpine" "$(IMAGE_NAME):alpine"; \ + $(DOCKER_CMD) build --progress=plain $(BUILD_ARGS) -t "$(IMAGE_ID)-alpine" --build-arg BASE_IMAGE=$(ALPINE_BASE_IMAGE) . && \ + $(DOCKER_CMD) build --progress=plain $(BUILD_ARGS) $(LEGACY_TABLESPACE) --build-arg BASE_IMAGE=$(ALPINE_BASE_IMAGE) -t "$(IMAGE_ID)-alpine_legacy-tablespace" . && \ + $(DOCKER_CMD) tag "$(IMAGE_ID)-alpine" "$(IMAGE_NAME):alpine"; \ fi push-alpine-image: - docker push $(IMAGE_ID)-alpine + $(DOCKER_CMD) push $(IMAGE_ID)-alpine ifeq ("$(RELEASE)", "true") - docker push "$(IMAGE_NAME):alpine" + $(DOCKER_CMD) push "$(IMAGE_NAME):alpine" endif sign-alpine-image: diff --git a/README.md b/README.md index 1316b40d..f66deff0 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ [Troubleshooting](#troubleshooting) [Operating principles](operating-principles.md) -# Description +## Description A [Prometheus](https://prometheus.io/) exporter for Oracle modeled after the MySQL exporter. I'm not a DBA or seasoned Go developer so PRs definitely welcomed. @@ -45,11 +45,11 @@ The following metrics are exposed currently. - oracledb_resource_current_utilization - oracledb_resource_limit_value -# Installation +## Installation -## Docker +### Docker / Podman -You can run via Docker using an existing image. Since version 0.4, the images are available on the github registry. +You can run via Docker/Podman using an existing image. Since version 0.4, the images are available on the github registry. Here an example to retrieve the version 0.5.0: @@ -94,14 +94,14 @@ Manager. See https://github.com/iamseth/oracledb_exporter/issues/153 for details. The versions above should have a more useful tablespace utilization calculation going forward. -## Binary Release +### Binary Release Pre-compiled versions for Linux 64 bit and Mac OSX 64 bit can be found under [releases](https://github.com/iamseth/oracledb_exporter/releases). In order to run, you'll need the [Oracle Instant Client Basic](http://www.oracle.com/technetwork/database/features/instant-client/index-097480.html) for your operating system. Only the basic version is required for execution. -## Running +#### Running Ensure that the environment variable DATA_SOURCE_NAME is set correctly before starting. DATA_SOURCE_NAME should be in Oracle Database connection string format: @@ -154,7 +154,7 @@ v$session v$resource_limit ``` -# Integration with System D +#### Integration with System D Create `oracledb_exporter` user with disabled login and `oracledb_exporter` group then run the following commands: @@ -222,12 +222,12 @@ Usage of oracledb_exporter: Path to configuration file that can enable TLS or authentication. ``` -# Default metrics +## Default metrics This exporter comes with a set of default metrics defined in **default-metrics.toml**. You can modify this file or provide a different one using `default.metrics` option. -# Custom metrics +### Custom metrics > NOTE: Do not put a `;` at the end of your SQL queries as this will **NOT** work. @@ -331,7 +331,7 @@ COPY custom-metrics.toml / ENTRYPOINT ["/oracledb_exporter", "--custom.metrics", "/custom-metrics.toml"] ``` -# Using a multiple host data source name +## Using a multiple host data source name > NOTE: This has been tested with v0.2.6a and will most probably work on versions above. @@ -369,7 +369,7 @@ database = - `TNS_ADMIN`: Path you choose for the tns admin folder (`/path/to/tns_admin` in the example file above) - `DATA_SOURCE_NAME`: Datasource pointing to the `TNS_ENTRY` (`user:password@database` in the example file above) -# TLS connection to database +## TLS connection to database First, set the following variables: @@ -400,13 +400,13 @@ Here a complete example of string connection: For more details, have a look at the following location: https://github.com/iamseth/oracledb_exporter/issues/84 -# Integration with Grafana +## Integration with Grafana An example Grafana dashboard is available [here](https://grafana.com/grafana/dashboards/3333-oracledb/). -# Build +## Build -## Docker build +### Docker/Podman build To build Ubuntu and Alpine image, run the following command: @@ -420,7 +420,7 @@ Or Alpine: make alpine-image -## Building Binaries +### Building Binaries Run build: @@ -472,9 +472,9 @@ Here is a small snippet of an example usage of the exporter in code: ``` -# FAQ/Troubleshooting +## FAQ/Troubleshooting -## Unable to convert current value to float (metric=par,metri...in.go:285 +### Unable to convert current value to float (metric=par,metri...in.go:285 Oracle is trying to send a value that we cannot convert to float. This could be anything like 'UNLIMITED' or 'UNDEFINED' or 'WHATEVER'. @@ -492,11 +492,11 @@ If the value of limite_value is 'UNLIMITED', the request send back the value -1. You can increase the log level (`--log.level debug`) in order to get the statement generating this error. -## error while loading shared libraries: libclntsh.so.xx.x: cannot open shared object file: No such file or directory +### error while loading shared libraries: libclntsh.so.xx.x: cannot open shared object file: No such file or directory Version before 0.5 use libs from Oracle in order to connect to Oracle Database. After 0.5 release, the oracle exporter use an pure Go DB driver and don't need binaries from Oracle anymore. -Please switch to version 0.5. +**Please switch to version 0.5.** For older version, you must install the Oracle binaries somewhere on your machine and **you must install the good version number**. If the error talk about the version 18.3, you **must** install 18.3 binary version. If it's 12.2, you **must** install 12.2. @@ -508,7 +508,7 @@ Here an example to run this exporter (to scrap metrics from system/oracle@//host `docker run -it --rm -p 9161:9161 -e DATA_SOURCE_NAME=oracle://system/oracle@//host:1521/service-or-sid iamseth/oracledb_exporter:0.2.6a` -## Error scraping for wait_time +### Error scraping for wait_time If you experience an error `Error scraping for wait_time: sql: Scan error on column index 1: converting driver.Value type string (",01") to a float64: invalid syntax source="main.go:144"` you may need to set the NLS_LANG variable. @@ -521,7 +521,7 @@ export DATA_SOURCE_NAME=system/oracle@myhost If using Docker, set the same variable using the -e flag. -## An Oracle instance generates a lot of trace files being monitored by exporter +### An Oracle instance generates a lot of trace files being monitored by exporter As being said, Oracle instance may (and probably does) generate a lot of trace files alongside its alert log file, one trace file per scraping event. The trace file contains the following lines @@ -539,7 +539,7 @@ The root cause is Oracle's reaction of quering ASM-related views without ASM use $ find $ORACLE_BASE/diag/rdbms -name '*.tr[cm]' -mtime +14 -delete ``` -## TLS and basic authentication +### TLS and basic authentication Apache Exporter supports TLS and basic authentication. This enables better control of the various HTTP endpoints. @@ -552,7 +552,7 @@ Note that the TLS and basic authentication settings affect all HTTP endpoints: /metrics for scraping, /probe for probing, and the web UI. -## Multi-target support +### Multi-target support This exporter supports the multi-target pattern. This allows running a single instance of this exporter for multiple Oracle targets. diff --git a/collector/collector.go b/collector/collector.go index 3278b167..7e41769d 100644 --- a/collector/collector.go +++ b/collector/collector.go @@ -113,7 +113,7 @@ func NewExporter(logger log.Logger, cfg *Config) (*Exporter, error) { Namespace: namespace, Subsystem: exporterName, Name: "scrape_errors_total", - Help: "Total number of times an error occured scraping a Oracle database.", + Help: "Total number of times an error occurred scraping a Oracle database.", }, []string{"collector"}), error: prometheus.NewGauge(prometheus.GaugeOpts{ Namespace: namespace, @@ -253,13 +253,13 @@ func (e *Exporter) scrape(ch chan<- prometheus.Metric) { level.Info(e.logger).Log("Reconnecting to DB") err = e.connect() if err != nil { - level.Error(e.logger).Log("Error reconnecting to DB", err) + level.Error(e.logger).Log("error reconnecting to DB", err.Error()) } } } if err = e.db.Ping(); err != nil { - level.Error(e.logger).Log("Error pinging oracle:", err) + level.Error(e.logger).Log("error pinging oracle:", err.Error()) e.up.Set(0) return } @@ -277,7 +277,7 @@ func (e *Exporter) scrape(ch chan<- prometheus.Metric) { wg.Add(1) metric := metric //https://golang.org/doc/faq#closures_and_goroutines - go func() { + f := func() { defer wg.Done() level.Debug(e.logger).Log("About to scrape metric: ") @@ -312,28 +312,29 @@ func (e *Exporter) scrape(ch chan<- prometheus.Metric) { scrapeStart := time.Now() if err = e.ScrapeMetric(e.db, ch, metric); err != nil { - level.Error(e.logger).Log("Error scraping for", metric.Context, "_", metric.MetricsDesc, time.Since(scrapeStart), ":", err.Error()) + level.Error(e.logger).Log("error scraping for", metric.Context, "_", metric.MetricsDesc, time.Since(scrapeStart), ":", err.Error()) e.scrapeErrors.WithLabelValues(metric.Context).Inc() } else { - level.Debug(e.logger).Log("Successfully scraped metric: ", metric.Context, metric.MetricsDesc, time.Since(scrapeStart)) + level.Debug(e.logger).Log("successfully scraped metric: ", metric.Context, metric.MetricsDesc, time.Since(scrapeStart)) } - }() + } + go f() } wg.Wait() } func (e *Exporter) connect() error { - level.Debug(e.logger).Log("Launching connection: ", maskDsn(e.dsn)) + level.Debug(e.logger).Log("launching connection: ", maskDsn(e.dsn)) db, err := sql.Open("oracle", e.dsn) if err != nil { - level.Error(e.logger).Log("Error while connecting to", e.dsn) + level.Error(e.logger).Log("error while connecting to", e.dsn) return err } level.Debug(e.logger).Log("set max idle connections to ", e.config.MaxIdleConns) db.SetMaxIdleConns(e.config.MaxIdleConns) level.Debug(e.logger).Log("set max open connections to ", e.config.MaxOpenConns) db.SetMaxOpenConns(e.config.MaxOpenConns) - level.Debug(e.logger).Log("Successfully connected to: ", maskDsn(e.dsn)) + level.Debug(e.logger).Log("successfully connected to: ", maskDsn(e.dsn)) e.db = db return nil } @@ -343,10 +344,10 @@ func (e *Exporter) checkIfMetricsChanged() bool { if len(_customMetrics) == 0 { continue } - level.Debug(e.logger).Log("Checking modifications in following metrics definition file:", _customMetrics) + level.Debug(e.logger).Log("checking modifications in following metrics definition file:", _customMetrics) h := sha256.New() if err := hashFile(h, _customMetrics); err != nil { - level.Error(e.logger).Log("Unable to get file hash", err) + level.Error(e.logger).Log("unable to get file hash", err.Error()) return false } // If any of files has been changed reload metrics @@ -397,7 +398,7 @@ func (e *Exporter) reloadMetrics() { // ScrapeMetric is an interface method to call scrapeGenericValues using Metric struct values func (e *Exporter) ScrapeMetric(db *sql.DB, ch chan<- prometheus.Metric, metricDefinition Metric) error { - level.Debug(e.logger).Log("Calling function ScrapeGenericValues()") + level.Debug(e.logger).Log("calling function ScrapeGenericValues()") return e.scrapeGenericValues(db, ch, metricDefinition.Context, metricDefinition.Labels, metricDefinition.MetricsDesc, metricDefinition.MetricsType, metricDefinition.MetricsBuckets, metricDefinition.FieldToAppend, metricDefinition.IgnoreZeroResult, @@ -516,8 +517,8 @@ func (e *Exporter) generatePrometheusMetrics(db *sql.DB, parse func(row map[stri defer cancel() rows, err := db.QueryContext(ctx, query) - if ctx.Err() == context.DeadlineExceeded { - return errors.New("Oracle query timed out") + if errors.Is(ctx.Err(), context.DeadlineExceeded) { + return errors.New("oracle query timed out") } if err != nil { diff --git a/main.go b/main.go index c7f56b0e..495cd3bb 100644 --- a/main.go +++ b/main.go @@ -5,7 +5,6 @@ import ( "net/http" "os" - "github.com/go-kit/log/level" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/prometheus/common/version" @@ -13,10 +12,12 @@ import ( webflag "github.com/prometheus/exporter-toolkit/web/kingpinflag" _ "github.com/sijms/go-ora/v2" - "github.com/alecthomas/kingpin/v2" + kingpin "github.com/alecthomas/kingpin/v2" "github.com/prometheus/common/promlog" "github.com/prometheus/common/promlog/flag" + "github.com/go-kit/log/level" + // Required for debugging // _ "net/http/pprof" @@ -27,13 +28,31 @@ var ( // Version will be set at build time. Version = "0.0.0.dev" metricPath = kingpin.Flag("web.telemetry-path", "Path under which to expose metrics. (env: TELEMETRY_PATH)").Default(getEnv("TELEMETRY_PATH", "/metrics")).String() - defaultFileMetrics = kingpin.Flag("default.metrics", "File with default metrics in a TOML file. (env: DEFAULT_METRICS)").Default(getEnv("DEFAULT_METRICS", "default-metrics.toml")).String() - customMetrics = kingpin.Flag("custom.metrics", "File that may contain various custom metrics in a TOML file. (env: CUSTOM_METRICS)").Default(getEnv("CUSTOM_METRICS", "")).String() - queryTimeout = kingpin.Flag("query.timeout", "Query timeout (in seconds). (env: QUERY_TIMEOUT)").Default(getEnv("QUERY_TIMEOUT", "5")).Int() - maxIdleConns = kingpin.Flag("database.maxIdleConns", "Number of maximum idle connections in the connection pool. (env: DATABASE_MAXIDLECONNS)").Default(getEnv("DATABASE_MAXIDLECONNS", "0")).Int() - maxOpenConns = kingpin.Flag("database.maxOpenConns", "Number of maximum open connections in the connection pool. (env: DATABASE_MAXOPENCONNS)").Default(getEnv("DATABASE_MAXOPENCONNS", "10")).Int() - scrapeInterval = kingpin.Flag("scrape.interval", "Interval between each scrape. Default is to scrape on collect requests").Default("0s").Duration() - toolkitFlags = webflag.AddFlags(kingpin.CommandLine, ":9161") + defaultFileMetrics = kingpin.Flag( + "default.metrics", + "File with default metrics in a TOML file. (env: DEFAULT_METRICS)", + ).Default(getEnv("DEFAULT_METRICS", "default-metrics.toml")).String() + customMetrics = kingpin.Flag( + "custom.metrics", + "File that may contain various custom metrics in a TOML file. (env: CUSTOM_METRICS)", + ).Default(getEnv("CUSTOM_METRICS", "")).String() + queryTimeout = kingpin.Flag( + "query.timeout", + "Query timeout (in seconds). (env: QUERY_TIMEOUT)", + ).Default(getEnv("QUERY_TIMEOUT", "5")).Int() + maxIdleConns = kingpin.Flag( + "database.maxIdleConns", + "Number of maximum idle connections in the connection pool. (env: DATABASE_MAXIDLECONNS)", + ).Default(getEnv("DATABASE_MAXIDLECONNS", "0")).Int() + maxOpenConns = kingpin.Flag( + "database.maxOpenConns", + "Number of maximum open connections in the connection pool. (env: DATABASE_MAXOPENCONNS)", + ).Default(getEnv("DATABASE_MAXOPENCONNS", "10")).Int() + scrapeInterval = kingpin.Flag( + "scrape.interval", + "Interval between each scrape. Default is to scrape on collect requests", + ).Default("0s").Duration() + toolkitFlags = webflag.AddFlags(kingpin.CommandLine, ":9161") ) func main() {