func NewProcessesCollector() (Collector, error) { var processesLabelNames = []string{"process"} return &processesCollector{ metrics: []prometheus.Collector{ prometheus.NewGaugeVec( prometheus.GaugeOpts{ Namespace: Namespace, Subsystem: processesSubsystem, Name: "memory_resident_usage_bytes", Help: "Resident memory size in bytes", }, processesLabelNames, ), prometheus.NewGaugeVec( prometheus.GaugeOpts{ Namespace: Namespace, Subsystem: processesSubsystem, Name: "cpu_usage_total_seconds", Help: "Total CPU user and system time in seconds", }, processesLabelNames, ), }, }, nil }
// NewPingCollector returns a new pingCollector func NewPingCollector(targets targets) *pingCollector { return &pingCollector{ targets: targets, metrics: pingers.Metrics{ Up: prometheus.NewGaugeVec(prometheus.GaugeOpts{ Namespace: pingers.Namespace, Name: "up", Help: "1 if url is reachable, 0 if not", }, []string{"url"}), Latency: prometheus.NewGaugeVec(prometheus.GaugeOpts{ Namespace: pingers.Namespace, Name: "latency_seconds", Help: "Latency of request for url", }, []string{"url"}), Size: prometheus.NewGaugeVec(prometheus.GaugeOpts{ Namespace: pingers.Namespace, Name: "size_bytes", Help: "Size of request for url", }, []string{"url"}), Code: prometheus.NewGaugeVec(prometheus.GaugeOpts{ Namespace: pingers.Namespace, Name: "response_code", Help: "Response code for url", }, []string{"url"}), }, } }
func NewExporter(uri string) *Exporter { return &Exporter{ URI: uri, up: prometheus.NewDesc( prometheus.BuildFQName(namespace, "", "up"), "Could the apache server be reached", nil, nil), scrapeFailures: prometheus.NewCounter(prometheus.CounterOpts{ Namespace: namespace, Name: "exporter_scrape_failures_total", Help: "Number of errors while scraping apache.", }), accessesTotal: prometheus.NewDesc( prometheus.BuildFQName(namespace, "", "accesses_total"), "Current total apache accesses", nil, nil), kBytesTotal: prometheus.NewDesc( prometheus.BuildFQName(namespace, "", "sent_kilobytes_total"), "Current total kbytes sent", nil, nil), uptime: prometheus.NewDesc( prometheus.BuildFQName(namespace, "", "uptime_seconds_total"), "Current uptime in seconds", nil, nil), workers: prometheus.NewGaugeVec(prometheus.GaugeOpts{ Namespace: namespace, Name: "workers", Help: "Apache worker statuses", }, []string{"state"}, ), scoreboard: prometheus.NewGaugeVec(prometheus.GaugeOpts{ Namespace: namespace, Name: "scoreboard", Help: "Apache scoreboard statuses", }, []string{"state"}, ), connections: prometheus.NewGaugeVec(prometheus.GaugeOpts{ Namespace: namespace, Name: "connections", Help: "Apache connection statuses", }, []string{"state"}, ), client: &http.Client{ Transport: &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: *insecure}, }, }, } }
// Takes a prometheus registry and returns a new Collector exposing // network device filesystems. func NewFilesystemCollector() (Collector, error) { var filesystemLabelNames = []string{"device", "mountpoint", "fstype"} return &filesystemCollector{ ignoredMountPointsPattern: regexp.MustCompile(*ignoredMountPoints), size: prometheus.NewGaugeVec( prometheus.GaugeOpts{ Namespace: Namespace, Subsystem: filesystemSubsystem, Name: "size", Help: "Filesystem size in bytes.", }, filesystemLabelNames, ), free: prometheus.NewGaugeVec( prometheus.GaugeOpts{ Namespace: Namespace, Subsystem: filesystemSubsystem, Name: "free", Help: "Filesystem free space in bytes.", }, filesystemLabelNames, ), avail: prometheus.NewGaugeVec( prometheus.GaugeOpts{ Namespace: Namespace, Subsystem: filesystemSubsystem, Name: "avail", Help: "Filesystem space available to non-root users in bytes.", }, filesystemLabelNames, ), files: prometheus.NewGaugeVec( prometheus.GaugeOpts{ Namespace: Namespace, Subsystem: filesystemSubsystem, Name: "files", Help: "Filesystem total file nodes.", }, filesystemLabelNames, ), filesFree: prometheus.NewGaugeVec( prometheus.GaugeOpts{ Namespace: Namespace, Subsystem: filesystemSubsystem, Name: "files_free", Help: "Filesystem total free file nodes.", }, filesystemLabelNames, ), }, nil }
func NewRunitCollector() (Collector, error) { var ( subsystem = "service" constLabels = prometheus.Labels{"supervisor": "runit"} labelNames = []string{"service"} ) return &runitCollector{ state: prometheus.NewGaugeVec( prometheus.GaugeOpts{ Namespace: Namespace, Subsystem: subsystem, Name: "state", Help: "State of runit service.", ConstLabels: constLabels, }, labelNames, ), stateDesired: prometheus.NewGaugeVec( prometheus.GaugeOpts{ Namespace: Namespace, Subsystem: subsystem, Name: "desired_state", Help: "Desired state of runit service.", ConstLabels: constLabels, }, labelNames, ), stateNormal: prometheus.NewGaugeVec( prometheus.GaugeOpts{ Namespace: Namespace, Subsystem: subsystem, Name: "normal_state", Help: "Normal state of runit service.", ConstLabels: constLabels, }, labelNames, ), stateTimestamp: prometheus.NewGaugeVec( prometheus.GaugeOpts{ Namespace: Namespace, Subsystem: subsystem, Name: "state_last_change_timestamp_seconds", Help: "Unix timestamp of the last runit service state change.", ConstLabels: constLabels, }, labelNames, ), }, nil }
func newAnnotationStats() *prometheus.GaugeVec { return prometheus.NewGaugeVec(prometheus.GaugeOpts{ Name: "annotations_total", Help: "Number of annotations per tag.", }, []string{"tag"}) }
// NewExporter returns an initialized Exporter. func NewExporter(uri string) *Exporter { return &Exporter{ URI: uri, scrapeFailures: prometheus.NewCounter(prometheus.CounterOpts{ Namespace: namespace, Name: "exporter_scrape_failures_total", Help: "Number of errors while scraping nginx.", }), processedConnections: prometheus.NewCounterVec(prometheus.CounterOpts{ Namespace: namespace, Name: "connections_processed_total", Help: "Number of connections processed by nginx", }, []string{"stage"}, ), currentConnections: prometheus.NewGaugeVec(prometheus.GaugeOpts{ Namespace: namespace, Name: "connections_current", Help: "Number of connections currently processed by nginx", }, []string{"state"}, ), client: &http.Client{ Transport: &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: *insecure}, }, }, } }
func (c *netDevCollector) Update(ch chan<- prometheus.Metric) (err error) { netDev, err := getNetDevStats(c.ignoredDevicesPattern) if err != nil { return fmt.Errorf("Couldn't get netstats: %s", err) } for direction, devStats := range netDev { for dev, stats := range devStats { for t, value := range stats { key := direction + "_" + t if _, ok := c.metrics[key]; !ok { c.metrics[key] = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Namespace: Namespace, Subsystem: netDevSubsystem, Name: key, Help: fmt.Sprintf("%s %s from /proc/net/dev.", t, direction), }, []string{"device"}, ) } v, err := strconv.ParseFloat(value, 64) if err != nil { return fmt.Errorf("Invalid value %s in netstats: %s", value, err) } c.metrics[key].WithLabelValues(dev).Set(v) } } } for _, m := range c.metrics { m.Collect(ch) } return err }
func ExampleGaugeVec() { binaryVersion := flag.String("binary_version", "debug", "Version of the binary: debug, canary, production.") flag.Parse() opsQueued := prometheus.NewGaugeVec( prometheus.GaugeOpts{ Namespace: "our_company", Subsystem: "blob_storage", Name: "ops_queued", Help: "Number of blob storage operations waiting to be processed, partitioned by user and type.", ConstLabels: prometheus.Labels{"binary_version": *binaryVersion}, }, []string{ // Which user has requested the operation? "user", // Of what type is the operation? "type", }, ) prometheus.MustRegister(opsQueued) // Increase a value using compact (but order-sensitive!) WithLabelValues(). opsQueued.WithLabelValues("bob", "put").Add(4) // Increase a value with a map using WithLabels. More verbose, but order // doesn't matter anymore. opsQueued.With(prometheus.Labels{"type": "delete", "user": "******"}).Inc() }
func registerMetrics() (err error) { items, err := muninList() if err != nil { return } for _, name := range items { graphs = append(graphs, name) configs, graphConfig, err := muninConfig(name) if err != nil { return err } for metric, config := range configs { metricName := name + "-" + metric desc := graphConfig["graph_title"] + ": " + config["label"] if config["info"] != "" { desc = desc + ", " + config["info"] } gv := prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: metricName, Help: desc, }, []string{"hostname"}, ) log.Printf("Registered %s: %s", metricName, desc) gaugePerMetric[metricName] = gv prometheus.Register(gv) } } return nil }
func (c *gmondCollector) setMetric(name, cluster string, metric ganglia.Metric) { if _, ok := c.metrics[name]; !ok { var desc string var title string for _, element := range metric.ExtraData.ExtraElements { switch element.Name { case "DESC": desc = element.Val case "TITLE": title = element.Val } if title != "" && desc != "" { break } } log.Debugf("Register %s: %s", name, desc) c.metrics[name] = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Namespace: gangliaNamespace, Name: name, Help: desc, }, []string{"cluster"}, ) } log.Debugf("Set %s{cluster=%q}: %f", name, cluster, metric.Value) c.metrics[name].WithLabelValues(cluster).Set(metric.Value) }
func (n *Namespace) NewLabeledGauge(name, help string, unit Unit, labels ...string) LabeledGauge { g := &labeledGauge{ pg: prometheus.NewGaugeVec(n.newGaugeOpts(name, help, unit), labels), } n.addMetric(g) return g }
func (e *exporter) setMetric(name string, labels map[string]string, metric Metric) { debug("%s{%s} = %f", name, labels, metric.Value) e.Lock() defer e.Unlock() if _, ok := e.Metrics[name]; !ok { var desc string var title string for _, element := range metric.ExtraData.ExtraElements { switch element.Name { case "DESC": desc = element.Val case "TITLE": title = element.Val } if title != "" && desc != "" { break } } debug("New metric: %s (%s)", name, desc) gv := prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: name, Help: desc, }, prometheusLabels, ) e.Metrics[name] = gv prometheus.Register(gv) // One GaugeVec per metric! } e.Metrics[name].With(labels).Set(metric.Value) }
func New(configFile string) (e exporter, err error) { e = exporter{ configFile: configFile, Metrics: map[string]*prometheus.GaugeVec{}, scrapeDuration: prometheus.NewSummaryVec( prometheus.SummaryOpts{ Namespace: namespace, Name: "scrape_duration_seconds", Help: "gmond_exporter: Duration of a scrape job.", }, []string{"endpoint", "result"}, ), metricsUpdated: prometheus.NewGaugeVec( prometheus.GaugeOpts{ Namespace: namespace, Name: "metrics_updated_count", Help: "gmond_exporter: Number of metrics updated.", }, []string{"endpoint"}, ), metricsExported: prometheus.NewGauge(prometheus.GaugeOpts{ Namespace: namespace, Name: "metrics_exported_count", Help: "gmond_exporter: Number of metrics exported.", }), configChan: make(chan config), listeningAddress: ":8080", gangliaScrapeInterval: 60 * time.Second, } conf, err := e.readConfig() if err != nil { return e, fmt.Errorf("Couldn't read config: %s", err) } e.conf = conf if conf.ListeningAddress != "" { e.listeningAddress = conf.ListeningAddress } if conf.GangliaScrapeInterval != 0 { e.gangliaScrapeInterval = time.Duration(conf.GangliaScrapeInterval) * time.Second } prometheus.MustRegister(e.scrapeDuration) prometheus.MustRegister(e.metricsUpdated) prometheus.MustRegister(e.metricsExported) debug("Registered internal metrics") sig := make(chan os.Signal, 1) signal.Notify(sig, syscall.SIGHUP) go func() { for _ = range sig { e.reloadConfig() // sends a new config to configChan } }() go e.serveStatus() return e, nil }
func gauge(subsystem, name, help string, labels ...string) *prometheus.GaugeVec { return prometheus.NewGaugeVec(prometheus.GaugeOpts{ Namespace: "mesos", Subsystem: subsystem, Name: name, Help: help, }, labels) }
// NewGauge returns a new Gauge backed by a Prometheus metric. The gauge is // automatically registered via prometheus.Register. func NewGauge(opts prometheus.GaugeOpts, fieldKeys []string) metrics.Gauge { m := prometheus.NewGaugeVec(opts, fieldKeys) prometheus.MustRegister(m) return prometheusGauge{ GaugeVec: m, Pairs: pairsFrom(fieldKeys), } }
// NewExporter returns an initialized exporter func NewExporter(server string) *Exporter { return &Exporter{ mc: memcache.New(server), up: prometheus.NewGauge( prometheus.GaugeOpts{ Name: "up", Namespace: namespace, Help: "Are the servers up.", ConstLabels: prometheus.Labels{"server": server}, }, ), uptime: prometheus.NewCounter( prometheus.CounterOpts{ Name: "uptime", Namespace: namespace, Help: "The uptime of the server.", ConstLabels: prometheus.Labels{"server": server}, }, ), cache: prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "cache", Namespace: namespace, Help: "The cache hits/misses broken down by command (get, set, etc.).", ConstLabels: prometheus.Labels{"server": server}, }, []string{"command", "status"}, ), usage: prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "usage", Namespace: namespace, Help: "Details the resource usage (items/connections) of the server, by time (current/total).", ConstLabels: prometheus.Labels{"server": server}, }, []string{"time", "resource"}, ), bytes: prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "bytes", Namespace: namespace, Help: "The bytes sent/received by the server.", ConstLabels: prometheus.Labels{"server": server}, }, []string{"direction"}, ), removals: prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "removal", Namespace: namespace, Help: "Number of items that have been evicted/expired (status), and if the were fetched ever or not.", ConstLabels: prometheus.Labels{"server": server}, }, []string{"status", "fetched"}, ), } }
func (p *prometheusExport) Prepare() { p.ProbeIsUp = prometheus.NewGaugeVec(prometheus.GaugeOpts{ Namespace: *prometheusProbeNameSpace, Name: "up", Help: "Indicates success/failure of the probe. Value of 1 is a success while 0 is a failure. Value of -1 could be because of probe timeout/error.", }, labels) p.ProbeLatency = prometheus.NewGaugeVec(prometheus.GaugeOpts{ Namespace: *prometheusProbeNameSpace, Name: "latency", Help: "The probe latency in milliseconds. Value of -1 could be because of probe timeout/error.", }, labels) p.ProbePayloadSize = prometheus.NewGaugeVec(prometheus.GaugeOpts{ Namespace: *prometheusProbeNameSpace, Name: "payload_size", Help: "The probe response payload size in bytes. Value of -1 could be because of probe timeout/error.", }, labels) p.ProbeErrorCount = prometheus.NewCounterVec(prometheus.CounterOpts{ Namespace: *prometheusProbeNameSpace, Name: "failure_count", Help: "The probe error count.", }, labels) p.ProbeTimeoutCount = prometheus.NewCounterVec(prometheus.CounterOpts{ Namespace: *prometheusProbeNameSpace, Name: "timeout_count", Help: "The probe timeout count.", }, labels) p.ProbeCount = prometheus.NewCounterVec(prometheus.CounterOpts{ Namespace: *prometheusProbeNameSpace, Name: "count", Help: "Total Probe count.", }, labels) prometheus.MustRegister(p.ProbeCount) prometheus.MustRegister(p.ProbeErrorCount) prometheus.MustRegister(p.ProbeTimeoutCount) prometheus.MustRegister(p.ProbeLatency) prometheus.MustRegister(p.ProbeIsUp) prometheus.MustRegister(p.ProbePayloadSize) }
func initPrometheusMetrics() { TotalClientCounter = stat.NewGauge(stat.GaugeOpts{ Name: "total_clients", Help: "Total number of connected clients", }) TotalNodes = stat.NewGauge(stat.GaugeOpts{ Name: "meshnodes_total", Help: "Total number of Nodes", }) TotalNodeTrafficRx = stat.NewCounter(stat.CounterOpts{ Name: "total_traffic_rx", Help: "Total accumulated received traffic as reported by Nodes", }) TotalNodeTrafficTx = stat.NewCounter(stat.CounterOpts{ Name: "total_traffic_tx", Help: "Total accumulated transmitted traffic as reported by Nodes", }) TotalNodeMgmtTrafficRx = stat.NewCounter(stat.CounterOpts{ Name: "total_traffic_mgmt_rx", Help: "Total accumulated received management traffic as reported by Nodes", }) TotalNodeMgmtTrafficTx = stat.NewCounter(stat.CounterOpts{ Name: "total_traffic_mgmt_tx", Help: "Total accumulated transmitted management traffic as reported by Nodes", }) OnlineNodes = stat.NewGauge(stat.GaugeOpts{ Name: "meshnodes_online_total", Help: "All online nodes", }) NodesTrafficRx = stat.NewCounterVec(stat.CounterOpts{ Name: "meshnode_traffic_rx", Help: "Transmitted traffic from nodes", }, append(nodeLabels, "type")) NodesTrafficTx = stat.NewCounterVec(stat.CounterOpts{ Name: "meshnode_traffic_tx", Help: "Received traffic on nodes", }, append(nodeLabels, "type")) NodesUptime = stat.NewCounterVec(stat.CounterOpts{ Name: "meshnode_uptime", Help: "Uptime of meshnodes", }, nodeLabels) NodesClients = stat.NewGaugeVec(stat.GaugeOpts{ Name: "meshnode_clients", Help: "Clients on single meshnodes", }, nodeLabels) }
func (e *Exporter) initGauges() { e.metrics = map[string]*prometheus.GaugeVec{} e.metrics["db_keys_total"] = prometheus.NewGaugeVec(prometheus.GaugeOpts{ Namespace: e.namespace, Name: "db_keys_total", Help: "Total number of keys by DB", }, []string{"addr", "db"}) e.metrics["db_expiring_keys_total"] = prometheus.NewGaugeVec(prometheus.GaugeOpts{ Namespace: e.namespace, Name: "db_expiring_keys_total", Help: "Total number of expiring keys by DB", }, []string{"addr", "db"}) e.metrics["db_avg_ttl_seconds"] = prometheus.NewGaugeVec(prometheus.GaugeOpts{ Namespace: e.namespace, Name: "db_avg_ttl_seconds", Help: "Avg TTL in seconds", }, []string{"addr", "db"}) }
func newQueueGaugeVec(metricName string, docString string) *prometheus.GaugeVec { return prometheus.NewGaugeVec( prometheus.GaugeOpts{ Namespace: namespace, Name: "queue_" + metricName, Help: docString, }, queueLabelNames, ) }
func NewTableMetrics(tableNames []string) *TableMetrics { namesMap := make(map[string]struct{}) for _, name := range tableNames { namesMap[name] = struct{}{} } metrics := map[string]*prometheus.GaugeVec{ "table_cache_hit_ratio": prometheus.NewGaugeVec(prometheus.GaugeOpts{ Namespace: namespace, Subsystem: "tables", Name: "cache_hit_ratio_percent", Help: "Table cache hit ratio", }, []string{"table"}), "table_items_count": prometheus.NewGaugeVec(prometheus.GaugeOpts{ Namespace: namespace, Subsystem: "tables", Name: "items_count_total", Help: "Table items count", }, []string{"table"}), "table_size": prometheus.NewGaugeVec(prometheus.GaugeOpts{ Namespace: namespace, Subsystem: "tables", Name: "size_bytes", Help: "Total table size including indexes", }, []string{"table"}), } for name, metric := range tableMetrics { metrics[name] = prometheus.NewGaugeVec(prometheus.GaugeOpts{ Namespace: namespace, Subsystem: "tables", Name: metric.Name, Help: metric.Help, }, []string{"table"}) } return &TableMetrics{ names: tableNames, namesMap: namesMap, metrics: metrics, } }
// NewBondingCollector returns a newly allocated bondingCollector. // It exposes the number of configured and active slave of linux bonding interfaces. func NewBondingCollector() (Collector, error) { return &bondingCollector{ slaves: prometheus.NewGaugeVec( prometheus.GaugeOpts{ Namespace: Namespace, Name: "net_bonding_slaves", Help: "Number of configured slaves per bonding interface.", }, []string{"master"}, ), active: prometheus.NewGaugeVec( prometheus.GaugeOpts{ Namespace: Namespace, Name: "net_bonding_slaves_active", Help: "Number of active slaves per bonding interface.", }, []string{"master"}, ), }, nil }
func newServerMetric(metricName string, docString string, constLabels prometheus.Labels) *prometheus.GaugeVec { return prometheus.NewGaugeVec( prometheus.GaugeOpts{ Namespace: namespace, Name: "server_" + metricName, Help: docString, ConstLabels: constLabels, }, serverLabelNames, ) }
func newBackendMetric(metricName string, docString string, constLabels prometheus.Labels) *prometheus.GaugeVec { return prometheus.NewGaugeVec( prometheus.GaugeOpts{ Namespace: namespace, Name: "backend_" + metricName, Help: docString, ConstLabels: constLabels, }, backendLabelNames, ) }
// Takes a prometheus registry and returns a new Collector exposing // RAID status through megacli. func NewMegaCliCollector() (Collector, error) { return &megaCliCollector{ cli: *megacliCommand, driveTemperature: prometheus.NewGaugeVec(prometheus.GaugeOpts{ Namespace: Namespace, Name: "megacli_drive_temperature_celsius", Help: "megacli: drive temperature", }, []string{"enclosure", "slot"}), driveCounters: prometheus.NewCounterVec(prometheus.CounterOpts{ Namespace: Namespace, Name: "megacli_drive_count", Help: "megacli: drive error and event counters", }, []string{"enclosure", "slot", "type"}), drivePresence: prometheus.NewGaugeVec(prometheus.GaugeOpts{ Namespace: Namespace, Name: "megacli_adapter_disk_presence", Help: "megacli: disk presence per adapter", }, []string{"type"}), }, nil }
func newMetrics(name string, help string, constLabels prometheus.Labels, labels []string) *prometheus.GaugeVec { return prometheus.NewGaugeVec( prometheus.GaugeOpts{ Namespace: namespace, Name: name, Help: help, ConstLabels: constLabels, }, labels, ) }
// Periodically queries a Mesos master to check for new slaves. func (e *masterPoller) run() { knownSlaves := make(map[string]struct{}) erroredSlaves := make(map[string]struct{}) e.frameworkResources = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Help: "Resources assigned to a framework", Name: "resources", Namespace: "mesos", Subsystem: "framework", }, []string{"name", "resource", "type"}) prometheus.MustRegister(e.frameworkResources) e.slaveResources = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Help: "Resources advertised by a slave", Name: "resources", Namespace: "mesos", Subsystem: "slave", }, []string{"pid", "resource"}) prometheus.MustRegister(e.slaveResources) e.tasksCounterVec = prometheus.NewCounterVec( prometheus.CounterOpts{ Help: "Cluster-wide task metrics", Name: "tasks", Namespace: "mesos", }, []string{"status"}) prometheus.MustRegister(e.tasksCounterVec) e.poll(knownSlaves, erroredSlaves) t := time.Tick(e.config.MesosMasterQueryInterval) for _ = range t { e.poll(knownSlaves, erroredSlaves) } }
func init() { buildInfo := prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "goproject_build_info", Help: "A metric with a constant '1' value labeled by version, revision, and branch from which goproject was built.", }, []string{"version", "revision", "branch"}, ) buildInfo.WithLabelValues(Version, Revision, Branch).Set(1) prometheus.MustRegister(buildInfo) }
// NewTCPStatCollector takes a returns // a new Collector exposing network stats. func NewTCPStatCollector() (Collector, error) { return &tcpStatCollector{ metric: prometheus.NewGaugeVec( prometheus.GaugeOpts{ Namespace: Namespace, Name: "tcp_connection_states", Help: "Number of connection states.", }, []string{"state"}, ), }, nil }