Skip to content

Commit 2c093b6

Browse files
authored
Version 2.3.0 (#603)
1 parent 9001475 commit 2c093b6

File tree

8 files changed

+39
-16
lines changed

8 files changed

+39
-16
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# Release Notes
22

3+
## [v2.3.0] (2024-11-14)
4+
5+
* Respect repr on fields when logging a dataclass by @dmontagu in [#592](https://github.com/pydantic/logfire/pull/592)
6+
* Allow `extract_args` to be an iterable of argument names by @alexmojaki in [#570](https://github.com/pydantic/logfire/pull/570)
7+
* Make metric instrument methods compatible with older OTel versions by @alexmojaki in [#600](https://github.com/pydantic/logfire/pull/600)
8+
* Add span links by @Kludex in [#587](https://github.com/pydantic/logfire/pull/587)
9+
310
## [v2.2.1] (2024-11-13)
411

512
* Ignore trivial/empty functions in auto-tracing by @alexmojaki in [#596](https://github.com/pydantic/logfire/pull/596)
@@ -419,3 +426,4 @@ First release from new repo!
419426
[v2.1.2]: https://github.com/pydantic/logfire/compare/v2.1.1...v2.1.2
420427
[v2.2.0]: https://github.com/pydantic/logfire/compare/v2.1.2...v2.2.0
421428
[v2.2.1]: https://github.com/pydantic/logfire/compare/v2.2.0...v2.2.1
429+
[v2.3.0]: https://github.com/pydantic/logfire/compare/v2.2.1...v2.3.0

logfire-api/logfire_api/_internal/instrument.pyi

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ from .utils import safe_repr as safe_repr, uniquify_sequence as uniquify_sequenc
55
from _typeshed import Incomplete
66
from collections.abc import Sequence
77
from opentelemetry.util import types as otel_types
8-
from typing import Any, Callable, TypeVar
8+
from typing import Any, Callable, ContextManager, Iterable, TypeVar
99
from typing_extensions import LiteralString, ParamSpec
1010

1111
P = ParamSpec('P')
@@ -14,5 +14,6 @@ CONTEXTMANAGER_HELPER_CODE: Incomplete
1414
ASYNCCONTEXTMANAGER_HELPER_CODE: Incomplete
1515
GENERATOR_WARNING_MESSAGE: str
1616

17-
def instrument(logfire: Logfire, tags: Sequence[str], msg_template: LiteralString | None, span_name: str | None, extract_args: bool, allow_generator: bool) -> Callable[[Callable[P, R]], Callable[P, R]]: ...
17+
def instrument(logfire: Logfire, tags: Sequence[str], msg_template: LiteralString | None, span_name: str | None, extract_args: bool | Iterable[str], allow_generator: bool) -> Callable[[Callable[P, R]], Callable[P, R]]: ...
18+
def get_open_span(logfire: Logfire, attributes: dict[str, otel_types.AttributeValue], span_name: str | None, extract_args: bool | Iterable[str], func: Callable[P, R]) -> Callable[P, ContextManager[Any]]: ...
1819
def get_attributes(func: Any, msg_template: str | None, tags: Sequence[str] | None) -> dict[str, otel_types.AttributeValue]: ...

logfire-api/logfire_api/_internal/main.pyi

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ from fastapi import FastAPI
3434
from flask.app import Flask
3535
from opentelemetry.metrics import CallbackT as CallbackT, Counter, Histogram, UpDownCounter, _Gauge as Gauge
3636
from opentelemetry.sdk.trace import ReadableSpan, Span
37-
from opentelemetry.trace import Tracer
37+
from opentelemetry.trace import SpanContext, Tracer
3838
from opentelemetry.util import types as otel_types
3939
from starlette.applications import Starlette
4040
from starlette.requests import Request as Request
@@ -202,7 +202,7 @@ class Logfire:
202202
_exc_info: Set to an exception or a tuple as returned by [`sys.exc_info()`][sys.exc_info]
203203
to record a traceback with the log message.
204204
"""
205-
def span(self, msg_template: str, /, *, _tags: Sequence[str] | None = None, _span_name: str | None = None, _level: LevelName | None = None, **attributes: Any) -> LogfireSpan:
205+
def span(self, msg_template: str, /, *, _tags: Sequence[str] | None = None, _span_name: str | None = None, _level: LevelName | None = None, _links: Sequence[tuple[SpanContext, otel_types.Attributes]] = (), **attributes: Any) -> LogfireSpan:
206206
"""Context manager for creating a span.
207207
208208
```py
@@ -219,10 +219,11 @@ class Logfire:
219219
_span_name: The span name. If not provided, the `msg_template` will be used.
220220
_tags: An optional sequence of tags to include in the span.
221221
_level: An optional log level name.
222+
_links: An optional sequence of links to other spans. Each link is a tuple of a span context and attributes.
222223
attributes: The arguments to include in the span and format the message template with.
223224
Attributes starting with an underscore are not allowed.
224225
"""
225-
def instrument(self, msg_template: LiteralString | None = None, *, span_name: str | None = None, extract_args: bool = True, allow_generator: bool = False) -> Callable[[Callable[P, R]], Callable[P, R]]:
226+
def instrument(self, msg_template: LiteralString | None = None, *, span_name: str | None = None, extract_args: bool | Iterable[str] = True, allow_generator: bool = False) -> Callable[[Callable[P, R]], Callable[P, R]]:
226227
"""Decorator for instrumenting a function as a span.
227228
228229
```py
@@ -239,7 +240,8 @@ class Logfire:
239240
Args:
240241
msg_template: The template for the span message. If not provided, the module and function name will be used.
241242
span_name: The span name. If not provided, the `msg_template` will be used.
242-
extract_args: Whether to extract arguments from the function signature and log them as span attributes.
243+
extract_args: By default, all function call arguments are logged as span attributes.
244+
Set to `False` to disable this, or pass an iterable of argument names to include.
243245
allow_generator: Set to `True` to prevent a warning when instrumenting a generator function.
244246
Read https://logfire.pydantic.dev/docs/guides/advanced/generators/#using-logfireinstrument first.
245247
"""
@@ -973,7 +975,7 @@ class FastLogfireSpan:
973975

974976
class LogfireSpan(ReadableSpan):
975977
end_on_exit: bool
976-
def __init__(self, span_name: str, otlp_attributes: dict[str, otel_types.AttributeValue], tracer: Tracer, json_schema_properties: JsonSchemaProperties) -> None: ...
978+
def __init__(self, span_name: str, otlp_attributes: dict[str, otel_types.AttributeValue], tracer: Tracer, json_schema_properties: JsonSchemaProperties, links: Sequence[tuple[SpanContext, otel_types.Attributes]]) -> None: ...
977979
def __getattr__(self, name: str) -> Any: ...
978980
def __enter__(self) -> LogfireSpan: ...
979981
def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: Any) -> None: ...
@@ -1006,6 +1008,7 @@ class LogfireSpan(ReadableSpan):
10061008
"""
10071009
def set_attributes(self, attributes: dict[str, Any]) -> None:
10081010
"""Sets the given attributes on the span."""
1011+
def add_link(self, context: SpanContext, attributes: otel_types.Attributes = None) -> None: ...
10091012
def record_exception(self, exception: BaseException, attributes: otel_types.Attributes = None, timestamp: int | None = None, escaped: bool = False) -> None:
10101013
"""Records an exception as a span event.
10111014

logfire-api/logfire_api/_internal/metrics.pyi

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ from opentelemetry.context import Context
55
from opentelemetry.metrics import CallbackT as CallbackT, Counter, Histogram, Instrument, Meter, MeterProvider, ObservableCounter, ObservableGauge, ObservableUpDownCounter, UpDownCounter, _Gauge
66
from opentelemetry.util.types import Attributes
77
from threading import Lock
8-
from typing import Any, Generic, Sequence, TypeVar
8+
from typing import Any, Generic, Sequence, TypeVar, TypedDict
9+
from typing_extensions import Unpack
910
from weakref import WeakSet
1011

1112
Gauge: Incomplete
@@ -37,6 +38,15 @@ class _ProxyMeter(Meter):
3738
def create_observable_up_down_counter(self, name: str, callbacks: Sequence[CallbackT] | None = None, unit: str = '', description: str = '') -> ObservableUpDownCounter: ...
3839
InstrumentT = TypeVar('InstrumentT', bound=Instrument)
3940

41+
class MaybeContext(TypedDict, total=False):
42+
"""Backward-compatible keyword arguments for methods like `Counter.add`.
43+
44+
Starting with opentelemetry-sdk 1.28.0, these methods accept an additional optional `context` argument.
45+
This is passed to the underlying instrument using `**kwargs` for compatibility with older versions.
46+
This is the type hint for those kwargs.
47+
"""
48+
context: Context | None
49+
4050
class _ProxyInstrument(ABC, Generic[InstrumentT]):
4151
def __init__(self, instrument: InstrumentT, name: str, unit: str, description: str) -> None: ...
4252
def on_meter_set(self, meter: Meter) -> None:
@@ -46,17 +56,17 @@ class _ProxyAsynchronousInstrument(_ProxyInstrument[InstrumentT], ABC):
4656
def __init__(self, instrument: InstrumentT, name: str, callbacks: Sequence[CallbackT] | None, unit: str, description: str) -> None: ...
4757

4858
class _ProxyCounter(_ProxyInstrument[Counter], Counter):
49-
def add(self, amount: int | float, attributes: Attributes | None = None, context: Context | None = None) -> None: ...
59+
def add(self, amount: int | float, attributes: Attributes | None = None, **kwargs: Unpack[MaybeContext]) -> None: ...
5060

5161
class _ProxyHistogram(_ProxyInstrument[Histogram], Histogram):
52-
def record(self, amount: int | float, attributes: Attributes | None = None, context: Context | None = None) -> None: ...
62+
def record(self, amount: int | float, attributes: Attributes | None = None, **kwargs: Unpack[MaybeContext]) -> None: ...
5363

5464
class _ProxyObservableCounter(_ProxyAsynchronousInstrument[ObservableCounter], ObservableCounter): ...
5565
class _ProxyObservableGauge(_ProxyAsynchronousInstrument[ObservableGauge], ObservableGauge): ...
5666
class _ProxyObservableUpDownCounter(_ProxyAsynchronousInstrument[ObservableUpDownCounter], ObservableUpDownCounter): ...
5767

5868
class _ProxyUpDownCounter(_ProxyInstrument[UpDownCounter], UpDownCounter):
59-
def add(self, amount: int | float, attributes: Attributes | None = None, context: Context | None = None) -> None: ...
69+
def add(self, amount: int | float, attributes: Attributes | None = None, **kwargs: Unpack[MaybeContext]) -> None: ...
6070

6171
class _ProxyGauge(_ProxyInstrument[Gauge], Gauge):
62-
def set(self, amount: int | float, attributes: Attributes | None = None, context: Context | None = None) -> None: ...
72+
def set(self, amount: int | float, attributes: Attributes | None = None, **kwargs: Unpack[MaybeContext]) -> None: ...

logfire-api/logfire_api/_internal/tracer.pyi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class _MaybeDeterministicTimestampSpan(trace_api.Span, ReadableSpan):
3838
def get_span_context(self) -> SpanContext: ...
3939
def set_attributes(self, attributes: dict[str, otel_types.AttributeValue]) -> None: ...
4040
def set_attribute(self, key: str, value: otel_types.AttributeValue) -> None: ...
41+
def add_link(self, context: SpanContext, attributes: otel_types.Attributes = None) -> None: ...
4142
def add_event(self, name: str, attributes: otel_types.Attributes = None, timestamp: int | None = None) -> None: ...
4243
def update_name(self, name: str) -> None: ...
4344
def is_recording(self) -> bool: ...

logfire-api/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "logfire-api"
7-
version = "2.2.1"
7+
version = "2.3.0"
88
description = "Shim for the Logfire SDK which does nothing unless Logfire is installed"
99
authors = [
1010
{ name = "Pydantic Team", email = "[email protected]" },

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "logfire"
7-
version = "2.2.1"
7+
version = "2.3.0"
88
description = "The best Python observability tool! 🪵🔥"
99
requires-python = ">=3.8"
1010
authors = [

uv.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)