Skip to content

Commit 1b1e8d8

Browse files
authored
opentelemetry-sdk: use stable code attributes (open-telemetry#4508)
1 parent e0cf233 commit 1b1e8d8

File tree

3 files changed

+35
-25
lines changed

3 files changed

+35
-25
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## Unreleased
99

10+
- opentelemetry-sdk: use stable code attributes: `code.function` -> `code.function.name`, `code.lineno` -> `code.line.number`, `code.filepath` -> `code.file.path`
11+
([#4508](https://github.com/open-telemetry/opentelemetry-python/pull/4508))
1012
- Fix serialization of extended attributes for logs signal
1113
([#4342](https://github.com/open-telemetry/opentelemetry-python/pull/4342))
1214
- docs: updated and added to the metrics and log examples

opentelemetry-sdk/src/opentelemetry/sdk/_logs/_internal/__init__.py

+12-9
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@
4545
from opentelemetry.sdk.resources import Resource
4646
from opentelemetry.sdk.util import ns_to_iso_str
4747
from opentelemetry.sdk.util.instrumentation import InstrumentationScope
48-
from opentelemetry.semconv.trace import SpanAttributes
48+
from opentelemetry.semconv._incubating.attributes import code_attributes
49+
from opentelemetry.semconv.attributes import exception_attributes
4950
from opentelemetry.trace import (
5051
format_span_id,
5152
format_trace_id,
@@ -487,22 +488,24 @@ def _get_attributes(record: logging.LogRecord) -> _ExtendedAttributes:
487488
}
488489

489490
# Add standard code attributes for logs.
490-
attributes[SpanAttributes.CODE_FILEPATH] = record.pathname
491-
attributes[SpanAttributes.CODE_FUNCTION] = record.funcName
492-
attributes[SpanAttributes.CODE_LINENO] = record.lineno
491+
attributes[code_attributes.CODE_FILE_PATH] = record.pathname
492+
attributes[code_attributes.CODE_FUNCTION_NAME] = record.funcName
493+
attributes[code_attributes.CODE_LINE_NUMBER] = record.lineno
493494

494495
if record.exc_info:
495496
exctype, value, tb = record.exc_info
496497
if exctype is not None:
497-
attributes[SpanAttributes.EXCEPTION_TYPE] = exctype.__name__
498+
attributes[exception_attributes.EXCEPTION_TYPE] = (
499+
exctype.__name__
500+
)
498501
if value is not None and value.args:
499-
attributes[SpanAttributes.EXCEPTION_MESSAGE] = str(
502+
attributes[exception_attributes.EXCEPTION_MESSAGE] = str(
500503
value.args[0]
501504
)
502505
if tb is not None:
503-
# https://github.com/open-telemetry/opentelemetry-specification/blob/9fa7c656b26647b27e485a6af7e38dc716eba98a/specification/trace/semantic_conventions/exceptions.md#stacktrace-representation
504-
attributes[SpanAttributes.EXCEPTION_STACKTRACE] = "".join(
505-
traceback.format_exception(*record.exc_info)
506+
# https://opentelemetry.io/docs/specs/semconv/exceptions/exceptions-spans/#stacktrace-representation
507+
attributes[exception_attributes.EXCEPTION_STACKTRACE] = (
508+
"".join(traceback.format_exception(*record.exc_info))
506509
)
507510
return attributes
508511

opentelemetry-sdk/tests/logs/test_handler.py

+21-16
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
LoggingHandler,
2828
LogRecordProcessor,
2929
)
30-
from opentelemetry.semconv.trace import SpanAttributes
30+
from opentelemetry.semconv._incubating.attributes import code_attributes
31+
from opentelemetry.semconv.attributes import exception_attributes
3132
from opentelemetry.trace import INVALID_SPAN_CONTEXT
3233

3334

@@ -127,17 +128,19 @@ def test_log_record_user_attributes(self):
127128
self.assertEqual(len(log_record.attributes), 4)
128129
self.assertEqual(log_record.attributes["http.status_code"], 200)
129130
self.assertTrue(
130-
log_record.attributes[SpanAttributes.CODE_FILEPATH].endswith(
131+
log_record.attributes[code_attributes.CODE_FILE_PATH].endswith(
131132
"test_handler.py"
132133
)
133134
)
134135
self.assertEqual(
135-
log_record.attributes[SpanAttributes.CODE_FUNCTION],
136+
log_record.attributes[code_attributes.CODE_FUNCTION_NAME],
136137
"test_log_record_user_attributes",
137138
)
138139
# The line of the log statement is not a constant (changing tests may change that),
139140
# so only check that the attribute is present.
140-
self.assertTrue(SpanAttributes.CODE_LINENO in log_record.attributes)
141+
self.assertTrue(
142+
code_attributes.CODE_LINE_NUMBER in log_record.attributes
143+
)
141144
self.assertTrue(isinstance(log_record.attributes, BoundedAttributes))
142145

143146
def test_log_record_exception(self):
@@ -156,15 +159,15 @@ def test_log_record_exception(self):
156159
self.assertTrue(isinstance(log_record.body, str))
157160
self.assertEqual(log_record.body, "Zero Division Error")
158161
self.assertEqual(
159-
log_record.attributes[SpanAttributes.EXCEPTION_TYPE],
162+
log_record.attributes[exception_attributes.EXCEPTION_TYPE],
160163
ZeroDivisionError.__name__,
161164
)
162165
self.assertEqual(
163-
log_record.attributes[SpanAttributes.EXCEPTION_MESSAGE],
166+
log_record.attributes[exception_attributes.EXCEPTION_MESSAGE],
164167
"division by zero",
165168
)
166169
stack_trace = log_record.attributes[
167-
SpanAttributes.EXCEPTION_STACKTRACE
170+
exception_attributes.EXCEPTION_STACKTRACE
168171
]
169172
self.assertIsInstance(stack_trace, str)
170173
self.assertTrue("Traceback" in stack_trace)
@@ -189,15 +192,15 @@ def test_log_record_recursive_exception(self):
189192
self.assertIsNotNone(log_record)
190193
self.assertEqual(log_record.body, "Zero Division Error")
191194
self.assertEqual(
192-
log_record.attributes[SpanAttributes.EXCEPTION_TYPE],
195+
log_record.attributes[exception_attributes.EXCEPTION_TYPE],
193196
ZeroDivisionError.__name__,
194197
)
195198
self.assertEqual(
196-
log_record.attributes[SpanAttributes.EXCEPTION_MESSAGE],
199+
log_record.attributes[exception_attributes.EXCEPTION_MESSAGE],
197200
"division by zero",
198201
)
199202
stack_trace = log_record.attributes[
200-
SpanAttributes.EXCEPTION_STACKTRACE
203+
exception_attributes.EXCEPTION_STACKTRACE
201204
]
202205
self.assertIsInstance(stack_trace, str)
203206
self.assertTrue("Traceback" in stack_trace)
@@ -219,12 +222,14 @@ def test_log_exc_info_false(self):
219222

220223
self.assertIsNotNone(log_record)
221224
self.assertEqual(log_record.body, "Zero Division Error")
222-
self.assertNotIn(SpanAttributes.EXCEPTION_TYPE, log_record.attributes)
223225
self.assertNotIn(
224-
SpanAttributes.EXCEPTION_MESSAGE, log_record.attributes
226+
exception_attributes.EXCEPTION_TYPE, log_record.attributes
227+
)
228+
self.assertNotIn(
229+
exception_attributes.EXCEPTION_MESSAGE, log_record.attributes
225230
)
226231
self.assertNotIn(
227-
SpanAttributes.EXCEPTION_STACKTRACE, log_record.attributes
232+
exception_attributes.EXCEPTION_STACKTRACE, log_record.attributes
228233
)
229234

230235
def test_log_record_exception_with_object_payload(self):
@@ -246,15 +251,15 @@ def __str__(self):
246251
self.assertTrue(isinstance(log_record.body, str))
247252
self.assertEqual(log_record.body, "CustomException stringified")
248253
self.assertEqual(
249-
log_record.attributes[SpanAttributes.EXCEPTION_TYPE],
254+
log_record.attributes[exception_attributes.EXCEPTION_TYPE],
250255
CustomException.__name__,
251256
)
252257
self.assertEqual(
253-
log_record.attributes[SpanAttributes.EXCEPTION_MESSAGE],
258+
log_record.attributes[exception_attributes.EXCEPTION_MESSAGE],
254259
"CustomException message",
255260
)
256261
stack_trace = log_record.attributes[
257-
SpanAttributes.EXCEPTION_STACKTRACE
262+
exception_attributes.EXCEPTION_STACKTRACE
258263
]
259264
self.assertIsInstance(stack_trace, str)
260265
self.assertTrue("Traceback" in stack_trace)

0 commit comments

Comments
 (0)