Tracing your charm execution
When we talk about tracing, we often refer to traces that are being sent from the workload
container. However, there might be cases, for debugging purposes, where you might want to instrument your charm
itself to send traces about its execution.
Fetch the charm_tracing charm library
charmcraft fetch-lib charms.tempo_k8s.v1.charm_tracing
For the purpose of auto-instrumenting your charm to send its traces, charm_tracing
charm library is used.
It contains utilities to instrument your charm
not the workload
with opentelemetry tracing data collection. This means that, if your charm is related to tempo-k8s
charm and tempo-k8s
is related to grafana-k8s
, you will be able to inspect in real time from the Grafana dashboard the execution flow of your charm.
Use charm_tracing
library
from charms.tempo_k8s.v1.charm_tracing import trace_charm
@trace_charm(
tracing_endpoint="my_tracing_endpoint",
)
class FooCharm:
...
@property
def my_tracing_endpoint(self) -> Optional[str]:
'''Tempo endpoint for charm tracing'''
if self.tracing.is_ready():
return self.tracing.otlp_http_endpoint()
else:
return None
by decorating your charm class Foo
with trace_charm
decorator, it’s expected to provide a Tempo Opentelemetry otlp_http
protocol endpoint to it, which will be retrieved from the class property my_tracing_endpoint
.
The decorator assumes your charm already have access to the tempo endpoint, which can be retrieved by integrating with tempo-k8s over tracing
using the otlp_http
protocol.
At this point your charm Foo
will be automatically instrumented so that:
- Every charm execution starts a
trace
, containing- every
juju event
as aspan
. - every
ops event
as aspan
. - every
charm
method call (except dunders) as aspan
.
- every
See more about the analogy between charm execution and traces in traces in the charm realm.
Auto instrument other types
The decorator will create spans for your Charm Class
method calls. However, you might have other classes that you make use of inside your charm class, like charm libs, relation endpoint wrappers, workload abstractions, …etc, and you want to auto-instrument them as well.
This can be achieved using extra_types
parameter.
Using extra_types
parameter
from charms.tempo_k8s.v1.charm_tracing import trace_charm
from charms.prometheus_k8s.v0.prometheus_scrape import MetricsEndpointProvider
@trace_charm(
tracing_endpoint="my_tracing_endpoint",
extra_types=[
MetricsEndpointProvider,
],
)
class FooCharm:
...
appending types
to the list passed to extra_types
will make the decorator get out-of-the-box traces for all method calls on instances of this class MetricsEndpointProvider
.