Skip to content
Merged
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

- **[FEATURE]**: feat(capture): add support for capture tracepoints [#34](https://github.com/intergral/deep/pull/34) [@Umaaz](https://github.com/Umaaz)
- **[BUGFIX]**: fix(duration): snapshot duration not set [#37](https://github.com/intergral/deep/pull/37) [@Umaaz](https://github.com/Umaaz)
- **[BUGFIX]**: fix(attributes): snapshot attributes not set [#38](https://github.com/intergral/deep/pull/38) [@Umaaz](https://github.com/Umaaz)

# 1.1.0 (06/02/2024)

Expand Down
3 changes: 2 additions & 1 deletion src/deep/api/plugin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,11 @@ class SnapshotDecorator(Plugin, abc.ABC):
"""Implement this to decorate collected snapshots with attributes."""

@abc.abstractmethod
def decorate(self, context: ActionContext) -> Optional[BoundedAttributes]:
def decorate(self, snapshot_id: str, context: ActionContext) -> Optional[BoundedAttributes]:
"""
Decorate a snapshot with additional data.

:param snapshot_id: the id of the collected snapshot
:param context: the action context for this action

:return: the additional attributes to attach
Expand Down
16 changes: 13 additions & 3 deletions src/deep/api/plugin/otel.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,22 @@ class OTelPlugin(ResourceProvider, SnapshotDecorator, SpanProcessor):
Provide span and trace information to the snapshot.
"""

def create_span(self, name: str) -> Optional['Span']:
def create_span(self, name: str, context_id: str, tracepoint_id: str) -> Optional['Span']:
"""
Create and return a new span.

:param name: the name of the span to create
:param context_id: the id of the context
:param tracepoint_id: the id of thr tracepoint
:return: the created span
"""
span = trace.get_tracer("deep").start_as_current_span(name, end_on_exit=False, attributes={'dynamic': 'deep'})
span = trace.get_tracer("deep").start_as_current_span(name,
end_on_exit=False,
attributes={'dynamic': 'deep',
'context': context_id,
"tracepoint": tracepoint_id
},
)
if span:
# noinspection PyUnresolvedReferences
# this is a generator contextlib._GeneratorContextManager
Expand Down Expand Up @@ -132,16 +140,18 @@ def resource(self) -> Optional[Resource]:
return Resource.create(attributes=attributes)
return None

def decorate(self, context: ActionContext) -> Optional[BoundedAttributes]:
def decorate(self, snapshot_id: str, context: ActionContext) -> Optional[BoundedAttributes]:
"""
Decorate a snapshot with additional data.

:param snapshot_id: the id of the collected snapshot
:param context: the action context for this action

:return: the additional attributes to attach
"""
span = self.current_span()
if span is not None:
span.add_attribute("snapshot", snapshot_id)
return BoundedAttributes(attributes={
"span_name": span.name,
"trace_id": span.trace_id,
Expand Down
3 changes: 2 additions & 1 deletion src/deep/api/plugin/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,11 @@ class PythonPlugin(ResourceProvider, SnapshotDecorator, TracepointLogger):
This plugin provides the python version to the resource, and the thread name to the attributes.
"""

def decorate(self, context: ActionContext) -> Optional[BoundedAttributes]:
def decorate(self, snapshot_id: str, context: ActionContext) -> Optional[BoundedAttributes]:
"""
Decorate a snapshot with additional data.

:param snapshot_id: the id of the collected snapshot
:param context: the action context for this action

:return: the additional attributes to attach
Expand Down
4 changes: 3 additions & 1 deletion src/deep/api/plugin/span/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@ class SpanProcessor(Plugin, abc.ABC):
"""Span processor connects Deep to a span provider."""

@abc.abstractmethod
def create_span(self, name: str) -> Optional['Span']:
def create_span(self, name: str, context_id: str, tracepoint_id: str) -> Optional['Span']:
"""
Create and return a new span.

:param name: the name of the span to create
:param context_id: the id of the context
:param tracepoint_id: the id of thr tracepoint
:return: the created span
"""
pass
Expand Down
5 changes: 5 additions & 0 deletions src/deep/api/tracepoint/eventsnapshot.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ def id(self):
"""The id of this snapshot."""
return self._id

@property
def id_str(self):
"""The id of this snapshot."""
return format(self._id, "032x")

@property
def tracepoint(self):
"""The tracepoint that triggered this snapshot."""
Expand Down
9 changes: 5 additions & 4 deletions src/deep/processor/context/snapshot_action.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,12 @@ def process(self, ctx: 'TriggerContext') -> Optional[ActionCallback]:
return DeferredSnapshotActionCallback(self.action_context, snapshot)

def _decorate_snapshot(self, ctx):
attributes = BoundedAttributes(attributes={'ctx_id': ctx.id}, immutable=False)
attributes = BoundedAttributes(
attributes={'context': ctx.id, 'tracepoint': self.action_context.location_action.tracepoint.id},
immutable=False)
for decorator in ctx.config.snapshot_decorators:
try:
decorate = decorator.decorate(self.action_context)
decorate = decorator.decorate(self.snapshot.id_str, self.action_context)
if decorate is not None:
attributes.merge_in(decorate)
except Exception:
Expand Down Expand Up @@ -231,8 +233,7 @@ def __init__(self, action_context: ActionContext, snapshot: EventSnapshot):
:param action_context: the action context that created this result
:param snapshot: the snapshot result
"""
self.action_context = action_context
self.snapshot = snapshot
super().__init__(action_context, snapshot)

def process(self, ctx: 'TriggerContext') -> Optional[ActionCallback]:
"""
Expand Down
2 changes: 1 addition & 1 deletion src/deep/processor/context/span_action.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def _process_action(self):
spans = []

for span_processor in self.trigger_context.config.span_processors:
span = span_processor.create_span(name)
span = span_processor.create_span(name, self.trigger_context.id, self.location_action.tracepoint.id)
if span:
spans.append(span)

Expand Down
10 changes: 9 additions & 1 deletion tests/unit_tests/api/plugin/test_otel.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,16 @@ def test_load_plugin(self):
def test_collect_attributes(self):
with trace.get_tracer_provider().get_tracer("test").start_as_current_span("test-span"):
plugin = OTelPlugin()
attributes = plugin.decorate(None)
attributes = plugin.decorate("snap_id", None)
self.assertIsNotNone(attributes)
self.assertEqual("test-span", attributes.get("span_name"))
self.assertIsNotNone(attributes.get("span_id"))
self.assertIsNotNone(attributes.get("trace_id"))
self.assertEqual(plugin.current_span().proxy.attributes, {"snapshot": "snap_id"})

def test_create_span(self):
plugin = OTelPlugin()
span = plugin.create_span("test", "ctx_id", "tp_id")
self.assertIsNotNone(span)
attributes = span.proxy.attributes
self.assertEqual({"dynamic": "deep", "context": "ctx_id", "tracepoint": "tp_id"}, attributes)
2 changes: 1 addition & 1 deletion tests/unit_tests/api/plugin/test_python.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@ def test_load_plugin(self):

def test_collect_attributes(self):
plugin = PythonPlugin()
attributes = plugin.decorate(None)
attributes = plugin.decorate("", None)
self.assertIsNotNone(attributes)
self.assertEqual("MainThread", attributes.get("thread_name"))
4 changes: 2 additions & 2 deletions tests/unit_tests/processor/test_trigger_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ def test_span_action(self):
config = MockConfigService({})
mock_plugin = mockito.mock(spec=SpanProcessor)
mock_span = mockito.mock()
mockito.when(mock_plugin).create_span('some_test_function').thenReturn(mock_span)
mockito.when(mock_plugin).create_span('some_test_function', mockito.ANY, mockito.ANY).thenReturn(mock_span)
config.plugins = [mock_plugin]
push = MockPushService(None, None)
handler = TriggerHandler(config, push)
Expand Down Expand Up @@ -285,7 +285,7 @@ def test_span_action(self):
pushed = push.pushed
self.assertEqual(0, len(pushed))

mockito.verify(mock_plugin, mockito.times(1)).create_span("some_test_function")
mockito.verify(mock_plugin, mockito.times(1)).create_span("some_test_function", mockito.ANY, mockito.ANY)

mockito.verify(mock_span, mockito.times(1)).close()

Expand Down