Files
wehub-resource-sync 498b235461
Build and test / Build and test AMD64 Ubuntu 22.04 (push) Failing after 0s
Publish Builder / amazonlinux2023 (push) Failing after 1s
Build and test / UT for Go (push) Has been skipped
Publish KRTE Images / KRTE (push) Failing after 1s
Build and test / Integration Test (push) Has been skipped
Build and test / Upload Code Coverage (push) Has been skipped
Publish Builder / rockylinux9 (push) Failing after 1s
Publish Builder / ubuntu22.04 (push) Failing after 0s
Publish Builder / ubuntu24.04 (push) Failing after 0s
Publish Gpu Builder / publish-gpu-builder (push) Failing after 1s
Publish Test Images / PyTest (push) Failing after 0s
Build and test / UT for Cpp (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:31:17 +08:00

144 lines
5.3 KiB
Go

package metricsutil
import (
"context"
"strconv"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/milvus-io/milvus/internal/util/streamingutil/status"
"github.com/milvus-io/milvus/pkg/v3/metrics"
"github.com/milvus-io/milvus/pkg/v3/mlog"
"github.com/milvus-io/milvus/pkg/v3/streaming/util/message"
"github.com/milvus-io/milvus/pkg/v3/streaming/util/types"
"github.com/milvus-io/milvus/pkg/v3/util/paramtable"
)
// NewWriteMetrics creates a new WriteMetrics.
func NewWriteMetrics(pchannel types.PChannelInfo, walName message.WALName) *WriteMetrics {
constLabel := prometheus.Labels{
metrics.NodeIDLabelName: paramtable.GetStringNodeID(),
metrics.WALChannelLabelName: pchannel.Name,
}
metrics.WALInfo.WithLabelValues(
paramtable.GetStringNodeID(),
pchannel.Name,
strconv.FormatInt(pchannel.Term, 10),
walName.String()).Set(1)
slowLogThreshold := paramtable.Get().StreamingCfg.LoggingAppendSlowThreshold.GetAsDurationByParse()
if slowLogThreshold <= 0 {
slowLogThreshold = time.Second
}
if walName == message.WALNameWoodpecker && slowLogThreshold < 3*time.Second {
// woodpecker wal is always slow, so we need to set a higher threshold by default.
slowLogThreshold = 3 * time.Second
}
return &WriteMetrics{
walName: walName.String(),
pchannel: pchannel,
constLabel: constLabel,
bytes: metrics.WALAppendMessageBytes.MustCurryWith(constLabel),
total: metrics.WALAppendMessageTotal.MustCurryWith(constLabel),
walDuration: metrics.WALAppendMessageDurationSeconds.MustCurryWith(constLabel),
walimplsRetryTotal: metrics.WALImplsAppendRetryTotal.With(constLabel),
walimplsDuration: metrics.WALImplsAppendMessageDurationSeconds.MustCurryWith(constLabel),
walBeforeInterceptorDuration: metrics.WALAppendMessageBeforeInterceptorDurationSeconds.MustCurryWith(constLabel),
walAfterInterceptorDuration: metrics.WALAppendMessageAfterInterceptorDurationSeconds.MustCurryWith(constLabel),
slowLogThreshold: time.Second,
}
}
type WriteMetrics struct {
mlog.Binder
walName string
pchannel types.PChannelInfo
constLabel prometheus.Labels
bytes prometheus.ObserverVec
total *prometheus.CounterVec
walDuration prometheus.ObserverVec
walimplsRetryTotal prometheus.Counter
walimplsDuration prometheus.ObserverVec
walBeforeInterceptorDuration prometheus.ObserverVec
walAfterInterceptorDuration prometheus.ObserverVec
slowLogThreshold time.Duration
}
func (m *WriteMetrics) StartAppend(msg message.MutableMessage) *AppendMetrics {
return &AppendMetrics{
wm: m,
msg: msg,
interceptors: make(map[string][]*InterceptorMetrics),
}
}
func (m *WriteMetrics) done(appendMetrics *AppendMetrics) {
if !appendMetrics.msg.IsPersisted() {
return
}
status := parseError(appendMetrics.err)
if appendMetrics.implAppendDuration != 0 {
m.walimplsDuration.WithLabelValues(status).Observe(appendMetrics.implAppendDuration.Seconds())
}
m.bytes.WithLabelValues(status).Observe(float64(appendMetrics.msg.EstimateSize()))
m.total.WithLabelValues(appendMetrics.msg.MessageType().String(), status).Inc()
m.walDuration.WithLabelValues(status).Observe(appendMetrics.appendDuration.Seconds())
for name, ims := range appendMetrics.interceptors {
for _, im := range ims {
if im.Before != 0 {
m.walBeforeInterceptorDuration.WithLabelValues(name).Observe(im.Before.Seconds())
}
if im.After != 0 {
m.walAfterInterceptorDuration.WithLabelValues(name).Observe(im.After.Seconds())
}
}
}
if appendMetrics.err != nil {
m.Logger().Warn(context.TODO(), "append message into wal failed", appendMetrics.IntoLogFields()...)
return
}
if appendMetrics.appendDuration >= m.slowLogThreshold {
// log slow append catch
m.Logger().Warn(context.TODO(), "append message into wal too slow", appendMetrics.IntoLogFields()...)
return
}
logLV := appendMetrics.msg.MessageType().LogLevel()
if m.Logger().LevelEnabled(logLV) {
m.Logger().Log(context.TODO(), logLV, "append message into wal", appendMetrics.IntoLogFields()...)
}
}
// ObserveRetry observes the retry of the walimpls.
func (m *WriteMetrics) ObserveRetry() {
m.walimplsRetryTotal.Inc()
}
func (m *WriteMetrics) Close() {
metrics.WALAppendMessageBeforeInterceptorDurationSeconds.DeletePartialMatch(m.constLabel)
metrics.WALAppendMessageAfterInterceptorDurationSeconds.DeletePartialMatch(m.constLabel)
metrics.WALAppendMessageBytes.DeletePartialMatch(m.constLabel)
metrics.WALAppendMessageTotal.DeletePartialMatch(m.constLabel)
metrics.WALAppendMessageDurationSeconds.DeletePartialMatch(m.constLabel)
metrics.WALImplsAppendRetryTotal.DeletePartialMatch(m.constLabel)
metrics.WALImplsAppendMessageDurationSeconds.DeletePartialMatch(m.constLabel)
metrics.WALInfo.DeleteLabelValues(
paramtable.GetStringNodeID(),
m.pchannel.Name,
strconv.FormatInt(m.pchannel.Term, 10),
m.walName,
)
}
// parseError parses the error to status.
func parseError(err error) string {
if err == nil {
return metrics.WALStatusOK
}
if status.IsCanceled(err) {
return metrics.WALStatusCancel
}
return metrics.WALStatusError
}