Skip to content

Commit d419558

Browse files
authored
Release v3.21.0 (#1150)
1 parent 516c8ab commit d419558

File tree

7 files changed

+28
-17
lines changed

7 files changed

+28
-17
lines changed

CHANGELOG.md

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

3+
## [v3.21.0] (2025-06-17)
4+
5+
* Add up counter/histogram metrics in spans by @alexmojaki in [#1099](https://github.com/pydantic/logfire/pull/1099)
6+
* Fix kwargs in proxy metric instruments, preventing warning about duplicate histograms by @alexmojaki in [#1149](https://github.com/pydantic/logfire/pull/1149)
7+
38
## [v3.20.0] (2025-06-16)
49

510
* Add baggage utilities by @dmontagu in [#1128](https://github.com/pydantic/logfire/pull/1128)
@@ -742,3 +747,4 @@ First release from new repo!
742747
[v3.18.0]: https://github.com/pydantic/logfire/compare/v3.17.0...v3.18.0
743748
[v3.19.0]: https://github.com/pydantic/logfire/compare/v3.18.0...v3.19.0
744749
[v3.20.0]: https://github.com/pydantic/logfire/compare/v3.19.0...v3.20.0
750+
[v3.21.0]: https://github.com/pydantic/logfire/compare/v3.20.0...v3.21.0

logfire-api/logfire_api/_internal/config.pyi

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,9 @@ class PydanticPlugin:
8181

8282
@dataclass
8383
class MetricsOptions:
84-
"""Configuration of metrics.
85-
86-
This only has one option for now, but it's a place to add more related options in the future.
87-
"""
84+
"""Configuration of metrics."""
8885
additional_readers: Sequence[MetricReader] = ...
86+
collect_in_spans: bool = ...
8987

9088
@dataclass
9189
class CodeSource:

logfire-api/logfire_api/_internal/metrics.pyi

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import dataclasses
2+
from .utils import handle_internal_errors as handle_internal_errors
23
from _typeshed import Incomplete
34
from abc import ABC
45
from collections.abc import Sequence
@@ -40,22 +41,19 @@ class _ProxyMeter(Meter):
4041
InstrumentT = TypeVar('InstrumentT', bound=Instrument)
4142

4243
class _ProxyInstrument(ABC, Generic[InstrumentT]):
43-
def __init__(self, instrument: InstrumentT, name: str, unit: str, description: str) -> None: ...
44+
def __init__(self, meter: Meter, **kwargs: Any) -> None: ...
4445
def on_meter_set(self, meter: Meter) -> None:
4546
"""Called when a real meter is set on the creating _ProxyMeter."""
4647

47-
class _ProxyAsynchronousInstrument(_ProxyInstrument[InstrumentT], ABC):
48-
def __init__(self, instrument: InstrumentT, name: str, callbacks: Sequence[CallbackT] | None, unit: str, description: str) -> None: ...
49-
5048
class _ProxyCounter(_ProxyInstrument[Counter], Counter):
5149
def add(self, amount: int | float, attributes: Attributes | None = None, *args: Any, **kwargs: Any) -> None: ...
5250

5351
class _ProxyHistogram(_ProxyInstrument[Histogram], Histogram):
5452
def record(self, amount: int | float, attributes: Attributes | None = None, *args: Any, **kwargs: Any) -> None: ...
5553

56-
class _ProxyObservableCounter(_ProxyAsynchronousInstrument[ObservableCounter], ObservableCounter): ...
57-
class _ProxyObservableGauge(_ProxyAsynchronousInstrument[ObservableGauge], ObservableGauge): ...
58-
class _ProxyObservableUpDownCounter(_ProxyAsynchronousInstrument[ObservableUpDownCounter], ObservableUpDownCounter): ...
54+
class _ProxyObservableCounter(_ProxyInstrument[ObservableCounter], ObservableCounter): ...
55+
class _ProxyObservableGauge(_ProxyInstrument[ObservableGauge], ObservableGauge): ...
56+
class _ProxyObservableUpDownCounter(_ProxyInstrument[ObservableUpDownCounter], ObservableUpDownCounter): ...
5957

6058
class _ProxyUpDownCounter(_ProxyInstrument[UpDownCounter], UpDownCounter):
6159
def add(self, amount: int | float, attributes: Attributes | None = None, *args: Any, **kwargs: Any) -> None: ...

logfire-api/logfire_api/_internal/tracer.pyi

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ from opentelemetry.trace.status import Status, StatusCode
1515
from opentelemetry.util import types as otel_types
1616
from threading import Lock
1717
from typing import Any, Callable
18-
from weakref import WeakKeyDictionary, WeakSet
18+
from weakref import WeakKeyDictionary, WeakValueDictionary
1919

20-
OPEN_SPANS: WeakSet[_LogfireWrappedSpan]
20+
OPEN_SPANS: WeakValueDictionary[tuple[int, int], _LogfireWrappedSpan]
2121

2222
@dataclass
2323
class ProxyTracerProvider(TracerProvider):
@@ -36,6 +36,12 @@ class ProxyTracerProvider(TracerProvider):
3636
def resource(self) -> Resource: ...
3737
def force_flush(self, timeout_millis: int = 30000) -> bool: ...
3838

39+
@dataclass
40+
class SpanMetric:
41+
details: dict[tuple[tuple[str, otel_types.AttributeValue], ...], float] = field(default_factory=Incomplete)
42+
def dump(self): ...
43+
def increment(self, attributes: Mapping[str, otel_types.AttributeValue], value: float): ...
44+
3945
@dataclass(eq=False)
4046
class _LogfireWrappedSpan(trace_api.Span, ReadableSpan):
4147
"""A span that wraps another span and overrides some behaviors in a logfire-specific way.
@@ -47,6 +53,8 @@ class _LogfireWrappedSpan(trace_api.Span, ReadableSpan):
4753
"""
4854
span: Span
4955
ns_timestamp_generator: Callable[[], int]
56+
record_metrics: bool
57+
metrics: dict[str, SpanMetric] = field(default_factory=Incomplete)
5058
def __post_init__(self) -> None: ...
5159
def end(self, end_time: int | None = None) -> None: ...
5260
def get_span_context(self) -> SpanContext: ...
@@ -58,6 +66,7 @@ class _LogfireWrappedSpan(trace_api.Span, ReadableSpan):
5866
def is_recording(self) -> bool: ...
5967
def set_status(self, status: Status | StatusCode, description: str | None = None) -> None: ...
6068
def record_exception(self, exception: BaseException, attributes: otel_types.Attributes = None, timestamp: int | None = None, escaped: bool = False) -> None: ...
69+
def increment_metric(self, name: str, attributes: Mapping[str, otel_types.AttributeValue], value: float) -> None: ...
6170
def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: Any) -> None: ...
6271
def __getattr__(self, name: str) -> Any: ...
6372

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 = "3.20.0"
7+
version = "3.21.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 = "3.20.0"
7+
version = "3.21.0"
88
description = "The best Python observability tool! 🪵🔥"
99
requires-python = ">=3.9"
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)