Skip to content

Commit 00571b8

Browse files
authored
Release v4.17.0 (#1603)
1 parent 52da802 commit 00571b8

File tree

10 files changed

+53
-8
lines changed

10 files changed

+53
-8
lines changed

CHANGELOG.md

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

3+
## [v4.17.0] (2026-01-07)
4+
5+
* `logfire.instrument_surrealdb` by @alexmojaki in [#1573](https://github.com/pydantic/logfire/pull/1573)
6+
* feat(config): allow custom Views in MetricOptions by @cyberksh in [#1552](https://github.com/pydantic/logfire/pull/1552)
7+
* Handle unpicklable configuration in `ProcessPoolExecutor` patch #1556 by @pipinstalled in [#1567](https://github.com/pydantic/logfire/pull/1567)
8+
* Maintain original LLM request context when logging the streaming response by @yiphei in [#1566](https://github.com/pydantic/logfire/pull/1566)
9+
* Add note about `write_token` permission in `logfire projects` commands by @Viicos in [#1545](https://github.com/pydantic/logfire/pull/1545)
10+
311
## [v4.16.0] (2025-12-04)
412

513
* Support OpenTelemetry 1.39.0, drop support for earlier versions, stop using the OTel events API/SDK by @alexmojaki in [#1562](https://github.com/pydantic/logfire/pull/1562)
@@ -985,3 +993,4 @@ First release from new repo!
985993
[v4.15.0]: https://github.com/pydantic/logfire/compare/v4.14.2...v4.15.0
986994
[v4.15.1]: https://github.com/pydantic/logfire/compare/v4.15.0...v4.15.1
987995
[v4.16.0]: https://github.com/pydantic/logfire/compare/v4.15.1...v4.16.0
996+
[v4.17.0]: https://github.com/pydantic/logfire/compare/v4.16.0...v4.17.0

logfire-api/logfire_api/__init__.pyi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ from logfire.propagate import attach_context as attach_context, get_context as g
1515
from logfire.sampling import SamplingOptions as SamplingOptions
1616
from typing import Any
1717

18-
__all__ = ['Logfire', 'LogfireSpan', 'LevelName', 'AdvancedOptions', 'ConsoleOptions', 'CodeSource', 'PydanticPlugin', 'configure', 'span', 'instrument', 'log', 'trace', 'debug', 'notice', 'info', 'warn', 'warning', 'error', 'exception', 'fatal', 'force_flush', 'log_slow_async_callbacks', 'install_auto_tracing', 'instrument_asgi', 'instrument_wsgi', 'instrument_pydantic', 'instrument_pydantic_ai', 'instrument_fastapi', 'instrument_openai', 'instrument_openai_agents', 'instrument_anthropic', 'instrument_google_genai', 'instrument_litellm', 'instrument_print', 'instrument_asyncpg', 'instrument_httpx', 'instrument_celery', 'instrument_requests', 'instrument_psycopg', 'instrument_django', 'instrument_flask', 'instrument_starlette', 'instrument_aiohttp_client', 'instrument_aiohttp_server', 'instrument_sqlalchemy', 'instrument_sqlite3', 'instrument_aws_lambda', 'instrument_redis', 'instrument_pymongo', 'instrument_mysql', 'instrument_system_metrics', 'instrument_mcp', 'AutoTraceModule', 'with_tags', 'with_settings', 'suppress_scopes', 'shutdown', 'no_auto_trace', 'ScrubMatch', 'ScrubbingOptions', 'VERSION', 'add_non_user_code_prefix', 'suppress_instrumentation', 'StructlogProcessor', 'LogfireLoggingHandler', 'loguru_handler', 'SamplingOptions', 'MetricsOptions', 'logfire_info', 'get_baggage', 'set_baggage', 'get_context', 'attach_context']
18+
__all__ = ['Logfire', 'LogfireSpan', 'LevelName', 'AdvancedOptions', 'ConsoleOptions', 'CodeSource', 'PydanticPlugin', 'configure', 'span', 'instrument', 'log', 'trace', 'debug', 'notice', 'info', 'warn', 'warning', 'error', 'exception', 'fatal', 'force_flush', 'log_slow_async_callbacks', 'install_auto_tracing', 'instrument_asgi', 'instrument_wsgi', 'instrument_pydantic', 'instrument_pydantic_ai', 'instrument_fastapi', 'instrument_openai', 'instrument_openai_agents', 'instrument_anthropic', 'instrument_google_genai', 'instrument_litellm', 'instrument_print', 'instrument_asyncpg', 'instrument_httpx', 'instrument_celery', 'instrument_requests', 'instrument_psycopg', 'instrument_django', 'instrument_flask', 'instrument_starlette', 'instrument_aiohttp_client', 'instrument_aiohttp_server', 'instrument_sqlalchemy', 'instrument_sqlite3', 'instrument_aws_lambda', 'instrument_redis', 'instrument_pymongo', 'instrument_mysql', 'instrument_surrealdb', 'instrument_system_metrics', 'instrument_mcp', 'AutoTraceModule', 'with_tags', 'with_settings', 'suppress_scopes', 'shutdown', 'no_auto_trace', 'ScrubMatch', 'ScrubbingOptions', 'VERSION', 'add_non_user_code_prefix', 'suppress_instrumentation', 'StructlogProcessor', 'LogfireLoggingHandler', 'loguru_handler', 'SamplingOptions', 'MetricsOptions', 'logfire_info', 'get_baggage', 'set_baggage', 'get_context', 'attach_context']
1919

2020
DEFAULT_LOGFIRE_INSTANCE = Logfire()
2121
span = DEFAULT_LOGFIRE_INSTANCE.span
@@ -50,6 +50,7 @@ instrument_aws_lambda = DEFAULT_LOGFIRE_INSTANCE.instrument_aws_lambda
5050
instrument_redis = DEFAULT_LOGFIRE_INSTANCE.instrument_redis
5151
instrument_pymongo = DEFAULT_LOGFIRE_INSTANCE.instrument_pymongo
5252
instrument_mysql = DEFAULT_LOGFIRE_INSTANCE.instrument_mysql
53+
instrument_surrealdb = DEFAULT_LOGFIRE_INSTANCE.instrument_surrealdb
5354
instrument_system_metrics = DEFAULT_LOGFIRE_INSTANCE.instrument_system_metrics
5455
instrument_mcp = DEFAULT_LOGFIRE_INSTANCE.instrument_mcp
5556
suppress_scopes = DEFAULT_LOGFIRE_INSTANCE.suppress_scopes

logfire-api/logfire_api/_internal/config.pyi

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,11 @@ from logfire.sampling._tail_sampling import TailSamplingProcessor as TailSamplin
3232
from logfire.version import VERSION as VERSION
3333
from opentelemetry.sdk._logs import LogRecordProcessor as LogRecordProcessor
3434
from opentelemetry.sdk.metrics.export import MetricReader as MetricReader
35+
from opentelemetry.sdk.metrics.view import View
3536
from opentelemetry.sdk.trace import SpanProcessor
3637
from opentelemetry.sdk.trace.id_generator import IdGenerator
3738
from pathlib import Path
38-
from typing import Any, Callable, Literal, TextIO, TypedDict
39+
from typing import Any, Callable, ClassVar, Literal, TextIO, TypedDict
3940
from typing_extensions import Self, Unpack
4041

4142
CREDENTIALS_FILENAME: str
@@ -78,8 +79,10 @@ class PydanticPlugin:
7879
@dataclass
7980
class MetricsOptions:
8081
"""Configuration of metrics."""
82+
DEFAULT_VIEWS: ClassVar[Sequence[View]] = ...
8183
additional_readers: Sequence[MetricReader] = ...
8284
collect_in_spans: bool = ...
85+
views: Sequence[View] = field(default_factory=Incomplete)
8386

8487
@dataclass
8588
class CodeSource:

logfire-api/logfire_api/_internal/integrations/executors.pyi

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from ..stack_info import warn_at_user_stacklevel as warn_at_user_stacklevel
12
from _typeshed import Incomplete
23
from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
34
from logfire.propagate import ContextCarrier as ContextCarrier, attach_context as attach_context, get_context as get_context
@@ -14,5 +15,11 @@ def submit_t(s: ThreadPoolExecutor, fn: Callable[..., Any], /, *args: Any, **kwa
1415
"""A wrapper around ThreadPoolExecutor.submit() that carries over OTEL context across threads."""
1516
def submit_p(s: ProcessPoolExecutor, fn: Callable[..., Any], /, *args: Any, **kwargs: Any):
1617
"""A wrapper around ProcessPoolExecutor.submit() that carries over OTEL context across processes."""
17-
def serialize_config() -> dict[str, Any]: ...
18-
def deserialize_config(config: dict[str, Any]) -> None: ...
18+
def serialize_config() -> dict[str, Any] | None:
19+
"""Serialize the global config for transmission to child processes.
20+
21+
Returns None if the config cannot be pickled, in which case a warning is emitted.
22+
See: https://github.com/pydantic/logfire/issues/1556
23+
"""
24+
def deserialize_config(config: dict[str, Any] | None) -> None:
25+
"""Deserialize a config dict and apply it to the global config."""

logfire-api/logfire_api/_internal/integrations/openai_agents.pyi

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ class LogfireTraceWrapper(LogfireWrapperBase[Trace], Trace):
6464
def trace_id(self) -> str: ...
6565
@property
6666
def name(self) -> str: ...
67+
@property
68+
def tracing_api_key(self) -> str | None: ...
6769
def export(self) -> dict[str, Any] | None: ...
6870

6971
@dataclass
@@ -89,6 +91,8 @@ class LogfireSpanWrapper(LogfireWrapperBase[Span[TSpanData]], Span[TSpanData]):
8991
def started_at(self) -> str | None: ...
9092
@property
9193
def ended_at(self) -> str | None: ...
94+
@property
95+
def tracing_api_key(self) -> str | None: ...
9296

9397
def attributes_from_span_data(span_data: SpanData, msg_template: str) -> dict[str, Any]: ...
9498
def get_basic_response_attributes(response: Response): ...
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from logfire._internal.main import Logfire as Logfire
2+
from logfire._internal.scrubbing import BaseScrubber as BaseScrubber
3+
from logfire._internal.utils import handle_internal_errors as handle_internal_errors
4+
from surrealdb.connections.async_template import AsyncTemplate
5+
from surrealdb.connections.sync_template import SyncTemplate
6+
from typing import Any
7+
8+
def get_all_surrealdb_classes() -> set[type]: ...
9+
def instrument_surrealdb(obj: SyncTemplate | AsyncTemplate | type[SyncTemplate] | type[AsyncTemplate] | None, logfire_instance: Logfire): ...
10+
@handle_internal_errors
11+
def patch_method(obj: Any, method_name: str, logfire_instance: Logfire): ...

logfire-api/logfire_api/_internal/main.pyi

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ from sqlalchemy.ext.asyncio import AsyncEngine
4949
from starlette.applications import Starlette
5050
from starlette.requests import Request as Request
5151
from starlette.websockets import WebSocket as WebSocket
52+
from surrealdb.connections.async_template import AsyncTemplate
53+
from surrealdb.connections.sync_template import SyncTemplate
5254
from types import ModuleType
5355
from typing import Any, Callable, Literal, TypeVar, overload
5456
from typing_extensions import LiteralString, ParamSpec, Unpack
@@ -403,6 +405,14 @@ class Logfire:
403405
modules in `sys.modules` (i.e. modules that have already been imported) match the modules to trace.
404406
Set to `'warn'` to issue a warning instead, or `'ignore'` to skip the check.
405407
"""
408+
def instrument_surrealdb(self, obj: SyncTemplate | AsyncTemplate | type[SyncTemplate] | type[AsyncTemplate] | None = None) -> None:
409+
"""Instrument [SurrealDB](https://surrealdb.com/) connections, creating a span for each method.
410+
411+
Args:
412+
obj: Pass a single connection instance to instrument only that connection.
413+
Pass a connection class to instrument all instances of that class.
414+
By default, all connection classes are instrumented.
415+
"""
406416
def instrument_mcp(self, *, propagate_otel_context: bool = True) -> None:
407417
"""Instrument the [MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk).
408418

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 = "4.16.0"
7+
version = "4.17.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 = "4.16.0"
7+
version = "4.17.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)