prometheus包

概述

普罗米修斯软件包是仪器仪表的核心。它为度量代码提供度量原语以进行监视。它还提供了Metric注册表。子包允许通过HTTP(包promhttp)公开已注册的指标,或将其推送到Pushgateway(包推送)。还有一个子包promauto,它为Metric构造函数提供自动注册。

除非另有说明,否则所有导出的函数和方法都可以安全地并发使用。

一个基本的例子

首先,给出一个非常基本的用法示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package main

import (
	"log"
	"net/http"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"
)

var (
	cpuTemp = prometheus.NewGauge(prometheus.GaugeOpts{
		Name: "cpu_temperature_celsius",
		Help: "Current temperature of the CPU.",
	})
	hdFailures = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Name: "hd_errors_total",
			Help: "Number of hard-disk errors.",
		},
		[]string{"device"},
	)
)

func init() {
	// Metrics have to be registered to be exposed:
	prometheus.MustRegister(cpuTemp)
	prometheus.MustRegister(hdFailures)
}

func main() {
	cpuTemp.Set(65.3)
	hdFailures.With(prometheus.Labels{"device":"/dev/sda"}).Inc()

	// The Handler function provides a default handler to expose metrics
	// via an HTTP server. "/metrics" is the usual endpoint for that.
	http.Handle("/metrics", promhttp.Handler())
	log.Fatal(http.ListenAndServe(":8080", nil))
}

这是一个完整的程序,可以导出两个指标,一个量规和一个计数器,后者带有标签,可以将其转换为(一维)向量。

指标

该软件包中导出的标识符的数量可能看起来有点不堪重负。但是,除了上面示例中显示的基本管道外,您仅需要了解不同的Metric类型及其向量版本即可基本使用。此外,如果您不关心何时以及如何在注册表中注册度量的精细控制,请查看promauto软件包,该软件包将有效地使您在简单情况下完全忽略注册。

在上方,您已经触摸了计数器和仪表。有两种更高级的Metric类型:“摘要”和“直方图”。可以在Prometheus docs中找到对这四种Metric类型的更详尽的描述:https://prometheus.io/docs/concepts/metric_types/

除了基本的Metric类型“量规”,“计数器”,“摘要”和“直方图”之外,Prometheus数据模型的一个非常重要的部分是沿称为标签的维度对样本进行划分,这将导致度量向量。基本类型是GaugeVec,CounterVec,SummaryVec和HistogramVec。

虽然仅基本Metric类型实现Metric接口,但Metric及其向量版本均实现了Collector接口。收集器管理许多Metric的收集,但为方便起见,Metric也可以“自行收集”。注意,Gauge,Counter,Summary和Histogram本身是接口,而GaugeVec,CounterVec,SummaryVec和HistogramVec不是接口。

要创建Metric及其向量版本的实例,您需要一个合适的…Opts结构,即GaugeOpts,CounterOpts,SummaryOpts或HistogramOpts。

自定义收集器和常量指标

尽管您可以创建自己的Metric实现,但很可能仅会自己实现Collector接口。乍一看,自定义收集器似乎很方便将Metric捆绑在一起以进行通用注册(以上述不同Metric向量的主要示例为例,该Metric捆绑了所有相同名称但具有不同标签的Metric)。

还有一个更复杂的用例:如果您已经有在Prometheus上下文之外创建的度量,则不需要各种Metric类型的接口。本质上,您希望在收集过程中将现有数字镜像到PrometheusMetric中。收集器接口的自己实现非常适合此操作。您可以使用NewConstMetric,NewConstHistogram和NewConstSummary(以及它们各自的Must…版本)“动态”创建Metric实例。 NewConstMetric用于仅以float64作为其值的所有Metric类型:Counter,Gauge和称为Untyped的特殊“类型”。如果不确定镜像指标是计数器还是量表,请使用后者。 Metric实例的创建在Collect方法中进行。 Describe方法必须返回单独的Desc实例,以代表稍后将创建的“丢弃”Metric。 NewDesc可以方便地创建这些Desc实例。或者,您可以根本不返回任何Desc,这会将收集器标记为“未选中”。在注册时不会执行任何检查,但是在刮刮时仍将确保Metric一致性,即任何不一致都会导致刮刮错误。因此,对于未经检查的收集器,不收集导致总刮除结果不一致的度量的责任在于收集器的实施者。虽然这不是理想的状态,但有时是必需的。典型的用例是在注册时无法预测要由收集器返回的确切度量的情况,但是实现者对整个系统有足够的知识以保证度量的一致性。

收集器示例说明了用例。您还可以查看processCollector(镜像流程指标),goCollector(镜像Go指标)或expvarCollector(镜像expvar指标)的源代码,作为在此包本身中使用的示例。

如果只需要调用一个函数来获取单个浮点值以作为度量收集,GaugeFunc,CounterFunc或UntypedFunc可能是有趣的快捷方式。

注册表的高级用法

虽然MustRegister是注册收集器的最常用方法,但有时您可能希望处理注册可能导致的错误。顾名思义,如果发生错误,MustRegister会出现混乱。使用Register方法,可以返回错误并可以处理。

如果注册的收集器与已注册的Metric不兼容或不一致,则返回错误。该注册表旨在根据Prometheus数据模型来确保所收集指标的一致性。理想情况下,在注册时而不是在收集时检测到不一致。通常,前者通常在程序启动时被检测到,而后者只会在抓取时发生,如果不一致仅在以后变得很重要,则可能甚至不会在第一次抓取时发生。这就是收集器和Metric必须向注册表描述自己的主要原因。

到目前为止,我们所做的一切都在所谓的默认注册表上进行,因为可以在全局DefaultRegisterer变量中找到它。使用NewRegistry,您可以创建自定义注册表,甚至可以自己实现Registerer或Gatherer接口。注册和注销方法在自定义注册表上的工作方式与默认注册表上的全局函数注册和注销的工作方式相同。

自定义注册表有多种用途:您可以使用具有特殊属性的注册表,请参阅NewPedanticRegistry。您可以避免由DefaultRegisterer施加的全局状态。您可以同时使用多个注册表,以不同的方式公开不同的指标。您可以将单独的注册表用于测试目的。

还请注意,DefaultRegisterer已注册了Go运行时Metric的收集器(通过NewGoCollector)和过程度量的收集器(通过NewProcessCollector)。使用自定义注册表,您可以控制并自行决定要注册的收集器。

HTTP解释

注册表实现了Gatherer接口。然后,Gather方法的调用者可以以某种方式公开收集的指标。通常,度量是通过/metrics端点上的HTTP提供的。在上面的示例中就是这种情况。通过HTTP公开指标的工具位于promhttp子软件包中。

推到Pushgateway

在push子包中可以找到用于推送到Pushgateway的功能。

Graphite Bridge

在Graphite Bridge子包中可以找到将度量从采集器推向Graphite的函数和示例。

通过遵循现有实现的方法,可以轻松添加更多公开指标的方法。

常量

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
const (
	// DefMaxAge is the default duration for which observations stay
	// relevant.
	DefMaxAge time.Duration = 10 * time.Minute
	// DefAgeBuckets is the default number of buckets used to calculate the
	// age of observations.
	DefAgeBuckets = 5
	// DefBufCap is the standard buffer size for collecting Summary observations.
	DefBufCap = 500
)

SummaryOpts的默认值。

1
const ExemplarMaxRunes = 64

ExemplarMaxRunes是示例标签中允许的最大符文总数。

变量

1
2
3
4
var (
	DefaultRegisterer Registerer = defaultRegistry
	DefaultGatherer   Gatherer   = defaultRegistry
)

DefaultRegisterer和DefaultGatherer是Registerer和Gatherer接口的实现,此包中的许多便捷功能都作用于该接口。最初,这两个变量都指向同一个注册表,该注册表具有一个进程收集器(当前仅在Linux上,请参阅NewProcessCollector)和一个Go收集器(请参阅NewGoCollector,尤其是有关1.9之前的Go版本的停止世界的注释)已经登记了。这种将默认实例保持为全局状态的方法反映了Go标准库中其他软件包的方法。请注意,有一些警告。仅当您了解后果后,才应谨慎更改变量。希望完全避免全局状态的用户不应使用便捷功能,而应对自定义实例进行操作。

1
2
3
var (
	DefBuckets = []float64{.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10}
)

DefBuckets是默认的直方图存储桶。定制了默认存储桶,以广泛地衡量网络服务的响应时间(以秒为单位)。但是,很可能需要您定义针对用例定制的存储桶。

func BuildFQName

1
func BuildFQName(namespace, subsystem, name string) string

BuildFQName通过“_”连接给定的三个名称组件。空名称组件将被忽略。如果name参数本身为空,则无论如何都将返回一个空字符串。该库中包含的Metric实现在内部使用此函数从其Opts中的名称组件生成完全限定的Metric名称。库的用户仅在实现自己的Metric或直接实例化Desc(使用NewDesc)时才需要此功能。

func DescribeByCollect

1
func DescribeByCollect(c Collector, descs chan<- *Desc)

DescribeByCollect是实现自定义收集器的Describe方法的助手。它从提供的收集器收集度量,并将其描述符发送到提供的通道。

如果收集器在其整个生命周期内收集相同的指标,则其Describe方法可以简单地实现为:

1
2
3
func (c customCollector) Describe(ch chan<- *Desc) {
	DescribeByCollect(c, ch)
}

但是,如果收集的指标在收集器的整个生命周期中以其描述符组合的集合也发生变化的方式动态变化,则这将不起作用。然后,快捷方式实现将违反Describe方法的约定。如果收集器有时根本不收集任何指标(例如,CounterVec,GaugeVec等向量,它们仅在访问具有完全指定的标签集的指标后才收集指标),它甚至可能注册为未经检查的收集器(参见。Registerer接口的Register方法)。因此,如果您确定要履行合同,请仅使用Describe的此快捷方式实现。

收集器示例演示了DescribeByCollect的用法。

func ExponentialBuckets

1
func ExponentialBuckets(start, factor float64, count int) []float64

ExponentialBuckets创建“计数”存储桶,其中最低存储桶的上限为“start”,随后每个存储桶的上限为“factor”乘以上一个存储桶的上限。最终的+ Inf存储桶不计算在内,也不包含在返回的切片中。返回的切片应用于HistogramOpts的Buckets字段。

如果’count’为0或负数,如果’start’为0或负数,或者’factor’小于或等于1,则函数将发生错误。

func LinearBuckets

1
func LinearBuckets(start, width float64, count int) []float64

LinearBuckets创建“计数”存储区,每个“宽度”宽,其中最低存储区的上限为“start”。最终的+ Inf存储桶不计算在内,也不包含在返回的切片中。返回的切片应用于HistogramOpts的Buckets字段。

如果“count”为零或负数,该函数将出现panic。

func MustRegister

1
func MustRegister(cs ...Collector)

MustRegister会使用DefaultRegisterer注册提供的收集器,如果发生任何错误,则会出现恐慌。

MustRegister是DefaultRegisterer.MustRegister(cs …)的快捷方式。请参阅此处以获取更多详细信息。

func Register

1
func Register(c Collector) error

Register向DefaultRegisterer注册提供的收集器。

Register是DefaultRegisterer.Register(c)的快捷方式。

例子

Code:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Imagine you have a worker pool and want to count the tasks completed.
taskCounter := prometheus.NewCounter(prometheus.CounterOpts{
	Subsystem: "worker_pool",
	Name:      "completed_tasks_total",
	Help:      "Total number of tasks completed.",
})
// This will register fine.
if err := prometheus.Register(taskCounter); err != nil {
	fmt.Println(err)
} else {
	fmt.Println("taskCounter registered.")
}
// Don't forget to tell the HTTP server about the Prometheus handler.
// (In a real program, you still need to start the HTTP server...)
http.Handle("/metrics", promhttp.Handler())

// Now you can start workers and give every one of them a pointer to
// taskCounter and let it increment it whenever it completes a task.
taskCounter.Inc() // This has to happen somewhere in the worker code.

// But wait, you want to see how individual workers perform. So you need
// a vector of counters, with one element for each worker.
taskCounterVec := prometheus.NewCounterVec(
	prometheus.CounterOpts{
		Subsystem: "worker_pool",
		Name:      "completed_tasks_total",
		Help:      "Total number of tasks completed.",
	},
	[]string{"worker_id"},
)

// Registering will fail because we already have a metric of that name.
if err := prometheus.Register(taskCounterVec); err != nil {
	fmt.Println("taskCounterVec not registered:", err)
} else {
	fmt.Println("taskCounterVec registered.")
}

// To fix, first unregister the old taskCounter.
if prometheus.Unregister(taskCounter) {
	fmt.Println("taskCounter unregistered.")
}

// Try registering taskCounterVec again.
if err := prometheus.Register(taskCounterVec); err != nil {
	fmt.Println("taskCounterVec not registered:", err)
} else {
	fmt.Println("taskCounterVec registered.")
}
// Bummer! Still doesn't work.

// Prometheus will not allow you to ever export metrics with
// inconsistent help strings or label names. After unregistering, the
// unregistered metrics will cease to show up in the /metrics HTTP
// response, but the registry still remembers that those metrics had
// been exported before. For this example, we will now choose a
// different name. (In a real program, you would obviously not export
// the obsolete metric in the first place.)
taskCounterVec = prometheus.NewCounterVec(
	prometheus.CounterOpts{
		Subsystem: "worker_pool",
		Name:      "completed_tasks_by_id",
		Help:      "Total number of tasks completed.",
	},
	[]string{"worker_id"},
)
if err := prometheus.Register(taskCounterVec); err != nil {
	fmt.Println("taskCounterVec not registered:", err)
} else {
	fmt.Println("taskCounterVec registered.")
}
// Finally it worked!

// The workers have to tell taskCounterVec their id to increment the
// right element in the metric vector.
taskCounterVec.WithLabelValues("42").Inc() // Code from worker 42.

// Each worker could also keep a reference to their own counter element
// around. Pick the counter at initialization time of the worker.
myCounter := taskCounterVec.WithLabelValues("42") // From worker 42 initialization code.
myCounter.Inc()                                   // Somewhere in the code of that worker.

// Note that something like WithLabelValues("42", "spurious arg") would
// panic (because you have provided too many label values). If you want
// to get an error instead, use GetMetricWithLabelValues(...) instead.
notMyCounter, err := taskCounterVec.GetMetricWithLabelValues("42", "spurious arg")
if err != nil {
	fmt.Println("Worker initialization failed:", err)
}
if notMyCounter == nil {
	fmt.Println("notMyCounter is nil.")
}

// A different (and somewhat tricky) approach is to use
// ConstLabels. ConstLabels are pairs of label names and label values
// that never change. Each worker creates and registers an own Counter
// instance where the only difference is in the value of the
// ConstLabels. Those Counters can all be registered because the
// different ConstLabel values guarantee that each worker will increment
// a different Counter metric.
counterOpts := prometheus.CounterOpts{
	Subsystem:   "worker_pool",
	Name:        "completed_tasks",
	Help:        "Total number of tasks completed.",
	ConstLabels: prometheus.Labels{"worker_id": "42"},
}
taskCounterForWorker42 := prometheus.NewCounter(counterOpts)
if err := prometheus.Register(taskCounterForWorker42); err != nil {
	fmt.Println("taskCounterVForWorker42 not registered:", err)
} else {
	fmt.Println("taskCounterForWorker42 registered.")
}
// Obviously, in real code, taskCounterForWorker42 would be a member
// variable of a worker struct, and the "42" would be retrieved with a
// GetId() method or something. The Counter would be created and
// registered in the initialization code of the worker.

// For the creation of the next Counter, we can recycle
// counterOpts. Just change the ConstLabels.
counterOpts.ConstLabels = prometheus.Labels{"worker_id": "2001"}
taskCounterForWorker2001 := prometheus.NewCounter(counterOpts)
if err := prometheus.Register(taskCounterForWorker2001); err != nil {
	fmt.Println("taskCounterVForWorker2001 not registered:", err)
} else {
	fmt.Println("taskCounterForWorker2001 registered.")
}

taskCounterForWorker2001.Inc()
taskCounterForWorker42.Inc()
taskCounterForWorker2001.Inc()

// Yet another approach would be to turn the workers themselves into
// Collectors and register them. See the Collector example for details.

Output:

1
2
3
4
5
6
7
8
9
taskCounter registered.
taskCounterVec not registered: a previously registered descriptor with the same fully-qualified name as Desc{fqName: "worker_pool_completed_tasks_total", help: "Total number of tasks completed.", constLabels: {}, variableLabels: [worker_id]} has different label names or a different help string
taskCounter unregistered.
taskCounterVec not registered: a previously registered descriptor with the same fully-qualified name as Desc{fqName: "worker_pool_completed_tasks_total", help: "Total number of tasks completed.", constLabels: {}, variableLabels: [worker_id]} has different label names or a different help string
taskCounterVec registered.
Worker initialization failed: inconsistent label cardinality: expected 1 label values but got 2 in []string{"42", "spurious arg"}
notMyCounter is nil.
taskCounterForWorker42 registered.
taskCounterForWorker2001 registered.

func Unregister

1
func Unregister(c Collector) bool

Unregister将从DefaultRegisterer中删除提供的收集器的注册。

Unregister是DefaultRegisterer.Unregister(c)的快捷方式。

func WriteToTextfile

1
func WriteToTextfile(filename string, g Gatherer) error

WriteToTextfile在提供的Gatherer上调用Gather,将结果编码为Prometheus文本格式,并将其写入临时文件。成功后,临时文件将重命名为提供的文件名。

这旨在与节点导出器的文本文件收集器一起使用。请注意,节点导出器期望文件名后缀为“ .prom”。

type AlreadyRegisteredError

1
2
3
type AlreadyRegisteredError struct {
	ExistingCollector, NewCollector Collector
}

如果以前已经注册了要注册的收集器,或者之前已经注册了收集相同度量的其他收集器,则Register方法将返回AlreadyRegisteredError。在这种情况下,注册失败,但是您可以从错误类型中检测出发生了什么。该错误包含现有收集器和与现有收集器相等的(被拒绝)新收集器的字段。如示例所示,这可用于查找是否已注册了相等的收集器,然后切换到使用旧的收集器。

例子

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
reqCounter := prometheus.NewCounter(prometheus.CounterOpts{
	Name: "requests_total",
	Help: "The total number of requests served.",
})
if err := prometheus.Register(reqCounter); err != nil {
	if are, ok := err.(prometheus.AlreadyRegisteredError); ok {
		// A counter for that metric has been registered before.
		// Use the old counter from now on.
		reqCounter = are.ExistingCollector.(prometheus.Counter)
	} else {
		// Something else went wrong!
		panic(err)
	}
}
reqCounter.Inc()

func (AlreadyRegisteredError) Error

1
func (err AlreadyRegisteredError) Error() string

type Collector

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
type Collector interface {
	// Describe sends the super-set of all possible descriptors of metrics
	// collected by this Collector to the provided channel and returns once
	// the last descriptor has been sent. The sent descriptors fulfill the
	// consistency and uniqueness requirements described in the Desc
	// documentation.
	//
	// It is valid if one and the same Collector sends duplicate
	// descriptors. Those duplicates are simply ignored. However, two
	// different Collectors must not send duplicate descriptors.
	//
	// Sending no descriptor at all marks the Collector as “unchecked”,
	// i.e. no checks will be performed at registration time, and the
	// Collector may yield any Metric it sees fit in its Collect method.
	//
	// This method idempotently sends the same descriptors throughout the
	// lifetime of the Collector. It may be called concurrently and
	// therefore must be implemented in a concurrency safe way.
	//
	// If a Collector encounters an error while executing this method, it
	// must send an invalid descriptor (created with NewInvalidDesc) to
	// signal the error to the registry.
	Describe(chan<- *Desc)
	// Collect is called by the Prometheus registry when collecting
	// metrics. The implementation sends each collected metric via the
	// provided channel and returns once the last metric has been sent. The
	// descriptor of each sent metric is one of those returned by Describe
	// (unless the Collector is unchecked, see above). Returned metrics that
	// share the same descriptor must differ in their variable label
	// values.
	//
	// This method may be called concurrently and must therefore be
	// implemented in a concurrency safe way. Blocking occurs at the expense
	// of total performance of rendering all registered metrics. Ideally,
	// Collector implementations support concurrent readers.
	Collect(chan<- Metric)
}

收集器是由Prometheus可以用来收集Metric的任何东西实现的接口。必须为收集器注册收集器。请参阅Registerer.Register。

此程序包提供的库存指标(量规,计数器,汇总,直方图,无类型)也是收集器(仅收集一个指标,即本身)。但是,收集器的实现者可以以协调的方式收集多个指标和/或即时创建指标。已经在该库中实现的收集器的示例是度量向量(即,同一Metric但具有不同标签值的多个实例的集合),例如GaugeVec或SummaryVec,以及ExpvarCollector。

例子

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package prometheus_test

import (
	"log"
	"net/http"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"
)

// ClusterManager is an example for a system that might have been built without
// Prometheus in mind. It models a central manager of jobs running in a
// cluster. Thus, we implement a custom Collector called
// ClusterManagerCollector, which collects information from a ClusterManager
// using its provided methods and turns them into Prometheus Metrics for
// collection.
//
// An additional challenge is that multiple instances of the ClusterManager are
// run within the same binary, each in charge of a different zone. We need to
// make use of wrapping Registerers to be able to register each
// ClusterManagerCollector instance with Prometheus.
type ClusterManager struct {
	Zone string
	// Contains many more fields not listed in this example.
}

// ReallyExpensiveAssessmentOfTheSystemState is a mock for the data gathering a
// real cluster manager would have to do. Since it may actually be really
// expensive, it must only be called once per collection. This implementation,
// obviously, only returns some made-up data.
func (c *ClusterManager) ReallyExpensiveAssessmentOfTheSystemState() (
	oomCountByHost map[string]int, ramUsageByHost map[string]float64,
) {
	// Just example fake data.
	oomCountByHost = map[string]int{
		"foo.example.org": 42,
		"bar.example.org": 2001,
	}
	ramUsageByHost = map[string]float64{
		"foo.example.org": 6.023e23,
		"bar.example.org": 3.14,
	}
	return
}

// ClusterManagerCollector implements the Collector interface.
type ClusterManagerCollector struct {
	ClusterManager *ClusterManager
}

// Descriptors used by the ClusterManagerCollector below.
var (
	oomCountDesc = prometheus.NewDesc(
		"clustermanager_oom_crashes_total",
		"Number of OOM crashes.",
		[]string{"host"}, nil,
	)
	ramUsageDesc = prometheus.NewDesc(
		"clustermanager_ram_usage_bytes",
		"RAM usage as reported to the cluster manager.",
		[]string{"host"}, nil,
	)
)

// Describe is implemented with DescribeByCollect. That's possible because the
// Collect method will always return the same two metrics with the same two
// descriptors.
func (cc ClusterManagerCollector) Describe(ch chan<- *prometheus.Desc) {
	prometheus.DescribeByCollect(cc, ch)
}

// Collect first triggers the ReallyExpensiveAssessmentOfTheSystemState. Then it
// creates constant metrics for each host on the fly based on the returned data.
//
// Note that Collect could be called concurrently, so we depend on
// ReallyExpensiveAssessmentOfTheSystemState to be concurrency-safe.
func (cc ClusterManagerCollector) Collect(ch chan<- prometheus.Metric) {
	oomCountByHost, ramUsageByHost := cc.ClusterManager.ReallyExpensiveAssessmentOfTheSystemState()
	for host, oomCount := range oomCountByHost {
		ch <- prometheus.MustNewConstMetric(
			oomCountDesc,
			prometheus.CounterValue,
			float64(oomCount),
			host,
		)
	}
	for host, ramUsage := range ramUsageByHost {
		ch <- prometheus.MustNewConstMetric(
			ramUsageDesc,
			prometheus.GaugeValue,
			ramUsage,
			host,
		)
	}
}

// NewClusterManager first creates a Prometheus-ignorant ClusterManager
// instance. Then, it creates a ClusterManagerCollector for the just created
// ClusterManager. Finally, it registers the ClusterManagerCollector with a
// wrapping Registerer that adds the zone as a label. In this way, the metrics
// collected by different ClusterManagerCollectors do not collide.
func NewClusterManager(zone string, reg prometheus.Registerer) *ClusterManager {
	c := &ClusterManager{
		Zone: zone,
	}
	cc := ClusterManagerCollector{ClusterManager: c}
	prometheus.WrapRegistererWith(prometheus.Labels{"zone": zone}, reg).MustRegister(cc)
	return c
}

func ExampleCollector() {
	// Since we are dealing with custom Collector implementations, it might
	// be a good idea to try it out with a pedantic registry.
	reg := prometheus.NewPedanticRegistry()

	// Construct cluster managers. In real code, we would assign them to
	// variables to then do something with them.
	NewClusterManager("db", reg)
	NewClusterManager("ca", reg)

	// Add the standard process and Go metrics to the custom registry.
	reg.MustRegister(
		prometheus.NewProcessCollector(prometheus.ProcessCollectorOpts{}),
		prometheus.NewGoCollector(),
	)

	http.Handle("/metrics", promhttp.HandlerFor(reg, promhttp.HandlerOpts{}))
	log.Fatal(http.ListenAndServe(":8080", nil))
}

func NewBuildInfoCollector

1
func NewBuildInfoCollector() Collector

NewBuildInfoCollector返回一个收集器,该收集器收集具有恒定值1和三个标签“ path”,“version”和“checksum”的单个度量“ go_build_info”。它们的标签值分别包含主模块路径,版本和校验和。如果二进制文件是通过Go模块支持并从从源存储库(而不是本地文件系统)检索的源代码构建的,则标签将只有有意义的值。通常,这可以通过从GOPATH外部进行构建来完成,并指定主软件包的完整地址,例如“ GO111MODULE = on go run github.com/prometheus/client_golang/examples/random”。如果构建时不支持Go模块,则所有标签值将为“未知”。如果使用Go模块支持构建,但使用本地文件系统的源代码,“path”将被适当设置,但“checksum”将为空,“version”将为“(devel)”。

该收集器仅将构建信息用于主模块。有关模块依赖项的收集器示例,请参见 https://github.com/povilasv/prommod

func NewExpvarCollector

1
func NewExpvarCollector(exports map[string]*Desc) Collector

NewExpvarCollector返回一个新分配的expvar收集器,该收集器仍必须在Prometheus注册表中进行注册。

expvar收集器从expvar接口收集指标。它提供了一种快速的方法来公开已经通过expvar导出为Prometheus指标的数值。请注意,expvar和Prometheus的数据模型本质上是不同的,并且expvar Collector本质上比本地Prometheus指标慢。因此,expvar Collector可能非常适合进行实验和原型制作,但是您应该认真考虑更直接地实现PrometheusMetric以监视生产系统。

exports map具有以下含义:

映射中的键对应于expvar键,即对于要导出为PrometheusMetric的每个expvar键,在导出映射中都需要一个条目。映射到每个键的描述符描述了如何导出expvar值。它定义PrometheusMetric的名称和帮助字符串,以替代expvar值。该类型将始终为“无类型”。

对于没有变量标签的描述符,expvar值必须是数字或布尔值。然后将数字直接导出为Prometheus样本值。(对于布尔值,“false”表示0,“ true”表示1)。不是数字或布尔值的Expvar值将被静默忽略。

如果描述符具有一个变量标签,则expvar值必须是一个expvar映射。expvar映射中的键成为一个Prometheus标签的各种值。如上所述,expvar映射中的值必须再次为数字或布尔值。

对于具有多个变量标签的描述符,expvar必须是嵌套的expvar映射,即,最顶部映射的值再次是映射等,直到达到与标签数量相对应的深度。该结构的叶子必须是上面的数字或布尔值,才能用作样本值。

任何不适合上述方案的内容都会被忽略。

例子

Code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
expvarCollector := prometheus.NewExpvarCollector(map[string]*prometheus.Desc{
	"memstats": prometheus.NewDesc(
		"expvar_memstats",
		"All numeric memstats as one metric family. Not a good role-model, actually... ;-)",
		[]string{"type"}, nil,
	),
	"lone-int": prometheus.NewDesc(
		"expvar_lone_int",
		"Just an expvar int as an example.",
		nil, nil,
	),
	"http-request-map": prometheus.NewDesc(
		"expvar_http_request_total",
		"How many http requests processed, partitioned by status code and http method.",
		[]string{"code", "method"}, nil,
	),
})
prometheus.MustRegister(expvarCollector)

// The Prometheus part is done here. But to show that this example is
// doing anything, we have to manually export something via expvar.  In
// real-life use-cases, some library would already have exported via
// expvar what we want to re-export as Prometheus metrics.
expvar.NewInt("lone-int").Set(42)
expvarMap := expvar.NewMap("http-request-map")
var (
	expvarMap1, expvarMap2                             expvar.Map
	expvarInt11, expvarInt12, expvarInt21, expvarInt22 expvar.Int
)
expvarMap1.Init()
expvarMap2.Init()
expvarInt11.Set(3)
expvarInt12.Set(13)
expvarInt21.Set(11)
expvarInt22.Set(212)
expvarMap1.Set("POST", &expvarInt11)
expvarMap1.Set("GET", &expvarInt12)
expvarMap2.Set("POST", &expvarInt21)
expvarMap2.Set("GET", &expvarInt22)
expvarMap.Set("404", &expvarMap1)
expvarMap.Set("200", &expvarMap2)
// Results in the following expvar map:
// "http-request-count": {"200": {"POST": 11, "GET": 212}, "404": {"POST": 3, "GET": 13}}

// Let's see what the scrape would yield, but exclude the memstats metrics.
metricStrings := []string{}
metric := dto.Metric{}
metricChan := make(chan prometheus.Metric)
go func() {
	expvarCollector.Collect(metricChan)
	close(metricChan)
}()
for m := range metricChan {
	if !strings.Contains(m.Desc().String(), "expvar_memstats") {
		metric.Reset()
		m.Write(&metric)
		metricStrings = append(metricStrings, metric.String())
	}
}
sort.Strings(metricStrings)
for _, s := range metricStrings {
	fmt.Println(strings.TrimRight(s, " "))
}

Output:

1
2
3
4
5
label:<name:"code" value:"200" > label:<name:"method" value:"GET" > untyped:<value:212 >
label:<name:"code" value:"200" > label:<name:"method" value:"POST" > untyped:<value:11 >
label:<name:"code" value:"404" > label:<name:"method" value:"GET" > untyped:<value:13 >
label:<name:"code" value:"404" > label:<name:"method" value:"POST" > untyped:<value:3 >
untyped:<value:42 >

func NewGoCollector

1
func NewGoCollector() Collector

NewGoCollector返回一个收集器,该收集器导出有关当前Go流程的指标。这包括内存统计信息。要收集这些内容,将调用runtime.ReadMemStats。这需要“停止世界”,通常仅在垃圾回收(GC)中发生。在决定是否使用Go收集器时,请考虑以下含义:

1.停止世界对性能的影响越重要,收集指标的频率就越高。但是,使用Go1.9或更高版本时,每个指标收集的世界停止时间非常短(〜25µs),因此对性能的影响仅在极少数情况下才重要。但是,对于较旧的Go版本,“停下世界”的持续时间取决于堆的大小,并且可能相当长(根据https://go-review.googlesource.com/c/go/+/,约为1.7 ms / GiB 34937)。

2.在进行中的GC期间,没有其他事情可以阻止世界。因此,如果指标收集恰好与GC一致,则只有在GC完成后才能完成。通常,GC足够快,不会引起问题。但是,对于非常大的堆,GC可能需要花费几秒钟的时间,这足以在常规设置中引起scrape超时。为避免此问题,如果runtime.ReadMemStats花费的时间超过1s,则Go收集器将使用先前集合中的memstats。但是,如果以前没有收集过memstats,或者它们的收集时间超过5m,则收集将阻塞,直到runtime.ReadMemStats成功。(该问题可能会在Go1.13中解决,有关相关的Go问题,请参见https://github.com/golang/go/issues/19812。)

func NewProcessCollector

1
func NewProcessCollector(opts ProcessCollectorOpts) Collector

NewProcessCollector返回一个收集器,该收集器导出过程度量的当前状态,包括CPU,内存和文件描述符的使用情况以及过程开始时间。详细行为由提供的ProcessCollectorOpts定义。ProcessCollectorOpts的零值将为当前进程创建一个收集器,该收集器具有空的名称空间字符串,并且没有错误报告。

收集器仅适用于具有Linux样式proc文件系统的操作系统以及Microsoft Windows。在其他操作系统上,它将不收集任何指标。

type Counter

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
type Counter interface {
	Metric
	Collector

	// Inc increments the counter by 1. Use Add to increment it by arbitrary
	// non-negative values.
	Inc()
	// Add adds the given value to the counter. It panics if the value is <
	// 0.
	Add(float64)
}

计数器是一种Metric,它表示只会递增的单个数值。这意味着它不能用于计数数量也可能下降的项目,例如当前正在运行的goroutines的数量。这些“计数器”由量规代表。

计数器通常用于对服务的请求,完成的任务,发生的错误等进行计数。

若要创建Counter实例,请使用NewCounter。

func NewCounter

1
func NewCounter(opts CounterOpts) Counter

NewCounter基于提供的CounterOpts创建一个新的Counter。

返回的实现还实现ExemplarAdder。执行相应的类型声明是安全的。

返回的实现在两个单独的变量float64和uint64中跟踪计数器值。后者用于跟踪Inc方法的调用和具有可以表示为uint64的值的Add方法的调用。这使得计数器的原子增量具有最佳性能。(通常在非常热的执行路径中进行Inc调用。)这两个内部跟踪值都在Write方法中相加。当涉及到精度和溢出行为时,必须考虑到这一点。

type CounterFunc

1
2
3
4
type CounterFunc interface {
	Metric
	Collector
}

CounterFunc是一个Counter,其值在收集时通过调用提供的函数确定。

若要创建CounterFunc实例,请使用NewCounterFunc。

func NewCounterFunc

1
func NewCounterFunc(opts CounterOpts, function func() float64) CounterFunc

NewCounterFunc基于提供的CounterOpts创建一个新的CounterFunc。报告的值是通过在Write方法中调用给定的函数确定的。考虑到指标收集可能会同时发生。如果这导致对Write的并发调用,例如将CounterFunc直接注册到Prometheus的情况,则提供的函数必须是并发安全的。该功能还应遵守计数器合同(值只会上升,不会下降),但不会检查合规性。

查看类似的GaugeFunc的ExampleGaugeFunc示例。

type CounterOpts

1
type CounterOpts Opts

CounterOpts是Opts的别名。请参阅此处以获取文档注释。

type CounterVec

1
2
3
type CounterVec struct {
	// contains filtered or unexported fields
}

CounterVec是一个收集器,捆绑了一组共享相同Desc,但其变量标签具有不同值的Counter。如果您要计算按不同维度划分的同一事物(例如,HTTP请求的数量,按响应代码和方法划分的),则使用此方法。使用NewCounterVec创建实例。

例子

Code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
httpReqs := prometheus.NewCounterVec(
	prometheus.CounterOpts{
		Name: "http_requests_total",
		Help: "How many HTTP requests processed, partitioned by status code and HTTP method.",
	},
	[]string{"code", "method"},
)
prometheus.MustRegister(httpReqs)

httpReqs.WithLabelValues("404", "POST").Add(42)

// If you have to access the same set of labels very frequently, it
// might be good to retrieve the metric only once and keep a handle to
// it. But beware of deletion of that metric, see below!
m := httpReqs.WithLabelValues("200", "GET")
for i := 0; i < 1000000; i++ {
	m.Inc()
}
// Delete a metric from the vector. If you have previously kept a handle
// to that metric (as above), future updates via that handle will go
// unseen (even if you re-create a metric with the same label set
// later).
httpReqs.DeleteLabelValues("200", "GET")
// Same thing with the more verbose Labels syntax.
httpReqs.Delete(prometheus.Labels{"method": "GET", "code": "200"})

func NewCounterVec

1
func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec

NewCounterVec基于提供的CounterOpts创建新的CounterVec,并按给定的标签名称进行分区。

func (CounterVec) Collect

1
func (m CounterVec) Collect(ch chan<- Metric)

Collect 实现 Collector.

func (*CounterVec) CurryWith

1
func (v *CounterVec) CurryWith(labels Labels) (*CounterVec, error)

CurryWith返回使用提供的标签进行咖喱处理的向量,即返回的向量具有针对其执行的所有标记操作预先设置的那些标签。相应地减小了咖喱矢量的基数。其余标签的顺序保持不变(只是将咖喱标签从序列中取出,这与(GetMetric)WithLabelValues方法有关)。可以咖喱咖喱的矢量,但只能使用之前尚未用于咖喱的标签。

CounterVec中包含的度量在已管理和未已管理向量之间共享。只是以不同的方式访问它们。在集合方面,咖喱和非咖喱向量的行为相同。必须在给定的注册表中注册一个(通常是未更新的版本)。即使对当前向量调用了Reset方法,Reset方法也会删除所有指标。

func (CounterVec) Delete

1
func (m CounterVec) Delete(labels Labels) bool

Delete会删除指标,其中变量标签与作为标签传入的标签相同。如果删除了指标,则返回true。

如果标签的编号和名称与Desc中的VariableLabel的编号和名称不一致,则不是错误。但是,此类不一致的标签永远无法与实际指标匹配,因此在这种情况下该方法将始终返回false。

此方法与DeleteLabelValues(… string)的用途相同。有关两种方法的优缺点,请参见此处。

func (CounterVec) DeleteLabelValues

1
func (m CounterVec) DeleteLabelValues(lvs ...string) bool

DeleteLabelValues删除Metric,其中变量标签与作为标签传入的变量相同(与Desc中的VariableLabel顺序相同)。如果删除了指标,则返回true。

如果标签值的数量与Desc中的VariableLabels的数量不同,这不是错误。但是,这种不一致的标签计数永远无法与实际指标匹配,因此在这种情况下该方法将始终返回false。

请注意,对于多个标签值,此方法很容易因参数顺序错误而导致错误。考虑使用Delete(Labels)来避免这种类型的错误。对于更高的标签编号,后者具有更易读(尽管更冗长)的语法,但是它会带来性能开销(用于创建和处理Labels映射)。另请参见CounterVec示例。

func (CounterVec) Describe

1
func (m CounterVec) Describe(ch chan<- *Desc)

Describe 实现 Collector.

func (*CounterVec) GetMetricWith

1
func (v *CounterVec) GetMetricWith(labels Labels) (Counter, error)

GetMetricWith返回给定Labels映射的Counter(标签名称必须与Desc中的VariableLabels的名称匹配)。如果是第一次访问该标签映射,则会创建一个新的计数器。不使用计数器创建计数器并保留该计数器供以后使用的含义与GetMetricWithLabelValues相同。

如果标签的编号和名称与Desc中的VariableLabel的编号和名称不一致(减去任何已处理的标签),则会返回错误。

此方法与GetMetricWithLabelValues(… string)的用途相同。有关两种方法的优缺点,请参见此处。

func (*CounterVec) GetMetricWithLabelValues

1
func (v *CounterVec) GetMetricWithLabelValues(lvs ...string) (Counter, error)

GetMetricWithLabelValues返回给定标签值切片的计数器(与Desc中的VariableLabels顺序相同)。如果是第一次访问标签值的组合,则会创建一个新的计数器。

可以调用此方法而无需使用返回的Counter来仅创建新的Counter,而将其保留为起始值0。另请参见SummaryVec示例。

可以保留Counter以便以后使用(如果性能至关重要,则应考虑使用),但是请记住,可以使用Reset,DeleteLabelValues和Delete从CounterVec删除Counter。在这种情况下,即使以后创建具有相同标签值的计数器,该计数器仍将存在,但不再导出。

如果标签值的数量与Desc中的VariableLabels的数量(减去任何已固化的标签)不同,则返回错误。

请注意,对于多个标签值,此方法很容易因参数顺序错误而导致错误。考虑使用GetMetricWith(Labels)作为替代方案来避免这种类型的错误。对于更高的标签编号,后者具有更易读(尽管更冗长)的语法,但是它会带来性能开销(用于创建和处理Labels映射)。另请参见GaugeVec示例。

func (*CounterVec) MustCurryWith

1
func (v *CounterVec) MustCurryWith(labels Labels) *CounterVec

MustCurryWith可以作为CurryWith使用,但在CurryWith会返回错误的情况下会出现panic。

func (CounterVec) Reset

1
func (m CounterVec) Reset()

重置将删除此向量中的所有指标。

func (*CounterVec) With

1
func (v *CounterVec) With(labels Labels) Counter

With与GetMetricWith一样工作,但在GetMetricWithLabels会返回错误的地方感到慌张。不返回错误允许使用以下快捷方式

1
myVec.WithLabelValues("404", "GET").Add(42)

func (*CounterVec) WithLabelValues

1
func (v *CounterVec) WithLabelValues(lvs ...string) Counter

WithLabelValues可以用作GetMetricWithLabelValues,但是在GetMetricWithLabelValues会返回错误的地方出现混乱。不返回错误允许使用以下快捷方式

1
myVec.WithLabelValues("404", "GET").Add(42)

type Gauge

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
type Gauge interface {
	Metric
	Collector

	// Set sets the Gauge to an arbitrary value.
	Set(float64)
	// Inc increments the Gauge by 1. Use Add to increment it by arbitrary
	// values.
	Inc()
	// Dec decrements the Gauge by 1. Use Sub to decrement it by arbitrary
	// values.
	Dec()
	// Add adds the given value to the Gauge. (The value can be negative,
	// resulting in a decrease of the Gauge.)
	Add(float64)
	// Sub subtracts the given value from the Gauge. (The value can be
	// negative, resulting in an increase of the Gauge.)
	Sub(float64)

	// SetToCurrentTime sets the Gauge to the current Unix time in seconds.
	SetToCurrentTime()
}

Gauge是一种Metric,代表可以任意增加和减少的单个数值。

仪表通常用于测量值,例如温度或当前的内存使用情况,还用于可能上升和下降的“计数”,例如正在运行的goroutine的数量。

要创建仪表实例,请使用NewGauge。

例子

Code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
opsQueued := prometheus.NewGauge(prometheus.GaugeOpts{
	Namespace: "our_company",
	Subsystem: "blob_storage",
	Name:      "ops_queued",
	Help:      "Number of blob storage operations waiting to be processed.",
})
prometheus.MustRegister(opsQueued)

// 10 operations queued by the goroutine managing incoming requests.
opsQueued.Add(10)
// A worker goroutine has picked up a waiting operation.
opsQueued.Dec()
// And once more...
opsQueued.Dec()

func NewGauge

1
func NewGauge(opts GaugeOpts) Gauge

NewGauge根据提供的GaugeOpts创建一个新的Gauge。

返回的实现针对快速Set方法进行了优化。如果您可以选择通过Set vs.Inc/Dec/Add/Sub来管理仪表的值,请选择前者。例如,返回的仪表的Inc方法比NewCounter返回的Counter的Inc方法慢。这与“Gauges”和“Counters”的典型方案相符,前者倾向于“重置类重载”,而后者倾向于“增加类重载”。

type GaugeFunc

1
2
3
4
type GaugeFunc interface {
	Metric
	Collector
}

GaugeFunc是一个Gauge,其值是在收集时通过调用提供的函数确定的。

要创建GaugeFunc实例,请使用NewGaugeFunc。

示例(ConstLabels)

Code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// primaryDB and secondaryDB represent two example *sql.DB connections we want to instrument.
var primaryDB, secondaryDB interface {
	Stats() struct{ OpenConnections int }
}

if err := prometheus.Register(prometheus.NewGaugeFunc(
	prometheus.GaugeOpts{
		Namespace:   "mysql",
		Name:        "connections_open",
		Help:        "Number of mysql connections open.",
		ConstLabels: prometheus.Labels{"destination": "primary"},
	},
	func() float64 { return float64(primaryDB.Stats().OpenConnections) },
)); err == nil {
	fmt.Println(`GaugeFunc 'connections_open' for primary DB connection registered with labels {destination="primary"}`)
}

if err := prometheus.Register(prometheus.NewGaugeFunc(
	prometheus.GaugeOpts{
		Namespace:   "mysql",
		Name:        "connections_open",
		Help:        "Number of mysql connections open.",
		ConstLabels: prometheus.Labels{"destination": "secondary"},
	},
	func() float64 { return float64(secondaryDB.Stats().OpenConnections) },
)); err == nil {
	fmt.Println(`GaugeFunc 'connections_open' for secondary DB connection registered with labels {destination="secondary"}`)
}

// Note that we can register more than once GaugeFunc with same metric name
// as long as their const labels are consistent.

Output:

1
2
GaugeFunc 'connections_open' for primary DB connection registered with labels {destination="primary"}
GaugeFunc 'connections_open' for secondary DB connection registered with labels {destination="secondary"}

示例(简单)

Code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
if err := prometheus.Register(prometheus.NewGaugeFunc(
	prometheus.GaugeOpts{
		Subsystem: "runtime",
		Name:      "goroutines_count",
		Help:      "Number of goroutines that currently exist.",
	},
	func() float64 { return float64(runtime.NumGoroutine()) },
)); err == nil {
	fmt.Println("GaugeFunc 'goroutines_count' registered.")
}
// Note that the count of goroutines is a gauge (and not a counter) as
// it can go up and down.

Output:

1
GaugeFunc 'goroutines_count' registered.

func NewGaugeFunc

1
func NewGaugeFunc(opts GaugeOpts, function func() float64) GaugeFunc

NewGaugeFunc基于提供的GaugeOpts创建一个新的GaugeFunc。报告的值是通过在Write方法中调用给定的函数确定的。考虑到指标收集可能会同时发生。因此,必须安全地同时调用提供的函数。

NewGaugeFunc是创建常量值为1的“信息”风格指标的好方法。示例:https://github.com/prometheus/common/blob/8558a5b7db3c84fa38b4766966059a7bd5bfa2ee/version/info.go#L36-L56

type GaugeOpts

1
type GaugeOpts Opts

GaugeOpts是Opts的别名。请参阅此处以获取文档注释。

type GaugeVec

1
2
3
type GaugeVec struct {
	// contains filtered or unexported fields
}

GaugeVec是一个收集器,它捆绑了一组共享相同Desc,但其变量标签具有不同值的Gauge。如果要统计按不同维度划分的同一事物(例如,排队的操作数,按用户和操作类型划分的分区),则使用此方法。使用NewGaugeVec创建实例。

例子

Code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
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.",
	},
	[]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": "alice"}).Inc()

func NewGaugeVec

1
func NewGaugeVec(opts GaugeOpts, labelNames []string) *GaugeVec

NewGaugeVec基于提供的GaugeOpts创建新的GaugeVec,并按给定的标签名称进行分区。

func (GaugeVec) Collect

1
func (m GaugeVec) Collect(ch chan<- Metric)

Collect 实现 Collector.

func (*GaugeVec) CurryWith

1
func (v *GaugeVec) CurryWith(labels Labels) (*GaugeVec, error)

CurryWith返回使用提供的标签进行咖喱处理的向量,即返回的向量具有针对其执行的所有标记操作预先设置的那些标签。相应地减小了咖喱矢量的基数。其余标签的顺序保持不变(只是将咖喱标签从序列中取出,这与(GetMetric)WithLabelValues方法有关)。可以咖喱咖喱的矢量,但只能使用之前尚未用于咖喱的标签。

GaugeVec中包含的Metric在已固化和未固化向量之间共享。只是以不同的方式访问它们。在集合方面,咖喱和非咖喱向量的行为相同。必须在给定的注册表中注册一个(通常是未更新的版本)。即使对当前向量调用了Reset方法,Reset方法也会删除所有指标。

func (GaugeVec) Delete

1
func (m GaugeVec) Delete(labels Labels) bool

删除会删除指标,其中变量标签与作为标签传入的标签相同。如果删除了指标,则返回true。

如果标签的编号和名称与Desc中的VariableLabel的编号和名称不一致,则不是错误。但是,此类不一致的标签永远无法与实际指标匹配,因此在这种情况下该方法将始终返回false。

此方法与DeleteLabelValues(… string)的用途相同。有关两种方法的优缺点,请参见此处。

func (GaugeVec) DeleteLabelValues

1
func (m GaugeVec) DeleteLabelValues(lvs ...string) bool

DeleteLabelValues删除Metric,其中变量标签与作为标签传入的变量相同(与Desc中的VariableLabel顺序相同)。如果删除了指标,则返回true。

如果标签值的数量与Desc中的VariableLabels的数量不同,这不是错误。但是,这种不一致的标签计数永远无法与实际指标匹配,因此在这种情况下该方法将始终返回false。

请注意,对于多个标签值,此方法很容易因参数顺序错误而导致错误。考虑使用Delete(Labels)来避免这种类型的错误。对于更高的标签编号,后者具有更易读(尽管更冗长)的语法,但是它会带来性能开销(用于创建和处理Labels映射)。另请参见CounterVec示例。

func (GaugeVec) Describe

1
func (m GaugeVec) Describe(ch chan<- *Desc

Describe 实现 Collector.

func (*GaugeVec) GetMetricWith

1
func (v *GaugeVec) GetMetricWith(labels Labels) (Gauge, error)

GetMetricWith返回给定Labels映射的Gauge(标签名称必须与Desc中的VariableLabels的名称匹配)。如果是第一次访问该标签图,则会创建一个新的Gauge。不使用仪表创建仪表并保留仪表以备后用的含义与GetMetricWithLabelValues相同。

如果标签的编号和名称与Desc中的VariableLabel的编号和名称不一致(减去任何已处理的标签),则会返回错误。

此方法与GetMetricWithLabelValues(… string)的用途相同。有关两种方法的优缺点,请参见此处。

func (*GaugeVec) GetMetricWithLabelValues

1
func (v *GaugeVec) GetMetricWithLabelValues(lvs ...string) (Gauge, error)

GetMetricWithLabelValues返回给定标签值切片的量规(与Desc中的VariableLabels顺序相同)。如果是第一次访问标签值的组合,则会创建一个新的仪表。

可以在不使用返回的Gauge的情况下调用此方法,仅创建新的Gauge,而将其保留为初始值0。另请参见SummaryVec示例。

可以保留仪表以备后用(如果性能至关重要,则应考虑使用),但请记住,可以使用Reset,DeleteLabelValues和Delete从GaugeVec删除仪表。在这种情况下,即使以后创建具有相同标签值的仪表,该仪表仍将存在,但将不再导出。另请参见CounterVec示例。

如果标签值的数量与Desc中的VariableLabels的数量(减去任何已固化的标签)不同,则返回错误。

请注意,对于多个标签值,此方法很容易因参数顺序错误而导致错误。考虑使用GetMetricWith(Labels)作为替代方案来避免这种类型的错误。对于更高的标签编号,后者具有更易读(尽管更冗长)的语法,但是它会带来性能开销(用于创建和处理Labels映射)。

func (*GaugeVec) MustCurryWith

1
func (v *GaugeVec) MustCurryWith(labels Labels) *GaugeVec

MustCurryWith可以作为CurryWith使用,但在CurryWith会返回错误的情况下会出现混乱。

func (GaugeVec) Reset

1
func (m GaugeVec) Reset()

重置将删除此向量中的所有指标。

func (*GaugeVec) With

1
func (v *GaugeVec) With(labels Labels) Gauge

With与GetMetricWith一样工作,但在GetMetricWithLabels会返回错误的地方感到慌张。不返回错误允许使用以下快捷方式

1
myVec.With(prometheus.Labels{"code": "404", "method": "GET"}).Add(42)

func (*GaugeVec) WithLabelValues

1
func (v *GaugeVec) WithLabelValues(lvs ...string) Gauge

WithLabelValues可以用作GetMetricWithLabelValues,但是在GetMetricWithLabelValues会返回错误的地方出现混乱。不返回错误允许使用以下快捷方式

1
myVec.WithLabelValues("404", "GET").Add(42)

type Histogram

1
2
3
4
5
6
7
type Histogram interface {
	Metric
	Collector

	// Observe adds a single observation to the histogram.
	Observe(float64)
}

直方图计算来自事件或样本流的可配置存储桶中的单个观察值。与摘要类似,它也提供观察值的总和和观察值。

在Prometheus服务器上,可以使用查询语言中的histogram_quantile函数从直方图计算分位数。

请注意,与摘要相比,直方图可以与Prometheus查询语言进行汇总(有关详细过程,请参见文档)。但是,直方图要求用户预先定义合适的bucket,并且通常精度较低。与摘要的Observe方法相比,直方图的Observe方法具有非常低的性能开销。

要创建直方图实例,请使用NewHistogram。

例子

Code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
temps := prometheus.NewHistogram(prometheus.HistogramOpts{
	Name:    "pond_temperature_celsius",
	Help:    "The temperature of the frog pond.", // Sorry, we can't measure how badly it smells.
	Buckets: prometheus.LinearBuckets(20, 5, 5),  // 5 buckets, each 5 centigrade wide.
})

// Simulate some observations.
for i := 0; i < 1000; i++ {
	temps.Observe(30 + math.Floor(120*math.Sin(float64(i)*0.1))/10)
}

// Just for demonstration, let's check the state of the histogram by
// (ab)using its Write method (which is usually only used by Prometheus
// internally).
metric := &dto.Metric{}
temps.Write(metric)
fmt.Println(proto.MarshalTextString(metric))

Output:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
histogram: <
  sample_count: 1000
  sample_sum: 29969.50000000001
  bucket: <
    cumulative_count: 192
    upper_bound: 20
  >
  bucket: <
    cumulative_count: 366
    upper_bound: 25
  >
  bucket: <
    cumulative_count: 501
    upper_bound: 30
  >
  bucket: <
    cumulative_count: 638
    upper_bound: 35
  >
  bucket: <
    cumulative_count: 816
    upper_bound: 40
  >
>

func NewHistogram

1
func NewHistogram(opts HistogramOpts) Histogram

NewHistogram基于提供的HistogramOpts创建新的直方图。如果HistogramOpts中的存储桶未严格按升序排序,则会感到恐慌。

返回的实现还实现ExemplarObserver。执行相应的类型声明是安全的。分别跟踪每个存储桶的示例。

type HistogramOpts

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
type HistogramOpts struct {
	// Namespace, Subsystem, and Name are components of the fully-qualified
	// name of the Histogram (created by joining these components with
	// "_"). Only Name is mandatory, the others merely help structuring the
	// name. Note that the fully-qualified name of the Histogram must be a
	// valid Prometheus metric name.
	Namespace string
	Subsystem string
	Name      string

	// Help provides information about this Histogram.
	//
	// Metrics with the same fully-qualified name must have the same Help
	// string.
	Help string

	// ConstLabels are used to attach fixed labels to this metric. Metrics
	// with the same fully-qualified name must have the same label names in
	// their ConstLabels.
	//
	// ConstLabels are only used rarely. In particular, do not use them to
	// attach the same labels to all your metrics. Those use cases are
	// better covered by target labels set by the scraping Prometheus
	// server, or by one specific metric (e.g. a build_info or a
	// machine_role metric). See also
	// https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels-not-static-scraped-labels
	ConstLabels Labels

	// Buckets defines the buckets into which observations are counted. Each
	// element in the slice is the upper inclusive bound of a bucket. The
	// values must be sorted in strictly increasing order. There is no need
	// to add a highest bucket with +Inf bound, it will be added
	// implicitly. The default value is DefBuckets.
	Buckets []float64
}

HistogramOpts捆绑了用于创建直方图度量的选项。必须将Name设置为非空字符串。尽管强烈建议您设置帮助字符串,但所有其他字段都是可选的,可以安全地保留其零值。

type HistogramVec

1
2
3
type HistogramVec struct {
	// contains filtered or unexported fields
}

HistogramVec是一个收集器,它捆绑一组直方图,这些直方图共享相同的Desc,但是其变量标签具有不同的值。如果要计算按不同维度划分的同一事物(例如,HTTP请求等待时间,按状态代码和方法划分的分区),则使用此方法。使用NewHistogramVec创建实例。

func NewHistogramVec

1
func NewHistogramVec(opts HistogramOpts, labelNames []string) *HistogramVec

NewHistogramVec基于提供的HistogramOpts创建一个新的HistogramVec,并按给定的标签名称进行分区。

func (HistogramVec) Collect

1
func (m HistogramVec) Collect(ch chan<- Metric)

Collect 实现 Collector.

func (*HistogramVec) CurryWith

1
func (v *HistogramVec) CurryWith(labels Labels) (ObserverVec, error)

CurryWith返回使用提供的标签进行咖喱处理的向量,即返回的向量具有针对其执行的所有标记操作预先设置的那些标签。相应地减小了咖喱矢量的基数。其余标签的顺序保持不变(只是将咖喱标签从序列中取出,这与(GetMetric)WithLabelValues方法有关)。可以咖喱咖喱的矢量,但只能使用之前尚未用于咖喱的标签。

HistogramVec中包含的度量在已固化和未固化向量之间共享。只是以不同的方式访问它们。在集合方面,咖喱和非咖喱向量的行为相同。必须在给定的注册表中注册一个(通常是未更新的版本)。即使对当前向量调用了Reset方法,Reset方法也会删除所有指标。

func (HistogramVec) Delete

1
func (m HistogramVec) Delete(labels Labels) bool

删除会删除指标,其中变量标签与作为标签传入的标签相同。如果删除了指标,则返回true。

如果标签的编号和名称与Desc中的VariableLabel的编号和名称不一致,则不是错误。但是,此类不一致的标签永远无法与实际指标匹配,因此在这种情况下该方法将始终返回false。

此方法与DeleteLabelValues(… string)的用途相同。有关两种方法的优缺点,请参见此处。

func (HistogramVec) DeleteLabelValues

1
func (m HistogramVec) DeleteLabelValues(lvs ...string) bool

DeleteLabelValues删除Metric,其中变量标签与作为标签传入的变量相同(与Desc中的VariableLabel顺序相同)。如果删除了指标,则返回true。

如果标签值的数量与Desc中的VariableLabels的数量不同,这不是错误。但是,这种不一致的标签计数永远无法与实际指标匹配,因此在这种情况下该方法将始终返回false。

请注意,对于多个标签值,此方法很容易因参数顺序错误而导致错误。考虑使用Delete(Labels)来避免这种类型的错误。对于更高的标签编号,后者具有更易读(尽管更冗长)的语法,但是它会带来性能开销(用于创建和处理Labels映射)。另请参见CounterVec示例。

func (HistogramVec) Describe

1
func (m HistogramVec) Describe(ch chan<- *Desc)

Describe 实现 Collector.

func (*HistogramVec) GetMetricWith

1
func (v *HistogramVec) GetMetricWith(labels Labels) (Observer, error)

GetMetricWith返回给定Labels映射的直方图(标签名称必须与Desc中的VariableLabel的名称匹配)。如果是第一次访问该标签图,则会创建一个新的直方图。不使用直方图创建直方图并保留直方图供以后使用的含义与GetMetricWithLabelValues相同。

如果标签的编号和名称与Desc中的VariableLabel的编号和名称不一致(减去任何已处理的标签),则会返回错误。

此方法与GetMetricWithLabelValues(… string)的用途相同。有关两种方法的优缺点,请参见此处。

func (*HistogramVec) GetMetricWithLabelValues

1
func (v *HistogramVec) GetMetricWithLabelValues(lvs ...string) (Observer, error)

GetMetricWithLabelValues返回给定标签值切片的直方图(与Desc中的VariableLabels顺序相同)。如果第一次访问标签值的组合,则会创建一个新的直方图。

可以在不使用返回的直方图的情况下调用此方法,仅创建新的直方图,而将其保留为初始值,即没有任何观察值的直方图。

可以保留直方图供以后使用(如果性能至关重要,则应考虑使用),但请记住,可以使用Reset,DeleteLabelValues和Delete从HistogramVec中删除直方图。在这种情况下,即使以后创建具有相同标签值的直方图,直方图仍将存在,但将不再导出。另请参见CounterVec示例。

如果标签值的数量与Desc中的VariableLabels的数量(减去任何已固化的标签)不同,则返回错误。

请注意,对于多个标签值,此方法很容易因参数顺序错误而导致错误。考虑使用GetMetricWith(Labels)作为替代方案来避免这种类型的错误。对于更高的标签编号,后者具有更易读(尽管更冗长)的语法,但是它会带来性能开销(用于创建和处理Labels映射)。另请参见GaugeVec示例。

func (*HistogramVec) MustCurryWith

1
func (v *HistogramVec) MustCurryWith(labels Labels) ObserverVec

MustCurryWith可以作为CurryWith使用,但在CurryWith会返回错误的情况下会出现混乱。

func (HistogramVec) Reset

1
func (m HistogramVec) Reset()

重置将删除此向量中的所有指标。

func (*HistogramVec) With

1
func (v *HistogramVec) With(labels Labels) Observer

With与GetMetricWith一样工作,但在GetMetricWithLabels会返回错误的地方感到慌张。不返回错误允许使用以下快捷方式

1
myVec.With(prometheus.Labels{"code": "404", "method": "GET"}).Observe(42.21)

func (*HistogramVec) WithLabelValues

1
func (v *HistogramVec) WithLabelValues(lvs ...string) Observer

WithLabelValues可以用作GetMetricWithLabelValues,但是在GetMetricWithLabelValues会返回错误的地方出现混乱。不返回错误允许使用以下快捷方式

1
myVec.WithLabelValues("404", "GET").Observe(42.21)

type Summary

1
2
3
4
5
6
7
type Summary interface {
	Metric
	Collector

	// Observe adds a single observation to the summary.
	Observe(float64)
}

摘要可从事件或样本流中捕获单个观察值,并以类似于传统摘要统计的方式对其进行摘要:1.观察值总和,2。观察值,3。排名估计。

一个典型的用例是观察请求延迟。默认情况下,摘要提供延迟的中位数,第90%和第99%作为等级估计。但是,默认行为将在即将发布的库v1.0.0中更改。默认情况下,将不会有任何排名估计。对于合理的过渡,建议明确设置所需的排名估计。

请注意,排名估计不能使用Prometheus查询语言以有意义的方式进行汇总(即,您不能对它们进行平均或相加)。如果您需要可汇总的分位数(例如,您希望跨服务的所有实例进行的所有查询的第99个百分位数的延迟),请考虑直方图度量类型。有关更多详细信息,请参见Prometheus文档。

若要创建摘要实例,请使用NewSummary。

Code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
temps := prometheus.NewSummary(prometheus.SummaryOpts{
	Name:       "pond_temperature_celsius",
	Help:       "The temperature of the frog pond.",
	Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
})

// Simulate some observations.
for i := 0; i < 1000; i++ {
	temps.Observe(30 + math.Floor(120*math.Sin(float64(i)*0.1))/10)
}

// Just for demonstration, let's check the state of the summary by
// (ab)using its Write method (which is usually only used by Prometheus
// internally).
metric := &dto.Metric{}
temps.Write(metric)
fmt.Println(proto.MarshalTextString(metric))

Output:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
summary: <
  sample_count: 1000
  sample_sum: 29969.50000000001
  quantile: <
    quantile: 0.5
    value: 31.1
  >
  quantile: <
    quantile: 0.9
    value: 41.3
  >
  quantile: <
    quantile: 0.99
    value: 41.9
  >

func NewSummary

1
func NewSummary(opts SummaryOpts) Summary

NewSummary基于提供的SummaryOpts创建一个新的Summary。

type SummaryOpts

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
type SummaryOpts struct {
	// Namespace, Subsystem, and Name are components of the fully-qualified
	// name of the Summary (created by joining these components with
	// "_"). Only Name is mandatory, the others merely help structuring the
	// name. Note that the fully-qualified name of the Summary must be a
	// valid Prometheus metric name.
	Namespace string
	Subsystem string
	Name      string

	// Help provides information about this Summary.
	//
	// Metrics with the same fully-qualified name must have the same Help
	// string.
	Help string

	// ConstLabels are used to attach fixed labels to this metric. Metrics
	// with the same fully-qualified name must have the same label names in
	// their ConstLabels.
	//
	// Due to the way a Summary is represented in the Prometheus text format
	// and how it is handled by the Prometheus server internally, “quantile”
	// is an illegal label name. Construction of a Summary or SummaryVec
	// will panic if this label name is used in ConstLabels.
	//
	// ConstLabels are only used rarely. In particular, do not use them to
	// attach the same labels to all your metrics. Those use cases are
	// better covered by target labels set by the scraping Prometheus
	// server, or by one specific metric (e.g. a build_info or a
	// machine_role metric). See also
	// https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels,-not-static-scraped-labels
	ConstLabels Labels

	// Objectives defines the quantile rank estimates with their respective
	// absolute error. If Objectives[q] = e, then the value reported for q
	// will be the φ-quantile value for some φ between q-e and q+e.  The
	// default value is an empty map, resulting in a summary without
	// quantiles.
	Objectives map[float64]float64

	// MaxAge defines the duration for which an observation stays relevant
	// for the summary. Must be positive. The default value is DefMaxAge.
	MaxAge time.Duration

	// AgeBuckets is the number of buckets used to exclude observations that
	// are older than MaxAge from the summary. A higher number has a
	// resource penalty, so only increase it if the higher resolution is
	// really required. For very high observation rates, you might want to
	// reduce the number of age buckets. With only one age bucket, you will
	// effectively see a complete reset of the summary each time MaxAge has
	// passed. The default value is DefAgeBuckets.
	AgeBuckets uint32

	// BufCap defines the default sample stream buffer size.  The default
	// value of DefBufCap should suffice for most uses. If there is a need
	// to increase the value, a multiple of 500 is recommended (because that
	// is the internal buffer size of the underlying package
	// "github.com/bmizerany/perks/quantile").
	BufCap uint32
}

SummaryOpts捆绑了用于创建“摘要”指标的选项。必须将Name设置为非空字符串。尽管所有其他字段都是可选的,并且可以安全地保留为零值,但是建议设置帮助字符串并将“ Objectives”字段明确设置为所需值,因为默认值将在库的即将发布的v1.0.0中更改。

type SummaryVec

1
2
3
type SummaryVec struct {
	// contains filtered or unexported fields
}

SummaryVec是一个收集器,捆绑了一组共享相同的Desc,但其变量标签具有不同值的摘要。如果要计算按不同维度划分的同一事物(例如,HTTP请求等待时间,按状态代码和方法划分的分区),则使用此方法。使用NewSummaryVec创建实例。

例子

Code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
temps := prometheus.NewSummaryVec(
	prometheus.SummaryOpts{
		Name:       "pond_temperature_celsius",
		Help:       "The temperature of the frog pond.",
		Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
	},
	[]string{"species"},
)

// Simulate some observations.
for i := 0; i < 1000; i++ {
	temps.WithLabelValues("litoria-caerulea").Observe(30 + math.Floor(120*math.Sin(float64(i)*0.1))/10)
	temps.WithLabelValues("lithobates-catesbeianus").Observe(32 + math.Floor(100*math.Cos(float64(i)*0.11))/10)
}

// Create a Summary without any observations.
temps.WithLabelValues("leiopelma-hochstetteri")

// Just for demonstration, let's check the state of the summary vector
// by registering it with a custom registry and then let it collect the
// metrics.
reg := prometheus.NewRegistry()
reg.MustRegister(temps)

metricFamilies, err := reg.Gather()
if err != nil || len(metricFamilies) != 1 {
	panic("unexpected behavior of custom test registry")
}
fmt.Println(proto.MarshalTextString(metricFamilies[0]))

Output:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
name: "pond_temperature_celsius"
help: "The temperature of the frog pond."
type: SUMMARY
metric: <
  label: <
    name: "species"
    value: "leiopelma-hochstetteri"
  >
  summary: <
    sample_count: 0
    sample_sum: 0
    quantile: <
      quantile: 0.5
      value: nan
    >
    quantile: <
      quantile: 0.9
      value: nan
    >
    quantile: <
      quantile: 0.99
      value: nan
    >
  >
>
metric: <
  label: <
    name: "species"
    value: "lithobates-catesbeianus"
  >
  summary: <
    sample_count: 1000
    sample_sum: 31956.100000000017
    quantile: <
      quantile: 0.5
      value: 32.4
    >
    quantile: <
      quantile: 0.9
      value: 41.4
    >
    quantile: <
      quantile: 0.99
      value: 41.9
    >
  >
>
metric: <
  label: <
    name: "species"
    value: "litoria-caerulea"
  >
  summary: <
    sample_count: 1000
    sample_sum: 29969.50000000001
    quantile: <
      quantile: 0.5
      value: 31.1
    >
    quantile: <
      quantile: 0.9
      value: 41.3
    >
    quantile: <
      quantile: 0.99
      value: 41.9
    >
  >
>

func NewSummaryVec

1
func NewSummaryVec(opts SummaryOpts, labelNames []string) *SummaryVec

NewSummaryVec基于提供的SummaryOpts创建一个新的SummaryVec,并按给定的标签名称进行分区。

由于摘要以Prometheus文本格式表示的方式以及Prometheus服务器在内部如何处理摘要,因此“quantile”是非法的标签名称。如果使用此标签名称,NewSummaryVec将惊慌。

func (SummaryVec) Collect

1
func (m SummaryVec) Collect(ch chan<- Metric)

收集器收集器。

func (*SummaryVec) CurryWith

1
func (v *SummaryVec) CurryWith(labels Labels) (ObserverVec, error)

CurryWith返回使用提供的标签进行咖喱处理的向量,即返回的向量具有针对其执行的所有标记操作预先设置的那些标签。相应地减小了咖喱矢量的基数。其余标签的顺序保持不变(只是将咖喱标签从序列中取出,这与(GetMetric)WithLabelValues方法有关)。可以咖喱咖喱的矢量,但只能使用之前尚未用于咖喱的标签。

SummaryVec中包含的度量在已管理和未已管理向量之间共享。只是以不同的方式访问它们。在集合方面,咖喱和非咖喱向量的行为相同。必须在给定的注册表中注册一个(通常是未更新的版本)。即使对当前向量调用了Reset方法,Reset方法也会删除所有指标。

func (SummaryVec) Delete

1
func (m SummaryVec) Delete(labels Labels) bool

删除会删除指标,其中变量标签与作为标签传入的标签相同。如果删除了指标,则返回true。

如果标签的编号和名称与Desc中的VariableLabel的编号和名称不一致,则不是错误。但是,此类不一致的标签永远无法与实际指标匹配,因此在这种情况下该方法将始终返回false。

此方法与DeleteLabelValues(… string)的用途相同。有关两种方法的优缺点,请参见此处。

func (SummaryVec) DeleteLabelValues

1
func (m SummaryVec) DeleteLabelValues(lvs ...string) bool

DeleteLabelValues删除Metric,其中变量标签与作为标签传入的变量相同(与Desc中的VariableLabel顺序相同)。如果删除了指标,则返回true。

如果标签值的数量与Desc中的VariableLabels的数量不同,这不是错误。但是,这种不一致的标签计数永远无法与实际指标匹配,因此在这种情况下该方法将始终返回false。

请注意,对于多个标签值,此方法很容易因参数顺序错误而导致错误。考虑使用Delete(Labels)来避免这种类型的错误。对于更高的标签编号,后者具有更易读(尽管更冗长)的语法,但是它会带来性能开销(用于创建和处理Labels映射)。另请参见CounterVec示例。

func (SummaryVec) Describe

1
func (m SummaryVec) Describe(ch chan<- *Desc)

描述工具收集器。

func (*SummaryVec) GetMetricWith

1
func (v *SummaryVec) GetMetricWith(labels Labels) (Observer, error)

GetMetricWith返回给定标签映射的摘要(标签名称必须与Desc中的VariableLabel的名称匹配)。如果是第一次访问该标签图,则会创建一个新的摘要。不使用摘要创建摘要并保留摘要供以后使用的含义与GetMetricWithLabelValues相同。

如果标签的编号和名称与Desc中的VariableLabel的编号和名称不一致(减去任何已处理的标签),则会返回错误。

此方法与GetMetricWithLabelValues(… string)的用途相同。有关两种方法的优缺点,请参见此处。

func (*SummaryVec) GetMetricWithLabelValues

1
func (v *SummaryVec) GetMetricWithLabelValues(lvs ...string) (Observer, error)

GetMetricWithLabelValues返回给定标签值切片的摘要(与Desc中的VariableLabels顺序相同)。如果是第一次访问标签值的组合,则会创建一个新的摘要。

可以在不使用返回的Summary的情况下调用此方法,仅创建新的Summary,而将其保留为初始值,即没有任何观察值的Summary。

保留摘要以备后用是可能的(如果性能至关重要,则应考虑使用),但请记住,可以使用Reset,DeleteLabelValues和Delete从SummaryVec中删除摘要。在这种情况下,即使稍后创建具有相同标签值的摘要,摘要仍将存在,但不再导出。另请参见CounterVec示例。

如果标签值的数量与Desc中的VariableLabels的数量(减去任何已固化的标签)不同,则返回错误。

请注意,对于多个标签值,此方法很容易因参数顺序错误而导致错误。考虑使用GetMetricWith(Labels)作为替代方案来避免这种类型的错误。对于更高的标签编号,后者具有更易读(尽管更冗长)的语法,但是它会带来性能开销(用于创建和处理Labels映射)。另请参见GaugeVec示例。

func (*SummaryVec) MustCurryWith

1
func (v *SummaryVec) MustCurryWith(labels Labels) ObserverVec

MustCurryWith可以作为CurryWith使用,但在CurryWith会返回错误的情况下会出现混乱。

func (SummaryVec) Reset

1
func (m SummaryVec) Reset()

重置将删除此向量中的所有指标。

func (*SummaryVec) With

1
func (v *SummaryVec) With(labels Labels) Observer

With与GetMetricWith一样工作,但在GetMetricWithLabels会返回错误的地方感到慌张。不返回错误允许使用以下快捷方式

1
myVec.With(prometheus.Labels{"code": "404", "method": "GET"}).Observe(42.21)

func (*SummaryVec) WithLabelValues

1
func (v *SummaryVec) WithLabelValues(lvs ...string) Observer

WithLabelValues可以用作GetMetricWithLabelValues,但是在GetMetricWithLabelValues会返回错误的地方出现混乱。不返回错误允许使用以下快捷方式

1
myVec.WithLabelValues("404", "GET").Observe(42.21)

type Desc

1
2
3
type Desc struct {
	// contains filtered or unexported fields
}

Desc是每个Prometheus指标使用的描述符。它本质上是Metric的不可变元数据。此程序包中包含的常规Metric实现在后台管理其Desc。如果用户使用诸​​如ExpvarCollector或自定义收集器和Metric之类的高级功能,则仅需处理Desc。

如果在相同的注册表中注册的描述符共享相同的完全限定名称,则它们必须满足某些一致性和唯一性条件:constLabels和variableLabels的描述符必须具有相同的帮助字符串和相同的标签名称(即标签尺寸),但是constLabels的值必须不同。

共享相同常量名称和constLabel相同标签值的描述符被视为相等。

使用NewDesc创建新的Desc实例。

func NewDesc

1
func NewDesc(fqName, help string, variableLabels []string, constLabels Labels) *Desc

NewDesc分配并初始化新的Desc。错误记录在Desc中,并将在注册时间报告。如果不应该设置这样的标签,variableLabels和constLabels可以为nil。fqName不能为空。

variableLabels仅包含标签名称。它们的标签值是可变的,因此不是Desc的一部分。(它们在Metric内管理。)

对于constLabels,标签值是恒定的。因此,它们在“描述”中已完全指定。有关用法模式,请参见收集器示例。

func NewInvalidDesc

1
func NewInvalidDesc(err error) *Desc

NewInvalidDesc返回无效的描述符,即具有提供的错误集的描述符。如果注册了返回此类描述符的收集器,则注册将失败,并显示所提供的错误。收集器可以使用NewInvalidDesc来表示无法描述自己。

func (*Desc) String

1
func (d *Desc) String() string

type ExemplarAdder

1
2
3
type ExemplarAdder interface {
	AddWithExemplar(value float64, exemplar Labels)
}

ExemplarAdder由Counters实现,Counter提供了与示例一起向Counter添加值的选项。它的AddWithExemplar方法的工作方式与Counter接口的Add方法类似,但是也用新的(由提供的值,当前时间作为时间戳记和提供的标签)创建的新示例替换了当前保存的示例(如果有)。空标签将导致有效的(无标签)示例。但是,如果Labels为nil,则当前示例保留不变。如果值<0,提供的任何标签无效或提供的标签总共包含64个以上符文,则AddWithExemplar会发生混乱。

type ExemplarObserver

1
2
3
type ExemplarObserver interface {
	ObserveWithExemplar(value float64, exemplar Labels)
}

ExemplarObserver由观察者实现,该观察者提供了与示例一起观察值的选项。它的ObserveWithExemplar方法的工作方式类似于Observer的Observe方法,但也用新的(由提供的值,当前时间作为时间戳记和提供的Label)创建的新示例替换了当前保存的示例(如果有)。空标签将导致有效的(无标签)示例。但是,如果Labels为nil,则当前示例保留不变。如果提供的任何标签无效或提供的标签总共包含64个以上符文,则ObserveWithExemplar会发生混乱。

type Gatherer

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
type Gatherer interface {
	// Gather calls the Collect method of the registered Collectors and then
	// gathers the collected metrics into a lexicographically sorted slice
	// of uniquely named MetricFamily protobufs. Gather ensures that the
	// returned slice is valid and self-consistent so that it can be used
	// for valid exposition. As an exception to the strict consistency
	// requirements described for metric.Desc, Gather will tolerate
	// different sets of label names for metrics of the same metric family.
	//
	// Even if an error occurs, Gather attempts to gather as many metrics as
	// possible. Hence, if a non-nil error is returned, the returned
	// MetricFamily slice could be nil (in case of a fatal error that
	// prevented any meaningful metric collection) or contain a number of
	// MetricFamily protobufs, some of which might be incomplete, and some
	// might be missing altogether. The returned error (which might be a
	// MultiError) explains the details. Note that this is mostly useful for
	// debugging purposes. If the gathered protobufs are to be used for
	// exposition in actual monitoring, it is almost always better to not
	// expose an incomplete result and instead disregard the returned
	// MetricFamily protobufs in case the returned error is non-nil.
	Gather() ([]*dto.MetricFamily, error)
}

Gatherer是注册表的一部分,负责将收集的指标收集到许多MetricFamilies中。Gatherer interface具有与Registerer interface 相同的一般含义。

type GathererFunc

1
type GathererFunc func() ([]*dto.MetricFamily, error)

GathererFunc将功能转换为Gatherer。

func (GathererFunc) Gather

1
func (gf GathererFunc) Gather() ([]*dto.MetricFamily, error)

Gather实现Gatherer。

type Gatherers

1
type Gatherers []Gatherer

Gatherers是实现Gatherer接口本身的Gatherer实例的一部分。它的Gather方法按顺序在切片中的所有Gatherer上调用Gather并返回合并的结果。从Gather调用返回的错误全部以扁平化的MultiError返回。跳过重复和不一致的Metric(以分片顺序获胜的方式首次出现),并在返回的错误中报告。

收集器可用于合并来自多个注册表的收集结果。它还提供了一种通过使用Gather方法创建自定义Gatherer的方法,将现有的MetricFamily原型直接注入到集合中,该方法仅返回现有的MetricFamily原型。请注意,不涉及注册(与收集器注册相反),因此显然无法进行注册时检查。收集的MetricFamilies之间的任何不一致都会通过Gather方法报告为错误,并且会删除不一致的Metric。MetricFamilies的无效部分(例如,语法上无效的Metric或标签名称)将不会被检测到。

Code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
reg := prometheus.NewRegistry()
temp := prometheus.NewGaugeVec(
	prometheus.GaugeOpts{
		Name: "temperature_kelvin",
		Help: "Temperature in Kelvin.",
	},
	[]string{"location"},
)
reg.MustRegister(temp)
temp.WithLabelValues("outside").Set(273.14)
temp.WithLabelValues("inside").Set(298.44)

var parser expfmt.TextParser

text := `
## TYPE humidity_percent gauge
## HELP humidity_percent Humidity in %.
humidity_percent{location="outside"} 45.4
humidity_percent{location="inside"} 33.2
## TYPE temperature_kelvin gauge
## HELP temperature_kelvin Temperature in Kelvin.
temperature_kelvin{location="somewhere else"} 4.5
`

parseText := func() ([]*dto.MetricFamily, error) {
	parsed, err := parser.TextToMetricFamilies(strings.NewReader(text))
	if err != nil {
		return nil, err
	}
	var result []*dto.MetricFamily
	for _, mf := range parsed {
		result = append(result, mf)
	}
	return result, nil
}

gatherers := prometheus.Gatherers{
	reg,
	prometheus.GathererFunc(parseText),
}

gathering, err := gatherers.Gather()
if err != nil {
	fmt.Println(err)
}

out := &bytes.Buffer{}
for _, mf := range gathering {
	if _, err := expfmt.MetricFamilyToText(out, mf); err != nil {
		panic(err)
	}
}
fmt.Print(out.String())
fmt.Println("----------")

// Note how the temperature_kelvin metric family has been merged from
// different sources. Now try
text = `
## TYPE humidity_percent gauge
## HELP humidity_percent Humidity in %.
humidity_percent{location="outside"} 45.4
humidity_percent{location="inside"} 33.2
## TYPE temperature_kelvin gauge
## HELP temperature_kelvin Temperature in Kelvin.
## Duplicate metric:
temperature_kelvin{location="outside"} 265.3
 ## Missing location label (note that this is undesirable but valid):
temperature_kelvin 4.5
`

gathering, err = gatherers.Gather()
if err != nil {
	fmt.Println(err)
}
// Note that still as many metrics as possible are returned:
out.Reset()
for _, mf := range gathering {
	if _, err := expfmt.MetricFamilyToText(out, mf); err != nil {
		panic(err)
	}
}
fmt.Print(out.String())

Output:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
## HELP humidity_percent Humidity in %.
## TYPE humidity_percent gauge
humidity_percent{location="inside"} 33.2
humidity_percent{location="outside"} 45.4
## HELP temperature_kelvin Temperature in Kelvin.
## TYPE temperature_kelvin gauge
temperature_kelvin{location="inside"} 298.44
temperature_kelvin{location="outside"} 273.14
temperature_kelvin{location="somewhere else"} 4.5
----------
collected metric "temperature_kelvin" { label:<name:"location" value:"outside" > gauge:<value:265.3 > } was collected before with the same name and label values
## HELP humidity_percent Humidity in %.
## TYPE humidity_percent gauge
humidity_percent{location="inside"} 33.2
humidity_percent{location="outside"} 45.4
## HELP temperature_kelvin Temperature in Kelvin.
## TYPE temperature_kelvin gauge
temperature_kelvin 4.5
temperature_kelvin{location="inside"} 298.44
temperature_kelvin{location="outside"} 273.14

func (Gatherers) Gather

1
func (gs Gatherers) Gather() ([]*dto.MetricFamily, error)

type Labels

1
type Labels map[string]string

标签代表标签名称->值映射的集合。此类型通常与度量矢量收集器的With(Labels)和GetMetricWith(Labels)方法一起使用,例如:

1
myVec.With(Labels{"code": "404", "method": "GET"}).Add(42)

另一个用例是在Opts中或创建Desc中指定常量标签对。

type Metric

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
type Metric interface {
	// Desc returns the descriptor for the Metric. This method idempotently
	// returns the same descriptor throughout the lifetime of the
	// Metric. The returned descriptor is immutable by contract. A Metric
	// unable to describe itself must return an invalid descriptor (created
	// with NewInvalidDesc).
	Desc() *Desc
	// Write encodes the Metric into a "Metric" Protocol Buffer data
	// transmission object.
	//
	// Metric implementations must observe concurrency safety as reads of
	// this metric may occur at any time, and any blocking occurs at the
	// expense of total performance of rendering all registered
	// metrics. Ideally, Metric implementations should support concurrent
	// readers.
	//
	// While populating dto.Metric, it is the responsibility of the
	// implementation to ensure validity of the Metric protobuf (like valid
	// UTF-8 strings or syntactically valid metric and label names). It is
	// recommended to sort labels lexicographically. Callers of Write should
	// still make sure of sorting if they depend on it.
	Write(*dto.Metric) error
}

Metric将单个样本值建模,并将其元数据导出到Prometheus。此程序包中Metric的实现是仪表,计数器,直方图,摘要和无类型的。

func MustNewConstHistogram

1
2
3
4
5
6
7
func MustNewConstHistogram(
	desc *Desc,
	count uint64,
	sum float64,
	buckets map[float64]uint64,
	labelValues ...string,
) Metric

MustNewConstHistogram是NewConstHistogram的一个版本,它会惊慌于NewConstHistogram返回错误的地方。

func MustNewConstMetric

1
func MustNewConstMetric(desc *Desc, valueType ValueType, value float64, labelValues ...string) Metric

MustNewConstMetric是NewConstMetric的一个版本,它会惊慌于NewConstMetric返回错误的地方。

func MustNewConstSummary

1
2
3
4
5
6
7
func MustNewConstSummary(
	desc *Desc,
	count uint64,
	sum float64,
	quantiles map[float64]float64,
	labelValues ...string,
) Metric

MustNewConstSummary是NewConstSummary的一个版本,它会惊慌,NewConstMetric将返回错误。

func NewConstHistogram

1
2
3
4
5
6
7
func NewConstHistogram(
	desc *Desc,
	count uint64,
	sum float64,
	buckets map[float64]uint64,
	labelValues ...string,
) (Metric, error)

NewConstHistogram返回一个表示Prometheus直方图的度量,该度量具有用于计数,总和和存储桶计数的固定值。由于无法更改这些参数,因此返回的值不会实现直方图接口(而只能实现公制接口)。使用此软件包的用户在常规操作中将不会使用太多。但是,在实现自定义收集器时,它是一种即用即弃的Metric,可以即时生成以用Collect方法将其发送给Prometheus。

buckets是上限到累积计数的映射,不包括+ Inf buckets。

如果labelValues的长度与Desc中的变量标签不一致,或者Desc无效,则NewConstHistogram返回错误。

例子

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
desc := prometheus.NewDesc(
	"http_request_duration_seconds",
	"A histogram of the HTTP request durations.",
	[]string{"code", "method"},
	prometheus.Labels{"owner": "example"},
)

// Create a constant histogram from values we got from a 3rd party telemetry system.
h := prometheus.MustNewConstHistogram(
	desc,
	4711, 403.34,
	map[float64]uint64{25: 121, 50: 2403, 100: 3221, 200: 4233},
	"200", "get",
)

// Just for demonstration, let's check the state of the histogram by
// (ab)using its Write method (which is usually only used by Prometheus
// internally).
metric := &dto.Metric{}
h.Write(metric)
fmt.Println(proto.MarshalTextString(metric))

Output:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
label: <
  name: "code"
  value: "200"
>
label: <
  name: "method"
  value: "get"
>
label: <
  name: "owner"
  value: "example"
>
histogram: <
  sample_count: 4711
  sample_sum: 403.34
  bucket: <
    cumulative_count: 121
    upper_bound: 25
  >
  bucket: <
    cumulative_count: 2403
    upper_bound: 50
  >
  bucket: <
    cumulative_count: 3221
    upper_bound: 100
  >
  bucket: <
    cumulative_count: 4233
    upper_bound: 200
  >
>

func NewConstMetric

1
func NewConstMetric(desc *Desc, valueType ValueType, value float64, labelValues ...string) (Metric, error)

NewConstMetric返回具有一个固定值且无法更改的度量。使用此软件包的用户在常规操作中将不会使用太多。但是,在实现自定义收集器时,它是一种即时生成的一次性指标,可以通过Collect方法将其发送给Prometheus。如果labelValues的长度与Desc中的变量标签不一致,或者Desc无效,则NewConstMetric返回错误。

func NewConstSummary

1
2
3
4
5
6
7
func NewConstSummary(
	desc *Desc,
	count uint64,
	sum float64,
	quantiles map[float64]float64,
	labelValues ...string,
) (Metric, error)

NewConstSummary返回一个Metric,该Metric表示Prometheus摘要,其计数,总和和分位数具有固定值。由于无法更改这些参数,因此返回的值不会实现Summary接口(而只能实现Metric接口)。使用此软件包的用户在常规操作中将不会使用太多。但是,在实现自定义收集器时,它是一种即时生成的一次性指标,可以通过Collect方法将其发送给Prometheus。

分位数图将等级排名为分位数。例如,中值等待时间为0.23s,第99个百分位等待时间为0.56s表示为:

1
map[float64]float64{0.5: 0.23, 0.99: 0.56}

如果labelValues的长度与Desc中的变量标签不一致,或者Desc无效,则NewConstSummary返回错误。

例子

Code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
desc := prometheus.NewDesc(
	"http_request_duration_seconds",
	"A summary of the HTTP request durations.",
	[]string{"code", "method"},
	prometheus.Labels{"owner": "example"},
)

// Create a constant summary from values we got from a 3rd party telemetry system.
s := prometheus.MustNewConstSummary(
	desc,
	4711, 403.34,
	map[float64]float64{0.5: 42.3, 0.9: 323.3},
	"200", "get",
)

// Just for demonstration, let's check the state of the summary by
// (ab)using its Write method (which is usually only used by Prometheus
// internally).
metric := &dto.Metric{}
s.Write(metric)
fmt.Println(proto.MarshalTextString(metric))

Output:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
label: <
  name: "code"
  value: "200"
>
label: <
  name: "method"
  value: "get"
>
label: <
  name: "owner"
  value: "example"
>
summary: <
  sample_count: 4711
  sample_sum: 403.34
  quantile: <
    quantile: 0.5
    value: 42.3
  >
  quantile: <
    quantile: 0.9
    value: 323.3
  >
>

func NewInvalidMetric

1
func NewInvalidMetric(desc *Desc, err error) Metric

NewInvalidMetric返回一个指标,该指标的Write方法始终返回提供的错误。如果收集器发现自己无法收集Metric并希望向注册表报告错误,这将很有用。

func NewMetricWithTimestamp

1
func NewMetricWithTimestamp(t time.Time, m Metric) Metric

NewMetricWithTimestamp返回一个新的Metric,该Metric以将显式时间戳记设置为所提供的Time的方式包装所提供的Metric。这仅在极少数情况下有用,因为PrometheusMetric的时间戳通常应由Prometheus服务器在抓取期间设置。例外情况包括具有来自其他Metric来源的给定时间戳的镜像Metric。

NewMetricWithTimestamp与MustNewConstMetric,MustNewConstHistogram和MustNewConstSummary一起使用效果最佳,请参见示例。

当前,Prometheus使用的展示格式仅限于毫秒分辨率。因此,提供的时间将舍入到下一个完整的毫秒值。

例子

Code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
desc := prometheus.NewDesc(
	"temperature_kelvin",
	"Current temperature in Kelvin.",
	nil, nil,
)

// Create a constant gauge from values we got from an external
// temperature reporting system. Those values are reported with a slight
// delay, so we want to add the timestamp of the actual measurement.
temperatureReportedByExternalSystem := 298.15
timeReportedByExternalSystem := time.Date(2009, time.November, 10, 23, 0, 0, 12345678, time.UTC)
s := prometheus.NewMetricWithTimestamp(
	timeReportedByExternalSystem,
	prometheus.MustNewConstMetric(
		desc, prometheus.GaugeValue, temperatureReportedByExternalSystem,
	),
)

// Just for demonstration, let's check the state of the gauge by
// (ab)using its Write method (which is usually only used by Prometheus
// internally).
metric := &dto.Metric{}
s.Write(metric)
fmt.Println(proto.MarshalTextString(metric))

Output:

1
2
3
4
gauge: <
  value: 298.15
>
timestamp_ms: 1257894000012

type MultiError

1
type MultiError []error

MultiError是实现错误接口的错误片段。收集器使用它来报告MetricFamily收集期间的多个错误。

func (*MultiError) Append

1
func (errs *MultiError) Append(err error)

如果错误不是nil,则追加会附加提供的错误。

func (MultiError) Error

1
func (errs MultiError) Error() string

func (MultiError) MaybeUnwrap

1
func (errs MultiError) MaybeUnwrap() error

如果len(errs)为0,则MaybeUnwrap返回nil。如果len(errs)为1,则返回第一个且仅包含错误的错误。在所有其他情况下,它直接返回MultiError。这对于以仅在需要时使用MultiError的方式返回MultiError很有帮助。

type Observer

1
2
3
type Observer interface {
	Observe(float64)
}

Observer是包装Observe方法的接口,直方图和摘要用于添加观察值。

type ObserverFunc

1
type ObserverFunc func(float64)

ObserverFunc类型是一个适配器,允许将普通功能用作Observers。如果f是具有适当签名的函数,则ObserverFunc(f)是调用f的Observer。

此适配器通常与Timer类型结合使用,并且有两种常规使用情况:

最常见的一种是将仪表用作计时器的观察器。请参见“仪表”计时器示例。

更高级的用例是创建一个功能,该功能可动态决定使用哪个观察者来观察持续时间。请参见“复杂”计时器示例。

func (ObserverFunc) Observe

1
func (f ObserverFunc) Observe(value float64)

Observe 调用 f(value)。它实现了observer。

type ObserverVec

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
type ObserverVec interface {
	GetMetricWith(Labels) (Observer, error)
	GetMetricWithLabelValues(lvs ...string) (Observer, error)
	With(Labels) Observer
	WithLabelValues(...string) Observer
	CurryWith(Labels) (ObserverVec, error)
	MustCurryWith(Labels) ObserverVec

	Collector
}

ObserverVec是由“HistogramVec”和“SummaryVec”实现的接口。

type Opts

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
type Opts struct {
	// Namespace, Subsystem, and Name are components of the fully-qualified
	// name of the Metric (created by joining these components with
	// "_"). Only Name is mandatory, the others merely help structuring the
	// name. Note that the fully-qualified name of the metric must be a
	// valid Prometheus metric name.
	Namespace string
	Subsystem string
	Name      string

	// Help provides information about this metric.
	//
	// Metrics with the same fully-qualified name must have the same Help
	// string.
	Help string

	// ConstLabels are used to attach fixed labels to this metric. Metrics
	// with the same fully-qualified name must have the same label names in
	// their ConstLabels.
	//
	// ConstLabels are only used rarely. In particular, do not use them to
	// attach the same labels to all your metrics. Those use cases are
	// better covered by target labels set by the scraping Prometheus
	// server, or by one specific metric (e.g. a build_info or a
	// machine_role metric). See also
	// https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels,-not-static-scraped-labels
	ConstLabels Labels
}

Opts捆绑了用于创建大多数指标类型的选项。每个度量实现XXX都有其自己的XXXOpts类型,但在大多数情况下,它只是该类型的别名(可能在需求出现时更改)。

必须将Name设置为非空字符串。尽管强烈建议您设置帮助字符串,但所有其他字段都是可选的,可以安全地保留其零值。

type ProcessCollectorOpts

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
type ProcessCollectorOpts struct {
	// PidFn returns the PID of the process the collector collects metrics
	// for. It is called upon each collection. By default, the PID of the
	// current process is used, as determined on construction time by
	// calling os.Getpid().
	PidFn func() (int, error)
	// If non-empty, each of the collected metrics is prefixed by the
	// provided string and an underscore ("_").
	Namespace string
	// If true, any error encountered during collection is reported as an
	// invalid metric (see NewInvalidMetric). Otherwise, errors are ignored
	// and the collected metrics will be incomplete. (Possibly, no metrics
	// will be collected at all.) While that's usually not desired, it is
	// appropriate for the common "mix-in" of process metrics, where process
	// metrics are nice to have, but failing to collect them should not
	// disrupt the collection of the remaining metrics.
	ReportErrors bool
}

ProcessCollectorOpts定义使用NewProcessCollector创建的过程指标收集器的行为。

type Registerer

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
type Registerer interface {
	// Register registers a new Collector to be included in metrics
	// collection. It returns an error if the descriptors provided by the
	// Collector are invalid or if they — in combination with descriptors of
	// already registered Collectors — do not fulfill the consistency and
	// uniqueness criteria described in the documentation of metric.Desc.
	//
	// If the provided Collector is equal to a Collector already registered
	// (which includes the case of re-registering the same Collector), the
	// returned error is an instance of AlreadyRegisteredError, which
	// contains the previously registered Collector.
	//
	// A Collector whose Describe method does not yield any Desc is treated
	// as unchecked. Registration will always succeed. No check for
	// re-registering (see previous paragraph) is performed. Thus, the
	// caller is responsible for not double-registering the same unchecked
	// Collector, and for providing a Collector that will not cause
	// inconsistent metrics on collection. (This would lead to scrape
	// errors.)
	Register(Collector) error
	// MustRegister works like Register but registers any number of
	// Collectors and panics upon the first registration that causes an
	// error.
	MustRegister(...Collector)
	// Unregister unregisters the Collector that equals the Collector passed
	// in as an argument.  (Two Collectors are considered equal if their
	// Describe method yields the same set of descriptors.) The function
	// returns whether a Collector was unregistered. Note that an unchecked
	// Collector cannot be unregistered (as its Describe method does not
	// yield any descriptor).
	//
	// Note that even after unregistering, it will not be possible to
	// register a new Collector that is inconsistent with the unregistered
	// Collector, e.g. a Collector collecting metrics with the same name but
	// a different help string. The rationale here is that the same registry
	// instance must only collect consistent metrics throughout its
	// lifetime.
	Unregister(Collector) bool
}

注册器是注册表中负责注册和注销的部分的接口。定制注册表的用户应将Registerer用作注册的类型(而不是直接使用Registry类型)。这样,他们可以自由使用自定义的Registerer实现(例如,出于测试目的)。

func WrapRegistererWith

1
func WrapRegistererWith(labels Labels, reg Registerer) Registerer

WrapRegistererWith返回包装提供的注册器的注册器。在返回的注册器中注册的收集器将以修改后的方式在包装的注册器中注册。修改后的收集器会将提供的标签添加到它收集的所有Metric中(作为ConstLabels)。未经修改的收集器收集的Metric不得重复任何这些标签。包装一个nil值是有效的,导致没有操作的register。

WrapRegistererWith提供了一种向收集器的子集添加固定标签的方法。不应将其用于向所有公开的指标添加固定标签。

仍将检测到通过原始注册器注册的收集器与通过包装注册器注册的收集器之间的冲突。由任一注册器的Register方法返回的任何AlreadyRegisteredError都将包含ExistingCollector,其形式已提供给相应的注册表。

收集器示例演示了WrapRegistererWith的用法。

func WrapRegistererWithPrefix

1
func WrapRegistererWithPrefix(prefix string, reg Registerer) Registerer

WrapRegistererWithPrefix返回包装提供的注册器的注册器。在返回的注册器中注册的收集器将以修改后的方式在包装的注册器中注册。修改后的收集器会将提供的前缀添加到它收集的所有Metric的名称中。包装一个nil值是有效的,导致没有操作寄存器。

WrapRegistererWithPrefix对于在一个子系统前面放置所有度量的前缀很有用。为此,请使用WrapRegistererWithPrefix返回的包装注册器注册子系统的度量。对于所有公开的指标,使用相同的前缀很少有用。特别是,不要在跨应用程序标准化的Metric名称前添加前缀,因为这会破坏水平监视,例如Go收集器(请参阅NewGoCollector)和流程收集器(请参阅NewProcessCollector)提供的Metric。(实际上,这些指标已经分别以“ go_”或“ process_”为前缀。)

仍将检测到通过原始注册器注册的收集器与通过包装注册器注册的收集器之间的冲突。由任一注册器的Register方法返回的任何AlreadyRegisteredError都将包含ExistingCollector,其形式已提供给相应的注册表。

type Registry

1
2
3
type Registry struct {
	// contains filtered or unexported fields
}

注册表注册Prometheus收集器,收集其度量,然后将其收集到MetricFamilies中进行说明。它同时实现了Registerer和Gatherer。零值不可用。使用NewRegistry或NewPedanticRegistry创建实例。

func NewPedanticRegistry

1
func NewPedanticRegistry() *Registry

NewPedanticRegistry返回一个注册表,该注册表在收集期间检查每个收集的指标是否与其报告的Desc一致,以及Desc是否实际上已在注册表中注册。未检查的收集器(其Describe方法不产生任何描述符的收集器)从检查中排除。

通常,只要所有收集的Metric的并集一致且有效,即使某些Metric与其自己的Desc或由其注册收集者提供的Desc不一致,注册管理机构也会很高兴。行为良好的收集器和指标只会提供一致的描述。该注册表对于测试收集器和Metric的实现很有用。

func NewRegistry

1
func NewRegistry() *Registry

NewRegistry会创建一个新的普通注册表,而无需预先注册任何收集器。

func (*Registry) Gather

1
func (r *Registry) Gather() ([]*dto.MetricFamily, error)

Gather实现Gatherer。

func (*Registry) MustRegister

1
func (r *Registry) MustRegister(cs ...Collector)

MustRegister实现Registerer。

func (*Registry) Register

1
func (r *Registry) Register(c Collector) error

Register实现Registerer。

func (*Registry) Unregister

1
func (r *Registry) Unregister(c Collector) bool

Unregister 实现 Registerer.

type Timer

1
2
3
type Timer struct {
	// contains filtered or unexported fields
}

计时器是计时功能的辅助类型。使用NewTimer创建新实例。

例子

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Code:

package prometheus_test

import (
	"math/rand"
	"time"

	"github.com/prometheus/client_golang/prometheus"
)

var (
	requestDuration = prometheus.NewHistogram(prometheus.HistogramOpts{
		Name:    "example_request_duration_seconds",
		Help:    "Histogram for the runtime of a simple example function.",
		Buckets: prometheus.LinearBuckets(0.01, 0.01, 10),
	})
)

func ExampleTimer() {
	// timer times this example function. It uses a Histogram, but a Summary
	// would also work, as both implement Observer. Check out
	// https://prometheus.io/docs/practices/histograms/ for differences.
	timer := prometheus.NewTimer(requestDuration)
	defer timer.ObserveDuration()

	// Do something here that takes time.
	time.Sleep(time.Duration(rand.NormFloat64()*10000+50000) * time.Microsecond)
}

示例(复杂)

Code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package prometheus_test

import (
	"net/http"

	"github.com/prometheus/client_golang/prometheus"
)

var (
	// apiRequestDuration tracks the duration separate for each HTTP status
	// class (1xx, 2xx, ...). This creates a fair amount of time series on
	// the Prometheus server. Usually, you would track the duration of
	// serving HTTP request without partitioning by outcome. Do something
	// like this only if needed. Also note how only status classes are
	// tracked, not every single status code. The latter would create an
	// even larger amount of time series. Request counters partitioned by
	// status code are usually OK as each counter only creates one time
	// series. Histograms are way more expensive, so partition with care and
	// only where you really need separate latency tracking. Partitioning by
	// status class is only an example. In concrete cases, other partitions
	// might make more sense.
	apiRequestDuration = prometheus.NewHistogramVec(
		prometheus.HistogramOpts{
			Name:    "api_request_duration_seconds",
			Help:    "Histogram for the request duration of the public API, partitioned by status class.",
			Buckets: prometheus.ExponentialBuckets(0.1, 1.5, 5),
		},
		[]string{"status_class"},
	)
)

func handler(w http.ResponseWriter, r *http.Request) {
	status := http.StatusOK
	// The ObserverFunc gets called by the deferred ObserveDuration and
	// decides which Histogram's Observe method is called.
	timer := prometheus.NewTimer(prometheus.ObserverFunc(func(v float64) {
		switch {
		case status >= 500: // Server error.
			apiRequestDuration.WithLabelValues("5xx").Observe(v)
		case status >= 400: // Client error.
			apiRequestDuration.WithLabelValues("4xx").Observe(v)
		case status >= 300: // Redirection.
			apiRequestDuration.WithLabelValues("3xx").Observe(v)
		case status >= 200: // Success.
			apiRequestDuration.WithLabelValues("2xx").Observe(v)
		default: // Informational.
			apiRequestDuration.WithLabelValues("1xx").Observe(v)
		}
	}))
	defer timer.ObserveDuration()

	// Handle the request. Set status accordingly.
	// ...
}

func ExampleTimer_complex() {
	http.HandleFunc("/api", handler)
}

示例(量规)

Code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package prometheus_test

import (
	"os"

	"github.com/prometheus/client_golang/prometheus"
)

var (
	// If a function is called rarely (i.e. not more often than scrapes
	// happen) or ideally only once (like in a batch job), it can make sense
	// to use a Gauge for timing the function call. For timing a batch job
	// and pushing the result to a Pushgateway, see also the comprehensive
	// example in the push package.
	funcDuration = prometheus.NewGauge(prometheus.GaugeOpts{
		Name: "example_function_duration_seconds",
		Help: "Duration of the last call of an example function.",
	})
)

func run() error {
	// The Set method of the Gauge is used to observe the duration.
	timer := prometheus.NewTimer(prometheus.ObserverFunc(funcDuration.Set))
	defer timer.ObserveDuration()

	// Do something. Return errors as encountered. The use of 'defer' above
	// makes sure the function is still timed properly.
	return nil
}

func ExampleTimer_gauge() {
	if err := run(); err != nil {
		os.Exit(1)
	}
}

func NewTimer

1
func NewTimer(o Observer) *Timer

NewTimer创建一个新的计时器。提供的观察者用于观察持续时间(以秒为单位)。计时器通常用于通过以下方式为函数调用计时:

1
2
3
4
5
func TimeMe() {
    timer := NewTimer(myHistogram)
    defer timer.ObserveDuration()
    // Do actual work.
}

func (*Timer) ObserveDuration

1
func (t *Timer) ObserveDuration() time.Duration

ObserveDuration记录自使用NewTimer创建计时器以来经过的持续时间。它调用构造期间提供的Observer的Observe方法,以持续时间(以秒为单位)作为参数。观察到的持续时间也将返回。通常使用defer语句调用ObserveDuration。

请注意,只有与Go1.9+一起使用时,才能保证此方法永远不会观察到负持续时间。

type UntypedFunc

1
2
3
4
type UntypedFunc interface {
	Metric
	Collector
}

UntypedFunc的作用类似于GaugeFunc,但收集的指标类型为“Untyped”。UntypedFunc可用于镜像未知类型的外部指标。

要创建UntypedFunc实例,请使用NewUntypedFunc。

func NewUntypedFunc

1
func NewUntypedFunc(opts UntypedOpts, function func() float64) UntypedFunc

NewUntypedFunc基于提供的UntypedOpts创建一个新的UntypedFunc。报告的值是通过在Write方法中调用给定的函数确定的。考虑到指标收集可能会同时发生。如果这导致对Write的并发调用,例如在UntypedFunc直接向Prometheus注册的情况下,则提供的函数必须是并发安全的。

type UntypedOpts
1
type UntypedOpts Opts

UntypedOpts是Opts的别名。请参阅此处以获取文档注释。

type ValueType

1
type ValueType int

ValueType是代表简单值的指标类型的枚举。

1
2
3
4
5
const (
	CounterValue ValueType
	GaugeValue
	UntypedValue
)

ValueType枚举的可能值。使用UntypedValue可以将指标标记为未知类型。

promhttp包

概述

软件包promhttp提供了围绕HTTP服务器和客户端的工具。

首先,该包允许创建http.Handler实例以通过HTTP公开Prometheus指标。promhttp.Handler作用于prometheus.DefaultGatherer。使用HandlerFor,您可以为自定义注册表或实现Gatherer接口的任何内容创建处理程序。它还允许创建对错误采取不同行动或允许记录错误的处理程序。

其次,该软件包提供了通过中间件来检测http.Handler实例的工具。中间件包装器遵循命名方案InstrumentHandlerX,其中X描述了中间件的预期用途。有关详细信息,请参见每个函数的文档注释。

最后,该程序包允许通过中间件检测http.RoundTripper。中间件包装器遵循InstrumentRoundTripperX的命名方案,其中X描述了中间件的预期用途。有关详细信息,请参见每个函数的文档注释。

func Handler

1
func Handler() http.Handler

处理程序使用默认的HandlerOpts返回prometheus.DefaultGatherer的http.Handler,即,它将第一个错误报告为HTTP错误,没有错误日志记录,并且如果客户端请求,则应用压缩。

返回的http.Handler已经使用InstrumentMetricHandler函数和prometheus.DefaultRegisterer进行了检测。如果通过分别调用Handler函数创建多个http.Handlers,则用于检测的度量将在它们之间共享,从而提供全局的scrape计数。

此func旨在涵盖大部分基本用例。如果您要执行需要更多自定义的操作(包括使用非默认的Gatherer,不同的instrumentation和非默认的HandlerOpts),请使用HandlerFor函数。有关详细信息,请参见此处。

func HandlerFor

1
func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler

HandlerFor为提供的Gatherer返回一个非instrumentation化的http.Handler。处理程序的行为由提供的HandlerOpts定义。因此,HandlerFor对于使用非默认HandlerOpts和/或使用自定义(或没有自定义)instrumentation的自定义收集器创建http.Handlers很有用。使用InstrumentMetricHandler函数可以应用与Handler函数所使用的相同类型的检测。

func InstrumentHandlerCounter

1
func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler) http.HandlerFunc

InstrumentHandlerCounter是一个中间件,包装了提供的http.Handler以使用提供的CounterVec观察请求结果。CounterVec必须具有零,一或两个非const非咖喱标签。对于这些标签,唯一允许的标签名称是“代码”和“方法”。否则,该功能会出现问题。如果CounterVec中存在相应的实例标签名称,则可以通过HTTP状态代码和/或HTTP方法对CounterVec进行分区。对于未分区的计数,请使用带有零标签的CounterVec。

如果包装的Handler未设置状态码,则假定状态码为200。

如果包装的处理程序出现紧急情况,则计数器不会增加。

有关用法示例,请参见InstrumentHandlerDuration的示例。

func InstrumentHandlerDuration

1
func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler) http.HandlerFunc

InstrumentHandlerDuration是一个中间件,该中间件包装提供的http.Handler以观察提供的ObserverVec的请求持续时间。ObserverVec必须具有零,一或两个非const非咖喱标签。对于这些标签,唯一允许的标签名称是“code”和“method”。否则,该功能会出现问题。调用ObserverVec中的Observer的Observe方法时,请求持续时间以秒为单位。如果ObserverVec中存在相应的实例标签名称,则通过HTTP状态代码和/或HTTP方法进行分区。对于未分区的观察,请使用带有零标签的ObserverVec。请注意,直方图的划分是昂贵的,应谨慎使用。

如果包装的Handler未设置状态码,则假定状态码为200。

如果包装的处理程序出现紧急情况,则不会报告任何值。

请注意,只有与Go1.9 +一起使用时,才能保证此方法永远不会观察到负持续时间。

例子

Code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
inFlightGauge := prometheus.NewGauge(prometheus.GaugeOpts{
	Name: "in_flight_requests",
	Help: "A gauge of requests currently being served by the wrapped handler.",
})

counter := prometheus.NewCounterVec(
	prometheus.CounterOpts{
		Name: "api_requests_total",
		Help: "A counter for requests to the wrapped handler.",
	},
	[]string{"code", "method"},
)

// duration is partitioned by the HTTP method and handler. It uses custom
// buckets based on the expected request duration.
duration := prometheus.NewHistogramVec(
	prometheus.HistogramOpts{
		Name:    "request_duration_seconds",
		Help:    "A histogram of latencies for requests.",
		Buckets: []float64{.25, .5, 1, 2.5, 5, 10},
	},
	[]string{"handler", "method"},
)

// responseSize has no labels, making it a zero-dimensional
// ObserverVec.
responseSize := prometheus.NewHistogramVec(
	prometheus.HistogramOpts{
		Name:    "response_size_bytes",
		Help:    "A histogram of response sizes for requests.",
		Buckets: []float64{200, 500, 900, 1500},
	},
	[]string{},
)

// Create the handlers that will be wrapped by the middleware.
pushHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Push"))
})
pullHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Pull"))
})

// Register all of the metrics in the standard registry.
prometheus.MustRegister(inFlightGauge, counter, duration, responseSize)

// Instrument the handlers with all the metrics, injecting the "handler"
// label by currying.
pushChain := InstrumentHandlerInFlight(inFlightGauge,
	InstrumentHandlerDuration(duration.MustCurryWith(prometheus.Labels{"handler": "push"}),
		InstrumentHandlerCounter(counter,
			InstrumentHandlerResponseSize(responseSize, pushHandler),
		),
	),
)
pullChain := InstrumentHandlerInFlight(inFlightGauge,
	InstrumentHandlerDuration(duration.MustCurryWith(prometheus.Labels{"handler": "pull"}),
		InstrumentHandlerCounter(counter,
			InstrumentHandlerResponseSize(responseSize, pullHandler),
		),
	),
)

http.Handle("/metrics", Handler())
http.Handle("/push", pushChain)
http.Handle("/pull", pullChain)

if err := http.ListenAndServe(":3000", nil); err != nil {
	log.Fatal(err)
}

func InstrumentHandlerInFlight

1
func InstrumentHandlerInFlight(g prometheus.Gauge, next http.Handler) http.Handler

InstrumentHandlerInFlight是包装提供的http.Handler的中间件。它将提供的prometheus.Gauge设置为当前由包装的http.Handler处理的请求数。

有关用法示例,请参见InstrumentHandlerDuration的示例。

func InstrumentHandlerRequestSize

1
func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler) http.HandlerFunc

InstrumentHandlerRequestSize是一个中间件,该中间件包装提供的http.Handler以观察提供的ObserverVec的请求大小。ObserverVec必须具有零,一或两个非const非咖喱标签。对于这些标签,唯一允许的标签名称是“code”和“method”。否则,该功能会出现问题。调用ObserverVec中的Observer的Observe方法时,请求大小以字节为单位。如果ObserverVec中存在相应的实例标签名称,则通过HTTP状态代码和/或HTTP方法进行分区。对于未分区的观察,请使用带有零标签的ObserverVec。请注意,直方图的划分是昂贵的,应谨慎使用。

如果包装的Handler未设置状态码,则假定状态码为200。

如果包装的处理程序出现紧急情况,则不会报告任何值。

有关用法示例,请参见InstrumentHandlerDuration的示例。

func InstrumentHandlerResponseSize

1
func InstrumentHandlerResponseSize(obs prometheus.ObserverVec, next http.Handler) http.Handler

InstrumentHandlerResponseSize是一个中间件,包装了提供的http.Handler以观察提供的ObserverVec的响应大小。ObserverVec必须具有零,一或两个非const非咖喱标签。对于这些标签,唯一允许的标签名称是“code”和“method”。否则,该功能会出现问题。调用ObserverVec中的Observer的Observe方法,其响应大小以字节为单位。如果ObserverVec中存在相应的实例标签名称,则通过HTTP状态代码和/或HTTP方法进行分区。对于未分区的观察,请使用带有零标签的ObserverVec。请注意,直方图的划分是昂贵的,应谨慎使用。

如果包装的Handler未设置状态码,则假定状态码为200。

如果包装的处理程序出现紧急情况,则不会报告任何值。

有关用法示例,请参见InstrumentHandlerDuration的示例。

func InstrumentHandlerTimeToWriteHeader

1
func InstrumentHandlerTimeToWriteHeader(obs prometheus.ObserverVec, next http.Handler) http.HandlerFunc

InstrumentHandlerTimeToWriteHeader是一个中间件,包装了提供的http.Handler,以使用提供的ObserverVec观察请求持续时间,直到写入响应标头为止。ObserverVec必须具有零,一或两个非const非咖喱标签。对于这些标签,唯一允许的标签名称是“code”和“method”。否则,该功能会出现问题。调用ObserverVec中的Observer的Observe方法时,请求持续时间以秒为单位。如果ObserverVec中存在相应的实例标签名称,则通过HTTP状态代码和/或HTTP方法进行分区。对于未分区的观察,请使用带有零标签的ObserverVec。请注意,直方图的划分是昂贵的,应谨慎使用。

如果包装的Handler在调用WriteHeader之前发生了混乱,则不会报告任何值。

请注意,只有与Go1.9 +一起使用时,才能保证此方法永远不会观察到负持续时间。

有关用法示例,请参见InstrumentHandlerDuration的示例。

func InstrumentMetricHandler

1
func InstrumentMetricHandler(reg prometheus.Registerer, handler http.Handler) http.Handler

InstrumentMetricHandler通常与HandlerFor函数返回的http.Handler一起使用。它使用两个度量为提供的http.Handler进行检测:一个计数器向量“promhttp_metric_handler_requests_total”对按HTTP状态码划分的scrapes进行计数,而量规“promhttp_metric_handler_requests_in_flight”则用于跟踪同时进行的scrapes数量。此功能使用提供的注册器为两个指标均等地注册收集器。如果注册失败,它将感到恐慌。所提供的度量标准对于查看有多少scrapes被监视目标(可能来自不同的Prometheus服务器或其他scrapes),以及它们重叠的频率(将导致同时有多个scrapes在飞行中)非常有用。请注意,飞行中的刮擦量具将包含其暴露的刮擦,而刮擦计数器仅在刮擦完成后才会递增(因为只有这样才能知道状态码)。要跟踪刮擦时间,请使用Prometheus服务器在每次scrape时创建的“ scrape_duration_seconds”量规。

type HandlerErrorHandling

1
type HandlerErrorHandling int

HandlerErrorHandling定义处理程序服务指标如何处理错误。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
const (
	// Serve an HTTP status code 500 upon the first error
	// encountered. Report the error message in the body. Note that HTTP
	// errors cannot be served anymore once the beginning of a regular
	// payload has been sent. Thus, in the (unlikely) case that encoding the
	// payload into the negotiated wire format fails, serving the response
	// will simply be aborted. Set an ErrorLog in HandlerOpts to detect
	// those errors.
	HTTPErrorOnError HandlerErrorHandling = iota
	// Ignore errors and try to serve as many metrics as possible.  However,
	// if no metrics can be served, serve an HTTP status code 500 and the
	// last error message in the body. Only use this in deliberate "best
	// effort" metrics collection scenarios. In this case, it is highly
	// recommended to provide other means of detecting errors: By setting an
	// ErrorLog in HandlerOpts, the errors are logged. By providing a
	// Registry in HandlerOpts, the exposed metrics include an error counter
	// "promhttp_metric_handler_errors_total", which can be used for
	// alerts.
	ContinueOnError
	// Panic upon the first error encountered (useful for "crash only" apps).
	PanicOnError
)

如果遇到错误,这些常量将导致服务度量标准的处理程序行为如所述。

type HandlerOpts

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
type HandlerOpts struct {
	// ErrorLog specifies an optional logger for errors collecting and
	// serving metrics. If nil, errors are not logged at all.
	ErrorLog Logger
	// ErrorHandling defines how errors are handled. Note that errors are
	// logged regardless of the configured ErrorHandling provided ErrorLog
	// is not nil.
	ErrorHandling HandlerErrorHandling
	// If Registry is not nil, it is used to register a metric
	// "promhttp_metric_handler_errors_total", partitioned by "cause". A
	// failed registration causes a panic. Note that this error counter is
	// different from the instrumentation you get from the various
	// InstrumentHandler... helpers. It counts errors that don't necessarily
	// result in a non-2xx HTTP status code. There are two typical cases:
	// (1) Encoding errors that only happen after streaming of the HTTP body
	// has already started (and the status code 200 has been sent). This
	// should only happen with custom collectors. (2) Collection errors with
	// no effect on the HTTP status code because ErrorHandling is set to
	// ContinueOnError.
	Registry prometheus.Registerer
	// If DisableCompression is true, the handler will never compress the
	// response, even if requested by the client.
	DisableCompression bool
	// The number of concurrent HTTP requests is limited to
	// MaxRequestsInFlight. Additional requests are responded to with 503
	// Service Unavailable and a suitable message in the body. If
	// MaxRequestsInFlight is 0 or negative, no limit is applied.
	MaxRequestsInFlight int
	// If handling a request takes longer than Timeout, it is responded to
	// with 503 ServiceUnavailable and a suitable Message. No timeout is
	// applied if Timeout is 0 or negative. Note that with the current
	// implementation, reaching the timeout simply ends the HTTP requests as
	// described above (and even that only if sending of the body hasn't
	// started yet), while the bulk work of gathering all the metrics keeps
	// running in the background (with the eventual result to be thrown
	// away). Until the implementation is improved, it is recommended to
	// implement a separate timeout in potentially slow Collectors.
	Timeout time.Duration
	// If true, the experimental OpenMetrics encoding is added to the
	// possible options during content negotiation. Note that Prometheus
	// 2.5.0+ will negotiate OpenMetrics as first priority. OpenMetrics is
	// the only way to transmit exemplars. However, the move to OpenMetrics
	// is not completely transparent. Most notably, the values of "quantile"
	// labels of Summaries and "le" labels of Histograms are formatted with
	// a trailing ".0" if they would otherwise look like integer numbers
	// (which changes the identity of the resulting series on the Prometheus
	// server).
	EnableOpenMetrics bool
}

HandlerOpts指定如何通过http.Handler提供指标的选项。HandlerOpts的零值为合理的默认值。

type InstrumentTrace

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
type InstrumentTrace struct {
	GotConn              func(float64)
	PutIdleConn          func(float64)
	GotFirstResponseByte func(float64)
	Got100Continue       func(float64)
	DNSStart             func(float64)
	DNSDone              func(float64)
	ConnectStart         func(float64)
	ConnectDone          func(float64)
	TLSHandshakeStart    func(float64)
	TLSHandshakeDone     func(float64)
	WroteHeaders         func(float64)
	Wait100Continue      func(float64)
	WroteRequest         func(float64)
}

InstrumentTrace用于在检测可用的httptrace.ClientTrace挂钩函数时提供灵活性。每个函数都传递了一个float64,表示自http请求开始以来的时间(以秒为单位)。用户可以选择单独使用存储桶直方图,也可以基于每个功能实现自定义实例标签。

type Logger

1
2
3
type Logger interface {
	Println(v ...interface{})
}

记录器是HandlerOpts记录所需的最小接口。请注意,标准库中的log.Logger实现了此接口,并且自定义记录器无论如何还很容易实现。

type RoundTripperFunc

1
type RoundTripperFunc func(req *http.Request) (*http.Response, error)

RoundTripperFunc类型是一个适配器,允许将常规功能用作RoundTrippers。如果f是具有适当签名的函数,则RountTripperFunc(f)是调用f的RoundTripper。

func InstrumentRoundTripperCounter

1
func InstrumentRoundTripperCounter(counter *prometheus.CounterVec, next http.RoundTripper) RoundTripperFunc

InstrumentRoundTripperCounter是一个中间件,包装了提供的http.RoundTripper来观察提供的CounterVec的请求结果。CounterVec必须具有零,一或两个非const非咖喱标签。对于这些标签,唯一允许的标签名称是“code”和“method”。否则,该功能会出现问题。如果CounterVec中存在相应的实例标签名称,则可以通过HTTP状态代码和/或HTTP方法对CounterVec进行分区。对于未分区的计数,请使用带有零标签的CounterVec。

如果包装的RoundTripper出现紧急情况或返回非nil错误,则计数器不会递增。

有关示例用法,请参见ExampleInstrumentRoundTripperDuration的示例。

func InstrumentRoundTripperDuration

1
func InstrumentRoundTripperDuration(obs prometheus.ObserverVec, next http.RoundTripper) RoundTripperFunc

InstrumentRoundTripperDuration是一个中间件,包装了提供的http.RoundTripper来观察提供的ObserverVec的请求持续时间。ObserverVec必须具有零,一或两个非const非咖喱标签。对于这些标签,唯一允许的标签名称是“code”和“method”。否则,该功能会出现问题。调用ObserverVec中的Observer的Observe方法时,请求持续时间以秒为单位。如果ObserverVec中存在相应的实例标签名称,则通过HTTP状态代码和/或HTTP方法进行分区。对于未分区的观察,请使用带有零标签的ObserverVec。请注意,直方图的划分是昂贵的,应谨慎使用。

如果包装的RoundTripper出现紧急情况或返回非nil错误,则不会报告任何值。

请注意,只有与Go1.9 +一起使用时,才能保证此方法永远不会观察到负持续时间。

例子

Code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
client := http.DefaultClient
client.Timeout = 1 * time.Second

inFlightGauge := prometheus.NewGauge(prometheus.GaugeOpts{
	Name: "client_in_flight_requests",
	Help: "A gauge of in-flight requests for the wrapped client.",
})

counter := prometheus.NewCounterVec(
	prometheus.CounterOpts{
		Name: "client_api_requests_total",
		Help: "A counter for requests from the wrapped client.",
	},
	[]string{"code", "method"},
)

// dnsLatencyVec uses custom buckets based on expected dns durations.
// It has an instance label "event", which is set in the
// DNSStart and DNSDonehook functions defined in the
// InstrumentTrace struct below.
dnsLatencyVec := prometheus.NewHistogramVec(
	prometheus.HistogramOpts{
		Name:    "dns_duration_seconds",
		Help:    "Trace dns latency histogram.",
		Buckets: []float64{.005, .01, .025, .05},
	},
	[]string{"event"},
)

// tlsLatencyVec uses custom buckets based on expected tls durations.
// It has an instance label "event", which is set in the
// TLSHandshakeStart and TLSHandshakeDone hook functions defined in the
// InstrumentTrace struct below.
tlsLatencyVec := prometheus.NewHistogramVec(
	prometheus.HistogramOpts{
		Name:    "tls_duration_seconds",
		Help:    "Trace tls latency histogram.",
		Buckets: []float64{.05, .1, .25, .5},
	},
	[]string{"event"},
)

// histVec has no labels, making it a zero-dimensional ObserverVec.
histVec := prometheus.NewHistogramVec(
	prometheus.HistogramOpts{
		Name:    "request_duration_seconds",
		Help:    "A histogram of request latencies.",
		Buckets: prometheus.DefBuckets,
	},
	[]string{},
)

// Register all of the metrics in the standard registry.
prometheus.MustRegister(counter, tlsLatencyVec, dnsLatencyVec, histVec, inFlightGauge)

// Define functions for the available httptrace.ClientTrace hook
// functions that we want to instrument.
trace := &InstrumentTrace{
	DNSStart: func(t float64) {
		dnsLatencyVec.WithLabelValues("dns_start").Observe(t)
	},
	DNSDone: func(t float64) {
		dnsLatencyVec.WithLabelValues("dns_done").Observe(t)
	},
	TLSHandshakeStart: func(t float64) {
		tlsLatencyVec.WithLabelValues("tls_handshake_start").Observe(t)
	},
	TLSHandshakeDone: func(t float64) {
		tlsLatencyVec.WithLabelValues("tls_handshake_done").Observe(t)
	},
}

// Wrap the default RoundTripper with middleware.
roundTripper := InstrumentRoundTripperInFlight(inFlightGauge,
	InstrumentRoundTripperCounter(counter,
		InstrumentRoundTripperTrace(trace,
			InstrumentRoundTripperDuration(histVec, http.DefaultTransport),
		),
	),
)

// Set the RoundTripper on our client.
client.Transport = roundTripper

resp, err := client.Get("http://google.com")
if err != nil {
	log.Printf("error: %v", err)
}
defer resp.Body.Close()

func InstrumentRoundTripperInFlight

1
func InstrumentRoundTripperInFlight(gauge prometheus.Gauge, next http.RoundTripper) RoundTripperFunc

InstrumentRoundTripperInFlight是包装提供的http.RoundTripper的中间件。它将提供的prometheus.Gauge设置为当前由包装的http.RoundTripper处理的请求数。

有关示例用法,请参见ExampleInstrumentRoundTripperDuration的示例。

func InstrumentRoundTripperTrace

1
func InstrumentRoundTripperTrace(it *InstrumentTrace, next http.RoundTripper) RoundTripperFunc

InstrumentRoundTripperTrace是一个中间件,包装了提供的RoundTripper并报告了InstrumentTrace结构中提供的挂钩函数的时间。提供的InstrumentTrace结构中不存在的挂钩函数将被忽略。向挂钩函数报告的时间是自请求开始以来的时间。只有使用Go1.9 +,这些时间才能保证永远不会为负。(早期的Go版本不使用单调时钟。)请注意,直方图的划分是昂贵的,应谨慎使用。

对于将错误作为参数接收的钩子函数,如果非零错误值,则不会进行观察。

有关示例用法,请参见ExampleInstrumentRoundTripperDuration的示例。

func (RoundTripperFunc) RoundTrip

1
func (rt RoundTripperFunc) RoundTrip(r *http.Request) (*http.Response, error)

RoundTrip实现RoundTripper接口。

promauto包

概述

软件包promauto为基本的Prometheus度量标准类型及其…Vec和…Func变体提供了替代构造函数。与prometheus程序包中的对应程序不同的是,promauto构造函数返回已在注册表中注册的Collector。有两组构造函数。第一组中的构造函数是顶级函数,而另一组中的构造函数是Factory类型的方法。顶级函数返回在全局注册表(prometheus.DefaultRegisterer)中注册的Collector,而方法返回在构造工厂的注册表中注册的Collector。如果注册失败,所有构造函数都会感到恐慌。

以下示例是一个完整的程序,可从math / rand程序包中创建正态分布的随机数直方图:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package main

import (
        "math/rand"
        "net/http"

        "github.com/prometheus/client_golang/prometheus"
        "github.com/prometheus/client_golang/prometheus/promauto"
        "github.com/prometheus/client_golang/prometheus/promhttp"
)

var histogram = promauto.NewHistogram(prometheus.HistogramOpts{
        Name:    "random_numbers",
        Help:    "A histogram of normally distributed random numbers.",
        Buckets: prometheus.LinearBuckets(-3, .1, 61),
})

func Random() {
        for {
                histogram.Observe(rand.NormFloat64())
        }
}

func main() {
        go Random()
        http.Handle("/metrics", promhttp.Handler())
        http.ListenAndServe(":1971", nil)
}

Prometheus的最小hello-world程序版本:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package main

import (
	"fmt"
	"net/http"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promauto"
	"github.com/prometheus/client_golang/prometheus/promhttp"
)

func main() {
	http.Handle("/", promhttp.InstrumentHandlerCounter(
		promauto.NewCounterVec(
			prometheus.CounterOpts{
				Name: "hello_requests_total",
				Help: "Total number of hello-world requests by HTTP code.",
			},
			[]string{"code"},
		),
		http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			fmt.Fprint(w, "Hello, world!")
		}),
	))
	http.Handle("/metrics", promhttp.Handler())
	http.ListenAndServe(":1971", nil)
}

使用With(prometheus.Registerer)函数创建一个Factory,该函数启用两种使用模式。With(prometheus.Registerer)可以每行调用一次:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
var (
	reg           = prometheus.NewRegistry()
	randomNumbers = promauto.With(reg).NewHistogram(prometheus.HistogramOpts{
		Name:    "random_numbers",
		Help:    "A histogram of normally distributed random numbers.",
		Buckets: prometheus.LinearBuckets(-3, .1, 61),
	})
	requestCount = promauto.With(reg).NewCounterVec(
		prometheus.CounterOpts{
			Name: "http_requests_total",
			Help: "Total number of HTTP requests by status code and method.",
		},
		[]string{"code", "method"},
	)
)

或者,它可以用于一次创建一个Factory,以便多次使用:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
var (
	reg           = prometheus.NewRegistry()
	factory       = promauto.With(reg)
	randomNumbers = factory.NewHistogram(prometheus.HistogramOpts{
		Name:    "random_numbers",
		Help:    "A histogram of normally distributed random numbers.",
		Buckets: prometheus.LinearBuckets(-3, .1, 61),
	})
	requestCount = factory.NewCounterVec(
		prometheus.CounterOpts{
			Name: "http_requests_total",
			Help: "Total number of HTTP requests by status code and method.",
		},
		[]string{"code", "method"},
	)
)

这看起来非常方便。那么,为什么将这些构造函数锁定在单独的程序包中呢?

主要问题是注册可能会失败,例如,如果已经注册了与新注册或注册的不一致或相等的度量标准。因此,prometheus.Registerer接口中的Register方法返回错误,顶级全局prometheus.Register函数向全局注册表进行注册的情况也是如此。prometheus软件包还提供了两者的MustRegister版本。如果注册失败,他们会感到恐慌,并且他们使用Must…惯用语清楚地指出了这一点。在这种情况下,恐慌是有问题的,因为它不仅会发生在调用方提供的输入本身就无效的情况下。这里的情况更加微妙:度量标准的创建和注册往往在代码库中广泛分布。很容易将不兼容的指标添加到代码的不相关部分,突然之间,曾经可以正常工作的代码开始出现恐慌(前提是新添加的度量标准的注册发生在先前存在的度量标准的注册之前)。对于全局注册表,这可能会带来更大的惊喜,在全局注册表中,简单地导入另一个程序包可能会引发恐慌(如果新导入的程序包在其init函数中注册了指标)。至少在普罗米修斯软件包中,指标和其他收集器的创建与注册是分开的。首先创建度量标准,然后明确决定是否要在本地或全局注册表中注册该度量标准,以及是否要处理该错误或可能出现恐慌。使用promauto软件包中的构造函数时,注册是自动的,并且如果注册失败,则总是会出现紧急情况。此外,

单独的软件包允许保守的用户完全忽略它。任何想要使用它的人都将明确使用它,并有机会阅读此警告。

负责任地享受promauto!

func NewCounter

1
func NewCounter(opts prometheus.CounterOpts) prometheus.Counter

NewCounter的工作原理与prometheus软件包中的同名功能相同,但它会自动向prometheus.DefaultRegisterer注册Counter。如果注册失败,NewCounter会慌张。

func NewCounterFunc

1
func NewCounterFunc(opts prometheus.CounterOpts, function func() float64) prometheus.CounterFunc

NewCounterFunc的工作原理与prometheus软件包中的同名功能相同,但是它会自动将CounterFunc注册到prometheus.DefaultRegisterer中。如果注册失败,NewCounterFunc会发生故障。

func NewCounterVec

1
func NewCounterVec(opts prometheus.CounterOpts, labelNames []string) *prometheus.CounterVec

NewCounterVec的工作方式与prometheus软件包中的同名功能相同,但是它会自动将CounterVec注册到prometheus.DefaultRegisterer中。如果注册失败,NewCounterVec会发生故障。

func NewGauge

1
func NewGauge(opts prometheus.GaugeOpts) prometheus.Gauge

NewGauge的工作原理与prometheus软件包中的同名功能相同,但是它会自动将pro-proeueus.DefaultRegisterer注册到Gauge。如果注册失败,NewGauge会慌张。

func NewGaugeFunc

1
func NewGaugeFunc(opts prometheus.GaugeOpts, function func() float64) prometheus.GaugeFunc

NewGaugeFunc的工作原理与prometheus软件包中的同名函数相同,但它会自动将GaugeFunc注册到prometheus.DefaultRegisterer中。如果注册失败,NewGaugeFunc会发生故障。

func NewGaugeVec

1
func NewGaugeVec(opts prometheus.GaugeOpts, labelNames []string) *prometheus.GaugeVec

NewGaugeVec的工作方式与prometheus软件包中的同名功能相同,但它会自动将GaugeVec注册到prometheus.DefaultRegisterer中。如果注册失败,NewGaugeVec会发生故障。

func NewHistogram

1
func NewHistogram(opts prometheus.HistogramOpts) prometheus.Histogram

NewHistogram的工作原理与prometheus软件包中的同名功能相同,但它会自动将prohisteus.DefaultRegisterer注册直方图。如果注册失败,NewHistogram会出现紧急情况。

func NewHistogramVec

1
func NewHistogramVec(opts prometheus.HistogramOpts, labelNames []string) *prometheus.HistogramVec

NewHistogramVec的工作原理与prometheus软件包中的同名功能相同,但它会自动向prometheus.DefaultRegisterer注册HistogramVec。如果注册失败,则NewHistogramVec会发生故障。

func NewSummary

1
func NewSummary(opts prometheus.SummaryOpts) prometheus.Summary

NewSummary的工作方式与prometheus软件包中的同名功能相同,但是它会自动将摘要摘要注册到prometheus.DefaultRegisterer中。如果注册失败,NewSummary会感到恐慌。

func NewSummaryVec

1
func NewSummaryVec(opts prometheus.SummaryOpts, labelNames []string) *prometheus.SummaryVec

NewSummaryVec的工作方式与prometheus程序包中的同名功能相同,但它会自动向prometheus.DefaultRegisterer注册SummaryVec。如果注册失败,NewSummaryVec会发生故障。

func NewSummaryVec

1
func NewSummaryVec(opts prometheus.SummaryOpts, labelNames []string) *prometheus.SummaryVec

NewUntypedFunc的工作原理与prometheus包中的同名函数相同,但是会自动将untypedFunc注册到prometheus.DefaultRegisterer中。如果注册失败,则NewUntypedFunc会发生故障。

type Factory

1
2
3
type Factory struct {
	// contains filtered or unexported fields
}

Factory提供了工厂方法来创建自动在注册器中注册的收集器。使用With功能创建Factory,提供注册器以自动注册创建的收集器。Factory的零值会创建未在任何注册器中注册的收集器。如果注册失败,则工厂将惊慌的所有方法。

func With

1
func With(r prometheus.Registerer) Factory

With使用提供的注册器创建工厂,用于注册创建的收集器。如果提供的注册器为nil,则返回的工厂将创建未在任何注册器中注册的收集器。

func (Factory) NewCounter

1
func (f Factory) NewCounter(opts prometheus.CounterOpts) prometheus.Counter

NewCounter的工作方式与prometheus软件包中的同名功能相同,但是它会自动将计数器注册到工厂的注册器中。

func (Factory) NewCounterFunc

1
func (f Factory) NewCounterFunc(opts prometheus.CounterOpts, function func() float64) prometheus.CounterFunc

NewCounterFunc的工作原理与prometheus软件包中的同名功能类似,但是它会自动将CounterFunc注册到Factory的Registerer。

func (Factory) NewCounterVec

1
func (f Factory) NewCounterVec(opts prometheus.CounterOpts, labelNames []string) *prometheus.CounterVec

NewCounterVec的工作方式与prometheus软件包中的同名功能相同,但是它会自动将CounterVec注册到工厂的注册器中。

func (Factory) NewGauge

1
func (f Factory) NewGauge(opts prometheus.GaugeOpts) prometheus.Gauge

NewGauge的工作方式与prometheus软件包中的同名功能相同,但它会自动将Gauge登记到Factory的Registerer。

func (Factory) NewGaugeFunc

1
func (f Factory) NewGaugeFunc(opts prometheus.GaugeOpts, function func() float64) prometheus.GaugeFunc

NewGaugeFunc的工作原理与prometheus软件包中的同名功能相同,但是它会自动将GaugeFunc注册到工厂的注册器。

func (Factory) NewGaugeVec

1
func (f Factory) NewGaugeVec(opts prometheus.GaugeOpts, labelNames []string) *prometheus.GaugeVec

NewGaugeVec的工作方式与prometheus软件包中的同名功能相同,但它会自动将GaugeVec注册到工厂的注册器。

func (Factory) NewHistogram

1
func (f Factory) NewHistogram(opts prometheus.HistogramOpts) prometheus.Histogram

NewHistogram的工作方式与Prometheus软件包中的同名功能相同,但它会自动将Histogram注册到Factory的Registerer中。

func (Factory) NewHistogramVec

1
func (f Factory) NewHistogramVec(opts prometheus.HistogramOpts, labelNames []string) *prometheus.HistogramVec

NewHistogramVec的工作方式与prometheus软件包中的同名功能相同,但是它会自动将HistogramVec注册到Factory的Registerer。

func (Factory) NewSummary

1
func (f Factory) NewSummary(opts prometheus.SummaryOpts) prometheus.Summary

NewSummary的工作方式与prometheus软件包中的同名功能相同,但它会自动向工厂的注册器注册摘要。

func (Factory) NewSummaryVec

1
func (f Factory) NewSummaryVec(opts prometheus.SummaryOpts, labelNames []string) *prometheus.SummaryVec

NewSummaryVec的工作方式与prometheus程序包中的同名功能相同,但它会自动向工厂的注册器注册SummaryVec。

func (Factory) NewUntypedFunc

1
func (f Factory) NewUntypedFunc(opts prometheus.UntypedOpts, function func() float64) prometheus.UntypedFunc

NewUntypedFunc的工作方式与prometheus包中的同名功能相同,但是它会自动将UntypedFunc注册到工厂的注册器中。