forked from TrueCloudLab/frostfs-s3-gw
245 lines
7.3 KiB
Go
245 lines
7.3 KiB
Go
package metrics
|
|
|
|
import (
|
|
"encoding/json"
|
|
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
dto "github.com/prometheus/client_model/go"
|
|
)
|
|
|
|
var appMetricsDesc = map[string]map[string]Description{
|
|
poolSubsystem: {
|
|
overallErrorsMetric: Description{
|
|
Type: dto.MetricType_GAUGE,
|
|
Namespace: namespace,
|
|
Subsystem: poolSubsystem,
|
|
Name: overallErrorsMetric,
|
|
Help: "Total number of errors in pool",
|
|
},
|
|
overallNodeErrorsMetric: Description{
|
|
Type: dto.MetricType_GAUGE,
|
|
Namespace: namespace,
|
|
Subsystem: poolSubsystem,
|
|
Name: overallNodeErrorsMetric,
|
|
Help: "Total number of errors for connection in pool",
|
|
VariableLabels: []string{"node"},
|
|
},
|
|
overallNodeRequestsMetric: Description{
|
|
Type: dto.MetricType_GAUGE,
|
|
Namespace: namespace,
|
|
Subsystem: poolSubsystem,
|
|
Name: overallNodeRequestsMetric,
|
|
Help: "Total number of requests to specific node in pool",
|
|
VariableLabels: []string{"node"},
|
|
},
|
|
currentErrorMetric: Description{
|
|
Type: dto.MetricType_GAUGE,
|
|
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{
|
|
Type: dto.MetricType_GAUGE,
|
|
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{
|
|
Type: dto.MetricType_GAUGE,
|
|
Namespace: namespace,
|
|
Subsystem: billingSubsystem,
|
|
Name: userRequestsMetric,
|
|
Help: "Accumulated user requests",
|
|
VariableLabels: []string{"user", "bucket", "cid", "operation"},
|
|
},
|
|
userTrafficMetric: Description{
|
|
Type: dto.MetricType_GAUGE,
|
|
Namespace: namespace,
|
|
Subsystem: billingSubsystem,
|
|
Name: userTrafficMetric,
|
|
Help: "Accumulated user traffic",
|
|
VariableLabels: []string{"user", "bucket", "cid", "direction"},
|
|
},
|
|
},
|
|
stateSubsystem: {
|
|
healthMetric: Description{
|
|
Type: dto.MetricType_GAUGE,
|
|
Namespace: namespace,
|
|
Subsystem: stateSubsystem,
|
|
Name: healthMetric,
|
|
Help: "Current S3 gateway state",
|
|
},
|
|
versionInfoMetric: Description{
|
|
Type: dto.MetricType_GAUGE,
|
|
Namespace: namespace,
|
|
Subsystem: stateSubsystem,
|
|
Name: versionInfoMetric,
|
|
Help: "Version of current FrostFS S3 Gate instance",
|
|
VariableLabels: []string{"version"},
|
|
},
|
|
},
|
|
statisticSubsystem: {
|
|
requestsSecondsMetric: Description{
|
|
Type: dto.MetricType_HISTOGRAM,
|
|
Namespace: namespace,
|
|
Subsystem: statisticSubsystem,
|
|
Name: requestsSecondsMetric,
|
|
Help: "Time taken by requests served by current FrostFS S3 Gate instance",
|
|
VariableLabels: []string{"api"},
|
|
},
|
|
requestsCurrentMetric: Description{
|
|
Type: dto.MetricType_GAUGE,
|
|
Namespace: namespace,
|
|
Subsystem: statisticSubsystem,
|
|
Name: requestsCurrentMetric,
|
|
Help: "Total number of running s3 requests in current FrostFS S3 Gate instance",
|
|
VariableLabels: []string{"api"},
|
|
},
|
|
requestsTotalMetric: Description{
|
|
Type: dto.MetricType_GAUGE,
|
|
Namespace: namespace,
|
|
Subsystem: statisticSubsystem,
|
|
Name: requestsTotalMetric,
|
|
Help: "Total number of s3 requests in current FrostFS S3 Gate instance",
|
|
VariableLabels: []string{"api"},
|
|
},
|
|
errorsTotalMetric: Description{
|
|
Type: dto.MetricType_GAUGE,
|
|
Namespace: namespace,
|
|
Subsystem: statisticSubsystem,
|
|
Name: errorsTotalMetric,
|
|
Help: "Total number of s3 errors in current FrostFS S3 Gate instance",
|
|
VariableLabels: []string{"api"},
|
|
},
|
|
txBytesTotalMetric: Description{
|
|
Type: dto.MetricType_GAUGE,
|
|
Namespace: namespace,
|
|
Subsystem: statisticSubsystem,
|
|
Name: txBytesTotalMetric,
|
|
Help: "Total number of bytes sent by current FrostFS S3 Gate instance",
|
|
},
|
|
rxBytesTotalMetric: Description{
|
|
Type: dto.MetricType_GAUGE,
|
|
Namespace: namespace,
|
|
Subsystem: statisticSubsystem,
|
|
Name: rxBytesTotalMetric,
|
|
Help: "Total number of bytes received by current FrostFS S3 Gate instance",
|
|
},
|
|
},
|
|
}
|
|
|
|
type Description struct {
|
|
Type dto.MetricType
|
|
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 {
|
|
Type string `json:"type"`
|
|
FQName string `json:"name"`
|
|
Help string `json:"help"`
|
|
ConstantLabels []KeyValue `json:"constant_labels"`
|
|
VariableLabels []string `json:"variable_labels"`
|
|
}{
|
|
Type: d.Type.String(),
|
|
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 mustNewGauge(description Description) prometheus.Gauge {
|
|
if description.Type != dto.MetricType_GAUGE {
|
|
panic("invalid metric type")
|
|
}
|
|
return prometheus.NewGauge(
|
|
prometheus.GaugeOpts(newOpts(description)),
|
|
)
|
|
}
|
|
|
|
func mustNewGaugeVec(description Description) *prometheus.GaugeVec {
|
|
if description.Type != dto.MetricType_GAUGE {
|
|
panic("invalid metric type")
|
|
}
|
|
return prometheus.NewGaugeVec(
|
|
prometheus.GaugeOpts(newOpts(description)),
|
|
description.VariableLabels,
|
|
)
|
|
}
|
|
|
|
func mustNewHistogramVec(description Description, buckets []float64) *prometheus.HistogramVec {
|
|
if description.Type != dto.MetricType_HISTOGRAM {
|
|
panic("invalid metric type")
|
|
}
|
|
|
|
return prometheus.NewHistogramVec(
|
|
prometheus.HistogramOpts{
|
|
Namespace: description.Namespace,
|
|
Subsystem: description.Subsystem,
|
|
Name: description.Name,
|
|
Help: description.Name,
|
|
ConstLabels: description.ConstLabelsMap(),
|
|
Buckets: buckets,
|
|
},
|
|
description.VariableLabels,
|
|
)
|
|
}
|