Tempo Coordinator K8S
- Canonical Observability
Channel | Revision | Published | Runs on |
---|---|---|---|
latest/edge | 37 | 20 Nov 2024 |
juju deploy tempo-coordinator-k8s --channel edge
Deploy Kubernetes operators easily with Juju, the Universal Operator Lifecycle Manager. Need a Kubernetes cluster? Install MicroK8s to create a full CNCF-certified Kubernetes system in under 60 seconds.
Platform:
charms.tempo_coordinator_k8s.v0.tracing
-
- Last updated 16 Oct 2024
- Revision Library version 0.3
Overview.
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 charms.tempo_coordinator_k8s.v0.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
- 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 thetracing
interface and it is strongly recommended that this relation be namedtracing
which is its default value.
For example a Tempo charm may instantiate the TracingEndpointProvider
in its constructor as
follows
from charms.tempo_coordinator_k8s.v0.tracing import TracingEndpointProvider
def __init__(self, *args):
super().__init__(*args)
# ...
self.tracing = TracingEndpointProvider(self)
# ...
Index
class TransportProtocolType
Description
Receiver Type. None
class TracingError
Description
Base class for custom errors raised by this library. None
class NotReadyError
Description
Raised by the provider wrapper if a requirer hasn't published the required data (yet). None
class ProtocolNotRequestedError
Description
Raised if the user attempts to obtain an endpoint for a protocol it did not request. None
class DataValidationError
Description
Raised when data validation fails on IPU relation data. None
class AmbiguousRelationUsageError
Description
Raised when one wrongly assumes that there can only be one relation on an endpoint. None
class Receiver
Description
Specification of an active receiver. None
class TracingProviderAppData
Description
Application databag model for the tracing provider. None
class TracingRequirerAppData
Description
Application databag model for the tracing requirer. None
class RelationNotFoundError
Description
Raised if no relation with the given name is found. None
Methods
RelationNotFoundError. __init__( self , relation_name: str )
class RelationInterfaceMismatchError
Description
Raised if the relation with the given name has an unexpected interface. None
Methods
RelationInterfaceMismatchError. __init__( self , relation_name: str , expected_relation_interface: str , actual_relation_interface: str )
class RelationRoleMismatchError
Description
Raised if the relation with the given name has a different role than expected. None
Methods
RelationRoleMismatchError. __init__( self , relation_name: str , expected_relation_role: RelationRole , actual_relation_role: RelationRole )
class RequestEvent
Description
Event emitted when a remote requests a tracing endpoint. None
Methods
RequestEvent. requested_receivers( self )
Description
List of receiver protocols that have been requested. None
class BrokenEvent
Description
Event emitted when a relation on tracing is broken. None
class TracingEndpointProviderEvents
Description
TracingEndpointProvider events. None
class TracingEndpointProvider
Description
Class representing a trace receiver service. None
Methods
TracingEndpointProvider. __init__( self , charm: CharmBase , external_url , relation_name: str )
Initialize.
Arguments
a CharmBase
instance that manages this instance of the Tempo service.
external address of the node hosting the tempo server, if an ingress is present.
an optional string name of the relation between charm
and the Tempo charmed service. The default is "tracing".
TracingEndpointProvider. is_requirer_ready( self , relation: Relation )
Description
Attempt to determine if requirer has already populated app data. None
TracingEndpointProvider. requested_protocols( self )
Description
All receiver protocols that have been requested by our related apps. None
TracingEndpointProvider. relations( self )
Description
All relations active on this endpoint. None
TracingEndpointProvider. publish_receivers( self , receivers )
Description
Let all requirers know that these receivers are active and listening. None
class EndpointRemovedEvent
Description
Event representing a change in one of the receiver endpoints. None
class EndpointChangedEvent
Description
Event representing a change in one of the receiver endpoints. None
Methods
EndpointChangedEvent. receivers( self )
Description
Cast receivers back from dict. None
class TracingEndpointRequirerEvents
Description
TracingEndpointRequirer events. None
class TracingEndpointRequirer
Description
A tracing endpoint for Tempo. None
Methods
TracingEndpointRequirer. __init__( self , charm: CharmBase , relation_name: str , protocols )
Construct a tracing requirer for a Tempo charm.
Arguments
a CharmBase
object that manages this
TracingEndpointRequirer
object. Typically, this is self
in the instantiating
class.
an optional string name of the relation between charm
and the Tempo charmed service. The default is "tracing". It is strongly
advised not to change the default, so that people deploying your charm will have a
consistent experience with all other charms that provide tracing endpoints.
optional list of protocols that the charm intends to send traces with. The provider will enable receivers for these and only these protocols, so be sure to enable all protocols the charm or its workload are going to need.
Description
If your application supports pushing traces to a distributed tracing backend, the
TracingEndpointRequirer
object enables your charm to easily access endpoint information
exchanged over a tracing
relation interface.
TracingEndpointRequirer. request_protocols( self , protocols , relation )
Description
Publish the list of protocols which the provider should activate. None
TracingEndpointRequirer. relations( self )
Description
The tracing relations associated with this endpoint. None
TracingEndpointRequirer. is_ready( self , relation )
Description
Is this endpoint ready? None
TracingEndpointRequirer. get_all_endpoints( self , relation )
Description
Unmarshalled relation data. None
TracingEndpointRequirer. get_endpoint( self , protocol: ReceiverProtocol , relation )
Receiver endpoint for the given protocol.
Description
It could happen that this function gets called before the provider publishes the endpoints.
In such a scenario, if a non-leader unit calls this function, a permission denied exception will be raised due to
restricted access. To prevent this, this function needs to be guarded by the is_ready
check.
Raises: ProtocolNotRequestedError: If the charm unit is the leader unit and attempts to obtain an endpoint for a protocol it did not request.
def
charm_tracing_config(
endpoint_requirer: TracingEndpointRequirer,
cert_path
)
Return the charm_tracing config you likely want.
Description
If no endpoint is provided: disable charm tracing. If https endpoint is provided but cert_path is not found on disk: disable charm tracing. If https endpoint is provided and cert_path is None: ERROR Else: proceed with charm tracing (with or without tls, as appropriate)
Usage: If you are using charm_tracing >= v1.9:
from lib.charms.tempo_coordinator_k8s.v0.charm_tracing import trace_charm from lib.charms.tempo_coordinator_k8s.v0.tracing import charm_tracing_config @trace_charm(tracing_endpoint="my_endpoint", cert_path="cert_path") class MyCharm(...): _cert_path = "/path/to/cert/on/charm/container.crt" def init(self, ...): self.tracing = TracingEndpointRequirer(...) self.my_endpoint, self.cert_path = charm_tracing_config( ... self.tracing, self._cert_path)
If you are using charm_tracing < v1.9:
from lib.charms.tempo_coordinator_k8s.v0.charm_tracing import trace_charm from lib.charms.tempo_coordinator_k8s.v0.tracing import charm_tracing_config @trace_charm(tracing_endpoint="my_endpoint", cert_path="cert_path") class MyCharm(...): _cert_path = "/path/to/cert/on/charm/container.crt" def init(self, ...): self.tracing = TracingEndpointRequirer(...) self._my_endpoint, self._cert_path = charm_tracing_config( ... self.tracing, self._cert_path) @property def my_endpoint(self): return self._my_endpoint @property def cert_path(self): return self._cert_path