From 7bdfb2009fd0cd5b5460dbc255fbd6862d4b7d6d Mon Sep 17 00:00:00 2001 From: PietroPasotti Date: Fri, 11 Oct 2024 11:31:20 +0200 Subject: [PATCH] migrated charm tracing libs (#296) * migrated charm tracing libs * pinned --- .../v0}/charm_tracing.py | 48 +++++++++---------- .../v0}/tracing.py | 33 +++++++------ requirements.txt | 3 +- src/charm.py | 4 +- 4 files changed, 47 insertions(+), 41 deletions(-) rename lib/charms/{tempo_k8s/v1 => tempo_coordinator_k8s/v0}/charm_tracing.py (95%) rename lib/charms/{tempo_k8s/v2 => tempo_coordinator_k8s/v0}/tracing.py (96%) diff --git a/lib/charms/tempo_k8s/v1/charm_tracing.py b/lib/charms/tempo_coordinator_k8s/v0/charm_tracing.py similarity index 95% rename from lib/charms/tempo_k8s/v1/charm_tracing.py rename to lib/charms/tempo_coordinator_k8s/v0/charm_tracing.py index 2dbdddd6..1e7ff840 100644 --- a/lib/charms/tempo_k8s/v1/charm_tracing.py +++ b/lib/charms/tempo_coordinator_k8s/v0/charm_tracing.py @@ -12,15 +12,15 @@ # Quickstart Fetch the following charm libs (and ensure the minimum version/revision numbers are satisfied): - charmcraft fetch-lib charms.tempo_k8s.v2.tracing # >= 1.10 - charmcraft fetch-lib charms.tempo_k8s.v1.charm_tracing # >= 2.7 + charmcraft fetch-lib charms.tempo_coordinator_k8s.v0.tracing # >= 1.10 + charmcraft fetch-lib charms.tempo_coordinator_k8s.v0.charm_tracing # >= 2.7 Then edit your charm code to include: ```python # import the necessary charm libs -from charms.tempo_k8s.v2.tracing import TracingEndpointRequirer, charm_tracing_config -from charms.tempo_k8s.v1.charm_tracing import charm_tracing +from charms.tempo_coordinator_k8s.v0.tracing import TracingEndpointRequirer, charm_tracing_config +from charms.tempo_coordinator_k8s.v0.charm_tracing import charm_tracing # decorate your charm class with charm_tracing: @charm_tracing( @@ -51,7 +51,7 @@ def __init__(self, ...): 2) add to your charm a "my_tracing_endpoint" (you can name this attribute whatever you like) **property**, **method** or **instance attribute** that returns an otlp http/https endpoint url. -If you are using the ``charms.tempo_k8s.v2.tracing.TracingEndpointRequirer`` as +If you are using the ``charms.tempo_coordinator_k8s.v0.tracing.TracingEndpointRequirer`` as ``self.tracing = TracingEndpointRequirer(self)``, the implementation could be: ``` @@ -80,7 +80,7 @@ def my_tracing_endpoint(self) -> Optional[str]: For example: ``` -from charms.tempo_k8s.v1.charm_tracing import trace_charm +from charms.tempo_coordinator_k8s.v0.charm_tracing import trace_charm @trace_charm( tracing_endpoint="my_tracing_endpoint", server_cert="_server_cert" @@ -129,7 +129,7 @@ def get_tracer(self) -> opentelemetry.trace.Tracer: For example: ``` - from charms.tempo_k8s.v0.charm_tracing import trace_charm + from charms.tempo_coordinator_k8s.v0.charm_tracing import trace_charm @trace_charm( tracing_endpoint="my_tracing_endpoint", @@ -150,7 +150,7 @@ def my_tracing_endpoint(self) -> Optional[str]: needs to be replaced with: ``` - from charms.tempo_k8s.v1.charm_tracing import trace_charm + from charms.tempo_coordinator_k8s.v0.charm_tracing import trace_charm @trace_charm( tracing_endpoint="my_tracing_endpoint", @@ -249,28 +249,27 @@ def _remove_stale_otel_sdk_packages(): from opentelemetry.sdk.resources import Resource from opentelemetry.sdk.trace import Span, TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor +from opentelemetry.trace import INVALID_SPAN, Tracer +from opentelemetry.trace import get_current_span as otlp_get_current_span from opentelemetry.trace import ( - INVALID_SPAN, - Tracer, get_tracer, get_tracer_provider, set_span_in_context, set_tracer_provider, ) -from opentelemetry.trace import get_current_span as otlp_get_current_span from ops.charm import CharmBase from ops.framework import Framework # The unique Charmhub library identifier, never change it -LIBID = "cb1705dcd1a14ca09b2e60187d1215c7" +LIBID = "01780f1e588c42c3976d26780fdf9b89" # Increment this major API version when introducing breaking changes -LIBAPI = 1 +LIBAPI = 0 # Increment this PATCH version before using `charmcraft publish-lib` or reset # to 0 if you are raising the major API version -LIBPATCH = 15 +LIBPATCH = 2 PYDEPS = ["opentelemetry-exporter-otlp-proto-http==1.21.0"] @@ -332,7 +331,7 @@ def _get_tracer() -> Optional[Tracer]: return tracer.get() except LookupError: # fallback: this course-corrects for a user error where charm_tracing symbols are imported - # from different paths (typically charms.tempo_k8s... and lib.charms.tempo_k8s...) + # from different paths (typically charms.tempo_coordinator_k8s... and lib.charms.tempo_coordinator_k8s...) try: ctx: Context = copy_context() if context_tracer := _get_tracer_from_context(ctx): @@ -372,10 +371,6 @@ class UntraceableObjectError(TracingError): """Raised when an object you're attempting to instrument cannot be autoinstrumented.""" -class TLSError(TracingError): - """Raised when the tracing endpoint is https but we don't have a cert yet.""" - - def _get_tracing_endpoint( tracing_endpoint_attr: str, charm_instance: object, @@ -485,10 +480,15 @@ def wrap_init(self: CharmBase, framework: Framework, *args, **kwargs): ) if tracing_endpoint.startswith("https://") and not server_cert: - raise TLSError( + logger.error( "Tracing endpoint is https, but no server_cert has been passed." - "Please point @trace_charm to a `server_cert` attr." + "Please point @trace_charm to a `server_cert` attr. " + "This might also mean that the tracing provider is related to a " + "certificates provider, but this application is not (yet). " + "In that case, you might just have to wait a bit for the certificates " + "integration to settle. " ) + return exporter = OTLPSpanExporter( endpoint=tracing_endpoint, @@ -562,8 +562,8 @@ def trace_charm( method calls on instances of this class. Usage: - >>> from charms.tempo_k8s.v1.charm_tracing import trace_charm - >>> from charms.tempo_k8s.v1.tracing import TracingEndpointRequirer + >>> from charms.tempo_coordinator_k8s.v0.charm_tracing import trace_charm + >>> from charms.tempo_coordinator_k8s.v0.tracing import TracingEndpointRequirer >>> from ops import CharmBase >>> >>> @trace_charm( @@ -626,7 +626,7 @@ def _autoinstrument( Usage: - >>> from charms.tempo_k8s.v1.charm_tracing import _autoinstrument + >>> from charms.tempo_coordinator_k8s.v0.charm_tracing import _autoinstrument >>> from ops.main import main >>> _autoinstrument( >>> MyCharm, diff --git a/lib/charms/tempo_k8s/v2/tracing.py b/lib/charms/tempo_coordinator_k8s/v0/tracing.py similarity index 96% rename from lib/charms/tempo_k8s/v2/tracing.py rename to lib/charms/tempo_coordinator_k8s/v0/tracing.py index 81bf1f1f..1f92867f 100644 --- a/lib/charms/tempo_k8s/v2/tracing.py +++ b/lib/charms/tempo_coordinator_k8s/v0/tracing.py @@ -16,7 +16,7 @@ This relation must use the `tracing` interface. The `TracingEndpointRequirer` object may be instantiated as follows - from charms.tempo_k8s.v2.tracing import TracingEndpointRequirer + from charms.tempo_coordinator_k8s.v0.tracing import TracingEndpointRequirer def __init__(self, *args): super().__init__(*args) @@ -58,7 +58,7 @@ def __init__(self, *args): For example a Tempo charm may instantiate the `TracingEndpointProvider` in its constructor as follows - from charms.tempo_k8s.v2.tracing import TracingEndpointProvider + from charms.tempo_coordinator_k8s.v0.tracing import TracingEndpointProvider def __init__(self, *args): super().__init__(*args) @@ -100,14 +100,14 @@ def __init__(self, *args): from pydantic import BaseModel, Field # The unique Charmhub library identifier, never change it -LIBID = "12977e9aa0b34367903d8afeb8c3d85d" +LIBID = "d2f02b1f8d1244b5989fd55bc3a28943" # Increment this major API version when introducing breaking changes -LIBAPI = 2 +LIBAPI = 0 # Increment this PATCH version before using `charmcraft publish-lib` or reset # to 0 if you are raising the major API version -LIBPATCH = 10 +LIBPATCH = 2 PYDEPS = ["pydantic"] @@ -947,8 +947,8 @@ def charm_tracing_config( Usage: If you are using charm_tracing >= v1.9: - >>> from lib.charms.tempo_k8s.v1.charm_tracing import trace_charm - >>> from lib.charms.tempo_k8s.v2.tracing import charm_tracing_config + >>> 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" @@ -958,8 +958,8 @@ def charm_tracing_config( ... self.tracing, self._cert_path) If you are using charm_tracing < v1.9: - >>> from lib.charms.tempo_k8s.v1.charm_tracing import trace_charm - >>> from lib.charms.tempo_k8s.v2.tracing import charm_tracing_config + >>> 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" @@ -985,11 +985,16 @@ def charm_tracing_config( is_https = endpoint.startswith("https://") if is_https: - if cert_path is None: - raise TracingError("Cannot send traces to an https endpoint without a certificate.") - elif not Path(cert_path).exists(): - # if endpoint is https BUT we don't have a server_cert yet: - # disable charm tracing until we do to prevent tls errors + if cert_path is None or not Path(cert_path).exists(): + # disable charm tracing until we obtain a cert to prevent tls errors + logger.error( + "Tracing endpoint is https, but no server_cert has been passed." + "Please point @trace_charm to a `server_cert` attr. " + "This might also mean that the tracing provider is related to a " + "certificates provider, but this application is not (yet). " + "In that case, you might just have to wait a bit for the certificates " + "integration to settle. " + ) return None, None return endpoint, str(cert_path) else: diff --git a/requirements.txt b/requirements.txt index 14e6801f..cfe46334 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,7 +11,8 @@ jsonschema # Code: https://github.com/canonical/operator/ # Docs: https://ops.rtfd.io/ # Deps: charm -ops >= 2.10 +# pinned to 2.16 as 2.17 breaks our unittests +ops == 2.16 # YAML processing framework # Code: https://github.com/yaml/pyyaml diff --git a/src/charm.py b/src/charm.py index 40a7a3cf..0f03ed0b 100755 --- a/src/charm.py +++ b/src/charm.py @@ -29,8 +29,8 @@ ) from charms.observability_libs.v1.cert_handler import CertHandler from charms.prometheus_k8s.v0.prometheus_scrape import MetricsEndpointProvider -from charms.tempo_k8s.v1.charm_tracing import trace_charm -from charms.tempo_k8s.v2.tracing import TracingEndpointRequirer +from charms.tempo_coordinator_k8s.v0.charm_tracing import trace_charm +from charms.tempo_coordinator_k8s.v0.tracing import TracingEndpointRequirer from charms.traefik_k8s.v2.ingress import IngressPerAppRequirer from ops.charm import ActionEvent, CharmBase from ops.main import main