Skip to content

Commit bc7f6b2

Browse files
authored
add logfire dep group for performance exploration (#17860)
1 parent 1c5064c commit bc7f6b2

File tree

6 files changed

+3189
-2998
lines changed

6 files changed

+3189
-2998
lines changed

pyproject.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,8 @@ dev = [
177177
"opentelemetry-test-utils>=0.48b0,<1.0.0",
178178
]
179179

180+
perf = ["logfire[fastapi,sqlalchemy]>=3.14.0", "pyinstrument>=5.0.0"]
181+
180182
markdown-docs = [
181183
"pytest-markdown-docs>=0.6.0",
182184
"prefect[aws]",

src/prefect/server/api/server.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,19 @@
6262
)
6363
from prefect.utilities.hashing import hash_objects
6464

65+
if os.environ.get("PREFECT_LOGFIRE_ENABLED"):
66+
import logfire # pyright: ignore
67+
68+
token: str | None = os.environ.get("PREFECT_LOGFIRE_WRITE_TOKEN")
69+
if token is None:
70+
raise ValueError(
71+
"PREFECT_LOGFIRE_WRITE_TOKEN must be set when PREFECT_LOGFIRE_ENABLED is true"
72+
)
73+
74+
logfire.configure(token=token) # pyright: ignore
75+
else:
76+
logfire = None
77+
6578
if TYPE_CHECKING:
6679
import logging
6780

@@ -250,7 +263,7 @@ def copy_directory(directory: str, path: str) -> None:
250263
shutil.rmtree(destination)
251264
shutil.copytree(source, destination, symlinks=True)
252265
# ensure copied files are writeable
253-
for root, dirs, files in os.walk(destination):
266+
for root, _, files in os.walk(destination):
254267
for f in files:
255268
os.chmod(os.path.join(root, f), 0o700)
256269
else:
@@ -329,6 +342,10 @@ def create_api_app(
329342

330343
fast_api_app_kwargs = fast_api_app_kwargs or {}
331344
api_app = FastAPI(title=API_TITLE, **fast_api_app_kwargs)
345+
346+
if logfire:
347+
logfire.instrument_fastapi(api_app) # pyright: ignore
348+
332349
api_app.add_middleware(GZipMiddleware)
333350

334351
@api_app.get(health_check_path, tags=["Root"])

src/prefect/server/database/configurations.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import os
12
import sqlite3
23
import traceback
34
from abc import ABC, abstractmethod
@@ -31,6 +32,19 @@
3132
)
3233
from prefect.utilities.asyncutils import add_event_loop_shutdown_callback
3334

35+
if os.getenv("PREFECT_LOGFIRE_ENABLED"):
36+
import logfire # pyright: ignore
37+
38+
token: str | None = os.getenv("PREFECT_LOGFIRE_WRITE_TOKEN")
39+
if token is None:
40+
raise ValueError(
41+
"PREFECT_LOGFIRE_WRITE_TOKEN must be set when PREFECT_LOGFIRE_ENABLED is true"
42+
)
43+
44+
logfire.configure(token=token) # pyright: ignore
45+
else:
46+
logfire = None
47+
3448
SQLITE_BEGIN_MODE: ContextVar[Optional[str]] = ContextVar( # novm
3549
"SQLITE_BEGIN_MODE", default=None
3650
)
@@ -265,6 +279,9 @@ async def engine(self) -> AsyncEngine:
265279
**kwargs,
266280
)
267281

282+
if logfire:
283+
logfire.instrument_sqlalchemy(engine) # pyright: ignore
284+
268285
if TRACKER.active:
269286
TRACKER.track_pool(engine.pool)
270287

@@ -389,6 +406,9 @@ async def engine(self) -> AsyncEngine:
389406
sa.event.listen(engine.sync_engine, "connect", self.setup_sqlite)
390407
sa.event.listen(engine.sync_engine, "begin", self.begin_sqlite_stmt)
391408

409+
if logfire:
410+
logfire.instrument_sqlalchemy(engine) # pyright: ignore
411+
392412
if TRACKER.active:
393413
TRACKER.track_pool(engine.pool)
394414

src/prefect/settings/base.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import inspect
44
from functools import partial
5-
from typing import Any, Dict, Tuple, Type
5+
from typing import Any
66

77
from pydantic import (
88
AliasChoices,
@@ -32,12 +32,12 @@ class PrefectBaseSettings(BaseSettings):
3232
@classmethod
3333
def settings_customise_sources(
3434
cls,
35-
settings_cls: Type[BaseSettings],
35+
settings_cls: type[BaseSettings],
3636
init_settings: PydanticBaseSettingsSource,
3737
env_settings: PydanticBaseSettingsSource,
3838
dotenv_settings: PydanticBaseSettingsSource,
3939
file_secret_settings: PydanticBaseSettingsSource,
40-
) -> Tuple[PydanticBaseSettingsSource, ...]:
40+
) -> tuple[PydanticBaseSettingsSource, ...]:
4141
"""
4242
Define an order for Prefect settings sources.
4343
@@ -93,9 +93,9 @@ def to_environment_variables(
9393
exclude_unset: bool = False,
9494
include_secrets: bool = True,
9595
include_aliases: bool = False,
96-
) -> Dict[str, str]:
96+
) -> dict[str, str]:
9797
"""Convert the settings object to a dictionary of environment variables."""
98-
env: Dict[str, Any] = self.model_dump(
98+
env: dict[str, Any] = self.model_dump(
9999
exclude_unset=exclude_unset,
100100
mode="json",
101101
context={"include_secrets": include_secrets},
@@ -192,7 +192,7 @@ class PrefectSettingsConfigDict(SettingsConfigDict, total=False):
192192

193193

194194
def _add_environment_variables(
195-
schema: Dict[str, Any], model: Type[PrefectBaseSettings]
195+
schema: dict[str, Any], model: type[PrefectBaseSettings]
196196
) -> None:
197197
for property in schema["properties"]:
198198
env_vars: list[str] = []
@@ -212,7 +212,7 @@ def _add_environment_variables(
212212

213213

214214
def build_settings_config(
215-
path: Tuple[str, ...] = tuple(), frozen: bool = False
215+
path: tuple[str, ...] = tuple(), frozen: bool = False
216216
) -> PrefectSettingsConfigDict:
217217
env_prefix = f"PREFECT_{'_'.join(path).upper()}_" if path else "PREFECT_"
218218
return PrefectSettingsConfigDict(

src/prefect/settings/models/experiments.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from __future__ import annotations
2+
13
from typing import ClassVar
24

35
from pydantic import AliasChoices, AliasPath, Field

0 commit comments

Comments
 (0)