3838 disableDefaultMetrics = kingpin .Flag ("disable-default-metrics" , "Do not include default metrics." ).Default ("false" ).OverrideDefaultFromEnvar ("PG_EXPORTER_DISABLE_DEFAULT_METRICS" ).Bool ()
3939 queriesPath = kingpin .Flag ("extend.query-path" , "Path to custom queries to run." ).Default ("" ).OverrideDefaultFromEnvar ("PG_EXPORTER_EXTEND_QUERY_PATH" ).String ()
4040 onlyDumpMaps = kingpin .Flag ("dumpmaps" , "Do not run, simply dump the maps." ).Bool ()
41+ constantLabelsList = kingpin .Flag ("constantLabels" , "A list of label=value separated by comma(,)." ).Default ("" ).OverrideDefaultFromEnvar ("PG_EXPORTER_CONTANT_LABELS" ).String ()
4142)
4243
4344// Metric name parts.
@@ -484,13 +485,15 @@ func makeDescMap(pgVersion semver.Version, metricMaps map[string]map[string]Colu
484485 thisMap := make (map [string ]MetricMap )
485486
486487 // Get the constant labels
487- var constLabels []string
488+ var variableLabels []string
488489 for columnName , columnMapping := range mappings {
489490 if columnMapping .usage == LABEL {
490- constLabels = append (constLabels , columnName )
491+ variableLabels = append (variableLabels , columnName )
491492 }
492493 }
493494
495+ constLabels := newConstLabels ()
496+
494497 for columnName , columnMapping := range mappings {
495498 // Check column version compatibility for the current map
496499 // Force to discard if not compatible.
@@ -522,23 +525,23 @@ func makeDescMap(pgVersion semver.Version, metricMaps map[string]map[string]Colu
522525 case COUNTER :
523526 thisMap [columnName ] = MetricMap {
524527 vtype : prometheus .CounterValue ,
525- desc : prometheus .NewDesc (fmt .Sprintf ("%s_%s" , namespace , columnName ), columnMapping .description , constLabels , nil ),
528+ desc : prometheus .NewDesc (fmt .Sprintf ("%s_%s" , namespace , columnName ), columnMapping .description , variableLabels , constLabels ),
526529 conversion : func (in interface {}) (float64 , bool ) {
527530 return dbToFloat64 (in )
528531 },
529532 }
530533 case GAUGE :
531534 thisMap [columnName ] = MetricMap {
532535 vtype : prometheus .GaugeValue ,
533- desc : prometheus .NewDesc (fmt .Sprintf ("%s_%s" , namespace , columnName ), columnMapping .description , constLabels , nil ),
536+ desc : prometheus .NewDesc (fmt .Sprintf ("%s_%s" , namespace , columnName ), columnMapping .description , variableLabels , constLabels ),
534537 conversion : func (in interface {}) (float64 , bool ) {
535538 return dbToFloat64 (in )
536539 },
537540 }
538541 case MAPPEDMETRIC :
539542 thisMap [columnName ] = MetricMap {
540543 vtype : prometheus .GaugeValue ,
541- desc : prometheus .NewDesc (fmt .Sprintf ("%s_%s" , namespace , columnName ), columnMapping .description , constLabels , nil ),
544+ desc : prometheus .NewDesc (fmt .Sprintf ("%s_%s" , namespace , columnName ), columnMapping .description , variableLabels , constLabels ),
542545 conversion : func (in interface {}) (float64 , bool ) {
543546 text , ok := in .(string )
544547 if ! ok {
@@ -555,7 +558,7 @@ func makeDescMap(pgVersion semver.Version, metricMaps map[string]map[string]Colu
555558 case DURATION :
556559 thisMap [columnName ] = MetricMap {
557560 vtype : prometheus .GaugeValue ,
558- desc : prometheus .NewDesc (fmt .Sprintf ("%s_%s_milliseconds" , namespace , columnName ), columnMapping .description , constLabels , nil ),
561+ desc : prometheus .NewDesc (fmt .Sprintf ("%s_%s_milliseconds" , namespace , columnName ), columnMapping .description , variableLabels , constLabels ),
559562 conversion : func (in interface {}) (float64 , bool ) {
560563 var durationString string
561564 switch t := in .(type ) {
@@ -583,7 +586,7 @@ func makeDescMap(pgVersion semver.Version, metricMaps map[string]map[string]Colu
583586 }
584587 }
585588
586- metricMap [namespace ] = MetricMapNamespace {constLabels , thisMap }
589+ metricMap [namespace ] = MetricMapNamespace {variableLabels , thisMap }
587590 }
588591
589592 return metricMap
@@ -711,33 +714,38 @@ func NewExporter(dsn string, disableDefaultMetrics bool, userQueriesPath string)
711714 disableDefaultMetrics : disableDefaultMetrics ,
712715 userQueriesPath : userQueriesPath ,
713716 duration : prometheus .NewGauge (prometheus.GaugeOpts {
714- Namespace : namespace ,
715- Subsystem : exporter ,
716- Name : "last_scrape_duration_seconds" ,
717- Help : "Duration of the last scrape of metrics from PostgresSQL." ,
717+ Namespace : namespace ,
718+ Subsystem : exporter ,
719+ Name : "last_scrape_duration_seconds" ,
720+ Help : "Duration of the last scrape of metrics from PostgresSQL." ,
721+ ConstLabels : newConstLabels (),
718722 }),
719723 totalScrapes : prometheus .NewCounter (prometheus.CounterOpts {
720- Namespace : namespace ,
721- Subsystem : exporter ,
722- Name : "scrapes_total" ,
723- Help : "Total number of times PostgresSQL was scraped for metrics." ,
724+ Namespace : namespace ,
725+ Subsystem : exporter ,
726+ Name : "scrapes_total" ,
727+ Help : "Total number of times PostgresSQL was scraped for metrics." ,
728+ ConstLabels : newConstLabels (),
724729 }),
725730 error : prometheus .NewGauge (prometheus.GaugeOpts {
726- Namespace : namespace ,
727- Subsystem : exporter ,
728- Name : "last_scrape_error" ,
729- Help : "Whether the last scrape of metrics from PostgreSQL resulted in an error (1 for error, 0 for success)." ,
731+ Namespace : namespace ,
732+ Subsystem : exporter ,
733+ Name : "last_scrape_error" ,
734+ Help : "Whether the last scrape of metrics from PostgreSQL resulted in an error (1 for error, 0 for success)." ,
735+ ConstLabels : newConstLabels (),
730736 }),
731737 psqlUp : prometheus .NewGauge (prometheus.GaugeOpts {
732- Namespace : namespace ,
733- Name : "up" ,
734- Help : "Whether the last scrape of metrics from PostgreSQL was able to connect to the server (1 for yes, 0 for no)." ,
738+ Namespace : namespace ,
739+ Name : "up" ,
740+ Help : "Whether the last scrape of metrics from PostgreSQL was able to connect to the server (1 for yes, 0 for no)." ,
741+ ConstLabels : newConstLabels (),
735742 }),
736743 userQueriesError : prometheus .NewGaugeVec (prometheus.GaugeOpts {
737- Namespace : namespace ,
738- Subsystem : exporter ,
739- Name : "user_queries_load_error" ,
740- Help : "Whether the user queries file was loaded and parsed successfully (1 for error, 0 for success)." ,
744+ Namespace : namespace ,
745+ Subsystem : exporter ,
746+ Name : "user_queries_load_error" ,
747+ Help : "Whether the user queries file was loaded and parsed successfully (1 for error, 0 for success)." ,
748+ ConstLabels : newConstLabels (),
741749 }, []string {"filename" , "hashsum" }),
742750 metricMap : nil ,
743751 queryOverrides : nil ,
@@ -783,10 +791,32 @@ func (e *Exporter) Collect(ch chan<- prometheus.Metric) {
783791 e .userQueriesError .Collect (ch )
784792}
785793
794+ func newConstLabels () prometheus.Labels {
795+ if constantLabelsList == nil || * constantLabelsList == "" {
796+ return nil
797+ }
798+
799+ var constLabels = make (prometheus.Labels )
800+ parts := strings .Split (* constantLabelsList , "," )
801+ for _ , p := range parts {
802+ keyValue := strings .Split (strings .TrimSpace (p ), "=" )
803+ if len (keyValue ) != 2 {
804+ continue
805+ }
806+ key := strings .TrimSpace (keyValue [0 ])
807+ value := strings .TrimSpace (keyValue [1 ])
808+ if key == "" || value == "" {
809+ continue
810+ }
811+ constLabels [key ] = value
812+ }
813+ return constLabels
814+ }
815+
786816func newDesc (subsystem , name , help string ) * prometheus.Desc {
787817 return prometheus .NewDesc (
788818 prometheus .BuildFQName (namespace , subsystem , name ),
789- help , nil , nil ,
819+ help , nil , newConstLabels () ,
790820 )
791821}
792822
@@ -872,7 +902,7 @@ func queryNamespaceMapping(ch chan<- prometheus.Metric, db *sql.DB, namespace st
872902 } else {
873903 // Unknown metric. Report as untyped if scan to float64 works, else note an error too.
874904 metricLabel := fmt .Sprintf ("%s_%s" , namespace , columnName )
875- desc := prometheus .NewDesc (metricLabel , fmt .Sprintf ("Unknown metric from %s" , namespace ), mapping .labels , nil )
905+ desc := prometheus .NewDesc (metricLabel , fmt .Sprintf ("Unknown metric from %s" , namespace ), mapping .labels , newConstLabels () )
876906
877907 // Its not an error to fail here, since the values are
878908 // unexpected anyway.
@@ -976,7 +1006,7 @@ func (e *Exporter) checkMapVersions(ch chan<- prometheus.Metric, db *sql.DB) err
9761006
9771007 // Output the version as a special metric
9781008 versionDesc := prometheus .NewDesc (fmt .Sprintf ("%s_%s" , namespace , staticLabelName ),
979- "Version string as reported by postgres" , []string {"version" , "short_version" }, nil )
1009+ "Version string as reported by postgres" , []string {"version" , "short_version" }, newConstLabels () )
9801010
9811011 ch <- prometheus .MustNewConstMetric (versionDesc ,
9821012 prometheus .UntypedValue , 1 , versionString , semanticVersion .String ())
0 commit comments