ops.tracing

The tracing facility for the Ops library.

Quick start

In your charmcraft.yaml, declare the charm tracing relation with a tracing interface and optionally the TLS relation with a certificate_transfer interface.:

requires:
    charm-tracing:
        interface: tracing
        limit: 1
        optional: true
    receive-ca-cert:
        interface: certificate_transfer
        limit: 1
        optional: true

If you’re migrating from the charm-tracing charm lib, you most likely already have relations like these. If the names of the relations differ from this recipe, please adjust the code on the rest of this page to your relation names.

Hint

Make sure to include the Rust build packages in your charmcraft.yaml, because this library depends on pydantic-core via pydantic.

parts:
    charm:
        plugin: charm
        source: .
        build-packages:
            - cargo

If you’re migrating from the charm-tracing charm lib, this configuration is likely already in place.

In your charm, add and initialise the Tracing object.:

import ops

class SomeCharm(ops.CharmBase):
    def __init__(self, framework: ops.Framework):
        super().__init__(framework)
        ...
        self.tracing = ops.tracing.Tracing(
            self,
            tracing_relation_name='charm-tracing',
            ca_relation_name='receive-ca-cert',
        )

The tracing relation name is required, while the CA relation name is optional, as it is possible to use a system certificate authority list, provide a custom list (for example from the certify package) or export the trace data over HTTP connections only. Declaring both relations is most common.

Note that you don’t have to import ops.tracing, that name is automatically available when your Python project depends on ops[tracing].

class ops_tracing.Tracing(
charm: CharmBase,
tracing_relation_name: str,
*,
ca_relation_name: str | None = None,
ca_data: str | None = None,
)[source]

Bases: Object

Initialise the tracing service.

Usage:
  • Include ops[tracing] in your dependencies.

  • Declare the relations that the charm supports.

  • Initialise Tracing with the names of these relations.

Example:

# charmcraft.yaml
requires:
    charm-tracing:
        interface: tracing
        limit: 1
        optional: true
    receive-ca-cert:
        interface: certificate_transfer
        limit: 1
        optional: true

# src/charm.py
import ops.tracing

class SomeCharm(ops.CharmBase):
    def __init__(self, framework: ops.Framework):
        ...
        self.tracing = ops.tracing.Tracing(
            self,
            tracing_relation_name="charm-tracing",
            ca_relation_name="receive-ca-cert",
        )
Parameters:
  • charm – your charm instance

  • tracing_relation_name – the name of the relation that provides the destination to send trace data to.

  • ca_relation_name – the name of the relation that provides the CA list to validate the tracing destination against.

  • ca_data – a fixed CA list (PEM bundle, a multi-line string).

If the destination is resolved to an HTTPS URL, a CA list is required to establish a secure connection.

The CA list can be provided over a relation via the ca_relation_name argument, as a fixed string via the ca_data argument, or the system CA list will be used if the earlier two are both None.

ops_tracing.set_destination(url: str | None, ca: str | None) None[source]

Configure the destination service for trace data.

Parameters:
  • url – the URL of the telemetry service to send trace data to. An example could be http://localhost/v1/traces. None or empty string disables sending out the data, which is still buffered.

  • ca – the CA list (PEM bundle, a multi-line string), only used for HTTPS URLs.

Open Telemetry resource attributes

  • service.namespace the UUID of the Juju model.

  • service.namespace.name the name of the Juju model.

  • service.name the application name, like user_db.

  • service.instance.id the unit number, like 0.

  • service.charm the charm class name, like DbCharm.

Tracing behaviour across test frameworks

ops[testing] (formerly Scenario) replaces the OpenTelemetry tracer provider with a mocked version that keeps the emitted spans in memory. This data is not presently exposed to the tests. See ops_tracing._mock.patch_tracing for details.

Harness (legacy) is not affected. This framework does not have a Manager and does not call ops.main() and therefore the tracing subsystem remains uninitialised. It is still safe to create OpenTelemetry spans and events, as the root span is a NonRecordingSpan in this case.