Skip to content
This repository has been archived by the owner on May 23, 2024. It is now read-only.

Normalize metric names and tags #222

Merged
merged 9 commits into from
Nov 27, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 22 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,19 +63,28 @@ The tracer emits a number of different metrics, defined in
tag-based metric names, e.g. instead of `statsd`-style string names
like `counters.my-service.jaeger.spans.started.sampled`, the metrics
are defined by a short name and a collection of key/value tags, for
example: `name:traces, state:started, sampled:true`.
example: `name:jaeger.traces, state:started, sampled:y`. See [metrics.go](./metrics.go)
file for the full list and descriptions of emitted metrics.

The monitoring backend is represented by the
[StatsReporter](stats_reporter.go) interface. An implementation
of that interface should be passed to the `New` method during
tracer initialization:
The monitoring backend is represented by the `metrics.Factory` interface from package
[`"github.com/uber/jaeger-lib/metrics"`](github.com/uber/jaeger-lib/metrics). An implementation
of that interface can be passed as an option to either the Configuration object or the Tracer
constructor, for example:

```go
stats := // create StatsReporter implementation
tracer := config.Tracing.New("your-service-name", stats)
import (
"github.com/uber/jaeger-client-go/config"
"github.com/uber/jaeger-lib/metrics/prometheus"
)

metricsFactory := prometheus.New()
tracer, closer, err := new(config.Configuration).New(
"your-service-name",
config.Metrics(metricsFactory),
)
```

By default, a no-op `NullStatsReporter` is used.
By default, a no-op `metrics.NullFactory` is used.

### Logging

Expand Down Expand Up @@ -143,18 +152,15 @@ are available:

### Baggage Injection

The OpenTracing spec allows for [baggage](https://github.com/opentracing/specification/blob/master/specification.md#set-a-baggage-item),
which are key value pairs that are added to the span context and propagated
throughout the trace.
An external process can inject baggage by setting the special
HTTP Header `jaeger-baggage` on a request
The OpenTracing spec allows for [baggage][baggage], which are key value pairs that are added
to the span context and propagated throughout the trace. An external process can inject baggage
by setting the special HTTP Header `jaeger-baggage` on a request:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should have a TODO to update documentation so that users are aware of https://github.com/jaegertracing/jaeger-client-go/blob/master/header.go#L30

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


```sh
curl -H "jaeger-baggage: key1=value1, key2=value2" http://myhost.com
```

Baggage can also be programatically set inside your service by doing
the following
Baggage can also be programatically set inside your service:

```go
if span := opentracing.SpanFromContext(ctx); span != nil {
Expand Down Expand Up @@ -229,3 +235,4 @@ However it is not the default propagation format, see [here](zipkin/README.md#Ne
[cov]: https://codecov.io/gh/jaegertracing/jaeger-client-go
[ot-img]: https://img.shields.io/badge/OpenTracing--1.0-enabled-blue.svg
[ot-url]: http://opentracing.io
[baggage]: https://github.com/opentracing/specification/blob/master/specification.md#set-a-baggage-item
6 changes: 3 additions & 3 deletions baggage_setter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,11 @@ func TestTruncateBaggage(t *testing.T) {

testutils.AssertCounterMetrics(t, factory,
testutils.ExpectedMetric{
Name: "jaeger.baggage-truncate",
Name: "jaeger.baggage_truncations",
Value: 1,
},
testutils.ExpectedMetric{
Name: "jaeger.baggage-update",
Name: "jaeger.baggage_updates",
Tags: map[string]string{"result": "ok"},
Value: 1,
},
Expand Down Expand Up @@ -85,7 +85,7 @@ func TestInvalidBaggage(t *testing.T) {

testutils.AssertCounterMetrics(t, factory,
testutils.ExpectedMetric{
Name: "jaeger.baggage-update",
Name: "jaeger.baggage_updates",
Tags: map[string]string{"result": "err"},
Value: 1,
},
Expand Down
2 changes: 1 addition & 1 deletion config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ func TestBaggageRestrictionsConfig(t *testing.T) {
require.NoError(t, err)
defer closer.Close()

metricName := "jaeger.baggage-restrictions-update"
metricName := "jaeger.baggage_restrictions_updates"
metricTags := map[string]string{"result": "err"}
key := metrics.GetKey(metricName, metricTags, "|", "=")
for i := 0; i < 100; i++ {
Expand Down
4 changes: 2 additions & 2 deletions crossdock/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ services:
image: jaegertracing/xdock-java
ports:
- "8080-8082"
# Udp sender needs to know agent's address
depends_on:
# Udp sender needs to know agent's address
- jaeger-agent
- jaeger-agent

python:
image: jaegertracing/xdock-py
Expand Down
56 changes: 45 additions & 11 deletions glide.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion glide.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ import:
- suite
- package: github.com/crossdock/crossdock-go
- package: github.com/uber/jaeger-lib
version: ^1.0.0
version: ^1.2.1
subpackages:
- metrics
testImport:
- package: github.com/prometheus/client_golang
version: v0.8.0
4 changes: 2 additions & 2 deletions internal/baggage/remote/restriction_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ func TestNewRemoteRestrictionManager(t *testing.T) {

testutils.AssertCounterMetrics(t, factory,
testutils.ExpectedMetric{
Name: "jaeger.baggage-restrictions-update",
Name: "jaeger.baggage_restrictions_updates",
Tags: map[string]string{"result": "ok"},
Value: 1,
},
Expand All @@ -147,7 +147,7 @@ func TestDenyBaggageOnInitializationFailure(t *testing.T) {
)
require.False(t, mgr.isReady())

metricName := "jaeger.baggage-restrictions-update"
metricName := "jaeger.baggage_restrictions_updates"
metricTags := map[string]string{"result": "err"}
key := metrics.GetKey(metricName, metricTags, "|", "=")
for i := 0; i < 100; i++ {
Expand Down
48 changes: 23 additions & 25 deletions metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,63 +33,61 @@ type Metrics struct {
TracesJoinedNotSampled metrics.Counter `metric:"traces" tags:"state=joined,sampled=n"`

// Number of sampled spans started by this tracer
SpansStarted metrics.Counter `metric:"spans" tags:"group=lifecycle,state=started"`
SpansStartedSampled metrics.Counter `metric:"started_spans" tags:"sampled=y"`

// Number of sampled spans finished by this tracer
SpansFinished metrics.Counter `metric:"spans" tags:"group=lifecycle,state=finished"`
// Number of unsampled spans started by this tracer
SpansStartedNotSampled metrics.Counter `metric:"started_spans" tags:"sampled=n"`

// Number of sampled spans started by this tracer
SpansSampled metrics.Counter `metric:"spans" tags:"group=sampling,sampled=y"`

// Number of not-sampled spans started by this tracer
SpansNotSampled metrics.Counter `metric:"spans" tags:"group=sampling,sampled=n"`
// Number of spans finished by this tracer
SpansFinished metrics.Counter `metric:"finished_spans"`

// Number of errors decoding tracing context
DecodingErrors metrics.Counter `metric:"decoding-errors"`
DecodingErrors metrics.Counter `metric:"span_context_decoding_errors"`

// Number of spans successfully reported
ReporterSuccess metrics.Counter `metric:"reporter-spans" tags:"state=success"`
ReporterSuccess metrics.Counter `metric:"reporter_spans" tags:"result=ok"`

// Number of spans in failed attempts to report
ReporterFailure metrics.Counter `metric:"reporter-spans" tags:"state=failure"`
// Number of spans not reported due to a Sender failure
ReporterFailure metrics.Counter `metric:"reporter_spans" tags:"result=err"`

// Number of spans dropped due to internal queue overflow
ReporterDropped metrics.Counter `metric:"reporter-spans" tags:"state=dropped"`
ReporterDropped metrics.Counter `metric:"reporter_spans" tags:"result=dropped"`

// Current number of spans in the reporter queue
ReporterQueueLength metrics.Gauge `metric:"reporter-queue"`
ReporterQueueLength metrics.Gauge `metric:"reporter_queue_length"`

// Number of times the Sampler succeeded to retrieve sampling strategy
SamplerRetrieved metrics.Counter `metric:"sampler" tags:"state=retrieved"`
SamplerRetrieved metrics.Counter `metric:"sampler_queries" tags:"result=ok"`

// Number of times the Sampler failed to retrieve sampling strategy
SamplerQueryFailure metrics.Counter `metric:"sampler_queries" tags:"result=err"`

// Number of times the Sampler succeeded to retrieve and update sampling strategy
SamplerUpdated metrics.Counter `metric:"sampler" tags:"state=updated"`
SamplerUpdated metrics.Counter `metric:"sampler_updates" tags:"result=ok"`

// Number of times the Sampler failed to update sampling strategy
SamplerUpdateFailure metrics.Counter `metric:"sampler" tags:"state=failure,phase=updating"`

// Number of times the Sampler failed to retrieve sampling strategy
SamplerQueryFailure metrics.Counter `metric:"sampler" tags:"state=failure,phase=query"`
SamplerUpdateFailure metrics.Counter `metric:"sampler_updates" tags:"result=err"`

// Number of times baggage was successfully written or updated on spans.
BaggageUpdateSuccess metrics.Counter `metric:"baggage-update" tags:"result=ok"`
BaggageUpdateSuccess metrics.Counter `metric:"baggage_updates" tags:"result=ok"`

// Number of times baggage failed to write or update on spans.
BaggageUpdateFailure metrics.Counter `metric:"baggage-update" tags:"result=err"`
BaggageUpdateFailure metrics.Counter `metric:"baggage_updates" tags:"result=err"`

// Number of times baggage was truncated as per baggage restrictions.
BaggageTruncate metrics.Counter `metric:"baggage-truncate"`
BaggageTruncate metrics.Counter `metric:"baggage_truncations"`

// Number of times baggage restrictions were successfully updated.
BaggageRestrictionsUpdateSuccess metrics.Counter `metric:"baggage-restrictions-update" tags:"result=ok"`
BaggageRestrictionsUpdateSuccess metrics.Counter `metric:"baggage_restrictions_updates" tags:"result=ok"`

// Number of times baggage restrictions failed to update.
BaggageRestrictionsUpdateFailure metrics.Counter `metric:"baggage-restrictions-update" tags:"result=err"`
BaggageRestrictionsUpdateFailure metrics.Counter `metric:"baggage_restrictions_updates" tags:"result=err"`
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pavolloffay @objectiser penny for your thoughts.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 - I assume the names will be consistent across all clients?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As much as possible. I don't think we have tag-based APIs in Python and Node.js clients.

Another option would be to drop tags completely and just encode them in the name, e.g. traces_started_sampled. It makes it harder to aggregate if say you don't care about the "is_sampled" dimension.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to have tags - is there any reason they can't be added to python and node clients?


// NewMetrics creates a new Metrics struct and initializes it.
func NewMetrics(factory metrics.Factory, globalTags map[string]string) *Metrics {
m := &Metrics{}
// TODO the namespace "jaeger" should be configurable (e.g. in all-in-one "jaeger-client" would make more sense)
metrics.Init(m, factory.Namespace("jaeger", nil), globalTags)
return m
}
Expand Down
36 changes: 36 additions & 0 deletions metrics/prometheus/metrics_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) 2017 Uber Technologies, Inc.
//
// 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 prometheus_test

import (
"testing"

"github.com/prometheus/client_golang/prometheus"
"github.com/stretchr/testify/require"
jprom "github.com/uber/jaeger-lib/metrics/prometheus"

"github.com/uber/jaeger-client-go"
)

// TestNewPrometheusMetrics ensures that the metrics do not have conflicting dimensions and will work with Prometheus.
func TestNewPrometheusMetrics(t *testing.T) {
tags := map[string]string{"lib": "jaeger"}

factory := jprom.New(jprom.WithRegisterer(prometheus.NewPedanticRegistry()))
m := jaeger.NewMetrics(factory, tags)

require.NotNil(t, m.SpansStartedSampled, "counter not initialized")
require.NotNil(t, m.ReporterQueueLength, "gauge not initialized")
}
Loading