Skip to content
Draft
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
18 changes: 15 additions & 3 deletions .docs/reference/libs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1716,6 +1716,18 @@ interfaces:
description: Manage TLS certificates. Deprecated in favor of ``charmlibs.interfaces.tls_certificates``.
tags:
- security
- name: charmlibs.interfaces.tracing
status: recommended
url: https://pypi.org/project/charmlibs-interfaces-tracing
docs: https://canonical.com/juju/docs/charmlibs/reference/charmlibs/interfaces/tracing
src: https://github.com/canonical/charmlibs/tree/main/interfaces/tracing
kind: PyPI
rel_name: tracing
rel_url_charmhub: https://charmhub.io/integrations/tracing
rel_url_schema: https://github.com/canonical/charm-relation-interfaces/tree/main/interfaces/tracing/v2
description: Provide and consume tracing data.
tags:
- observability
- name: charms.tempo_k8s.tracing
status: legacy
url: https://charmhub.io/tempo-k8s/libraries/tracing
Expand All @@ -1725,19 +1737,19 @@ interfaces:
rel_name: tracing
rel_url_charmhub: https://charmhub.io/integrations/tracing
rel_url_schema: https://github.com/canonical/charm-relation-interfaces/tree/main/interfaces/tracing/v2
description: Deprecated in favour of ``tempo_coordinator_k8s .tracing``.
description: Deprecated in favor of ``charmlibs.interfaces.tracing``.
tags:
- observability
- name: charms.tempo_coordinator_k8s.tracing

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Should we also update the lib field in interfaces/tracing/interface/v2/interface.yaml? Or wait until this PR has merged?

status: ''
status: legacy
url: https://charmhub.io/tempo-coordinator-k8s/libraries/tracing
docs: ''
src: https://github.com/canonical/tempo-coordinator-k8s-operator
kind: Charmhub
rel_name: tracing
rel_url_charmhub: https://charmhub.io/integrations/tracing
rel_url_schema: https://github.com/canonical/charm-relation-interfaces/tree/main/interfaces/tracing/v2
description: Provide and consume tracing data.
description: Provide and consume tracing data. Deprecated in favor of ``charmlibs.interfaces.tracing``.
tags:
- observability
- name: charms.traefik_route_k8s.traefik_route
Expand Down
3 changes: 3 additions & 0 deletions interfaces/tracing/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# 1.0.0

Initial release, migrated from charms.tempo_coordinator_k8s.v0.tracing (LIBAPI 0, LIBPATCH 11).
11 changes: 11 additions & 0 deletions interfaces/tracing/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# charmlibs.interfaces.tracing

The `tracing` interface library.

To install, add `charmlibs-interfaces-tracing` to your Python dependencies. Then in your Python code, import as:

```py
from charmlibs.interfaces import tracing
```

See the [reference documentation](https://canonical.com/juju/docs/charmlibs/reference/charmlibs/interfaces/tracing) for more.
100 changes: 100 additions & 0 deletions interfaces/tracing/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
[project]
name = "charmlibs-interfaces-tracing"
description = "The charmlibs.interfaces.tracing package."
readme = "README.md"
requires-python = ">=3.10"
authors = [
{name="The Observability team at Canonical"},
]
license = "Apache-2.0"
classifiers = [
"Programming Language :: Python :: 3",
"Intended Audience :: Developers",
"Operating System :: POSIX :: Linux",
"Development Status :: 5 - Production/Stable",
]
dynamic = ["version"]
dependencies = [
# Libraries should use clear but wide dependency bounds to avoid overly constraining charms.
# Ops 3 is backwards compatible with Ops 2, but drops Python 3.8 support.
# Ops 3 has new features not present in Ops 2.23 (the last Ops 2 feature release).
# See the Ops 2.23 maintenance branch changelog and the Ops 3 changelog for current information:
# - https://github.com/canonical/operator/blob/2.23-maintenance/CHANGES.md
# - https://github.com/canonical/operator/blob/main/CHANGES.md
# Set the dependency bounds according to the features and fixes your library needs.
# "ops>=2.23.1,<4",
"ops>=2.23.1,<4",
"pydantic>=2",
]

[dependency-groups]
lint = [ # installed for `just lint interfaces/tracing` (unit, functional, and integration are also installed)
# "typing_extensions",
]
unit = [ # installed for `just unit interfaces/tracing`
"ops[testing]",
"pytest",
]
functional = [ # installed for `just functional interfaces/tracing`
]
integration = [ # installed for `just integration interfaces/tracing`
"jubilant",
]

[project.urls]
"Documentation" = "https://canonical.com/juju/docs/charmlibs/reference/charmlibs/interfaces/tracing"
"Repository" = "https://github.com/canonical/charmlibs/tree/main/interfaces/tracing"
"Issues" = "https://github.com/canonical/charmlibs/issues"
"Changelog" = "https://github.com/canonical/charmlibs/blob/main/interfaces/tracing/CHANGELOG.md"

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.hatch.build.targets.wheel]
packages = ["src/charmlibs"]

[tool.hatch.version]
path = "src/charmlibs/interfaces/tracing/_version.py"

[tool.ruff]
extend = "../../pyproject.toml"
src = ["src", "tests/unit", "tests/functional", "tests/integration"] # correctly sort local imports in tests

[tool.ruff.format]
quote-style = "preserve"

[tool.ruff.lint.extend-per-file-ignores]
# add additional per-file-ignores here to avoid overriding repo-level config
"./**/schema.py" = [
"CPY", # copyright
"D", # docs
"E501", # line too long
]
"src/charmlibs/interfaces/tracing/_tracing.py" = [
"B904", # FIXME: use raise ... from
"PERF203", # FIXME: try-except within loop
"RUF012", # FIXME: mutable class attribute
"SIM102", # FIXME: nested if
]
"tests/**/*" = [
"E501", # line too long
]

[tool.pyright]
extends = "../../pyproject.toml"
include = ["src", "tests"]
pythonVersion = "3.10" # check no python > 3.10 features are used
ignore = [
"src/charmlibs/interfaces/tracing/_tracing.py", # FIXME: ~200 errors
]

[tool.charmlibs.functional]
ubuntu = [] # ubuntu versions to run functional tests with, e.g. "24.04" (defaults to just "latest")
pebble = [] # pebble versions to run functional tests with, e.g. "v1.0.0", "master" (defaults to no pebble versions)
sudo = false # whether to run functional tests with sudo (defaults to false)

[tool.charmlibs.integration]
# tags to run integration tests with (defaults to running once with no tag, i.e. tags = [''])
# Available in CI in tests/integration/pack.sh and integration tests as CHARMLIBS_TAG
tags = [] # Not used by the pack.sh and integration tests generated by the template
11 changes: 0 additions & 11 deletions interfaces/tracing/ruff.toml

This file was deleted.

156 changes: 156 additions & 0 deletions interfaces/tracing/src/charmlibs/interfaces/tracing/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
# Copyright 2026 Canonical Ltd.
#
# 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.

"""Provide and consume tracing data using the ``tracing`` interface.

This document explains how to integrate with the Tempo charm for the purpose of pushing traces to a
tracing endpoint provided by Tempo. It also explains how alternative implementations of the
Tempo charm
may maintain the same interface and be backward compatible with all currently integrated charms.

======================
Requirer Library Usage
======================

Charms seeking to push traces to Tempo, must do so using the ``TracingEndpointRequirer``
object from this charm library. For the simplest use cases, using the ``TracingEndpointRequirer``
object only requires instantiating it, typically in the constructor of your charm. The
``TracingEndpointRequirer`` constructor requires the name of the relation over which a tracing
endpoint
is exposed by the Tempo charm, and a list of protocols it intends to send traces with.
This relation must use the ``tracing`` interface.
The ``TracingEndpointRequirer`` object may be instantiated as follows::

from charmlibs.interfaces.tracing import TracingEndpointRequirer

def __init__(self, *args):
super().__init__(*args)
# ...
self.tracing = TracingEndpointRequirer(self,
protocols=['otlp_grpc', 'otlp_http', 'jaeger_http_thrift']
)
# ...

Note that the first argument (``self``) to ``TracingEndpointRequirer`` is always a reference to the
parent charm.

Alternatively to providing the list of requested protocols at init time, the charm can do it at
any point in time by calling the
``TracingEndpointRequirer.request_protocols(*protocol:str, relation:Optional[Relation])`` method.
Using this method also allows you to use per-relation protocols.

Units of requirer charms obtain the tempo endpoint to which they will push their traces by calling
``TracingEndpointRequirer.get_endpoint(protocol: str)``, where ``protocol`` is, for example:

- ``otlp_grpc``
- ``otlp_http``
- ``zipkin``
- ``tempo``

If the ``protocol`` is not in the list of protocols that the charm requested at endpoint set-up
time,
the library will raise an error.

We recommend that you scale up your tracing provider and relate it to an ingress so that your
tracing requests go through the ingress and get load balanced across all units. Otherwise, if
the provider's leader goes down, your tracing goes down.

======================
Provider Library Usage
======================

The ``TracingEndpointProvider`` object may be used by charms to manage relations with their
trace sources. For this purposes a Tempo-like charm needs to do two things:

1. Instantiate the ``TracingEndpointProvider`` object by providing it a
reference to the parent (Tempo) charm and optionally the name of the relation that the Tempo charm
uses to interact with its trace sources. This relation must conform to the ``tracing`` interface
and it is strongly recommended that this relation be named ``tracing`` which is its
default value.

For example a Tempo charm may instantiate the ``TracingEndpointProvider`` in its constructor as
follows::

from charmlibs.interfaces.tracing import TracingEndpointProvider

def __init__(self, *args):
super().__init__(*args)
# ...
self.tracing = TracingEndpointProvider(self)
# ...



"""

from ._tracing import (
AmbiguousRelationUsageError,
BrokenEvent,
DataAccessPermissionError,
DatabagModel,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Do we expect people to subclass this? Should it even be exported?

DataValidationError,
EndpointChangedEvent,
EndpointRemovedEvent,
NotReadyError,
ProtocolNotRequestedError,
ProtocolType,
RawReceiver,
Receiver,
ReceiverProtocol,
RelationInterfaceMismatchError,
RelationNotFoundError,
RelationRoleMismatchError,
RequestEvent,
TracingEndpointProvider,
TracingEndpointProviderEvents,
TracingEndpointRequirer,
TracingEndpointRequirerEvents,
TracingError,
TracingProviderAppData,
TracingRequirerAppData,
TransportProtocolType,
charm_tracing_config,
receiver_protocol_to_transport_protocol,
)
from ._version import __version__ as __version__

__all__ = [
"AmbiguousRelationUsageError",
"BrokenEvent",
"DataAccessPermissionError",
"DataValidationError",
"DatabagModel",
"EndpointChangedEvent",
"EndpointRemovedEvent",
"NotReadyError",
"ProtocolNotRequestedError",
"ProtocolType",
"RawReceiver",
"Receiver",
"ReceiverProtocol",
"RelationInterfaceMismatchError",
"RelationNotFoundError",
"RelationRoleMismatchError",
"RequestEvent",
"TracingEndpointProvider",
"TracingEndpointProviderEvents",
"TracingEndpointRequirer",
"TracingEndpointRequirerEvents",
"TracingError",
"TracingProviderAppData",
"TracingRequirerAppData",
"TransportProtocolType",
"charm_tracing_config",
"receiver_protocol_to_transport_protocol",
]
Loading
Loading