123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- package main
- import (
- "context"
- "log/slog"
- "net/http"
- "os"
- "xugu_exporter/collector"
- _ "gitee.com/XuguDB/go-xugu-driver"
- kingpin "github.com/alecthomas/kingpin/v2"
- "github.com/go-kit/log/level"
- "github.com/prometheus/client_golang/prometheus"
- "github.com/prometheus/client_golang/prometheus/collectors"
- "github.com/prometheus/client_golang/prometheus/promhttp"
- "github.com/prometheus/common/promlog"
- "github.com/prometheus/common/promlog/flag"
- "github.com/prometheus/common/version"
- "github.com/prometheus/exporter-toolkit/web"
- webflag "github.com/prometheus/exporter-toolkit/web/kingpinflag"
-
-
- )
- var (
-
- Version = "0.0.1.dev"
-
-
- metricPath = kingpin.Flag("web.telemetry-path", "Path under which to expose metrics. (env: TELEMETRY_PATH)").Default(getEnv("TELEMETRY_PATH", "/metrics")).String()
-
- dsn = kingpin.Flag("database.dsn",
- "Connection string to a data source. (env: DATA_SOURCE_NAME)",
- ).Default(getEnv("DATA_SOURCE_NAME", "")).String()
-
- dsnFile = kingpin.Flag("database.dsnFile",
- "File to read a string to a data source from. (env: DATA_SOURCE_NAME_FILE)",
- ).Default(getEnv("DATA_SOURCE_NAME_FILE", "")).String()
-
- defaultFileMetrics = kingpin.Flag(
- "default.metrics",
- "File with default metrics in a toml format. (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 format. (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() {
-
- promLogConfig := &promlog.Config{}
-
- flag.AddFlags(kingpin.CommandLine, promLogConfig)
-
- kingpin.HelpFlag.Short('\n')
-
- kingpin.Version(version.Print("xugudb_exporter"))
-
- kingpin.Parse()
-
- logger := promlog.New(promLogConfig)
-
- if dsnFile != nil && *dsnFile != "" {
- dsnFileContent, err := os.ReadFile(*dsnFile)
- if err != nil {
-
- level.Error(logger).Log("msg", "Unable to read DATA_SOURCE_NAME_FILE", "file", dsnFile, "error", err)
- os.Exit(1)
- }
-
- *dsn = string(dsnFileContent)
- }
-
- config := &collector.Config{
- DSN: *dsn,
- MaxOpenConns: *maxOpenConns,
- MaxIdleConns: *maxIdleConns,
- CustomMetrics: *customMetrics,
- QueryTimeout: *queryTimeout,
- DefaultMetricsFile: *defaultFileMetrics,
- }
-
- exporter, err := collector.NewExporter(logger, config)
- if err != nil {
-
- level.Error(logger).Log("unable to connect to DB", err)
- }
-
- if *scrapeInterval != 0 {
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
-
- go exporter.RunScheduledScrapes(ctx, *scrapeInterval)
- }
-
- prometheus.MustRegister(exporter)
-
- prometheus.MustRegister(collectors.NewBuildInfoCollector())
-
- level.Info(logger).Log("msg", "Starting xugudb_exporter", "version", version.Info())
- level.Info(logger).Log("msg", "Build context", "build", version.BuildContext())
- level.Info(logger).Log("msg", "Collect from: ", "metricPath", *metricPath)
-
- opts := promhttp.HandlerOpts{
- ErrorHandling: promhttp.ContinueOnError,
- }
-
- http.Handle(*metricPath, promhttp.HandlerFor(prometheus.DefaultGatherer, opts))
-
- http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
- w.Write([]byte("<html><head><title>xugu DB Exporter " + Version + "</title></head><body><h1>xugu DB Exporter " + Version + "</h1><p><a href='" + *metricPath + "'>Metrics</a></p></body></html>"))
- })
-
- handlerS := slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
- Level: slog.LevelInfo,
- })
-
- loggerS := slog.New(handlerS)
-
-
-
- loggerS.Info("This is an info message")
- loggerS.Warn("This is a warning message")
- loggerS.Error("This is an error message")
-
- loggerS.With("context", "example").Info("This is a context-aware info message")
-
- server := &http.Server{}
-
- if err := web.ListenAndServe(server, toolkitFlags, loggerS); err != nil {
-
- level.Error(logger).Log("msg", "Listening error", "reason", err)
- os.Exit(1)
- }
- }
- func getEnv(key, fallback string) string {
-
-
- if value, ok := os.LookupEnv(key); ok {
-
- return value
- }
-
- return fallback
- }
|