Skip to content

Commit 5ddb8e7

Browse files
authored
[logs-sdk] Remove LogData and extend SDK LogRecord to have instrumentation scope (open-telemetry#4676)
* removing LogData and extending SDK LogRecord to have instrumentation scope * Fix tests * Keep LogData to avoid errors * Removing LogData * Update * Update test * Update * Update event test * Update * Address comments * Update * Add ReadableLogRecord and ReadWriteLogRecord * Update * Update tests * Add dropped_attributes in ReadableLogRecord, this is used to encode logs in OTLP * Convert to ReadWriteLogRecord before exporting * Update EventLogger * Update * Fix events tests * Update * Update event test * Update after merge * Update otlp common test * Update * Address comments * Update * Update * Update * Update * ruff * Addressing comments * Final cleanup
1 parent 20dedf5 commit 5ddb8e7

File tree

22 files changed

+715
-740
lines changed

22 files changed

+715
-740
lines changed

CHANGELOG.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,51 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2121
([#4760](https://github.com/open-telemetry/opentelemetry-python/pull/4760))
2222
- semantic-conventions: Bump to 1.38.0
2323
([#4791](https://github.com/open-telemetry/opentelemetry-python/pull/4791))
24+
- [BREAKING] Remove LogData and extend SDK LogRecord to have instrumentation scope
25+
([#4676](https://github.com/open-telemetry/opentelemetry-python/pull/4676))
26+
27+
**Migration Guide:**
28+
29+
`LogData` has been removed. Users should update their code as follows:
30+
31+
- **For Log Exporters:** Change from `Sequence[LogData]` to `Sequence[ReadableLogRecord]`
32+
```python
33+
# Before
34+
from opentelemetry.sdk._logs import LogData
35+
def export(self, batch: Sequence[LogData]) -> LogExportResult:
36+
...
37+
38+
# After
39+
from opentelemetry.sdk._logs import ReadableLogRecord
40+
def export(self, batch: Sequence[ReadableLogRecord]) -> LogExportResult:
41+
...
42+
```
43+
44+
- **For Log Processors:** Use `ReadWriteLogRecord` for processing, `ReadableLogRecord` for exporting
45+
```python
46+
# Before
47+
from opentelemetry.sdk._logs import LogData
48+
def on_emit(self, log_data: LogData):
49+
...
50+
51+
# After
52+
from opentelemetry.sdk._logs import ReadWriteLogRecord, ReadableLogRecord
53+
def on_emit(self, log_record: ReadWriteLogRecord):
54+
# Convert to ReadableLogRecord before exporting
55+
readable = ReadableLogRecord(
56+
log_record=log_record.log_record,
57+
resource=log_record.resource or Resource.create({}),
58+
instrumentation_scope=log_record.instrumentation_scope,
59+
limits=log_record.limits,
60+
)
61+
...
62+
```
63+
64+
- **Accessing log data:** Use the same attributes on `ReadableLogRecord`/`ReadWriteLogRecord`
65+
- `log_record.log_record` - The API LogRecord (contains body, severity, attributes, etc.)
66+
- `log_record.resource` - The Resource
67+
- `log_record.instrumentation_scope` - The InstrumentationScope (now included, was in LogData before)
68+
- `log_record.limits` - The LogLimits
2469

2570
## Version 1.38.0/0.59b0 (2025-10-16)
2671

exporter/opentelemetry-exporter-otlp-proto-common/src/opentelemetry/exporter/otlp/proto/common/_internal/_log_encoder/__init__.py

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -30,51 +30,55 @@
3030
ResourceLogs,
3131
ScopeLogs,
3232
)
33-
from opentelemetry.sdk._logs import LogData
33+
from opentelemetry.sdk._logs import ReadableLogRecord
3434

3535

36-
def encode_logs(batch: Sequence[LogData]) -> ExportLogsServiceRequest:
36+
def encode_logs(
37+
batch: Sequence[ReadableLogRecord],
38+
) -> ExportLogsServiceRequest:
3739
return ExportLogsServiceRequest(resource_logs=_encode_resource_logs(batch))
3840

3941

40-
def _encode_log(log_data: LogData) -> PB2LogRecord:
42+
def _encode_log(readable_log_record: ReadableLogRecord) -> PB2LogRecord:
4143
span_id = (
4244
None
43-
if log_data.log_record.span_id == 0
44-
else _encode_span_id(log_data.log_record.span_id)
45+
if readable_log_record.log_record.span_id == 0
46+
else _encode_span_id(readable_log_record.log_record.span_id)
4547
)
4648
trace_id = (
4749
None
48-
if log_data.log_record.trace_id == 0
49-
else _encode_trace_id(log_data.log_record.trace_id)
50+
if readable_log_record.log_record.trace_id == 0
51+
else _encode_trace_id(readable_log_record.log_record.trace_id)
5052
)
51-
body = log_data.log_record.body
53+
body = readable_log_record.log_record.body
5254
return PB2LogRecord(
53-
time_unix_nano=log_data.log_record.timestamp,
54-
observed_time_unix_nano=log_data.log_record.observed_timestamp,
55+
time_unix_nano=readable_log_record.log_record.timestamp,
56+
observed_time_unix_nano=readable_log_record.log_record.observed_timestamp,
5557
span_id=span_id,
5658
trace_id=trace_id,
57-
flags=int(log_data.log_record.trace_flags),
59+
flags=int(readable_log_record.log_record.trace_flags),
5860
body=_encode_value(body, allow_null=True),
59-
severity_text=log_data.log_record.severity_text,
61+
severity_text=readable_log_record.log_record.severity_text,
6062
attributes=_encode_attributes(
61-
log_data.log_record.attributes, allow_null=True
63+
readable_log_record.log_record.attributes, allow_null=True
6264
),
63-
dropped_attributes_count=log_data.log_record.dropped_attributes,
65+
dropped_attributes_count=readable_log_record.dropped_attributes,
6466
severity_number=getattr(
65-
log_data.log_record.severity_number, "value", None
67+
readable_log_record.log_record.severity_number, "value", None
6668
),
67-
event_name=log_data.log_record.event_name,
69+
event_name=readable_log_record.log_record.event_name,
6870
)
6971

7072

71-
def _encode_resource_logs(batch: Sequence[LogData]) -> List[ResourceLogs]:
73+
def _encode_resource_logs(
74+
batch: Sequence[ReadableLogRecord],
75+
) -> List[ResourceLogs]:
7276
sdk_resource_logs = defaultdict(lambda: defaultdict(list))
7377

74-
for sdk_log in batch:
75-
sdk_resource = sdk_log.log_record.resource
76-
sdk_instrumentation = sdk_log.instrumentation_scope or None
77-
pb2_log = _encode_log(sdk_log)
78+
for readable_log in batch:
79+
sdk_resource = readable_log.resource
80+
sdk_instrumentation = readable_log.instrumentation_scope or None
81+
pb2_log = _encode_log(readable_log)
7882

7983
sdk_resource_logs[sdk_resource][sdk_instrumentation].append(pb2_log)
8084

0 commit comments

Comments
 (0)