Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release v3.1.0 #789

Merged
merged 1 commit into from
Jan 9, 2025
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
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Release Notes

## [v3.1.0] (2025-01-09)

* Add `capture_all` to `instrument_httpx` by @Kludex in [#780](https://github.com/pydantic/logfire/pull/780)
* Ensure cleanup when forked process ends by @alexmojaki in [#785](https://github.com/pydantic/logfire/pull/785)
* Generate trace IDs as ULIDs by default by @adriangb in [#783](https://github.com/pydantic/logfire/pull/783)

## [v3.0.0] (2025-01-07)

* **BREAKING CHANGE**: Removed `capture_request_json_body`, `capture_request_text_body`, `capture_request_form_data`, and `capture_response_json_body` parameters from `logfire.instrument_httpx()`, replaced with `capture_request_body` `capture_response_body` by @Kludex in [#769](https://github.com/pydantic/logfire/pull/769)
Expand Down Expand Up @@ -517,3 +523,4 @@ First release from new repo!
[v2.11.0]: https://github.com/pydantic/logfire/compare/v2.10.0...v2.11.0
[v2.11.1]: https://github.com/pydantic/logfire/compare/v2.11.0...v2.11.1
[v3.0.0]: https://github.com/pydantic/logfire/compare/v2.11.1...v3.0.0
[v3.1.0]: https://github.com/pydantic/logfire/compare/v3.0.0...v3.1.0
2 changes: 1 addition & 1 deletion logfire-api/logfire_api/_internal/integrations/httpx.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ from typing import Any, Awaitable, Callable, Literal, Mapping, ParamSpec

P = ParamSpec('P')

def instrument_httpx(logfire_instance: Logfire, client: httpx.Client | httpx.AsyncClient | None, capture_headers: bool, capture_request_body: bool, capture_response_body: bool, request_hook: RequestHook | AsyncRequestHook | None, response_hook: ResponseHook | AsyncResponseHook | None, async_request_hook: AsyncRequestHook | None, async_response_hook: AsyncResponseHook | None, **kwargs: Any) -> None:
def instrument_httpx(logfire_instance: Logfire, client: httpx.Client | httpx.AsyncClient | None, capture_all: bool, capture_headers: bool, capture_request_body: bool, capture_response_body: bool, request_hook: RequestHook | AsyncRequestHook | None, response_hook: ResponseHook | AsyncResponseHook | None, async_request_hook: AsyncRequestHook | None, async_response_hook: AsyncResponseHook | None, **kwargs: Any) -> None:
"""Instrument the `httpx` module so that spans are automatically created for each request.

See the `Logfire.instrument_httpx` method for details.
Expand Down
6 changes: 3 additions & 3 deletions logfire-api/logfire_api/_internal/main.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -553,11 +553,11 @@ class Logfire:
def instrument_asyncpg(self, **kwargs: Any) -> None:
"""Instrument the `asyncpg` module so that spans are automatically created for each query."""
@overload
def instrument_httpx(self, client: httpx.Client, *, capture_headers: bool = False, capture_request_body: bool = False, capture_response_body: bool = False, request_hook: HttpxRequestHook | None = None, response_hook: HttpxResponseHook | None = None, **kwargs: Any) -> None: ...
def instrument_httpx(self, client: httpx.Client, *, capture_all: bool = False, capture_headers: bool = False, capture_request_body: bool = False, capture_response_body: bool = False, request_hook: HttpxRequestHook | None = None, response_hook: HttpxResponseHook | None = None, **kwargs: Any) -> None: ...
@overload
def instrument_httpx(self, client: httpx.AsyncClient, *, capture_headers: bool = False, capture_request_body: bool = False, capture_response_body: bool = False, request_hook: HttpxRequestHook | HttpxAsyncRequestHook | None = None, response_hook: HttpxResponseHook | HttpxAsyncResponseHook | None = None, **kwargs: Any) -> None: ...
def instrument_httpx(self, client: httpx.AsyncClient, *, capture_all: bool = False, capture_headers: bool = False, capture_request_body: bool = False, capture_response_body: bool = False, request_hook: HttpxRequestHook | HttpxAsyncRequestHook | None = None, response_hook: HttpxResponseHook | HttpxAsyncResponseHook | None = None, **kwargs: Any) -> None: ...
@overload
def instrument_httpx(self, client: None = None, *, capture_headers: bool = False, capture_request_body: bool = False, capture_response_body: bool = False, request_hook: HttpxRequestHook | None = None, response_hook: HttpxResponseHook | None = None, async_request_hook: HttpxAsyncRequestHook | None = None, async_response_hook: HttpxAsyncResponseHook | None = None, **kwargs: Any) -> None: ...
def instrument_httpx(self, client: None = None, *, capture_all: bool = False, capture_headers: bool = False, capture_request_body: bool = False, capture_response_body: bool = False, request_hook: HttpxRequestHook | None = None, response_hook: HttpxResponseHook | None = None, async_request_hook: HttpxAsyncRequestHook | None = None, async_response_hook: HttpxAsyncResponseHook | None = None, **kwargs: Any) -> None: ...
def instrument_celery(self, **kwargs: Any) -> None:
"""Instrument `celery` so that spans are automatically created for each task.

Expand Down
29 changes: 29 additions & 0 deletions logfire-api/logfire_api/_internal/ulid.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from random import Random
from typing import Callable

def ulid(random: Random, ms_timestamp_generator: Callable[[], int]) -> int:
"""Generate an integer ULID compatible with UUID v4.

ULIDs as defined by the [spec](https://github.com/ulid/spec) look like this:

01AN4Z07BY 79KA1307SR9X4MV3
|----------| |----------------|
Timestamp Randomness
48bits 80bits

In the future it would be nice to make this compatible with a UUID,
e.g. v4 UUIDs by setting the version and variant bits correctly.
We can't currently do this because setting these bits would leave us with only 7 bytes of randomness,
which isn't enough for the Python SDK's sampler that currently expects 8 bytes of randomness.
In the future OTEL will probably adopt https://www.w3.org/TR/trace-context-2/#random-trace-id-flag
which relies only on the lower 7 bytes of the trace ID, then all SDKs and tooling should be updated
and leaving only 7 bytes of randomness should be fine.

Right now we only care about:
- Our SDK / Python SDK's in general.
- The OTEL collector.

And both behave properly with 8 bytes of randomness because trace IDs were originally 64 bits
so to be compatible with old trace IDs nothing in OTEL can assume >8 bytes of randomness in trace IDs
unless they generated the trace ID themselves (e.g. the Go SDK _does_ expect >8 bytes of randomness internally).
"""
3 changes: 2 additions & 1 deletion logfire-api/logfire_api/_internal/utils.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ from _typeshed import Incomplete
from collections.abc import Generator
from dataclasses import dataclass
from logfire._internal.stack_info import is_user_code as is_user_code
from logfire._internal.ulid import ulid as ulid
from opentelemetry import trace as trace_api
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import Event as Event, ReadableSpan
Expand Down Expand Up @@ -91,7 +92,7 @@ def handle_internal_errors() -> Generator[None]: ...
def maybe_capture_server_headers(capture: bool): ...
def is_asgi_send_receive_span_name(name: str) -> bool: ...

@dataclass(repr=True)
@dataclass(repr=True, eq=True)
class SeededRandomIdGenerator(IdGenerator):
"""Generate random span/trace IDs from a seed for deterministic tests.

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 = "3.0.0"
version = "3.1.0"
description = "Shim for the Logfire SDK which does nothing unless Logfire is installed"
authors = [
{ name = "Pydantic Team", email = "[email protected]" },
Expand Down
2 changes: 1 addition & 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 = "3.0.0"
version = "3.1.0"
description = "The best Python observability tool! 🪵🔥"
requires-python = ">=3.8"
authors = [
Expand Down
10 changes: 5 additions & 5 deletions uv.lock

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

Loading