Skip to content

Commit 85e9742

Browse files
authored
Add process runtime information (#811)
1 parent a9ffc35 commit 85e9742

File tree

3 files changed

+34
-1
lines changed

3 files changed

+34
-1
lines changed

logfire/_internal/config.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,10 @@ def _initialize(self) -> None:
712712
otel_resource_attributes: dict[str, Any] = {
713713
ResourceAttributes.SERVICE_NAME: self.service_name,
714714
ResourceAttributes.PROCESS_PID: os.getpid(),
715+
# https://opentelemetry.io/docs/specs/semconv/resource/process/#python-runtimes
716+
ResourceAttributes.PROCESS_RUNTIME_NAME: sys.implementation.name,
717+
ResourceAttributes.PROCESS_RUNTIME_VERSION: get_runtime_version(),
718+
ResourceAttributes.PROCESS_RUNTIME_DESCRIPTION: sys.version,
715719
# Having this giant blob of data associated with every span/metric causes various problems so it's
716720
# disabled for now, but we may want to re-enable something like it in the future
717721
# RESOURCE_ATTRIBUTES_PACKAGE_VERSIONS: json.dumps(collect_package_info(), separators=(',', ':')),
@@ -1560,5 +1564,12 @@ def default_project_name():
15601564
return sanitize_project_name(os.path.basename(os.getcwd()))
15611565

15621566

1567+
def get_runtime_version() -> str:
1568+
version_info = sys.implementation.version
1569+
if version_info.releaselevel == 'final' and not version_info.serial:
1570+
return '.'.join(map(str, version_info[:3]))
1571+
return '.'.join(map(str, version_info)) # pragma: no cover
1572+
1573+
15631574
class LogfireNotConfiguredWarning(UserWarning):
15641575
pass

tests/test_configure.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import pytest
1717
import requests.exceptions
1818
import requests_mock
19+
from dirty_equals import IsStr
1920
from inline_snapshot import snapshot
2021
from opentelemetry.exporter.otlp.proto.http.metric_exporter import OTLPMetricExporter
2122
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
@@ -62,6 +63,9 @@
6263
from logfire.propagate import NoExtractTraceContextPropagator, WarnOnExtractTraceContextPropagator
6364
from logfire.testing import TestExporter
6465

66+
PROCESS_RUNTIME_VERSION_REGEX = r'(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)'
67+
PROCESS_RUNTIME_DESCRIPTION_REGEX = r'(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+) \((?P<branch>\w+), (?P<month>[A-Za-z]{3})\s+(?P<day>\d{1,2}) (?P<year>\d{4}), (?P<hour>\d{2}):(?P<minute>\d{2}):(?P<second>\d{2})\)\s*\[\w+ (?P<clang_version>[\d.]+)\s*\]'
68+
6569

6670
def test_propagate_config_to_tags(exporter: TestExporter) -> None:
6771
tags1 = logfire.with_tags('tag1', 'tag2')
@@ -673,6 +677,9 @@ def test_otel_service_name_env_var(config_kwargs: dict[str, Any], exporter: Test
673677
'service.name': 'potato',
674678
'service.version': '1.2.3',
675679
'service.instance.id': '00000000000000000000000000000000',
680+
'process.runtime.name': 'cpython',
681+
'process.runtime.version': IsStr(regex=PROCESS_RUNTIME_VERSION_REGEX),
682+
'process.runtime.description': IsStr(regex=PROCESS_RUNTIME_DESCRIPTION_REGEX),
676683
'process.pid': 1234,
677684
}
678685
},
@@ -716,6 +723,9 @@ def test_otel_otel_resource_attributes_env_var(config_kwargs: dict[str, Any], ex
716723
'service.version': '1.2.3',
717724
'service.instance.id': 'instance_id',
718725
'process.pid': 1234,
726+
'process.runtime.name': 'cpython',
727+
'process.runtime.version': IsStr(regex=PROCESS_RUNTIME_VERSION_REGEX),
728+
'process.runtime.description': IsStr(regex=PROCESS_RUNTIME_DESCRIPTION_REGEX),
719729
}
720730
},
721731
}
@@ -760,6 +770,9 @@ def test_otel_service_name_has_priority_on_otel_resource_attributes_service_name
760770
'service.version': '1.2.3',
761771
'service.instance.id': '00000000000000000000000000000000',
762772
'process.pid': 1234,
773+
'process.runtime.name': 'cpython',
774+
'process.runtime.version': IsStr(regex=PROCESS_RUNTIME_VERSION_REGEX),
775+
'process.runtime.description': IsStr(regex=PROCESS_RUNTIME_DESCRIPTION_REGEX),
763776
}
764777
},
765778
}
@@ -1658,6 +1671,9 @@ def test_environment(config_kwargs: dict[str, Any], exporter: TestExporter):
16581671
'telemetry.sdk.version': '0.0.0',
16591672
'service.name': 'unknown_service',
16601673
'process.pid': 1234,
1674+
'process.runtime.name': 'cpython',
1675+
'process.runtime.version': IsStr(regex=PROCESS_RUNTIME_VERSION_REGEX),
1676+
'process.runtime.description': IsStr(regex=PROCESS_RUNTIME_DESCRIPTION_REGEX),
16611677
'service.version': '1.2.3',
16621678
'deployment.environment.name': 'production',
16631679
}
@@ -1705,6 +1721,9 @@ def test_code_source(config_kwargs: dict[str, Any], exporter: TestExporter):
17051721
'telemetry.sdk.version': '0.0.0',
17061722
'service.name': 'unknown_service',
17071723
'process.pid': 1234,
1724+
'process.runtime.name': 'cpython',
1725+
'process.runtime.version': IsStr(regex=PROCESS_RUNTIME_VERSION_REGEX),
1726+
'process.runtime.description': IsStr(regex=PROCESS_RUNTIME_DESCRIPTION_REGEX),
17081727
'logfire.code.root_path': 'logfire',
17091728
'logfire.code.work_dir': os.getcwd(),
17101729
'vcs.repository.url.full': 'https://github.com/pydantic/logfire',
@@ -1754,6 +1773,9 @@ def test_code_source_without_root_path(config_kwargs: dict[str, Any], exporter:
17541773
'telemetry.sdk.version': '0.0.0',
17551774
'service.name': 'unknown_service',
17561775
'process.pid': 1234,
1776+
'process.runtime.name': 'cpython',
1777+
'process.runtime.version': IsStr(regex=PROCESS_RUNTIME_VERSION_REGEX),
1778+
'process.runtime.description': IsStr(regex=PROCESS_RUNTIME_DESCRIPTION_REGEX),
17571779
'logfire.code.work_dir': os.getcwd(),
17581780
'vcs.repository.url.full': 'https://github.com/pydantic/logfire',
17591781
'vcs.repository.ref.revision': 'main',

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)