logfire-api 0.46.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- logfire_api-0.46.1/.gitignore +10 -0
- logfire_api-0.46.1/PKG-INFO +15 -0
- logfire_api-0.46.1/README.md +7 -0
- logfire_api-0.46.1/logfire_api/__init__.py +190 -0
- logfire_api-0.46.1/logfire_api/__init__.pyi +47 -0
- logfire_api-0.46.1/logfire_api/_internal/__init__.pyi +0 -0
- logfire_api-0.46.1/logfire_api/_internal/ast_utils.pyi +34 -0
- logfire_api-0.46.1/logfire_api/_internal/async_.pyi +22 -0
- logfire_api-0.46.1/logfire_api/_internal/auth.pyi +55 -0
- logfire_api-0.46.1/logfire_api/_internal/auto_trace/__init__.pyi +15 -0
- logfire_api-0.46.1/logfire_api/_internal/auto_trace/import_hook.pyi +38 -0
- logfire_api-0.46.1/logfire_api/_internal/auto_trace/rewrite_ast.pyi +51 -0
- logfire_api-0.46.1/logfire_api/_internal/auto_trace/types.pyi +24 -0
- logfire_api-0.46.1/logfire_api/_internal/backfill.pyi +72 -0
- logfire_api-0.46.1/logfire_api/_internal/cli.pyi +48 -0
- logfire_api-0.46.1/logfire_api/_internal/collect_system_info.pyi +6 -0
- logfire_api-0.46.1/logfire_api/_internal/config.pyi +307 -0
- logfire_api-0.46.1/logfire_api/_internal/config_params.pyi +82 -0
- logfire_api-0.46.1/logfire_api/_internal/constants.pyi +38 -0
- logfire_api-0.46.1/logfire_api/_internal/exporters/__init__.pyi +0 -0
- logfire_api-0.46.1/logfire_api/_internal/exporters/console.pyi +39 -0
- logfire_api-0.46.1/logfire_api/_internal/exporters/fallback.pyi +12 -0
- logfire_api-0.46.1/logfire_api/_internal/exporters/file.pyi +64 -0
- logfire_api-0.46.1/logfire_api/_internal/exporters/otlp.pyi +49 -0
- logfire_api-0.46.1/logfire_api/_internal/exporters/processor_wrapper.pyi +18 -0
- logfire_api-0.46.1/logfire_api/_internal/exporters/quiet_metrics.pyi +8 -0
- logfire_api-0.46.1/logfire_api/_internal/exporters/remove_pending.pyi +9 -0
- logfire_api-0.46.1/logfire_api/_internal/exporters/tail_sampling.pyi +35 -0
- logfire_api-0.46.1/logfire_api/_internal/exporters/wrapper.pyi +32 -0
- logfire_api-0.46.1/logfire_api/_internal/formatter.pyi +50 -0
- logfire_api-0.46.1/logfire_api/_internal/instrument.pyi +17 -0
- logfire_api-0.46.1/logfire_api/_internal/integrations/__init__.pyi +0 -0
- logfire_api-0.46.1/logfire_api/_internal/integrations/aiohttp_client.pyi +7 -0
- logfire_api-0.46.1/logfire_api/_internal/integrations/asyncpg.pyi +5 -0
- logfire_api-0.46.1/logfire_api/_internal/integrations/django.pyi +7 -0
- logfire_api-0.46.1/logfire_api/_internal/integrations/executors.pyi +18 -0
- logfire_api-0.46.1/logfire_api/_internal/integrations/fastapi.pyi +28 -0
- logfire_api-0.46.1/logfire_api/_internal/integrations/flask.pyi +8 -0
- logfire_api-0.46.1/logfire_api/_internal/integrations/httpx.pyi +7 -0
- logfire_api-0.46.1/logfire_api/_internal/integrations/psycopg.pyi +12 -0
- logfire_api-0.46.1/logfire_api/_internal/integrations/pymongo.pyi +7 -0
- logfire_api-0.46.1/logfire_api/_internal/integrations/redis.pyi +7 -0
- logfire_api-0.46.1/logfire_api/_internal/integrations/requests.pyi +7 -0
- logfire_api-0.46.1/logfire_api/_internal/integrations/sqlalchemy.pyi +7 -0
- logfire_api-0.46.1/logfire_api/_internal/integrations/starlette.pyi +8 -0
- logfire_api-0.46.1/logfire_api/_internal/json_encoder.pyi +12 -0
- logfire_api-0.46.1/logfire_api/_internal/json_formatter.pyi +15 -0
- logfire_api-0.46.1/logfire_api/_internal/json_schema.pyi +21 -0
- logfire_api-0.46.1/logfire_api/_internal/json_types.pyi +55 -0
- logfire_api-0.46.1/logfire_api/_internal/main.pyi +927 -0
- logfire_api-0.46.1/logfire_api/_internal/metrics.pyi +67 -0
- logfire_api-0.46.1/logfire_api/_internal/scrubbing.pyi +93 -0
- logfire_api-0.46.1/logfire_api/_internal/stack_info.pyi +39 -0
- logfire_api-0.46.1/logfire_api/_internal/tracer.pyi +75 -0
- logfire_api-0.46.1/logfire_api/_internal/utils.pyi +85 -0
- logfire_api-0.46.1/logfire_api/cli.pyi +3 -0
- logfire_api-0.46.1/logfire_api/exceptions.pyi +2 -0
- logfire_api-0.46.1/logfire_api/integrations/__init__.pyi +0 -0
- logfire_api-0.46.1/logfire_api/integrations/logging.pyi +30 -0
- logfire_api-0.46.1/logfire_api/integrations/loguru.pyi +19 -0
- logfire_api-0.46.1/logfire_api/integrations/pydantic.pyi +96 -0
- logfire_api-0.46.1/logfire_api/integrations/structlog.pyi +12 -0
- logfire_api-0.46.1/logfire_api/propagate.pyi +41 -0
- logfire_api-0.46.1/logfire_api/version.pyi +3 -0
- logfire_api-0.46.1/pyproject.toml +31 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: logfire-api
|
|
3
|
+
Version: 0.46.1
|
|
4
|
+
Summary: Shim for the Logfire SDK which does nothing unless Logfire is installed
|
|
5
|
+
Author-email: Pydantic Team <engineering@pydantic.dev>, Samuel Colvin <samuel@pydantic.dev>, Hasan Ramezani <hasan@pydantic.dev>, Adrian Garcia Badaracco <adrian@pydantic.dev>, David Montague <david@pydantic.dev>, Marcelo Trylesinski <marcelo@pydantic.dev>, David Hewitt <david.hewitt@pydantic.dev>, Alex Hall <alex@pydantic.dev>
|
|
6
|
+
Requires-Python: >=3.8
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
|
|
9
|
+
# logfire-api
|
|
10
|
+
|
|
11
|
+
Shim for the logfire SDK Python API which does nothing unless logfire is installed.
|
|
12
|
+
|
|
13
|
+
This package is designed to be used by packages that want to provide opt-in integration with [Logfire](https://github.com/pydantic/logfire).
|
|
14
|
+
|
|
15
|
+
The package provides a clone of the Python API exposed by the `logfire` package which does nothing if the `logfire` package is not installed, but makes real calls when it is.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# logfire-api
|
|
2
|
+
|
|
3
|
+
Shim for the logfire SDK Python API which does nothing unless logfire is installed.
|
|
4
|
+
|
|
5
|
+
This package is designed to be used by packages that want to provide opt-in integration with [Logfire](https://github.com/pydantic/logfire).
|
|
6
|
+
|
|
7
|
+
The package provides a clone of the Python API exposed by the `logfire` package which does nothing if the `logfire` package is not installed, but makes real calls when it is.
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from contextlib import contextmanager
|
|
4
|
+
import importlib
|
|
5
|
+
import sys
|
|
6
|
+
from typing import TYPE_CHECKING, ContextManager, Literal
|
|
7
|
+
from contextlib import nullcontext
|
|
8
|
+
from unittest.mock import MagicMock
|
|
9
|
+
|
|
10
|
+
try:
|
|
11
|
+
logfire_module = importlib.import_module('logfire')
|
|
12
|
+
sys.modules[__name__] = logfire_module
|
|
13
|
+
|
|
14
|
+
except ImportError:
|
|
15
|
+
if not TYPE_CHECKING: # pragma: no branch
|
|
16
|
+
LevelName = Literal['trace', 'debug', 'info', 'notice', 'warn', 'warning', 'error', 'fatal']
|
|
17
|
+
VERSION = '0.0.0'
|
|
18
|
+
METRICS_PREFERRED_TEMPORALITY = {}
|
|
19
|
+
|
|
20
|
+
def configure(*args, **kwargs): ...
|
|
21
|
+
|
|
22
|
+
class LogfireSpan:
|
|
23
|
+
def __getattr__(self, attr):
|
|
24
|
+
return MagicMock() # pragma: no cover
|
|
25
|
+
|
|
26
|
+
def __enter__(self):
|
|
27
|
+
return self
|
|
28
|
+
|
|
29
|
+
def __exit__(self, *args, **kwargs) -> None: ...
|
|
30
|
+
|
|
31
|
+
@property
|
|
32
|
+
def message_template(self) -> str: # pragma: no cover
|
|
33
|
+
return ''
|
|
34
|
+
|
|
35
|
+
@property
|
|
36
|
+
def tags(self) -> Sequence[str]: # pragma: no cover
|
|
37
|
+
return []
|
|
38
|
+
|
|
39
|
+
@property
|
|
40
|
+
def message(self) -> str: # pragma: no cover
|
|
41
|
+
return ''
|
|
42
|
+
|
|
43
|
+
@message.setter
|
|
44
|
+
def message(self, message: str): ... # pragma: no cover
|
|
45
|
+
|
|
46
|
+
def is_recording(self) -> bool: # pragma: no cover
|
|
47
|
+
return False
|
|
48
|
+
|
|
49
|
+
class Logfire:
|
|
50
|
+
def __getattr__(self, attr):
|
|
51
|
+
return MagicMock() # pragma: no cover
|
|
52
|
+
|
|
53
|
+
def __init__(self, *args, **kwargs) -> None: ...
|
|
54
|
+
|
|
55
|
+
def span(self, *args, **kwargs) -> LogfireSpan:
|
|
56
|
+
return LogfireSpan()
|
|
57
|
+
|
|
58
|
+
def log(self, *args, **kwargs) -> None: ...
|
|
59
|
+
|
|
60
|
+
def trace(self, *args, **kwargs) -> None: ...
|
|
61
|
+
|
|
62
|
+
def debug(self, *args, **kwargs) -> None: ...
|
|
63
|
+
|
|
64
|
+
def notice(self, *args, **kwargs) -> None: ...
|
|
65
|
+
|
|
66
|
+
def info(self, *args, **kwargs) -> None: ...
|
|
67
|
+
|
|
68
|
+
def warn(self, *args, **kwargs) -> None: ...
|
|
69
|
+
|
|
70
|
+
def error(self, *args, **kwargs) -> None: ...
|
|
71
|
+
|
|
72
|
+
def fatal(self, *args, **kwargs) -> None: ...
|
|
73
|
+
|
|
74
|
+
def with_tags(self, *args, **kwargs) -> Logfire:
|
|
75
|
+
return self
|
|
76
|
+
|
|
77
|
+
def with_settings(self, *args, **kwargs) -> Logfire:
|
|
78
|
+
return self
|
|
79
|
+
|
|
80
|
+
def force_flush(self, *args, **kwargs) -> None: ...
|
|
81
|
+
|
|
82
|
+
def log_slow_async_callbacks(self, *args, **kwargs) -> None: # pragma: no branch
|
|
83
|
+
return nullcontext()
|
|
84
|
+
|
|
85
|
+
def install_auto_tracing(self, *args, **kwargs) -> None: ...
|
|
86
|
+
|
|
87
|
+
def instrument(self, *args, **kwargs):
|
|
88
|
+
def decorator(func):
|
|
89
|
+
return func
|
|
90
|
+
|
|
91
|
+
return decorator
|
|
92
|
+
|
|
93
|
+
def instrument_fastapi(self, *args, **kwargs) -> ContextManager[None]:
|
|
94
|
+
return nullcontext()
|
|
95
|
+
|
|
96
|
+
def instrument_pymongo(self, *args, **kwargs) -> None: ...
|
|
97
|
+
|
|
98
|
+
def instrument_sqlalchemy(self, *args, **kwargs) -> None: ...
|
|
99
|
+
|
|
100
|
+
def instrument_redis(self, *args, **kwargs) -> None: ...
|
|
101
|
+
|
|
102
|
+
def instrument_flask(self, *args, **kwargs) -> None: ...
|
|
103
|
+
|
|
104
|
+
def instrument_starlette(self, *args, **kwargs) -> None: ...
|
|
105
|
+
|
|
106
|
+
def instrument_django(self, *args, **kwargs) -> None: ...
|
|
107
|
+
|
|
108
|
+
def instrument_psycopg(self, *args, **kwargs) -> None: ...
|
|
109
|
+
|
|
110
|
+
def instrument_requests(self, *args, **kwargs) -> None: ...
|
|
111
|
+
|
|
112
|
+
def instrument_httpx(self, *args, **kwargs) -> None: ...
|
|
113
|
+
|
|
114
|
+
def instrument_asyncpg(self, *args, **kwargs) -> None: ...
|
|
115
|
+
|
|
116
|
+
def instrument_anthropic(self, *args, **kwargs) -> ContextManager[None]:
|
|
117
|
+
return nullcontext()
|
|
118
|
+
|
|
119
|
+
def instrument_openai(self, *args, **kwargs) -> ContextManager[None]:
|
|
120
|
+
return nullcontext()
|
|
121
|
+
|
|
122
|
+
def instrument_aiohttp_client(self, *args, **kwargs) -> None: ...
|
|
123
|
+
|
|
124
|
+
def shutdown(self, *args, **kwargs) -> None: ...
|
|
125
|
+
|
|
126
|
+
DEFAULT_LOGFIRE_INSTANCE = Logfire()
|
|
127
|
+
span = DEFAULT_LOGFIRE_INSTANCE.span
|
|
128
|
+
log = DEFAULT_LOGFIRE_INSTANCE.log
|
|
129
|
+
trace = DEFAULT_LOGFIRE_INSTANCE.trace
|
|
130
|
+
debug = DEFAULT_LOGFIRE_INSTANCE.debug
|
|
131
|
+
notice = DEFAULT_LOGFIRE_INSTANCE.notice
|
|
132
|
+
info = DEFAULT_LOGFIRE_INSTANCE.info
|
|
133
|
+
warn = DEFAULT_LOGFIRE_INSTANCE.warn
|
|
134
|
+
error = DEFAULT_LOGFIRE_INSTANCE.error
|
|
135
|
+
fatal = DEFAULT_LOGFIRE_INSTANCE.fatal
|
|
136
|
+
with_tags = DEFAULT_LOGFIRE_INSTANCE.with_tags
|
|
137
|
+
with_settings = DEFAULT_LOGFIRE_INSTANCE.with_settings
|
|
138
|
+
force_flush = DEFAULT_LOGFIRE_INSTANCE.force_flush
|
|
139
|
+
log_slow_async_callbacks = DEFAULT_LOGFIRE_INSTANCE.log_slow_async_callbacks
|
|
140
|
+
install_auto_tracing = DEFAULT_LOGFIRE_INSTANCE.install_auto_tracing
|
|
141
|
+
instrument = DEFAULT_LOGFIRE_INSTANCE.instrument
|
|
142
|
+
instrument_fastapi = DEFAULT_LOGFIRE_INSTANCE.instrument_fastapi
|
|
143
|
+
instrument_openai = DEFAULT_LOGFIRE_INSTANCE.instrument_openai
|
|
144
|
+
instrument_anthropic = DEFAULT_LOGFIRE_INSTANCE.instrument_anthropic
|
|
145
|
+
instrument_asyncpg = DEFAULT_LOGFIRE_INSTANCE.instrument_asyncpg
|
|
146
|
+
instrument_httpx = DEFAULT_LOGFIRE_INSTANCE.instrument_httpx
|
|
147
|
+
instrument_requests = DEFAULT_LOGFIRE_INSTANCE.instrument_requests
|
|
148
|
+
instrument_psycopg = DEFAULT_LOGFIRE_INSTANCE.instrument_psycopg
|
|
149
|
+
instrument_django = DEFAULT_LOGFIRE_INSTANCE.instrument_django
|
|
150
|
+
instrument_flask = DEFAULT_LOGFIRE_INSTANCE.instrument_flask
|
|
151
|
+
instrument_starlette = DEFAULT_LOGFIRE_INSTANCE.instrument_starlette
|
|
152
|
+
instrument_aiohttp_client = DEFAULT_LOGFIRE_INSTANCE.instrument_aiohttp_client
|
|
153
|
+
instrument_sqlalchemy = DEFAULT_LOGFIRE_INSTANCE.instrument_sqlalchemy
|
|
154
|
+
instrument_redis = DEFAULT_LOGFIRE_INSTANCE.instrument_redis
|
|
155
|
+
instrument_pymongo = DEFAULT_LOGFIRE_INSTANCE.instrument_pymongo
|
|
156
|
+
shutdown = DEFAULT_LOGFIRE_INSTANCE.shutdown
|
|
157
|
+
|
|
158
|
+
def no_auto_trace(x):
|
|
159
|
+
return x
|
|
160
|
+
|
|
161
|
+
@contextmanager
|
|
162
|
+
def suppress_instrumentation():
|
|
163
|
+
yield
|
|
164
|
+
|
|
165
|
+
class ConsoleOptions:
|
|
166
|
+
def __init__(self, *args, **kwargs) -> None: ...
|
|
167
|
+
|
|
168
|
+
class TailSamplingOptions:
|
|
169
|
+
def __init__(self, *args, **kwargs) -> None: ...
|
|
170
|
+
|
|
171
|
+
class ScrubbingOptions:
|
|
172
|
+
def __init__(self, *args, **kwargs) -> None: ...
|
|
173
|
+
|
|
174
|
+
class PydanticPlugin:
|
|
175
|
+
def __init__(self, *args, **kwargs) -> None: ...
|
|
176
|
+
|
|
177
|
+
class ScrubMatch:
|
|
178
|
+
def __init__(self, *args, **kwargs) -> None: ...
|
|
179
|
+
|
|
180
|
+
class AutoTraceModule:
|
|
181
|
+
def __init__(self, *args, **kwargs) -> None: ...
|
|
182
|
+
|
|
183
|
+
class StructlogProcessor:
|
|
184
|
+
def __init__(self, *args, **kwargs) -> None: ...
|
|
185
|
+
|
|
186
|
+
class LogfireLoggingHandler:
|
|
187
|
+
def __init__(self, *args, **kwargs) -> None: ...
|
|
188
|
+
|
|
189
|
+
def load_spans_from_file(*args, **kwargs):
|
|
190
|
+
return []
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
from ._internal.auto_trace import AutoTraceModule as AutoTraceModule
|
|
2
|
+
from ._internal.auto_trace.rewrite_ast import no_auto_trace as no_auto_trace
|
|
3
|
+
from ._internal.config import ConsoleOptions as ConsoleOptions, METRICS_PREFERRED_TEMPORALITY as METRICS_PREFERRED_TEMPORALITY, PydanticPlugin as PydanticPlugin, configure as configure
|
|
4
|
+
from ._internal.constants import LevelName as LevelName
|
|
5
|
+
from ._internal.exporters.file import load_file as load_spans_from_file
|
|
6
|
+
from ._internal.exporters.tail_sampling import TailSamplingOptions as TailSamplingOptions
|
|
7
|
+
from ._internal.main import Logfire as Logfire, LogfireSpan as LogfireSpan
|
|
8
|
+
from ._internal.scrubbing import ScrubMatch as ScrubMatch, ScrubbingOptions as ScrubbingOptions
|
|
9
|
+
from ._internal.utils import suppress_instrumentation as suppress_instrumentation
|
|
10
|
+
from .integrations.logging import LogfireLoggingHandler as LogfireLoggingHandler
|
|
11
|
+
from .integrations.structlog import LogfireProcessor as StructlogProcessor
|
|
12
|
+
from .version import VERSION as VERSION
|
|
13
|
+
|
|
14
|
+
__all__ = ['Logfire', 'LogfireSpan', 'LevelName', 'ConsoleOptions', 'PydanticPlugin', 'configure', 'span', 'instrument', 'log', 'trace', 'debug', 'notice', 'info', 'warn', 'error', 'fatal', 'force_flush', 'log_slow_async_callbacks', 'install_auto_tracing', 'instrument_fastapi', 'instrument_openai', 'instrument_anthropic', 'instrument_asyncpg', 'instrument_httpx', 'instrument_requests', 'instrument_psycopg', 'instrument_django', 'instrument_flask', 'instrument_starlette', 'instrument_aiohttp_client', 'instrument_sqlalchemy', 'instrument_redis', 'instrument_pymongo', 'AutoTraceModule', 'with_tags', 'with_settings', 'shutdown', 'load_spans_from_file', 'no_auto_trace', 'METRICS_PREFERRED_TEMPORALITY', 'ScrubMatch', 'ScrubbingOptions', 'VERSION', 'suppress_instrumentation', 'StructlogProcessor', 'LogfireLoggingHandler', 'TailSamplingOptions']
|
|
15
|
+
|
|
16
|
+
DEFAULT_LOGFIRE_INSTANCE = Logfire()
|
|
17
|
+
span = DEFAULT_LOGFIRE_INSTANCE.span
|
|
18
|
+
instrument = DEFAULT_LOGFIRE_INSTANCE.instrument
|
|
19
|
+
force_flush = DEFAULT_LOGFIRE_INSTANCE.force_flush
|
|
20
|
+
log_slow_async_callbacks = DEFAULT_LOGFIRE_INSTANCE.log_slow_async_callbacks
|
|
21
|
+
install_auto_tracing = DEFAULT_LOGFIRE_INSTANCE.install_auto_tracing
|
|
22
|
+
instrument_fastapi = DEFAULT_LOGFIRE_INSTANCE.instrument_fastapi
|
|
23
|
+
instrument_openai = DEFAULT_LOGFIRE_INSTANCE.instrument_openai
|
|
24
|
+
instrument_anthropic = DEFAULT_LOGFIRE_INSTANCE.instrument_anthropic
|
|
25
|
+
instrument_asyncpg = DEFAULT_LOGFIRE_INSTANCE.instrument_asyncpg
|
|
26
|
+
instrument_httpx = DEFAULT_LOGFIRE_INSTANCE.instrument_httpx
|
|
27
|
+
instrument_requests = DEFAULT_LOGFIRE_INSTANCE.instrument_requests
|
|
28
|
+
instrument_psycopg = DEFAULT_LOGFIRE_INSTANCE.instrument_psycopg
|
|
29
|
+
instrument_django = DEFAULT_LOGFIRE_INSTANCE.instrument_django
|
|
30
|
+
instrument_flask = DEFAULT_LOGFIRE_INSTANCE.instrument_flask
|
|
31
|
+
instrument_starlette = DEFAULT_LOGFIRE_INSTANCE.instrument_starlette
|
|
32
|
+
instrument_aiohttp_client = DEFAULT_LOGFIRE_INSTANCE.instrument_aiohttp_client
|
|
33
|
+
instrument_sqlalchemy = DEFAULT_LOGFIRE_INSTANCE.instrument_sqlalchemy
|
|
34
|
+
instrument_redis = DEFAULT_LOGFIRE_INSTANCE.instrument_redis
|
|
35
|
+
instrument_pymongo = DEFAULT_LOGFIRE_INSTANCE.instrument_pymongo
|
|
36
|
+
shutdown = DEFAULT_LOGFIRE_INSTANCE.shutdown
|
|
37
|
+
with_tags = DEFAULT_LOGFIRE_INSTANCE.with_tags
|
|
38
|
+
with_settings = DEFAULT_LOGFIRE_INSTANCE.with_settings
|
|
39
|
+
log = DEFAULT_LOGFIRE_INSTANCE.log
|
|
40
|
+
trace = DEFAULT_LOGFIRE_INSTANCE.trace
|
|
41
|
+
debug = DEFAULT_LOGFIRE_INSTANCE.debug
|
|
42
|
+
info = DEFAULT_LOGFIRE_INSTANCE.info
|
|
43
|
+
notice = DEFAULT_LOGFIRE_INSTANCE.notice
|
|
44
|
+
warn = DEFAULT_LOGFIRE_INSTANCE.warn
|
|
45
|
+
error = DEFAULT_LOGFIRE_INSTANCE.error
|
|
46
|
+
fatal = DEFAULT_LOGFIRE_INSTANCE.fatal
|
|
47
|
+
__version__ = VERSION
|
|
File without changes
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import ast
|
|
2
|
+
from .constants import ATTRIBUTES_MESSAGE_TEMPLATE_KEY as ATTRIBUTES_MESSAGE_TEMPLATE_KEY, ATTRIBUTES_SAMPLE_RATE_KEY as ATTRIBUTES_SAMPLE_RATE_KEY, ATTRIBUTES_TAGS_KEY as ATTRIBUTES_TAGS_KEY
|
|
3
|
+
from .stack_info import StackInfo as StackInfo, get_filepath_attribute as get_filepath_attribute
|
|
4
|
+
from .utils import uniquify_sequence as uniquify_sequence
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from opentelemetry.util import types as otel_types
|
|
7
|
+
|
|
8
|
+
@dataclass(frozen=True)
|
|
9
|
+
class LogfireArgs:
|
|
10
|
+
"""Values passed to `logfire.instrument` and/or values stored in a logfire instance as basic configuration.
|
|
11
|
+
|
|
12
|
+
These determine the arguments passed to the method calls added by the AST transformer.
|
|
13
|
+
"""
|
|
14
|
+
tags: tuple[str, ...]
|
|
15
|
+
sample_rate: float | None
|
|
16
|
+
msg_template: str | None = ...
|
|
17
|
+
span_name: str | None = ...
|
|
18
|
+
extract_args: bool = ...
|
|
19
|
+
|
|
20
|
+
@dataclass
|
|
21
|
+
class BaseTransformer(ast.NodeTransformer):
|
|
22
|
+
"""Helper for rewriting ASTs to wrap function bodies in `with {logfire_method_name}(...):`."""
|
|
23
|
+
logfire_args: LogfireArgs
|
|
24
|
+
logfire_method_name: str
|
|
25
|
+
filename: str
|
|
26
|
+
module_name: str
|
|
27
|
+
qualname_stack = ...
|
|
28
|
+
def __post_init__(self) -> None: ...
|
|
29
|
+
def visit_ClassDef(self, node: ast.ClassDef): ...
|
|
30
|
+
def visit_FunctionDef(self, node: ast.FunctionDef | ast.AsyncFunctionDef): ...
|
|
31
|
+
def visit_AsyncFunctionDef(self, node: ast.AsyncFunctionDef): ...
|
|
32
|
+
def rewrite_function(self, node: ast.FunctionDef | ast.AsyncFunctionDef, qualname: str) -> ast.AST: ...
|
|
33
|
+
def logfire_method_call_node(self, node: ast.FunctionDef | ast.AsyncFunctionDef, qualname: str) -> ast.Call: ...
|
|
34
|
+
def logfire_method_arg_values(self, qualname: str, lineno: int) -> tuple[str, dict[str, otel_types.AttributeValue]]: ...
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from .constants import ONE_SECOND_IN_NANOSECONDS as ONE_SECOND_IN_NANOSECONDS
|
|
2
|
+
from .main import Logfire as Logfire
|
|
3
|
+
from .stack_info import StackInfo as StackInfo, get_code_object_info as get_code_object_info, get_stack_info_from_frame as get_stack_info_from_frame
|
|
4
|
+
from .utils import safe_repr as safe_repr
|
|
5
|
+
from _typeshed import Incomplete
|
|
6
|
+
from types import CoroutineType
|
|
7
|
+
from typing import Any, ContextManager
|
|
8
|
+
|
|
9
|
+
ASYNCIO_PATH: Incomplete
|
|
10
|
+
|
|
11
|
+
def log_slow_callbacks(logfire: Logfire, slow_duration: float) -> ContextManager[None]:
|
|
12
|
+
"""Log a warning whenever a function running in the asyncio event loop blocks for too long.
|
|
13
|
+
|
|
14
|
+
See Logfire.log_slow_async_callbacks.
|
|
15
|
+
Inspired by https://gitlab.com/quantlane/libs/aiodebug.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
class _CallbackAttributes(StackInfo, total=False):
|
|
19
|
+
name: str
|
|
20
|
+
stack: list[StackInfo]
|
|
21
|
+
|
|
22
|
+
def stack_info_from_coroutine(coro: CoroutineType[Any, Any, Any]) -> StackInfo: ...
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
from .utils import UnexpectedResponse as UnexpectedResponse
|
|
3
|
+
from _typeshed import Incomplete
|
|
4
|
+
from logfire.exceptions import LogfireConfigError as LogfireConfigError
|
|
5
|
+
from typing import TypedDict
|
|
6
|
+
|
|
7
|
+
HOME_LOGFIRE: Incomplete
|
|
8
|
+
DEFAULT_FILE: Incomplete
|
|
9
|
+
|
|
10
|
+
class UserTokenData(TypedDict):
|
|
11
|
+
"""User token data."""
|
|
12
|
+
token: str
|
|
13
|
+
expiration: str
|
|
14
|
+
|
|
15
|
+
class DefaultFile(TypedDict):
|
|
16
|
+
"""Content of the default.toml file."""
|
|
17
|
+
tokens: dict[str, UserTokenData]
|
|
18
|
+
|
|
19
|
+
class NewDeviceFlow(TypedDict):
|
|
20
|
+
"""Matches model of the same name in the backend."""
|
|
21
|
+
device_code: str
|
|
22
|
+
frontend_auth_url: str
|
|
23
|
+
|
|
24
|
+
def request_device_code(session: requests.Session, base_api_url: str) -> tuple[str, str]:
|
|
25
|
+
"""Request a device code from the Logfire API.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
session: The `requests` session to use.
|
|
29
|
+
base_api_url: The base URL of the Logfire instance.
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
return data['device_code'], data['frontend_auth_url']
|
|
33
|
+
The device code and the frontend URL to authenticate the device at, as a `NewDeviceFlow` dict.
|
|
34
|
+
"""
|
|
35
|
+
def poll_for_token(session: requests.Session, device_code: str, base_api_url: str) -> UserTokenData:
|
|
36
|
+
"""Poll the Logfire API for the user token.
|
|
37
|
+
|
|
38
|
+
This function will keep polling the API until it receives a user token, not that
|
|
39
|
+
each request should take ~10 seconds as the API endpoint will block waiting for the user to
|
|
40
|
+
complete authentication.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
session: The `requests` session to use.
|
|
44
|
+
device_code: The device code to poll for.
|
|
45
|
+
base_api_url: The base URL of the Logfire instance.
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
The user token.
|
|
49
|
+
"""
|
|
50
|
+
def is_logged_in(data: DefaultFile, logfire_url: str) -> bool:
|
|
51
|
+
"""Check if the user is logged in.
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
True if the user is logged in, False otherwise.
|
|
55
|
+
"""
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from ..constants import ONE_SECOND_IN_NANOSECONDS as ONE_SECOND_IN_NANOSECONDS
|
|
2
|
+
from ..main import Logfire as Logfire
|
|
3
|
+
from .import_hook import LogfireFinder as LogfireFinder
|
|
4
|
+
from .types import AutoTraceModule as AutoTraceModule
|
|
5
|
+
from typing import Callable, Literal, Sequence
|
|
6
|
+
|
|
7
|
+
def install_auto_tracing(logfire: Logfire, modules: Sequence[str] | Callable[[AutoTraceModule], bool], *, check_imported_modules: Literal['error', 'warn', 'ignore'] = 'error', min_duration: float = 0) -> None:
|
|
8
|
+
"""Install automatic tracing.
|
|
9
|
+
|
|
10
|
+
See `Logfire.install_auto_tracing` for more information.
|
|
11
|
+
"""
|
|
12
|
+
def modules_func_from_sequence(modules: Sequence[str]) -> Callable[[AutoTraceModule], bool]: ...
|
|
13
|
+
|
|
14
|
+
class AutoTraceModuleAlreadyImportedException(Exception): ...
|
|
15
|
+
class AutoTraceModuleAlreadyImportedWarning(Warning): ...
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from ..main import Logfire as Logfire
|
|
2
|
+
from .rewrite_ast import exec_source as exec_source
|
|
3
|
+
from .types import AutoTraceModule as AutoTraceModule
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
from importlib.abc import Loader, MetaPathFinder
|
|
6
|
+
from importlib.machinery import ModuleSpec
|
|
7
|
+
from types import ModuleType
|
|
8
|
+
from typing import Callable, Sequence
|
|
9
|
+
|
|
10
|
+
@dataclass
|
|
11
|
+
class LogfireFinder(MetaPathFinder):
|
|
12
|
+
"""The import hook entry point, inserted into `sys.meta_path` to apply AST rewriting to matching modules."""
|
|
13
|
+
logfire: Logfire
|
|
14
|
+
modules_filter: Callable[[AutoTraceModule], bool]
|
|
15
|
+
min_duration: int
|
|
16
|
+
def find_spec(self, fullname: str, path: Sequence[str] | None, target: ModuleType | None = None) -> ModuleSpec | None:
|
|
17
|
+
"""This is the method that is called by the import system.
|
|
18
|
+
|
|
19
|
+
It uses the other existing meta path finders to do most of the standard work,
|
|
20
|
+
particularly finding the module's source code and filename.
|
|
21
|
+
If it finds a module spec that matches the filter, it returns a new spec that uses the LogfireLoader.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
@dataclass
|
|
25
|
+
class LogfireLoader(Loader):
|
|
26
|
+
"""An import loader produced by LogfireFinder which executes a modified AST of the module's source code."""
|
|
27
|
+
plain_spec: ModuleSpec
|
|
28
|
+
source: str
|
|
29
|
+
logfire: Logfire
|
|
30
|
+
min_duration: int
|
|
31
|
+
def exec_module(self, module: ModuleType):
|
|
32
|
+
"""Execute a modified AST of the module's source code in the module's namespace.
|
|
33
|
+
|
|
34
|
+
This is called by the import system.
|
|
35
|
+
"""
|
|
36
|
+
def create_module(self, spec: ModuleSpec): ...
|
|
37
|
+
def __getattr__(self, item: str):
|
|
38
|
+
"""Forward some methods to the plain spec's loader (likely a `SourceFileLoader`) if they exist."""
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import ast
|
|
2
|
+
from ..ast_utils import BaseTransformer as BaseTransformer, LogfireArgs as LogfireArgs
|
|
3
|
+
from ..main import Logfire as Logfire
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
from typing import Any, Callable, ContextManager, TypeVar
|
|
6
|
+
|
|
7
|
+
def exec_source(source: str, filename: str, module_name: str, globs: dict[str, Any], logfire_instance: Logfire, min_duration: int) -> None:
|
|
8
|
+
"""Execute a modified AST of the module's source code in the module's namespace.
|
|
9
|
+
|
|
10
|
+
The modified AST wraps the body of every function definition in `with context_factories[index]():`.
|
|
11
|
+
`context_factories` is added to the module's namespace as `logfire_<uuid>`.
|
|
12
|
+
`index` is a different constant number for each function definition.
|
|
13
|
+
`context_factories[index]` is one of these:
|
|
14
|
+
- `partial(logfire_instance._fast_span, name, attributes)` where the name and attributes
|
|
15
|
+
are constructed from `filename`, `module_name`, attributes of `logfire_instance`,
|
|
16
|
+
and the qualified name and line number of the current function.
|
|
17
|
+
- `MeasureTime`, a class that measures the time elapsed. If it exceeds `min_duration`,
|
|
18
|
+
then `context_factories[index]` is replaced with the `partial` above.
|
|
19
|
+
If `min_duration` is greater than 0, then `context_factories[index]` is initially `MeasureTime`.
|
|
20
|
+
Otherwise, it's initially the `partial` above.
|
|
21
|
+
"""
|
|
22
|
+
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: ...
|
|
23
|
+
|
|
24
|
+
@dataclass
|
|
25
|
+
class AutoTraceTransformer(BaseTransformer):
|
|
26
|
+
"""Trace all encountered functions except those explicitly marked with `@no_auto_trace`."""
|
|
27
|
+
logfire_instance: Logfire
|
|
28
|
+
context_factories: list[Callable[[], ContextManager[Any]]]
|
|
29
|
+
min_duration: int
|
|
30
|
+
def check_no_auto_trace(self, node: ast.FunctionDef | ast.AsyncFunctionDef | ast.ClassDef) -> bool:
|
|
31
|
+
"""Return true if the node has a `@no_auto_trace` or `@logfire.no_auto_trace` decorator."""
|
|
32
|
+
def visit_ClassDef(self, node: ast.ClassDef): ...
|
|
33
|
+
def visit_FunctionDef(self, node: ast.FunctionDef | ast.AsyncFunctionDef): ...
|
|
34
|
+
def logfire_method_call_node(self, node: ast.FunctionDef | ast.AsyncFunctionDef, qualname: str) -> ast.Call: ...
|
|
35
|
+
T = TypeVar('T')
|
|
36
|
+
|
|
37
|
+
def no_auto_trace(x: T) -> T:
|
|
38
|
+
"""Decorator to prevent a function/class from being traced by `logfire.install_auto_tracing`.
|
|
39
|
+
|
|
40
|
+
This is useful for small functions that are called very frequently and would generate too much noise.
|
|
41
|
+
|
|
42
|
+
The decorator is detected at import time.
|
|
43
|
+
Only `@no_auto_trace` or `@logfire.no_auto_trace` are supported.
|
|
44
|
+
Renaming/aliasing either the function or module won't work.
|
|
45
|
+
Neither will calling this indirectly via another function.
|
|
46
|
+
|
|
47
|
+
Any decorated function, or any function defined anywhere inside a decorated function/class,
|
|
48
|
+
will be completely ignored by `logfire.install_auto_tracing`.
|
|
49
|
+
|
|
50
|
+
This decorator simply returns the argument unchanged, so there is zero runtime overhead.
|
|
51
|
+
"""
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Sequence
|
|
3
|
+
|
|
4
|
+
@dataclass
|
|
5
|
+
class AutoTraceModule:
|
|
6
|
+
"""Information about a module being imported that should maybe be traced automatically.
|
|
7
|
+
|
|
8
|
+
This object will be passed to a function that should return True if the module should be traced.
|
|
9
|
+
In particular it'll be passed to a function that's passed to `install_auto_tracing` as the `modules` argument.
|
|
10
|
+
"""
|
|
11
|
+
name: str
|
|
12
|
+
filename: str | None
|
|
13
|
+
def parts_start_with(self, prefix: str | Sequence[str]) -> bool:
|
|
14
|
+
"""Return True if the module name starts with any of the given prefixes, using dots as boundaries.
|
|
15
|
+
|
|
16
|
+
For example, if the module name is `foo.bar.spam`, then `parts_start_with('foo')` will return True,
|
|
17
|
+
but `parts_start_with('bar')` or `parts_start_with('foo_bar')` will return False.
|
|
18
|
+
In other words, this will match the module itself or any submodules.
|
|
19
|
+
|
|
20
|
+
If a prefix contains any characters other than letters, numbers, and dots,
|
|
21
|
+
then it will be treated as a regular expression.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
def get_module_pattern(module: str): ...
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
from .constants import LevelName
|
|
2
|
+
from _typeshed import Incomplete
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from pydantic import BaseModel
|
|
6
|
+
from typing import Any, IO
|
|
7
|
+
|
|
8
|
+
__all__ = ['generate_trace_id', 'generate_span_id', 'Log', 'StartSpan', 'PrepareBackfill']
|
|
9
|
+
|
|
10
|
+
def generate_trace_id() -> int:
|
|
11
|
+
"""Generate a new trace ID.
|
|
12
|
+
|
|
13
|
+
Returns:
|
|
14
|
+
A new trace ID.
|
|
15
|
+
"""
|
|
16
|
+
def generate_span_id() -> int:
|
|
17
|
+
"""Generate a new span ID.
|
|
18
|
+
|
|
19
|
+
Returns:
|
|
20
|
+
A new span ID.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
class Log(BaseModel):
|
|
24
|
+
"""A log record."""
|
|
25
|
+
model_config = pydantic_config
|
|
26
|
+
msg_template: str
|
|
27
|
+
level: LevelName
|
|
28
|
+
service_name: str
|
|
29
|
+
attributes: dict[str, Any]
|
|
30
|
+
trace_id: int
|
|
31
|
+
span_id: int
|
|
32
|
+
parent_span_id: int | None
|
|
33
|
+
timestamp: datetime | None
|
|
34
|
+
formatted_msg: str | None
|
|
35
|
+
otel_resource_attributes: dict[str, Any]
|
|
36
|
+
|
|
37
|
+
class StartSpan(BaseModel):
|
|
38
|
+
"""A span."""
|
|
39
|
+
model_config = pydantic_config
|
|
40
|
+
span_name: str
|
|
41
|
+
msg_template: str
|
|
42
|
+
service_name: str
|
|
43
|
+
parent: StartSpan | int | None
|
|
44
|
+
log_attributes: dict[str, Any]
|
|
45
|
+
span_id: int
|
|
46
|
+
trace_id: int
|
|
47
|
+
parent_span_id: int | None
|
|
48
|
+
start_timestamp: datetime | None
|
|
49
|
+
formatted_msg: str | None
|
|
50
|
+
otel_resource_attributes: dict[str, Any]
|
|
51
|
+
def end(self, end_timestamp: datetime) -> Span:
|
|
52
|
+
"""End the span at a given timestamp."""
|
|
53
|
+
|
|
54
|
+
class Span(StartSpan):
|
|
55
|
+
end_timestamp: datetime | None
|
|
56
|
+
|
|
57
|
+
class PrepareBackfill:
|
|
58
|
+
"""Prepare a backfill of logfire logs and spans from a file or stream.
|
|
59
|
+
|
|
60
|
+
Attributes:
|
|
61
|
+
store_path: The path to the file or stream to backfill.
|
|
62
|
+
open_spans: A mapping of open spans, keyed by (trace_id, span_id).
|
|
63
|
+
processor: The span processor to use for the backfill.
|
|
64
|
+
"""
|
|
65
|
+
store_path: Incomplete
|
|
66
|
+
processor: Incomplete
|
|
67
|
+
scrubber: Incomplete
|
|
68
|
+
def __init__(self, file: Path | str | IO[bytes], batch: bool = True) -> None: ...
|
|
69
|
+
def __enter__(self) -> PrepareBackfill: ...
|
|
70
|
+
def write(self, data: Log | Span) -> None:
|
|
71
|
+
"""Write the data to the backfill."""
|
|
72
|
+
def __exit__(self, *_: Any) -> None: ...
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
from ..version import VERSION as VERSION
|
|
3
|
+
from .auth import DEFAULT_FILE as DEFAULT_FILE, DefaultFile as DefaultFile, HOME_LOGFIRE as HOME_LOGFIRE, is_logged_in as is_logged_in, poll_for_token as poll_for_token, request_device_code as request_device_code
|
|
4
|
+
from .config import LogfireCredentials as LogfireCredentials
|
|
5
|
+
from .config_params import ParamManager as ParamManager
|
|
6
|
+
from .constants import LOGFIRE_BASE_URL as LOGFIRE_BASE_URL
|
|
7
|
+
from .tracer import SDKTracerProvider as SDKTracerProvider
|
|
8
|
+
from .utils import read_toml_file as read_toml_file
|
|
9
|
+
from _typeshed import Incomplete
|
|
10
|
+
from logfire.exceptions import LogfireConfigError as LogfireConfigError
|
|
11
|
+
from logfire.propagate import ContextCarrier as ContextCarrier, get_context as get_context
|
|
12
|
+
|
|
13
|
+
BASE_OTEL_INTEGRATION_URL: str
|
|
14
|
+
BASE_DOCS_URL: str
|
|
15
|
+
INTEGRATIONS_DOCS_URL: Incomplete
|
|
16
|
+
LOGFIRE_LOG_FILE: Incomplete
|
|
17
|
+
file_handler: Incomplete
|
|
18
|
+
logger: Incomplete
|
|
19
|
+
|
|
20
|
+
def version_callback() -> None:
|
|
21
|
+
"""Show the version and exit."""
|
|
22
|
+
def parse_whoami(args: argparse.Namespace) -> None:
|
|
23
|
+
"""Show user authenticated username and the URL to your Logfire project."""
|
|
24
|
+
def parse_clean(args: argparse.Namespace) -> None:
|
|
25
|
+
"""Remove the contents of the Logfire data directory."""
|
|
26
|
+
def parse_backfill(args: argparse.Namespace) -> None:
|
|
27
|
+
"""Bulk upload data to Logfire."""
|
|
28
|
+
|
|
29
|
+
OTEL_PACKAGES: set[str]
|
|
30
|
+
OTEL_PACKAGE_LINK: Incomplete
|
|
31
|
+
|
|
32
|
+
def parse_inspect(args: argparse.Namespace) -> None:
|
|
33
|
+
"""Inspect installed packages and recommend packages that might be useful."""
|
|
34
|
+
def parse_auth(args: argparse.Namespace) -> None:
|
|
35
|
+
"""Authenticate with Logfire.
|
|
36
|
+
|
|
37
|
+
This will authenticate your machine with Logfire and store the credentials.
|
|
38
|
+
"""
|
|
39
|
+
def parse_list_projects(args: argparse.Namespace) -> None:
|
|
40
|
+
"""List user projects."""
|
|
41
|
+
def parse_create_new_project(args: argparse.Namespace) -> None:
|
|
42
|
+
"""Create a new project."""
|
|
43
|
+
def parse_use_project(args: argparse.Namespace) -> None:
|
|
44
|
+
"""Use an existing project."""
|
|
45
|
+
def parse_info(_args: argparse.Namespace) -> None:
|
|
46
|
+
"""Show versions of logfire, OS and related packages."""
|
|
47
|
+
def main(args: list[str] | None = None) -> None:
|
|
48
|
+
"""Run the CLI."""
|