frostfs-s3-gw/metrics/desc.go
Denis Kirillov 9e72fe1662 [#80] Refactor metrics, support dump descriptions
Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
2023-04-20 11:14:52 +03:00

202 lines
5.9 KiB
Go

package metrics
import (
"encoding/json"
"github.com/prometheus/client_golang/prometheus"
)
var AppMetricsDesc = map[string]map[string]Description{
poolSubsystem: {
overallErrorsMetric: Description{
Namespace: namespace,
Subsystem: poolSubsystem,
Name: overallErrorsMetric,
Help: "Total number of errors in pool",
},
overallNodeErrorsMetric: Description{
Namespace: namespace,
Subsystem: poolSubsystem,
Name: overallNodeErrorsMetric,
Help: "Total number of errors for connection in pool",
VariableLabels: []string{"node"},
},
overallNodeRequestsMetric: Description{
Namespace: namespace,
Subsystem: poolSubsystem,
Name: overallNodeRequestsMetric,
Help: "Total number of requests to specific node in pool",
VariableLabels: []string{"node"},
},
currentErrorMetric: Description{
Namespace: namespace,
Subsystem: poolSubsystem,
Name: currentErrorMetric,
Help: "Number of errors on current connections that will be reset after the threshold",
VariableLabels: []string{"node"},
},
avgRequestDurationMetric: Description{
Namespace: namespace,
Subsystem: poolSubsystem,
Name: avgRequestDurationMetric,
Help: "Average request duration (in milliseconds) for specific method on node in pool",
VariableLabels: []string{"node", "method"},
},
},
billingSubsystem: {
userRequestsMetric: Description{
Namespace: namespace,
Subsystem: billingSubsystem,
Name: userRequestsMetric,
Help: "Accumulated user requests",
VariableLabels: []string{"user", "bucket", "cid", "operation"},
},
userTrafficMetric: Description{
Namespace: namespace,
Subsystem: billingSubsystem,
Name: userTrafficMetric,
Help: "Accumulated user traffic",
VariableLabels: []string{"user", "bucket", "cid", "direction"},
},
},
stateSubsystem: {
healthMetric: Description{
Namespace: namespace,
Subsystem: stateSubsystem,
Name: healthMetric,
Help: "Current S3 gateway state",
},
versionInfoMetric: Description{
Namespace: namespace,
Subsystem: stateSubsystem,
Name: versionInfoMetric,
Help: "Version of current FrostFS S3 Gate instance",
VariableLabels: []string{"version"},
},
},
statisticSubsystem: {
requestsSecondsMetric: Description{
Namespace: namespace,
Subsystem: statisticSubsystem,
Name: requestsSecondsMetric,
Help: "Time taken by requests served by current FrostFS S3 Gate instance",
VariableLabels: []string{"api"},
},
requestsCurrentMetric: Description{
Namespace: namespace,
Subsystem: statisticSubsystem,
Name: requestsCurrentMetric,
Help: "Total number of running s3 requests in current FrostFS S3 Gate instance",
VariableLabels: []string{"api"},
},
requestsTotalMetric: Description{
Namespace: namespace,
Subsystem: statisticSubsystem,
Name: requestsTotalMetric,
Help: "Total number of s3 requests in current FrostFS S3 Gate instance",
VariableLabels: []string{"api"},
},
errorsTotalMetric: Description{
Namespace: namespace,
Subsystem: statisticSubsystem,
Name: errorsTotalMetric,
Help: "Total number of s3 errors in current FrostFS S3 Gate instance",
VariableLabels: []string{"api"},
},
txBytesTotalMetric: Description{
Namespace: namespace,
Subsystem: statisticSubsystem,
Name: txBytesTotalMetric,
Help: "Total number of bytes sent by current FrostFS S3 Gate instance",
},
rxBytesTotalMetric: Description{
Namespace: namespace,
Subsystem: statisticSubsystem,
Name: rxBytesTotalMetric,
Help: "Total number of bytes received by current FrostFS S3 Gate instance",
},
},
}
type Description struct {
Namespace string
Subsystem string
Name string
Help string
ConstantLabels []KeyValue
VariableLabels []string
}
type KeyValue struct {
Key string `json:"key"`
Value string `json:"value"`
}
func (d *Description) MarshalJSON() ([]byte, error) {
return json.Marshal(&struct {
FQName string `json:"name"`
Help string `json:"help"`
ConstantLabels []KeyValue `json:"constant_labels"`
VariableLabels []string `json:"variable_labels"`
}{
FQName: d.BuildFQName(),
Help: d.Help,
ConstantLabels: d.ConstantLabels,
VariableLabels: d.VariableLabels,
})
}
func (d *Description) BuildFQName() string {
return prometheus.BuildFQName(d.Namespace, d.Subsystem, d.Name)
}
func (d *Description) ConstLabelsMap() map[string]string {
constsLabels := make(map[string]string, len(d.ConstantLabels))
for _, kv := range d.ConstantLabels {
constsLabels[kv.Key] = kv.Value
}
return constsLabels
}
// DescribeAll returns descriptions for metrics.
func DescribeAll() []Description {
var list []Description
for _, m := range AppMetricsDesc {
for _, description := range m {
list = append(list, description)
}
}
return list
}
func NewOpts(description Description) prometheus.Opts {
return prometheus.Opts{
Namespace: description.Namespace,
Subsystem: description.Subsystem,
Name: description.Name,
Help: description.Help,
ConstLabels: description.ConstLabelsMap(),
}
}
func NewDesc(description Description) *prometheus.Desc {
return prometheus.NewDesc(
description.BuildFQName(),
description.Help,
description.VariableLabels,
description.ConstLabelsMap())
}
func NewGauge(description Description) prometheus.Gauge {
return prometheus.NewGauge(
prometheus.GaugeOpts(NewOpts(description)),
)
}
func NewGaugeVec(description Description) *prometheus.GaugeVec {
return prometheus.NewGaugeVec(
prometheus.GaugeOpts(NewOpts(description)),
description.VariableLabels,
)
}