diff --git a/telemetry/instrumentation/otelhertz/extractlabels.go b/telemetry/instrumentation/otelhertz/extractlabels.go deleted file mode 100644 index 0d91806..0000000 --- a/telemetry/instrumentation/otelhertz/extractlabels.go +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright 2022 CloudWeGo Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package otelhertz - -import ( - "context" - - "github.com/cloudwego-contrib/cwgo-pkg/log/logging" - "github.com/cloudwego-contrib/cwgo-pkg/telemetry/instrumentation/internal" - "github.com/cloudwego-contrib/cwgo-pkg/telemetry/meter/label" - "github.com/cloudwego-contrib/cwgo-pkg/telemetry/semantic" - "github.com/cloudwego/hertz/pkg/app" - "github.com/cloudwego/hertz/pkg/common/adaptor" - "github.com/cloudwego/hertz/pkg/common/tracer/stats" - "go.opentelemetry.io/otel/attribute" - semconv "go.opentelemetry.io/otel/semconv/v1.12.0" - "go.opentelemetry.io/otel/trace" -) - -var _ label.LabelControl = OtelLabelControl{} - -type OtelLabelControl struct { - tracer trace.Tracer - shouldIgnore ConditionFunc - serverHttpRouteFormatter func(c *app.RequestContext) string -} - -func NewOtelLabelControl(tracer trace.Tracer, shouldIgnore ConditionFunc, serverHttpRouteFormatter func(c *app.RequestContext) string) OtelLabelControl { - return OtelLabelControl{ - tracer: tracer, - shouldIgnore: shouldIgnore, - serverHttpRouteFormatter: serverHttpRouteFormatter, - } -} - -func (o OtelLabelControl) ProcessAndInjectLabels(ctx context.Context) context.Context { - c, ok := ctx.Value(requestContextKey).(*app.RequestContext) - if !ok { - return ctx - } - if o.shouldIgnore(ctx, c) { - return ctx - } - tc := &internal.TraceCarrier{} - tc.SetTracer(o.tracer) - - return internal.WithTraceCarrier(ctx, tc) -} - -func (o OtelLabelControl) ProcessAndExtractLabels(ctx context.Context) []label.CwLabel { - c, ok := ctx.Value(requestContextKey).(*app.RequestContext) - if !ok { - return nil - } - if o.shouldIgnore(ctx, c) { - return nil - } - // trace carrier from context - tc := internal.TraceCarrierFromContext(ctx) - if tc == nil { - logging.Debugf("get tracer container failed") - return nil - } - - ti := c.GetTraceInfo() - st := ti.Stats() - - if st.Level() == stats.LevelDisabled { - return nil - } - - httpStart := st.GetEvent(stats.HTTPStart) - if httpStart == nil { - return nil - } - - // span - span := tc.Span() - if span == nil || !span.IsRecording() { - return nil - } - - // span attributes from original http request - if httpReq, err := adaptor.GetCompatRequest(c.GetRequest()); err == nil { - span.SetAttributes(semconv.NetAttributesFromHTTPRequest("tcp", httpReq)...) - span.SetAttributes(semconv.EndUserAttributesFromHTTPRequest(httpReq)...) - span.SetAttributes(semconv.HTTPServerAttributesFromHTTPRequest("", o.serverHttpRouteFormatter(c), httpReq)...) - span.SetStatus(semconv.SpanStatusFromHTTPStatusCode(c.Response.StatusCode())) - } - - // span attributes - attrs := []attribute.KeyValue{ - semconv.HTTPURLKey.String(c.URI().String()), - semconv.NetPeerIPKey.String(c.ClientIP()), - semconv.HTTPStatusCodeKey.Int(c.Response.StatusCode()), - } - span.SetAttributes(attrs...) - - injectStatsEventsToSpan(span, st) - - if panicMsg, panicStack, httpErr := parseHTTPError(ti); httpErr != nil || len(panicMsg) > 0 { - recordErrorSpanWithStack(span, httpErr, panicMsg, panicStack) - } - - span.End(trace.WithTimestamp(getEndTimeOrNow(ti))) - - metricsAttributes := semantic.ExtractMetricsAttributesFromSpan(span) - return label.ToCwLabelsFromOtels(metricsAttributes) -} diff --git a/telemetry/instrumentation/otelhertz/hertz_tracer.go b/telemetry/instrumentation/otelhertz/hertz_tracer.go index 71efc5c..2ced4b6 100644 --- a/telemetry/instrumentation/otelhertz/hertz_tracer.go +++ b/telemetry/instrumentation/otelhertz/hertz_tracer.go @@ -27,12 +27,20 @@ package otelhertz import ( "context" + "strconv" "time" + "github.com/cloudwego-contrib/cwgo-pkg/telemetry/instrumentation/internal" + "github.com/cloudwego-contrib/cwgo-pkg/telemetry/meter/label" cwmetric "github.com/cloudwego-contrib/cwgo-pkg/telemetry/meter/metric" + "github.com/cloudwego-contrib/cwgo-pkg/telemetry/semantic" "github.com/cloudwego/hertz/pkg/app" + "github.com/cloudwego/hertz/pkg/common/adaptor" "github.com/cloudwego/hertz/pkg/common/tracer" "github.com/cloudwego/hertz/pkg/common/tracer/stats" + "go.opentelemetry.io/otel/attribute" + semconv "go.opentelemetry.io/otel/semconv/v1.12.0" + "go.opentelemetry.io/otel/trace" ) var _ tracer.Tracer = (*HertzTracer)(nil) @@ -45,8 +53,13 @@ type HertzTracer struct { } func (h HertzTracer) Start(ctx context.Context, c *app.RequestContext) context.Context { - ctx = context.WithValue(ctx, requestContextKey, c) - return h.Measure.ProcessAndInjectLabels(ctx) + if h.cfg.shouldIgnore(ctx, c) { + return ctx + } + tc := &internal.TraceCarrier{} + tc.SetTracer(h.cfg.tracer) + + return internal.WithTraceCarrier(ctx, tc) } func (h HertzTracer) Finish(ctx context.Context, c *app.RequestContext) { @@ -63,8 +76,65 @@ func (h HertzTracer) Finish(ctx context.Context, c *app.RequestContext) { return } elapsedTime := float64(st.GetEvent(stats.HTTPFinish).Time().Sub(httpStart.Time())) / float64(time.Millisecond) - labels := h.Measure.ProcessAndExtractLabels(ctx) + labels := []label.CwLabel{ + { + Key: semantic.LabelHttpMethodKey, + Value: defaultValIfEmpty(string(c.Request.Method()), semantic.UnknownLabelValue), + }, + { + Key: semantic.LabelKeyStatus, + Value: defaultValIfEmpty(strconv.Itoa(c.Response.Header.StatusCode()), semantic.UnknownLabelValue), + }, + { + Key: semantic.LabelPath, + Value: defaultValIfEmpty(c.FullPath(), semantic.UnknownLabelValue), + }, + } + tc := internal.TraceCarrierFromContext(ctx) + var span trace.Span + if tc != nil { + span = tc.Span() + if span != nil && span.IsRecording() { + // span attributes from original http request + if httpReq, err := adaptor.GetCompatRequest(c.GetRequest()); err == nil { + span.SetAttributes(semconv.NetAttributesFromHTTPRequest("tcp", httpReq)...) + span.SetAttributes(semconv.EndUserAttributesFromHTTPRequest(httpReq)...) + span.SetAttributes(semconv.HTTPServerAttributesFromHTTPRequest("", h.cfg.serverHttpRouteFormatter(c), httpReq)...) + } + + // span attributes + attrs := []attribute.KeyValue{ + semconv.HTTPURLKey.String(c.URI().String()), + semconv.NetPeerIPKey.String(c.ClientIP()), + } + span.SetAttributes(attrs...) + + injectStatsEventsToSpan(span, st) + + if panicMsg, panicStack, httpErr := parseHTTPError(ti); httpErr != nil || len(panicMsg) > 0 { + recordErrorSpanWithStack(span, httpErr, panicMsg, panicStack) + } + + span.End(trace.WithTimestamp(getEndTimeOrNow(ti))) + + metricsAttributes := semantic.ExtractMetricsAttributesFromSpan(span) + + labels = append(labels, label.ToCwLabelsFromOtels(metricsAttributes)...) + } + } + //labels := h.Measure.ProcessAndExtractLabels(ctx) + /* labels := make(prom.Labels) + labels[semantic.LabelHttpMethodKey] = defaultValIfEmpty(string(c.Request.Method()), semantic.UnknownLabelValue) + labels[semantic.LabelKeyStatus] = defaultValIfEmpty(strconv.Itoa(c.Response.Header.StatusCode()), semantic.UnknownLabelValue) + labels[semantic.LabelPath] = defaultValIfEmpty(c.FullPath(), semantic.UnknownLabelValue)*/ h.Measure.Inc(ctx, labels) h.Measure.Record(ctx, elapsedTime, labels) } + +func defaultValIfEmpty(val, def string) string { + if val == "" { + return def + } + return val +} diff --git a/telemetry/instrumentation/otelhertz/trace.go b/telemetry/instrumentation/otelhertz/trace.go index e3cb874..ccc2b91 100644 --- a/telemetry/instrumentation/otelhertz/trace.go +++ b/telemetry/instrumentation/otelhertz/trace.go @@ -39,8 +39,8 @@ func NewServerTracer(opts ...Option) *HertzTracer { metric.WithDescription("measures th incoming end to end duration"), ) handleErr(err) - labelControl := NewOtelLabelControl(cfg.tracer, cfg.shouldIgnore, cfg.serverHttpRouteFormatter) - cfg.measure = cwmetric.NewMeasure(cwmetric.NewOtelCounter(serverRequestCountMeasure), cwmetric.NewOtelRecorder(serverLatencyMeasure), labelControl) + + cfg.measure = cwmetric.NewMeasure(cwmetric.NewOtelCounter(serverRequestCountMeasure), cwmetric.NewOtelRecorder(serverLatencyMeasure)) } return &HertzTracer{ diff --git a/telemetry/instrumentation/otelkitex/extractlabels.go b/telemetry/instrumentation/otelkitex/extractlabels.go deleted file mode 100644 index 3cd0d11..0000000 --- a/telemetry/instrumentation/otelkitex/extractlabels.go +++ /dev/null @@ -1,88 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package otelkitex - -import ( - "context" - - "github.com/cloudwego-contrib/cwgo-pkg/telemetry/instrumentation/internal" - "github.com/cloudwego-contrib/cwgo-pkg/telemetry/meter/label" - "github.com/cloudwego-contrib/cwgo-pkg/telemetry/semantic" - "github.com/cloudwego/kitex/pkg/rpcinfo" - "go.opentelemetry.io/otel/attribute" - "go.opentelemetry.io/otel/trace" -) - -var _ label.LabelControl = OtelLabelControl{} - -type OtelLabelControl struct { - tracer trace.Tracer - recordSourceOperation bool -} - -func NewOtelLabelControl(tracer trace.Tracer, recordoperation bool) OtelLabelControl { - return OtelLabelControl{ - tracer: tracer, - recordSourceOperation: recordoperation, - } -} - -func (o OtelLabelControl) ProcessAndInjectLabels(ctx context.Context) context.Context { - tc := &internal.TraceCarrier{} - tc.SetTracer(o.tracer) - - return internal.WithTraceCarrier(ctx, tc) -} - -func (o OtelLabelControl) ProcessAndExtractLabels(ctx context.Context) []label.CwLabel { - ri := rpcinfo.GetRPCInfo(ctx) - st := ri.Stats() - tc := internal.TraceCarrierFromContext(ctx) - if tc == nil { - return nil - } - // span - span := tc.Span() - if span == nil || !span.IsRecording() { - return nil - } - - // span attributes - attrs := []attribute.KeyValue{ - semantic.RPCSystemKitex, - attribute.Key(semantic.LabelRPCMethodKey).String(ri.To().Method()), - attribute.Key(semantic.LabelRPCCalleeKey).String(ri.To().ServiceName()), - attribute.Key(semantic.LabelRPCCallerKey).String(ri.From().ServiceName()), - - semantic.RPCSystemKitexRecvSize.Int64(int64(st.RecvSize())), - semantic.RPCSystemKitexSendSize.Int64(int64(st.SendSize())), - semantic.RequestProtocolKey.String(ri.Config().TransportProtocol().String()), - } - - // The source operation dimension maybe cause high cardinality issues - if o.recordSourceOperation { - attrs = append(attrs, semantic.SourceOperationKey.String(ri.From().Method())) - } - - span.SetAttributes(attrs...) - - injectStatsEventsToSpan(span, st) - - if panicMsg, panicStack, rpcErr := parseRPCError(ri); rpcErr != nil || len(panicMsg) > 0 { - recordErrorSpanWithStack(span, rpcErr, panicMsg, panicStack) - } - - span.End(trace.WithTimestamp(getEndTimeOrNow(ri))) - metricsAttributes := semantic.ExtractMetricsAttributesFromSpan(span) - return label.ToCwLabelsFromOtels(metricsAttributes) -} diff --git a/telemetry/instrumentation/otelkitex/kitex_tracer.go b/telemetry/instrumentation/otelkitex/kitex_tracer.go index 121f735..ebf6b9a 100644 --- a/telemetry/instrumentation/otelkitex/kitex_tracer.go +++ b/telemetry/instrumentation/otelkitex/kitex_tracer.go @@ -16,6 +16,12 @@ import ( "context" "time" + "github.com/cloudwego-contrib/cwgo-pkg/telemetry/instrumentation/internal" + "github.com/cloudwego-contrib/cwgo-pkg/telemetry/meter/label" + "github.com/cloudwego-contrib/cwgo-pkg/telemetry/semantic" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" + cwmetric "github.com/cloudwego-contrib/cwgo-pkg/telemetry/meter/metric" "github.com/cloudwego/kitex/pkg/rpcinfo" "github.com/cloudwego/kitex/pkg/stats" @@ -24,12 +30,18 @@ import ( var _ stats.Tracer = (*KitexTracer)(nil) type KitexTracer struct { - Measure cwmetric.Measure - cfg *Config + Measure cwmetric.Measure + cfg *Config + recordSourceOperation bool } func (s *KitexTracer) Start(ctx context.Context) context.Context { - return s.Measure.ProcessAndInjectLabels(ctx) + tc := &internal.TraceCarrier{} + if s.cfg.tracer != nil { + tc.SetTracer(s.cfg.tracer) + } + + return internal.WithTraceCarrier(ctx, tc) } func (s *KitexTracer) Finish(ctx context.Context) { @@ -45,7 +57,89 @@ func (s *KitexTracer) Finish(ctx context.Context) { duration := rpcFinish.Time().Sub(rpcStart.Time()) elapsedTime := float64(duration) / float64(time.Millisecond) - labels := s.Measure.ProcessAndExtractLabels(ctx) + // promlabels := s.Measure.ProcessAndExtractLabels(ctx) + caller := ri.From() + callee := ri.To() + labels := []label.CwLabel{ + { + Key: semantic.LabelRPCCallerKey, + Value: defaultValIfEmpty(caller.ServiceName(), semantic.UnknownLabelValue), + }, + { + Key: semantic.LabelRPCCalleeKey, + Value: defaultValIfEmpty(callee.ServiceName(), semantic.UnknownLabelValue), + }, + { + Key: semantic.LabelRPCMethodKey, + Value: defaultValIfEmpty(callee.Method(), semantic.UnknownLabelValue), + }, + } + retry := label.CwLabel{ + Key: semantic.LabelKeyRetry, + Value: semantic.StatusSucceed, + } + if retriedCnt, ok := callee.Tag(rpcinfo.RetryTag); ok { + retry = label.CwLabel{ + Key: semantic.LabelKeyRetry, + Value: retriedCnt, + } + } + labels = append(labels, retry) + + tc := internal.TraceCarrierFromContext(ctx) + var span trace.Span + if tc != nil { + span = tc.Span() + if span != nil && span.IsRecording() { + // span attributes + attrs := []attribute.KeyValue{ + semantic.RPCSystemKitex, + semantic.RPCSystemKitexRecvSize.Int64(int64(st.RecvSize())), + semantic.RPCSystemKitexSendSize.Int64(int64(st.SendSize())), + semantic.RequestProtocolKey.String(ri.Config().TransportProtocol().String()), + } + + // The source operation dimension maybe cause high cardinality issues + if s.recordSourceOperation { + attrs = append(attrs, semantic.SourceOperationKey.String(ri.From().Method())) + } + + span.SetAttributes(attrs...) + + injectStatsEventsToSpan(span, st) + + if panicMsg, panicStack, rpcErr := parseRPCError(ri); rpcErr != nil || len(panicMsg) > 0 { + recordErrorSpanWithStack(span, rpcErr, panicMsg, panicStack) + } + + span.End(trace.WithTimestamp(getEndTimeOrNow(ri))) + metricsAttributes := semantic.ExtractMetricsAttributesFromSpan(span) + spanlabels := label.ToCwLabelsFromOtels(metricsAttributes) + + labels = append(labels, spanlabels...) + } + } + if span == nil || !span.IsRecording() { + stateless := label.CwLabel{ + Key: semantic.LabelKeyStatus, + Value: semantic.StatusSucceed, + } + if ri.Stats().Error() != nil { + stateless = label.CwLabel{ + Key: semantic.LabelKeyStatus, + Value: semantic.StatusError, + } + } + labels = append(labels, stateless) + } + // Measure s.Measure.Inc(ctx, labels) s.Measure.Record(ctx, elapsedTime, labels) } + +func defaultValIfEmpty(val, def string) string { + if val == "" { + return def + } + return val +} diff --git a/telemetry/instrumentation/otelkitex/tracer.go b/telemetry/instrumentation/otelkitex/tracer.go index eeefb21..0694927 100644 --- a/telemetry/instrumentation/otelkitex/tracer.go +++ b/telemetry/instrumentation/otelkitex/tracer.go @@ -28,8 +28,7 @@ func NewServerTracer(options ...Option) *KitexTracer { if cfg.measure == nil { serverDurationMeasure, err := cfg.meter.Float64Histogram(semantic.ServerDuration) HandleErr(err) - labelcontrol := NewOtelLabelControl(cfg.tracer, cfg.recordSourceOperation) - cfg.measure = metric.NewMeasure(nil, metric.NewOtelRecorder(serverDurationMeasure), labelcontrol) + cfg.measure = metric.NewMeasure(nil, metric.NewOtelRecorder(serverDurationMeasure)) } return &KitexTracer{ Measure: cfg.measure, @@ -43,8 +42,7 @@ func NewClientTracer(options ...Option) *KitexTracer { if cfg.measure == nil { clientDurationMeasure, err := cfg.meter.Float64Histogram(semantic.ClientDuration) HandleErr(err) - labelcontrol := NewOtelLabelControl(cfg.tracer, cfg.recordSourceOperation) - cfg.measure = metric.NewMeasure(nil, metric.NewOtelRecorder(clientDurationMeasure), labelcontrol) + cfg.measure = metric.NewMeasure(nil, metric.NewOtelRecorder(clientDurationMeasure)) } return &KitexTracer{ Measure: cfg.measure, diff --git a/telemetry/meter/label/labelControl.go b/telemetry/meter/label/labelControl.go deleted file mode 100644 index 16be4b2..0000000 --- a/telemetry/meter/label/labelControl.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2022 CloudWeGo Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package label - -import ( - "context" -) - -type LabelControl interface { - ProcessAndInjectLabels(ctx context.Context) context.Context - ProcessAndExtractLabels(ctx context.Context) []CwLabel -} diff --git a/telemetry/meter/metric/measureImp.go b/telemetry/meter/metric/measureImp.go index a15c64e..322cb73 100644 --- a/telemetry/meter/metric/measureImp.go +++ b/telemetry/meter/metric/measureImp.go @@ -27,18 +27,12 @@ var _ Measure = &MeasureImpl{} type MeasureImpl struct { Counter Recorder - label.LabelControl } -func (m *MeasureImpl) SetLabelControl(control label.LabelControl) { - m.LabelControl = control -} - -func NewMeasure(counter Counter, recorder Recorder, labelcontrol label.LabelControl) Measure { +func NewMeasure(counter Counter, recorder Recorder) Measure { return &MeasureImpl{ - Counter: counter, - Recorder: recorder, - LabelControl: labelcontrol, + Counter: counter, + Recorder: recorder, } } @@ -55,11 +49,3 @@ func (m *MeasureImpl) Add(ctx context.Context, value int, labels []label.CwLabel func (m *MeasureImpl) Record(ctx context.Context, value float64, labels []label.CwLabel) error { return m.Recorder.Record(ctx, value, labels) } - -func (m *MeasureImpl) ProcessAndInjectLabels(ctx context.Context) context.Context { - return m.LabelControl.ProcessAndInjectLabels(ctx) -} - -func (m *MeasureImpl) ProcessAndExtractLabels(ctx context.Context) []label.CwLabel { - return m.LabelControl.ProcessAndExtractLabels(ctx) -} diff --git a/telemetry/meter/metric/metric.go b/telemetry/meter/metric/metric.go index 90b2884..642b4a0 100644 --- a/telemetry/meter/metric/metric.go +++ b/telemetry/meter/metric/metric.go @@ -23,8 +23,6 @@ import ( type Measure interface { Counter Recorder - label.LabelControl - SetLabelControl(label.LabelControl) } type Counter interface { Inc(ctx context.Context, labels []label.CwLabel) error diff --git a/telemetry/meter/metric/promemetric_test.go b/telemetry/meter/metric/promemetric_test.go index 951ea28..2612c63 100644 --- a/telemetry/meter/metric/promemetric_test.go +++ b/telemetry/meter/metric/promemetric_test.go @@ -67,7 +67,7 @@ func TestMetrics(t *testing.T) { "test1": "abc", "test2": "def", } - prommmetric := NewMeasure(NewPromCounter(counter), NewPromRecorder(histogram), nil) + prommmetric := NewMeasure(NewPromCounter(counter), NewPromRecorder(histogram)) assert.Nil(t, prommmetric.Add(ctx, 6, label.ToCwLabelFromPromelabel(labels))) assert.Nil(t, prommmetric.Record(ctx, float64(100*time.Millisecond.Microseconds()), label.ToCwLabelFromPromelabel(labels))) diff --git a/telemetry/provider/promprovider/httplabelController.go b/telemetry/provider/promprovider/httplabelController.go deleted file mode 100644 index 60f00ae..0000000 --- a/telemetry/provider/promprovider/httplabelController.go +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2024 CloudWeGo Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package promprovider - -import ( - "context" - "strconv" - - "github.com/cloudwego-contrib/cwgo-pkg/telemetry/meter/label" - "github.com/cloudwego-contrib/cwgo-pkg/telemetry/semantic" - "github.com/cloudwego/hertz/pkg/app" - prom "github.com/prometheus/client_golang/prometheus" -) - -const ( - requestContextKey = "requestContext" -) - -var _ label.LabelControl = PromLabelControl{} - -type PromLabelControl struct{} - -func DefaultHttpPromLabelControl() PromLabelControl { - return PromLabelControl{} -} - -func (p PromLabelControl) ProcessAndInjectLabels(ctx context.Context) context.Context { - return ctx -} - -func (p PromLabelControl) ProcessAndExtractLabels(ctx context.Context) []label.CwLabel { - c, ok := ctx.Value(requestContextKey).(*app.RequestContext) - if !ok { - return nil - } - labels := make(prom.Labels) - labels[semantic.LabelHttpMethodKey] = defaultValIfEmpty(string(c.Request.Method()), semantic.UnknownLabelValue) - labels[semantic.LabelKeyStatus] = defaultValIfEmpty(strconv.Itoa(c.Response.Header.StatusCode()), semantic.UnknownLabelValue) - labels[semantic.LabelPath] = defaultValIfEmpty(c.FullPath(), semantic.UnknownLabelValue) - - return label.ToCwLabelFromPromelabel(labels) -} diff --git a/telemetry/provider/promprovider/promprovider.go b/telemetry/provider/promprovider/promprovider.go index a4a19e3..8fc18b0 100644 --- a/telemetry/provider/promprovider/promprovider.go +++ b/telemetry/provider/promprovider/promprovider.go @@ -105,7 +105,7 @@ func NewPromProvider(addr string, opts ...Option) *promProvider { cfg.registry.MustRegister(clientHandledHistogramRPC) recorder = metric.NewPromRecorder(clientHandledHistogramRPC) } - measure = metric.NewMeasure(counter, recorder, DefaultRPCPromLabelControl()) + measure = metric.NewMeasure(counter, recorder) } else { if cfg.enableCounter { HttpCounterVec := prometheus.NewCounterVec( @@ -129,7 +129,7 @@ func NewPromProvider(addr string, opts ...Option) *promProvider { ) cfg.registry.MustRegister(serverHandledHistogram) } - measure = metric.NewMeasure(counter, recorder, DefaultHttpPromLabelControl()) + measure = metric.NewMeasure(counter, recorder) } pp := &promProvider{ diff --git a/telemetry/provider/promprovider/promprovider_test.go b/telemetry/provider/promprovider/promprovider_test.go index d2d1df9..ae7554c 100644 --- a/telemetry/provider/promprovider/promprovider_test.go +++ b/telemetry/provider/promprovider/promprovider_test.go @@ -51,7 +51,7 @@ func TestPromProvider(t *testing.T) { mux := http.NewServeMux() - measure := metric.NewMeasure(metric.NewPromCounter(counter), metric.NewPromRecorder(histogram), nil) + measure := metric.NewMeasure(metric.NewPromCounter(counter), metric.NewPromRecorder(histogram)) provider := NewPromProvider(":9090", WithRegistry(registry), WithMeasure(measure), diff --git a/telemetry/provider/promprovider/rpclabelcontroller.go b/telemetry/provider/promprovider/rpclabelcontroller.go deleted file mode 100644 index a9246c8..0000000 --- a/telemetry/provider/promprovider/rpclabelcontroller.go +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2024 CloudWeGo Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package promprovider - -import ( - "context" - - "github.com/cloudwego-contrib/cwgo-pkg/telemetry/meter/label" - "github.com/cloudwego-contrib/cwgo-pkg/telemetry/semantic" - "github.com/cloudwego/kitex/pkg/rpcinfo" - prom "github.com/prometheus/client_golang/prometheus" -) - -var _ label.LabelControl = RPCPromLabelControl{} - -type RPCPromLabelControl struct{} - -func DefaultRPCPromLabelControl() RPCPromLabelControl { - return RPCPromLabelControl{} -} - -func (p RPCPromLabelControl) ProcessAndInjectLabels(ctx context.Context) context.Context { - return ctx -} - -func (p RPCPromLabelControl) ProcessAndExtractLabels(ctx context.Context) []label.CwLabel { - ri := rpcinfo.GetRPCInfo(ctx) - extraLabels := make(prom.Labels) - extraLabels[semantic.LabelKeyStatus] = semantic.StatusSucceed - if ri.Stats().Error() != nil { - extraLabels[semantic.LabelKeyStatus] = semantic.StatusError - } - var ( - labels = make(prom.Labels) - - caller = ri.From() - callee = ri.To() - ) - labels[semantic.LabelRPCCallerKey] = defaultValIfEmpty(caller.ServiceName(), semantic.UnknownLabelValue) - labels[semantic.LabelRPCCalleeKey] = defaultValIfEmpty(callee.ServiceName(), semantic.UnknownLabelValue) - labels[semantic.LabelRPCMethodKey] = defaultValIfEmpty(callee.Method(), semantic.UnknownLabelValue) - - labels[semantic.LabelKeyStatus] = semantic.StatusSucceed - if ri.Stats().Error() != nil { - labels[semantic.LabelKeyStatus] = semantic.StatusError - } - - labels[semantic.LabelKeyRetry] = "0" - if retriedCnt, ok := callee.Tag(rpcinfo.RetryTag); ok { - labels[semantic.LabelKeyRetry] = retriedCnt - } - return label.ToCwLabelFromPromelabel(labels) -} - -func defaultValIfEmpty(val, def string) string { - if val == "" { - return def - } - return val -} diff --git a/telemetry/semantic/semconv.go b/telemetry/semantic/semconv.go index b7ba51b..a174824 100644 --- a/telemetry/semantic/semconv.go +++ b/telemetry/semantic/semconv.go @@ -115,4 +115,4 @@ const ( ) // RPCSystemKitex Semantic convention for otelkitex as the remoting system. -var RPCSystemKitex = semconv.RPCSystemKey.String("otelkitex") +var RPCSystemKitex = semconv.RPCSystemKey.String("kitex")