Skip to content

Commit cc6c8fa

Browse files
committed
Otel distributions cleanup
1 parent fcbb9aa commit cc6c8fa

1 file changed

Lines changed: 59 additions & 0 deletions

File tree

src/charm.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,63 @@
44

55
"""Charmed Machine Operator for the PostgreSQL database."""
66

7+
8+
def _remove_stale_otel_sdk_packages():
9+
"""Hack to remove stale opentelemetry sdk packages from the charm's python venv.
10+
11+
See https://github.com/canonical/grafana-agent-operator/issues/146 and
12+
https://bugs.launchpad.net/juju/+bug/2058335 for more context. This patch can be removed after
13+
this juju issue is resolved and sufficient time has passed to expect most users of this library
14+
have migrated to the patched version of juju. When this patch is removed, un-ignore rule E402 for this file in the pyproject.toml (see setting
15+
[tool.ruff.lint.per-file-ignores] in pyproject.toml).
16+
17+
This only has an effect if executed on an upgrade-charm event.
18+
"""
19+
# all imports are local to keep this function standalone, side-effect-free, and easy to revert later
20+
import os
21+
22+
if os.getenv("JUJU_DISPATCH_PATH") != "hooks/upgrade-charm":
23+
return
24+
25+
import logging
26+
import shutil
27+
from collections import defaultdict
28+
29+
from importlib_metadata import distributions
30+
31+
otel_logger = logging.getLogger("charm_tracing_otel_patcher")
32+
otel_logger.debug("Applying _remove_stale_otel_sdk_packages patch on charm upgrade")
33+
# group by name all distributions starting with "opentelemetry_"
34+
otel_distributions = defaultdict(list)
35+
for distribution in distributions():
36+
name = distribution._normalized_name
37+
if name.startswith("opentelemetry_"):
38+
otel_distributions[name].append(distribution)
39+
40+
otel_logger.debug(f"Found {len(otel_distributions)} opentelemetry distributions")
41+
42+
# If we have multiple distributions with the same name, remove any that have 0 associated files
43+
for name, distributions_ in otel_distributions.items():
44+
if len(distributions_) <= 1:
45+
continue
46+
47+
otel_logger.debug(f"Package {name} has multiple ({len(distributions_)}) distributions.")
48+
for distribution in distributions_:
49+
if not distribution.files: # Not None or empty list
50+
path = distribution._path
51+
otel_logger.info(f"Removing empty distribution of {name} at {path}.")
52+
shutil.rmtree(path)
53+
54+
otel_logger.debug("Successfully applied _remove_stale_otel_sdk_packages patch. ")
55+
56+
57+
# apply hacky patch to remove stale opentelemetry sdk packages on upgrade-charm.
58+
# it could be trouble if someone ever decides to implement their own tracer parallel to
59+
# ours and before the charm has inited. We assume they won't.
60+
# !!IMPORTANT!! keep all otlp imports UNDER this call.
61+
_remove_stale_otel_sdk_packages()
62+
63+
# ruff: disable[E402]
764
import json
865
import logging
966
import os
@@ -122,6 +179,8 @@
122179
from upgrade import PostgreSQLUpgrade, get_postgresql_dependencies_model
123180
from utils import new_password, snap_refreshed
124181

182+
# ruff: enable[E402]
183+
125184
logger = logging.getLogger(__name__)
126185
logging.getLogger("httpx").setLevel(logging.WARNING)
127186
logging.getLogger("httpcore").setLevel(logging.WARNING)

0 commit comments

Comments
 (0)