The "Zen" of Python Exemplars - OTel Community Day

PaigeBernier 396 views 35 slides Jun 26, 2024
Slide 1
Slide 1 of 35
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11
Slide 12
12
Slide 13
13
Slide 14
14
Slide 15
15
Slide 16
16
Slide 17
17
Slide 18
18
Slide 19
19
Slide 20
20
Slide 21
21
Slide 22
22
Slide 23
23
Slide 24
24
Slide 25
25
Slide 26
26
Slide 27
27
Slide 28
28
Slide 29
29
Slide 30
30
Slide 31
31
Slide 32
32
Slide 33
33
Slide 34
34
Slide 35
35

About This Presentation

The Zen of Python states "There should be one-- and preferably only one --obvious way to do it." OpenTelemetry is the obvious choice for traces but bad news for Pythonistas when it comes to metrics because both Prometheus and OpenTelemetry offer compelling choices. Let's look at all of...


Slide Content

@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
01Exemplars Explained
02Example Exemplars
03Exemplar Enlightenment
Table Of ‘Contents’ {
}
talk.json
00The 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 {
}
01Traces are discoverable in typical workflows
02Jumpstart good/bad trace comparisons
03Bridge 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
}