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
35 changes: 35 additions & 0 deletions docs/introduction/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,24 @@ For FastStream there is additionally:
health-check span is recorded unless `opentelemetry_generate_health_check_spans` is False, and any
`opentelemetry_instrumentors` are applied.

### Resource

The `Resource` is built with the SDK's `Resource.create`, so OpenTelemetry resource detectors work
with no lite-bootstrap setting. Name them, comma-separated, in `OTEL_EXPERIMENTAL_RESOURCE_DETECTORS`;
each name is an entry point in the `opentelemetry_resource_detector` group. The SDK registers
`process`, `os` and `host`; separately installed detector packages register their own names:

```bash
OTEL_EXPERIMENTAL_RESOURCE_DETECTORS=process,os
```

`OTEL_RESOURCE_ATTRIBUTES` is honoured as well.

The attributes lite-bootstrap sets (`service.name`, `service.namespace`, `service.version`,
`container.name`) are merged last and override anything a detector or environment variable supplies.
`service_name` defaults to `"micro-service"`, so `OTEL_SERVICE_NAME` is overridden unless `service_name`
is empty: set `opentelemetry_service_name` or `service_name` instead.


## Pyroscope

Expand All @@ -187,6 +205,23 @@ Additional parameters:

When OpenTelemetry is also enabled, a `PyroscopeSpanProcessor` is automatically added to the tracer provider. It tags root spans with a `pyroscope.profile.id` attribute and sets Pyroscope thread tags so that traces and profiles can be linked in the Grafana UI.

`pyroscope-io` publishes no free-threaded wheels, so the `pyroscope` extra cannot install on
free-threaded CPython ([#171](https://github.com/modern-python/lite-bootstrap/issues/171)). Sentry's
continuous profiler is pure Python and runs there; enable it through `sentry_additional_params`:

```python
import sentry_sdk

config = FreeConfig(
sentry_dsn="https://key@sentry.example.com/1",
sentry_additional_params={"profile_session_sample_rate": 1.0, "profile_lifecycle": "manual"},
)
FreeBootstrapper(config).bootstrap()
sentry_sdk.profiler.start_profiler()
```

Read more about Sentry's profiling options [here](https://docs.sentry.io/platforms/python/profiling/).

## Structlog

Structlog is bootstrapped by default. To opt out, set `logging_enabled=False`.
Expand Down
41 changes: 41 additions & 0 deletions tests/instruments/test_opentelemetry_instrument.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
import os
import re
import sys
import typing
Expand Down Expand Up @@ -122,6 +123,46 @@ def test_opentelemetry_sampler_wins_over_sampler_env_vars(monkeypatch: pytest.Mo
instrument.teardown()


@pytest.mark.parametrize(
("config", "expected_service_name"),
[
(OpenTelemetryConfig(opentelemetry_log_traces=True), "micro-service"),
(OpenTelemetryConfig(opentelemetry_log_traces=True, service_name="configured"), "configured"),
(
OpenTelemetryConfig(
opentelemetry_log_traces=True, service_name="configured", opentelemetry_service_name="otel-configured"
),
"otel-configured",
),
],
)
def test_opentelemetry_configured_service_name_wins_over_env(
monkeypatch: pytest.MonkeyPatch, config: OpenTelemetryConfig, expected_service_name: str
) -> None:
monkeypatch.setenv("OTEL_SERVICE_NAME", "from-env")
instrument = OpenTelemetryInstrument(bootstrap_config=config)
try:
instrument.bootstrap()
assert instrument._tracer_provider is not None # noqa: SLF001
assert instrument._tracer_provider.resource.attributes["service.name"] == expected_service_name # noqa: SLF001
finally:
instrument.teardown()


def test_opentelemetry_resource_detectors_enrich_resource(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setenv("OTEL_EXPERIMENTAL_RESOURCE_DETECTORS", "process")
monkeypatch.setenv("OTEL_RESOURCE_ATTRIBUTES", "deployment.environment=from-env")
instrument = OpenTelemetryInstrument(bootstrap_config=OpenTelemetryConfig(opentelemetry_log_traces=True))
try:
instrument.bootstrap()
assert instrument._tracer_provider is not None # noqa: SLF001
attributes = instrument._tracer_provider.resource.attributes # noqa: SLF001
assert attributes["process.pid"] == os.getpid()
assert attributes["deployment.environment"] == "from-env"
finally:
instrument.teardown()


def test_opentelemetry_instrument_teardown_shuts_down_tracer_provider() -> None:
instrument = OpenTelemetryInstrument(
bootstrap_config=OpenTelemetryConfig(opentelemetry_log_traces=True),
Expand Down
Loading