文章目录
- lables.go
- labelset.go
- metric.go
- value.go
- alert.go
- fnv.go
- signature.go
- 收获
github.com/prometheus/common@v0.35.0/model
lables.go
- 首先声明一系列标签常量,其中
__meta_
和__tmp_
前缀用于标签的中间处理 - 标签名
LabelName
是字符串,命名规范是“可以包含大写或小写英文字母、数字和下划线,不能以数字开头” LabelNames
是LabelName
的切片,支持排序- 标签值
LabelValue
是 utf8 字符串,LabelValues
是LabelValue
的切片,支持排序 LablePair
是LabelName
和LabelValue
组成的结构体LablePairs
是LablePair
的切片,支持排序,排序依据是先按标签名再按标签值
labelset.go
- LabelSet 是一个map,一组标签键值对的集合
type LabelSet map[LabelName]LabelValue
- LabelSet 的 String() 函数会对键值对进行字符串排序,这样在前端查询时显示的标签集都是有序的,比较清晰
metric.go
type Metric LabelSet
的底层类型就是 LabelSet,区别在于 Metrics 是单例,并且关联且仅引用一系列样本- 指标名命名规范:可以包含大小写英文字母、数字、下划线和冒号,不能以数字开头
String()
方法要判断是否只有__name__
标签,如果是就不显示标签集的大括号了,否则返回除__name__{labels}
这种格式的字符串- 实现了 LabelSet 的一些方法
value.go
- 样本值是 float64类型:
type SampleValue float64
,代表某个时间的某个样本的值 - 判等函数中有关于 NaN 不等于 NaN 的说明
- 样本对包含时间戳和样本值
type SamplePair struct {
Timestamp Time
Value SampleValue
}
- 样本是指标、样本值和时间戳组成的结构体
type Sample struct {
Metric Metric `json:"metric"`
Value SampleValue `json:"value"`
Timestamp Time `json:"timestamp"`
}
- 样本串是一个指标和一组样本对
type SampleStream struct {
Metric Metric `json:"metric"`
Values []SamplePair `json:"values"`
}
- 值是实现了
Type()
方法的接口,是查询语句的结果,有无值、标量、向量、矩阵和字符串五种类型的值
type Value interface {
Type() ValueType
String() string
}
func (Matrix) Type() ValueType { return ValMatrix }
func (Vector) Type() ValueType { return ValVector }
func (*Scalar) Type() ValueType { return ValScalar }
func (*String) Type() ValueType { return ValString }
type ValueType int
const (
ValNone ValueType = iota
ValScalar
ValVector
ValMatrix
ValString
)
- 向量类型是具有相同时间戳的
*Sample
的切片 - 矩阵类型是
*SampleStream
的切片
alert.go
- 告警指纹是告警标签集的指纹
- Go 的零时是时间戳为0的时间
January 1, year 1, 00:00:00 UTC
fnv.go
对标准库 hash/fnv 的 FNV-1A 64-bit 算法做了一些简化,性能有大幅提升,甚至超过了 murmur3,我做了一个benchmark
cpu: Intel(R) Core(TM) i7-8565U CPU @ 1.80GHz
BenchmarkMD5
BenchmarkMD5-8 5231271 222.5 ns/op
BenchmarkFNV
BenchmarkFNV-8 12151196 90.65 ns/op
BenchmarkFNVProm
BenchmarkFNVProm-8 57570523 20.62 ns/op
BenchmarkMurmer3
BenchmarkMurmer3-8 18314626 54.97 ns/op
signature.go
- 用简化 FNV-1A 64-bit 算法计算指标或者标签的哈希值作为指纹
LabelsToSignature
计算标签(Labels) map 的指纹labelSetToFingerprint
计算标签集(LabelSet)的指纹func SignatureForLabels(m Metric, labels ...LabelName) uint64
计算指标的指纹,哈希时除了计算指定的标签外还计算指标值func SignatureWithoutLabels(m Metric, labels map[LabelName]struct{}) uint64
计算不包含指定标签的指标的指纹- 快速指纹算法不排序,但是更容易产生碰撞,研究了半天才明白
收获
这个包有很多实用的数据类型和函数,在自己开发系统时可以直接用
- 很多数据模型比如 label、labelset、alert 可以在自己开发监控告警系统时直接使用
- fnv 算法性能好碰撞几率小,以后可以直接用
- 计算多元素类型的哈希时先排序