diff --git a/dont-merge/fake-charm.py b/dont-merge/fake-charm.py index 8c1514726..5e6427484 100755 --- a/dont-merge/fake-charm.py +++ b/dont-merge/fake-charm.py @@ -25,6 +25,31 @@ tracer = opentelemetry.trace.get_tracer(__name__) +class DatabaseReadyEvent(ops.charm.EventBase): + """Event representing that the database is ready.""" + + +class DatabaseRequirerEvents(ops.framework.ObjectEvents): + """Container for Database Requirer events.""" + + ready = ops.charm.EventSource(DatabaseReadyEvent) + + +class DatabaseRequirer(ops.framework.Object): + """Dummy docstring.""" + + on = DatabaseRequirerEvents() # type: ignore + + def __init__(self, charm: ops.CharmBase): + """Dummy docstring.""" + super().__init__(charm, 'foo') + self.framework.observe(charm.on.start, self._on_db_changed) + + def _on_db_changed(self, event: ops.StartEvent) -> None: + """Dummy docstring.""" + self.on.ready.emit() + + class FakeCharm(ops.CharmBase): """Dummy docstring.""" @@ -33,13 +58,17 @@ def __init__(self, framework: ops.Framework): super().__init__(framework) self.framework.observe(self.on.start, self._on_start) self.framework.observe(self.on.collect_app_status, self._on_collect_app_status) - self.framework.observe(self.on.collect_unit_status, self._on_collect_unit_status) + self.db_requirer = DatabaseRequirer(self) + self.framework.observe(self.db_requirer.on.ready, self._on_db_ready) def _on_start(self, event: ops.StartEvent) -> None: """Dummy docstring.""" ops.set_tracing_destination(url='http://localhost:4318/v1/traces') self.dummy_load(event, 0.0025) + def _on_db_ready(self, event: DatabaseReadyEvent) -> None: + self.dummy_load(event, 0.001) + def _on_collect_app_status(self, event: ops.CollectStatusEvent) -> None: """Dummy docstring.""" self.dummy_load(event) diff --git a/ops/charm.py b/ops/charm.py index 3f137eb58..300fb453b 100644 --- a/ops/charm.py +++ b/ops/charm.py @@ -1333,8 +1333,6 @@ def __init__(self, framework: ops.Framework): @property def on(self) -> CharmEvents: ... # noqa - # FIXME not sure if this is needed - # may help to exclude `super().__init__(...)` from `UserCharm.__init__` @tracer.start_as_current_span('ops.CharmBase') # type: ignore def __init__(self, framework: Framework): super().__init__(framework, None) @@ -1391,8 +1389,6 @@ def config(self) -> model.ConfigData: return self.model.config -# FIXME may or may not be useful -@tracer.start_as_current_span('ops.charm._evaluate_status') # type: ignore def _evaluate_status(charm: CharmBase): # pyright: ignore[reportUnusedFunction] """Trigger collect-status events and evaluate and set the highest-priority status. @@ -1565,7 +1561,6 @@ def __init__( } @staticmethod - @tracer.start_as_current_span('ops.CharmMeta.from_charm_root') # type: ignore def from_charm_root(charm_root: Union[pathlib.Path, str]): """Initialise CharmMeta from the path to a charm repository root folder.""" _charm_root = pathlib.Path(charm_root) @@ -1925,8 +1920,6 @@ class ContainerMeta: resource is specified. """ - # FIXME is this ever needed? maybe if there are really many mounts? - @tracer.start_as_current_span('ops.ContainerMeta') # type: ignore def __init__(self, name: str, raw: Dict[str, Any]): self.name = name self._mounts: Dict[str, ContainerStorageMeta] = {} diff --git a/ops/framework.py b/ops/framework.py index 529d1c3c2..7afdb2e83 100644 --- a/ops/framework.py +++ b/ops/framework.py @@ -603,7 +603,6 @@ class Framework(Object): @property def on(self) -> 'FrameworkEvents': ... # noqa - @tracer.start_as_current_span('ops.Framework') # type: ignore def __init__( self, storage: Union[SQLiteStorage, JujuStorage], @@ -697,7 +696,6 @@ def _forget(self, obj: 'Serializable'): """Stop tracking the given object. See also _track.""" self._objects.pop(obj.handle.path, None) - @tracer.start_as_current_span('ops.Framework.commit') # type: ignore def commit(self) -> None: """Save changes to the underlying backends.""" # Give a chance for objects to persist data they want to before a commit is made. @@ -871,12 +869,16 @@ def _event_is_in_storage( return True return False - @tracer.start_as_current_span('ops.Framework._emit') # type: ignore def _emit(self, event: EventBase): """See BoundEvent.emit for the public way to call this.""" saved = False event_path = event.handle.path event_kind = event.handle.kind + ops_event = event.__class__.__module__.startswith('ops.') + opentelemetry.trace.get_current_span().add_event( + f'{"ops." if ops_event else ""}{event.__class__.__name__}', + attributes={'deferred': event.deferred, 'kind': event_kind}, + ) parent = event.handle.parent assert isinstance(parent, Handle), 'event handle must have a parent' parent_path = parent.path @@ -913,7 +915,6 @@ def _emit(self, event: EventBase): if saved: self._reemit(event_path) - @tracer.start_as_current_span('ops.Framework.reemit') # type: ignore def reemit(self) -> None: """Reemit previously deferred events to the observers that deferred them.