@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
The “Zen” {
Paige Cruz, Chronosphere
[of Python Exemplars]
}
@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
01 Exemplars Explained
02 Example Exemplars
03 Exemplar Enlightenment
Table Of ‘Contents’ {
}
talk.json
00 The Zen of Python
@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
00 {
[The Zen of Python]
}
@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
hello.py
@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
The Zen of Python (aka PEP 20)
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
…
There should be one-- and preferably only
one --obvious way to do it.
…
The Zen of Python (aka PEP 20)
@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
��
@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
01 {
[Exemplars Explained]
}
@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
02 {
Example Exemplars:
OpenTelemetry
}
@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
— OpenTelemetry Metrics Data Model Spec
“An exemplar is a recorded value that
associates OpenTelemetry context to a
metric event within a Metric”
definition.txt
@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Value
Filtered Attributes
< Unix Epoch nanoseconds >
Observation Timestamp
OpenTelemetry ‘Exemplars’{
}
Trace
@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
OpenTelemetry Metrics {
}
Metric Point
Sum ✅
Gauge ✅
Histogram /
Exponential
Histogram
✅
Exemplars?
@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
02 {
Example Exemplars:
Prometheus
}
@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
— OpenMetrics Specification
< “Exemplars are references to data
outside of the MetricSet. A common use
case are IDs of program traces.” >
definition.txt
@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
< Integer or 64-bit float >
< traceID, spanID <=128 UTF-8 chars >
Value
LabelSet
< Unix Epoch seconds >
Timestamp
OpenMetrics ‘Exemplars’{
}
@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Prometheus Metrics {
}
Metric Type
Counter ✅
Histogram ✅
Gauge ❌
Summary ❌
Exemplars?
@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
traces
metrics
@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
def do_something():
with tracer.start_as_current_span("do_something") as span:
data = call_api()
filtered = parse_data(data)
trace_id = '{:032x}'.format(span.get_span_context().trace_id)
TASK_COUNTER.inc(1, exemplar={"trace_id": trace_id, "trace_url":
f"http://localhost:16686/trace/{trace_id}"})
return filtered
script.py
@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
FROM prom/prometheus:v2.48.0
ADD prometheus.yml /etc/prometheus
ENTRYPOINT [ "prometheus" ]
CMD [ "--config.file=/etc/prometheus/prometheus.yml",
"--enable-feature=exemplar-storage" ]
Buildfile-prom
@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
02 {
[Example Exemplars]
Prometheus < > OTel
}
@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
musings.md
@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
03 {
Exemplar Enlightenment
}
@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Exemplars {
}
01 Traces are discoverable in typical workflows
02 Jumpstart good/bad trace comparisons
03 Bridge for (potentially) siloed telemetry
the_good.txt
@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
OpenMetrics Spec
OTel Compatibility with Prom & OpenMetrics
@paigerduty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
CREDITS: This presentation template was
created by Slidesgo, including icons by
Flaticon, and infographics & images by Freepik
Thanks <3 {
paigerduty
@hachyderm.io
@chronopshere.io
www.paigerduty.com
Get in touch
}

The "Zen" of Python Exemplars - OTel Community Day