Skip to content

Commit

Permalink
Release v2.4.0 (#615)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexmojaki authored Nov 20, 2024
1 parent 43ba1e0 commit be4bad5
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 15 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Release Notes

## [v2.4.0] (2024-11-20)

* Support `logfire.instrument` without arguments by @Kludex in [#607](https://github.com/pydantic/logfire/pull/607)
* Handle internal errors in `create_json_schema` by @alexmojaki in [#613](https://github.com/pydantic/logfire/pull/613)
* Handle errors in auto-tracing better by @alexmojaki in [#610](https://github.com/pydantic/logfire/pull/610)

## [v2.3.0] (2024-11-14)

* Respect repr on fields when logging a dataclass by @dmontagu in [#592](https://github.com/pydantic/logfire/pull/592)
Expand Down Expand Up @@ -427,3 +433,4 @@ First release from new repo!
[v2.2.0]: https://github.com/pydantic/logfire/compare/v2.1.2...v2.2.0
[v2.2.1]: https://github.com/pydantic/logfire/compare/v2.2.0...v2.2.1
[v2.3.0]: https://github.com/pydantic/logfire/compare/v2.2.1...v2.3.0
[v2.4.0]: https://github.com/pydantic/logfire/compare/v2.3.0...v2.4.0
9 changes: 4 additions & 5 deletions logfire-api/logfire_api/_internal/auto_trace/import_hook.pyi
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
from ..main import Logfire as Logfire
from .rewrite_ast import exec_source as exec_source
from ..utils import log_internal_error as log_internal_error
from .rewrite_ast import compile_source as compile_source
from .types import AutoTraceModule as AutoTraceModule
from dataclasses import dataclass
from importlib.abc import Loader, MetaPathFinder
from importlib.machinery import ModuleSpec
from types import ModuleType
from typing import Callable, Sequence
from typing import Any, Callable, Sequence

@dataclass
class LogfireFinder(MetaPathFinder):
Expand All @@ -25,9 +26,7 @@ class LogfireFinder(MetaPathFinder):
class LogfireLoader(Loader):
"""An import loader produced by LogfireFinder which executes a modified AST of the module's source code."""
plain_spec: ModuleSpec
source: str
logfire: Logfire
min_duration: int
execute: Callable[[dict[str, Any]], None]
def exec_module(self, module: ModuleType):
"""Execute a modified AST of the module's source code in the module's namespace.
Expand Down
8 changes: 5 additions & 3 deletions logfire-api/logfire_api/_internal/auto_trace/rewrite_ast.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ from ..main import Logfire as Logfire
from dataclasses import dataclass
from typing import Any, Callable, ContextManager, TypeVar

def exec_source(source: str, filename: str, module_name: str, globs: dict[str, Any], logfire_instance: Logfire, min_duration: int) -> None:
"""Execute a modified AST of the module's source code in the module's namespace.
def compile_source(tree: ast.AST, filename: str, module_name: str, logfire_instance: Logfire, min_duration: int) -> Callable[[dict[str, Any]], None]:
"""Compile a modified AST of the module's source code in the module's namespace.
Returns a function which accepts module globals and executes the compiled code.
The modified AST wraps the body of every function definition in `with context_factories[index]():`.
`context_factories` is added to the module's namespace as `logfire_<uuid>`.
Expand All @@ -19,7 +21,7 @@ def exec_source(source: str, filename: str, module_name: str, globs: dict[str, A
If `min_duration` is greater than 0, then `context_factories[index]` is initially `MeasureTime`.
Otherwise, it's initially the `partial` above.
"""
def rewrite_ast(source: str, filename: str, logfire_name: str, module_name: str, logfire_instance: Logfire, context_factories: list[Callable[[], ContextManager[Any]]], min_duration: int) -> ast.AST: ...
def rewrite_ast(tree: ast.AST, filename: str, logfire_name: str, module_name: str, logfire_instance: Logfire, context_factories: list[Callable[[], ContextManager[Any]]], min_duration: int) -> ast.AST: ...

@dataclass
class AutoTraceTransformer(BaseTransformer):
Expand Down
18 changes: 17 additions & 1 deletion logfire-api/logfire_api/_internal/main.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ from opentelemetry.util import types as otel_types
from starlette.applications import Starlette
from starlette.requests import Request as Request
from starlette.websockets import WebSocket as WebSocket
from typing import Any, Callable, ContextManager, Iterable, Literal, Sequence, TypeVar
from typing import Any, Callable, ContextManager, Iterable, Literal, Sequence, TypeVar, overload
from typing_extensions import LiteralString, ParamSpec, Unpack
from wsgiref.types import WSGIApplication

Expand Down Expand Up @@ -223,6 +223,7 @@ class Logfire:
attributes: The arguments to include in the span and format the message template with.
Attributes starting with an underscore are not allowed.
"""
@overload
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]]:
"""Decorator for instrumenting a function as a span.
Expand All @@ -245,6 +246,21 @@ class Logfire:
allow_generator: Set to `True` to prevent a warning when instrumenting a generator function.
Read https://logfire.pydantic.dev/docs/guides/advanced/generators/#using-logfireinstrument first.
"""
@overload
def instrument(self, func: Callable[P, R]) -> Callable[P, R]:
"""Decorator for instrumenting a function as a span, with default configuration.
```py
import logfire
logfire.configure()
@logfire.instrument
def my_function(a: int):
logfire.info('new log {a=}', a=a)
```
"""
def log(self, level: LevelName | int, msg_template: str, attributes: dict[str, Any] | None = None, tags: Sequence[str] | None = None, exc_info: ExcInfo = False, console_log: bool | None = None) -> None:
"""Log a message.
Expand Down
1 change: 1 addition & 0 deletions logfire-api/logfire_api/_internal/stack_info.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ def is_user_code(code: CodeType) -> bool:
- the standard library
- site-packages (specifically wherever opentelemetry is installed)
- the logfire package
- an unknown location (e.g. a dynamically generated code object) indicated by a filename starting with '<'
- It is a list/dict/set comprehension.
These are artificial frames only created before Python 3.12,
and they are always called directly from the enclosing function so it makes sense to skip them.
Expand Down
2 changes: 1 addition & 1 deletion logfire-api/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "hatchling.build"

[project]
name = "logfire-api"
version = "2.3.0"
version = "2.4.0"
description = "Shim for the Logfire SDK which does nothing unless Logfire is installed"
authors = [
{ name = "Pydantic Team", email = "[email protected]" },
Expand Down
38 changes: 36 additions & 2 deletions logfire/_internal/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -548,10 +548,44 @@ def instrument(
span_name: str | None = None,
extract_args: bool | Iterable[str] = True,
allow_generator: bool = False,
) -> Callable[[Callable[P, R]], Callable[P, R]]: ...
) -> Callable[[Callable[P, R]], Callable[P, R]]:
"""Decorator for instrumenting a function as a span.
```py
import logfire
logfire.configure()
@logfire.instrument('This is a span {a=}')
def my_function(a: int):
logfire.info('new log {a=}', a=a)
```
Args:
msg_template: The template for the span message. If not provided, the module and function name will be used.
span_name: The span name. If not provided, the `msg_template` will be used.
extract_args: By default, all function call arguments are logged as span attributes.
Set to `False` to disable this, or pass an iterable of argument names to include.
allow_generator: Set to `True` to prevent a warning when instrumenting a generator function.
Read https://logfire.pydantic.dev/docs/guides/advanced/generators/#using-logfireinstrument first.
"""

@overload
def instrument(self, func: Callable[P, R]) -> Callable[P, R]: ...
def instrument(self, func: Callable[P, R]) -> Callable[P, R]:
"""Decorator for instrumenting a function as a span, with default configuration.
```py
import logfire
logfire.configure()
@logfire.instrument
def my_function(a: int):
logfire.info('new log {a=}', a=a)
```
"""

def instrument( # type: ignore[reportInconsistentOverload]
self,
Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "hatchling.build"

[project]
name = "logfire"
version = "2.3.0"
version = "2.4.0"
description = "The best Python observability tool! 🪵🔥"
requires-python = ">=3.8"
authors = [
Expand Down Expand Up @@ -202,6 +202,7 @@ ignore = [
"D100", # ignore missing docstring in module
"D104", # ignore missing docstring in public package
"D105", # ignore missing docstring in magic methods
"D418", # allow docstrings on overloads for the sake of logfire-api stubs
"C901", # ignore too complex functions, doesn't seem to be worth it
]

Expand Down
4 changes: 2 additions & 2 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit be4bad5

Please sign in to comment.