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

Add logfire.instrument_system_metrics() #373

Merged
merged 55 commits into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
b713282
system_metrics.py
alexmojaki Aug 8, 2024
7400de8
use OTEL config for most metrics
alexmojaki Aug 8, 2024
c1c4e6b
tests
alexmojaki Aug 8, 2024
13d0baa
Update generated stubs
alexmojaki Aug 8, 2024
dd05380
Update generated stubs
alexmojaki Aug 8, 2024
ac2b5d7
Remove collect_system_metrics and old code
alexmojaki Aug 8, 2024
f882a10
Test config errors
alexmojaki Aug 8, 2024
4a9ade1
Update generated stubs
alexmojaki Aug 8, 2024
be7282c
Don't uninstrument automatically
alexmojaki Aug 13, 2024
6d7f158
Merge branch 'main' into alex/instrument-system-metrics
alexmojaki Aug 13, 2024
ea40267
wip
alexmojaki Aug 14, 2024
7b397d6
docs for new API
alexmojaki Aug 15, 2024
48c31bd
Remove available metrics section
alexmojaki Aug 15, 2024
68e3f28
Remove logfire prefix
alexmojaki Aug 15, 2024
7a90d6d
simpler API with smaller defaults
alexmojaki Aug 15, 2024
2ab5017
test bases
alexmojaki Aug 15, 2024
1087dc1
test_custom_system_metrics_collection
alexmojaki Aug 15, 2024
19fca49
Fix test_full_base
alexmojaki Aug 15, 2024
a3d5335
smarter simple_utilization
alexmojaki Aug 16, 2024
c9e889b
MetricName also needs to be updated
alexmojaki Aug 16, 2024
34ed55c
pyright
alexmojaki Aug 16, 2024
fb9a784
pragma
alexmojaki Aug 16, 2024
44c17c1
Update generated stubs
alexmojaki Aug 16, 2024
3ad0209
Update generated stubs
alexmojaki Aug 16, 2024
142ba70
3.8
alexmojaki Aug 16, 2024
8c78289
rename dashboard
alexmojaki Aug 16, 2024
d1dd843
Document both basic system metrics dashboards
alexmojaki Aug 16, 2024
edb3ad8
update metrics docs
alexmojaki Aug 16, 2024
86073d5
docstring
alexmojaki Aug 16, 2024
8aa1d1b
docstring
alexmojaki Aug 16, 2024
5ec79e5
comments
alexmojaki Aug 19, 2024
3fc0971
comments
alexmojaki Aug 19, 2024
2cc9e1a
uninstrument automatically
alexmojaki Aug 19, 2024
8b69741
pin griffe
alexmojaki Aug 19, 2024
9bb6b43
pin griffe
alexmojaki Aug 19, 2024
f9d86eb
pin griffe
alexmojaki Aug 19, 2024
da3e3fa
Update generated stubs
alexmojaki Aug 19, 2024
389b920
format link
alexmojaki Aug 19, 2024
e953802
format link
alexmojaki Aug 19, 2024
8ea604f
Merge branch 'main' into alex/instrument-system-metrics
alexmojaki Aug 19, 2024
99ada07
Merge branch 'alex/instrument-system-metrics' of github.com:pydantic/…
alexmojaki Aug 20, 2024
900c8e6
Merge branch 'main' of github.com:pydantic/logfire into alex/instrume…
alexmojaki Aug 20, 2024
e8b0e26
add popover explaining None value
alexmojaki Aug 20, 2024
a35d665
warn about costs
alexmojaki Aug 20, 2024
cdbcb84
Link to guide in configure param docs
alexmojaki Aug 20, 2024
86acff7
Merge branch 'main' of github.com:pydantic/logfire into alex/instrume…
alexmojaki Aug 20, 2024
d7f4902
Split into two CPU metrics
alexmojaki Aug 21, 2024
be5e9ef
document each basic metric
alexmojaki Aug 21, 2024
bae2c6d
Apply review suggestions to docs
alexmojaki Aug 21, 2024
b2144ad
Ensure process.runtime.cpu.utilization values don't start at 0
alexmojaki Aug 21, 2024
90df9ca
fix check
alexmojaki Aug 21, 2024
f0b8d86
fix range of values of process.runtime.cpu.utilization
alexmojaki Aug 22, 2024
c39b697
Merge branch 'main' of github.com:pydantic/logfire into alex/instrume…
alexmojaki Aug 22, 2024
2102b39
Update descriptions of dashboards
alexmojaki Aug 22, 2024
0ba76a7
Merge branch 'main' into alex/instrument-system-metrics
alexmojaki Aug 22, 2024
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
88 changes: 64 additions & 24 deletions docs/integrations/system_metrics.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,68 @@
By default, **Logfire** does not collect system metrics.
The [`logfire.instrument_system_metrics()`][logfire.Logfire.instrument_system_metrics] method can be used to collect system metrics with **Logfire**, such as CPU and memory usage.

To enable metrics, you need to install the `logfire[system-metrics]` extra:
## Installation

Install `logfire` with the `system-metrics` extra:

{{ install_logfire(extras=['system-metrics']) }}

### Available Metrics

alexmojaki marked this conversation as resolved.
Show resolved Hide resolved
Logfire collects the following system metrics:

* `system.cpu.time`: CPU time spent in different modes.
* `system.cpu.utilization`: CPU utilization in different modes.
* `system.memory.usage`: Memory usage.
* `system.memory.utilization`: Memory utilization in different modes.
* `system.swap.usage`: Swap usage.
* `system.swap.utilization`: Swap utilization
* `system.disk.io`: Disk I/O operations (read/write).
* `system.disk.operations`: Disk operations (read/write).
* `system.disk.time`: Disk time (read/write).
* `system.network.dropped.packets`: Dropped packets (transmit/receive).
* `system.network.packets`: Packets (transmit/receive).
* `system.network.errors`: Network errors (transmit/receive).
* `system.network.io`: Network I/O (transmit/receive).
* `system.network.connections`: Network connections (family/type).
* `system.thread_count`: Thread count.
* `process.runtime.memory`: Process memory usage.
* `process.runtime.cpu.time`: Process CPU time.
* `process.runtime.gc_count`: Process garbage collection count.
## Usage

```py
import logfire

logfire.configure()

logfire.instrument_system_metrics()
```

Then in your project, click on 'Dashboards' in the top bar, click 'New Dashboard', and select 'Basic System Metrics' from the dropdown.

## Configuration

By default, `instrument_system_metrics` collects only the metrics it needs to display the 'Basic System Metrics' dashboard. You can choose exactly which metrics to collect and how much data to collect about each metric. The default is equivalent to this:

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current 'Basic System Metrics' dashboard template won't work with this new set of reduced metrics. I will create a PR with a new template. That PR will need to be ready to merge before these changes can be merged, and it should be deployed approximately when this is released.

When users upgrade the SDK, system metrics will stop being collected, if they were being collected at all. Since their collection was the implicit default, we can't warn them about this in code, and must rely on the changelog and announcements in slack. If the only thing that users do is add logfire.instrument_system_metrics() then existing basic system metrics dashboards will still not work, so we need to make it clear that they also need to switch to the new template.

The old template is still useful though, because it works with OTEL conventions, so system metrics collected by means other than the logfire SDK can be used with the old template. So we should keep and document both. We need to figure out how to name them to clarify the difference, e.g. 'Basic System Metrics (Logfire)' and 'Basic System Metrics (OpenTelemetry)'.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

```py
logfire.instrument_system_metrics({
'system.cpu.simple_utilization': None,
'system.memory.utilization': ['available'],
alexmojaki marked this conversation as resolved.
Show resolved Hide resolved
'system.swap.utilization': ['used'],
})
```

To collect lots of detailed data about all available metrics, use `logfire.instrument_system_metrics(base='full')`. This is equivalent to:

alexmojaki marked this conversation as resolved.
Show resolved Hide resolved
```py
logfire.instrument_system_metrics({
'system.cpu.simple_utilization': None,
'system.cpu.time': ['idle', 'user', 'system', 'irq', 'softirq', 'nice', 'iowait', 'steal', 'interrupt', 'dpc'],
'system.cpu.utilization': ['idle', 'user', 'system', 'irq', 'softirq', 'nice', 'iowait', 'steal', 'interrupt', 'dpc'],
'system.memory.usage': ['available', 'used', 'free', 'active', 'inactive', 'buffers', 'cached', 'shared', 'wired', 'slab', 'total'],
'system.memory.utilization': ['available', 'used', 'free', 'active', 'inactive', 'buffers', 'cached', 'shared', 'wired', 'slab'],
'system.swap.usage': ['used', 'free'],
'system.swap.utilization': ['used'],
'system.disk.io': ['read', 'write'],
'system.disk.operations': ['read', 'write'],
'system.disk.time': ['read', 'write'],
'system.network.dropped.packets': ['transmit', 'receive'],
'system.network.packets': ['transmit', 'receive'],
'system.network.errors': ['transmit', 'receive'],
'system.network.io': ['transmit', 'receive'],
'system.thread_count': None,
'process.runtime.memory': ['rss', 'vms'],
'process.runtime.cpu.time': ['user', 'system'],
'process.runtime.gc_count': None,
'process.runtime.thread_count': None,
'process.runtime.cpu.utilization': None,
'process.runtime.context_switches': ['involuntary', 'voluntary'],
'process.open_file_descriptor.count': None,
})
```

Each key here is a metric name. The values have different meanings for different metrics. For example, for `system.cpu.utilization`, the value is a list of CPU modes. So there will be a separate row for each CPU core saying what percentage of time it spent idle, another row for the time spent waiting for IO, etc. There are no fields to configure for `system.thread_count`, so the value is `None`.

The first dict argument is merged with the base. For example, if you want to collect disk read operations (but not writes) you can write:

alexmojaki marked this conversation as resolved.
Show resolved Hide resolved
- `logfire.instrument_system_metrics({'system.disk.operations': ['read']})` to collect that data in addition to the basic defaults.
- `logfire.instrument_system_metrics({'system.disk.operations': ['read']}, base='full')` to collect detailed data about all metrics, excluding disk write operations.
- `logfire.instrument_system_metrics({'system.disk.operations': ['read']}, base=None)` to collect only disk read operations and nothing else.
3 changes: 3 additions & 0 deletions logfire-api/logfire_api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ def instrument_openai(self, *args, **kwargs) -> ContextManager[None]:

def instrument_aiohttp_client(self, *args, **kwargs) -> None: ...

def instrument_system_metrics(self, *args, **kwargs) -> None: ...

def shutdown(self, *args, **kwargs) -> None: ...

DEFAULT_LOGFIRE_INSTANCE = Logfire()
Expand Down Expand Up @@ -158,6 +160,7 @@ def shutdown(self, *args, **kwargs) -> None: ...
instrument_redis = DEFAULT_LOGFIRE_INSTANCE.instrument_redis
instrument_pymongo = DEFAULT_LOGFIRE_INSTANCE.instrument_pymongo
instrument_mysql = DEFAULT_LOGFIRE_INSTANCE.instrument_mysql
instrument_system_metrics = DEFAULT_LOGFIRE_INSTANCE.instrument_system_metrics
shutdown = DEFAULT_LOGFIRE_INSTANCE.shutdown

def no_auto_trace(x):
Expand Down
3 changes: 2 additions & 1 deletion logfire-api/logfire_api/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ from .integrations.logging import LogfireLoggingHandler as LogfireLoggingHandler
from .integrations.structlog import LogfireProcessor as StructlogProcessor
from .version import VERSION as VERSION

__all__ = ['Logfire', 'LogfireSpan', 'LevelName', 'ConsoleOptions', 'PydanticPlugin', 'configure', 'span', 'instrument', 'log', 'trace', 'debug', 'notice', 'info', 'warn', 'error', 'exception', 'fatal', 'force_flush', 'log_slow_async_callbacks', 'install_auto_tracing', 'instrument_fastapi', 'instrument_openai', 'instrument_anthropic', 'instrument_asyncpg', 'instrument_httpx', 'instrument_celery', 'instrument_requests', 'instrument_psycopg', 'instrument_django', 'instrument_flask', 'instrument_starlette', 'instrument_aiohttp_client', 'instrument_sqlalchemy', 'instrument_redis', 'instrument_pymongo', 'instrument_mysql', 'AutoTraceModule', 'with_tags', 'with_settings', 'shutdown', 'load_spans_from_file', 'no_auto_trace', 'METRICS_PREFERRED_TEMPORALITY', 'ScrubMatch', 'ScrubbingOptions', 'VERSION', 'suppress_instrumentation', 'StructlogProcessor', 'LogfireLoggingHandler', 'TailSamplingOptions']
__all__ = ['Logfire', 'LogfireSpan', 'LevelName', 'ConsoleOptions', 'PydanticPlugin', 'configure', 'span', 'instrument', 'log', 'trace', 'debug', 'notice', 'info', 'warn', 'error', 'exception', 'fatal', 'force_flush', 'log_slow_async_callbacks', 'install_auto_tracing', 'instrument_fastapi', 'instrument_openai', 'instrument_anthropic', 'instrument_asyncpg', 'instrument_httpx', 'instrument_celery', 'instrument_requests', 'instrument_psycopg', 'instrument_django', 'instrument_flask', 'instrument_starlette', 'instrument_aiohttp_client', 'instrument_sqlalchemy', 'instrument_redis', 'instrument_pymongo', 'instrument_mysql', 'instrument_system_metrics', 'AutoTraceModule', 'with_tags', 'with_settings', 'shutdown', 'load_spans_from_file', 'no_auto_trace', 'METRICS_PREFERRED_TEMPORALITY', 'ScrubMatch', 'ScrubbingOptions', 'VERSION', 'suppress_instrumentation', 'StructlogProcessor', 'LogfireLoggingHandler', 'TailSamplingOptions']

DEFAULT_LOGFIRE_INSTANCE = Logfire()
span = DEFAULT_LOGFIRE_INSTANCE.span
Expand All @@ -35,6 +35,7 @@ instrument_sqlalchemy = DEFAULT_LOGFIRE_INSTANCE.instrument_sqlalchemy
instrument_redis = DEFAULT_LOGFIRE_INSTANCE.instrument_redis
instrument_pymongo = DEFAULT_LOGFIRE_INSTANCE.instrument_pymongo
instrument_mysql = DEFAULT_LOGFIRE_INSTANCE.instrument_mysql
instrument_system_metrics = DEFAULT_LOGFIRE_INSTANCE.instrument_system_metrics
shutdown = DEFAULT_LOGFIRE_INSTANCE.shutdown
with_tags = DEFAULT_LOGFIRE_INSTANCE.with_tags
with_settings = DEFAULT_LOGFIRE_INSTANCE.with_settings
Expand Down
12 changes: 5 additions & 7 deletions logfire-api/logfire_api/_internal/config.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ from .exporters.remove_pending import RemovePendingSpansExporter as RemovePendin
from .exporters.tail_sampling import TailSamplingOptions as TailSamplingOptions, TailSamplingProcessor as TailSamplingProcessor
from .exporters.test import TestExporter as TestExporter
from .integrations.executors import instrument_executors as instrument_executors
from .metrics import ProxyMeterProvider as ProxyMeterProvider, configure_metrics as configure_metrics
from .metrics import ProxyMeterProvider as ProxyMeterProvider
from .scrubbing import BaseScrubber as BaseScrubber, NOOP_SCRUBBER as NOOP_SCRUBBER, ScrubCallback as ScrubCallback, Scrubber as Scrubber, ScrubbingOptions as ScrubbingOptions
from .stack_info import warn_at_user_stacklevel as warn_at_user_stacklevel
from .tracer import PendingSpanProcessor as PendingSpanProcessor, ProxyTracerProvider as ProxyTracerProvider
Expand Down Expand Up @@ -54,7 +54,7 @@ class PydanticPlugin:
include: set[str] = ...
exclude: set[str] = ...

def configure(*, send_to_logfire: bool | Literal['if-token-present'] | None = None, token: str | None = None, project_name: str | None = None, service_name: str | None = None, service_version: str | None = None, trace_sample_rate: float | None = None, console: ConsoleOptions | Literal[False] | None = None, show_summary: bool | None = None, config_dir: Path | str | None = None, data_dir: Path | str | None = None, base_url: str | None = None, collect_system_metrics: bool | None = None, id_generator: IdGenerator | None = None, ns_timestamp_generator: Callable[[], int] | None = None, processors: None = None, additional_span_processors: Sequence[SpanProcessor] | None = None, default_span_processor: Callable[[SpanExporter], SpanProcessor] | None = None, metric_readers: None = None, additional_metric_readers: Sequence[MetricReader] | None = None, pydantic_plugin: PydanticPlugin | None = None, fast_shutdown: bool = False, scrubbing_patterns: Sequence[str] | None = None, scrubbing_callback: ScrubCallback | None = None, scrubbing: ScrubbingOptions | Literal[False] | None = None, inspect_arguments: bool | None = None, tail_sampling: TailSamplingOptions | None = None) -> None:
def configure(*, send_to_logfire: bool | Literal['if-token-present'] | None = None, token: str | None = None, project_name: str | None = None, service_name: str | None = None, service_version: str | None = None, trace_sample_rate: float | None = None, console: ConsoleOptions | Literal[False] | None = None, show_summary: bool | None = None, config_dir: Path | str | None = None, data_dir: Path | str | None = None, base_url: str | None = None, collect_system_metrics: None = None, id_generator: IdGenerator | None = None, ns_timestamp_generator: Callable[[], int] | None = None, processors: None = None, additional_span_processors: Sequence[SpanProcessor] | None = None, default_span_processor: Callable[[SpanExporter], SpanProcessor] | None = None, metric_readers: None = None, additional_metric_readers: Sequence[MetricReader] | None = None, pydantic_plugin: PydanticPlugin | None = None, fast_shutdown: bool = False, scrubbing_patterns: Sequence[str] | None = None, scrubbing_callback: ScrubCallback | None = None, scrubbing: ScrubbingOptions | Literal[False] | None = None, inspect_arguments: bool | None = None, tail_sampling: TailSamplingOptions | None = None) -> None:
"""Configure the logfire SDK.

Args:
Expand All @@ -81,8 +81,7 @@ def configure(*, send_to_logfire: bool | Literal['if-token-present'] | None = No
`LOGFIRE_CONFIG_DIR` environment variable, otherwise defaults to the current working directory.
data_dir: Directory to store credentials, and logs. If `None` uses the `LOGFIRE_CREDENTIALS_DIR` environment variable, otherwise defaults to `'.logfire'`.
base_url: Root URL for the Logfire API. If `None` uses the `LOGFIRE_BASE_URL` environment variable, otherwise defaults to https://logfire-api.pydantic.dev.
collect_system_metrics: Whether to collect system metrics like CPU and memory usage. If `None` uses the `LOGFIRE_COLLECT_SYSTEM_METRICS` environment variable,
otherwise defaults to `True`.
collect_system_metrics: Legacy argument, use `logfire.instrument_system_metrics()` instead.
id_generator: Generator for span IDs. Defaults to `RandomIdGenerator()` from the OpenTelemetry SDK.
ns_timestamp_generator: Generator for nanosecond timestamps. Defaults to [`time.time_ns`][time.time_ns] from the
Python standard library.
Expand Down Expand Up @@ -127,7 +126,6 @@ class _LogfireConfigData:
console: ConsoleOptions | Literal[False] | None
show_summary: bool
data_dir: Path
collect_system_metrics: bool
id_generator: IdGenerator
ns_timestamp_generator: Callable[[], int]
additional_span_processors: Sequence[SpanProcessor] | None
Expand All @@ -139,14 +137,14 @@ class _LogfireConfigData:
tail_sampling: TailSamplingOptions | None

class LogfireConfig(_LogfireConfigData):
def __init__(self, base_url: str | None = None, send_to_logfire: bool | None = None, token: str | None = None, project_name: str | None = None, service_name: str | None = None, service_version: str | None = None, trace_sample_rate: float | None = None, console: ConsoleOptions | Literal[False] | None = None, show_summary: bool | None = None, config_dir: Path | None = None, data_dir: Path | None = None, collect_system_metrics: bool | None = None, id_generator: IdGenerator | None = None, ns_timestamp_generator: Callable[[], int] | None = None, additional_span_processors: Sequence[SpanProcessor] | None = None, default_span_processor: Callable[[SpanExporter], SpanProcessor] | None = None, additional_metric_readers: Sequence[MetricReader] | None = None, pydantic_plugin: PydanticPlugin | None = None, fast_shutdown: bool = False, scrubbing: ScrubbingOptions | Literal[False] | None = None, inspect_arguments: bool | None = None, tail_sampling: TailSamplingOptions | None = None) -> None:
def __init__(self, base_url: str | None = None, send_to_logfire: bool | None = None, token: str | None = None, project_name: str | None = None, service_name: str | None = None, service_version: str | None = None, trace_sample_rate: float | None = None, console: ConsoleOptions | Literal[False] | None = None, show_summary: bool | None = None, config_dir: Path | None = None, data_dir: Path | None = None, id_generator: IdGenerator | None = None, ns_timestamp_generator: Callable[[], int] | None = None, additional_span_processors: Sequence[SpanProcessor] | None = None, default_span_processor: Callable[[SpanExporter], SpanProcessor] | None = None, additional_metric_readers: Sequence[MetricReader] | None = None, pydantic_plugin: PydanticPlugin | None = None, fast_shutdown: bool = False, scrubbing: ScrubbingOptions | Literal[False] | None = None, inspect_arguments: bool | None = None, tail_sampling: TailSamplingOptions | None = None) -> None:
"""Create a new LogfireConfig.

Users should never need to call this directly, instead use `logfire.configure`.

See `_LogfireConfigData` for parameter documentation.
"""
def configure(self, base_url: str | None, send_to_logfire: bool | Literal['if-token-present'] | None, token: str | None, project_name: str | None, service_name: str | None, service_version: str | None, trace_sample_rate: float | None, console: ConsoleOptions | Literal[False] | None, show_summary: bool | None, config_dir: Path | None, data_dir: Path | None, collect_system_metrics: bool | None, id_generator: IdGenerator | None, ns_timestamp_generator: Callable[[], int] | None, additional_span_processors: Sequence[SpanProcessor] | None, default_span_processor: Callable[[SpanExporter], SpanProcessor] | None, additional_metric_readers: Sequence[MetricReader] | None, pydantic_plugin: PydanticPlugin | None, fast_shutdown: bool, scrubbing: ScrubbingOptions | Literal[False] | None, inspect_arguments: bool | None, tail_sampling: TailSamplingOptions | None) -> None: ...
def configure(self, base_url: str | None, send_to_logfire: bool | Literal['if-token-present'] | None, token: str | None, project_name: str | None, service_name: str | None, service_version: str | None, trace_sample_rate: float | None, console: ConsoleOptions | Literal[False] | None, show_summary: bool | None, config_dir: Path | None, data_dir: Path | None, id_generator: IdGenerator | None, ns_timestamp_generator: Callable[[], int] | None, additional_span_processors: Sequence[SpanProcessor] | None, default_span_processor: Callable[[SpanExporter], SpanProcessor] | None, additional_metric_readers: Sequence[MetricReader] | None, pydantic_plugin: PydanticPlugin | None, fast_shutdown: bool, scrubbing: ScrubbingOptions | Literal[False] | None, inspect_arguments: bool | None, tail_sampling: TailSamplingOptions | None) -> None: ...
def initialize(self) -> ProxyTracerProvider:
"""Configure internals to start exporting traces and metrics."""
def force_flush(self, timeout_millis: int = 30000) -> bool:
Expand Down
2 changes: 0 additions & 2 deletions logfire-api/logfire_api/_internal/config_params.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ from logfire.exceptions import LogfireConfigError as LogfireConfigError
from pathlib import Path
from typing import Any, Callable, TypeVar

COLLECT_SYSTEM_METRICS_DEFAULT: bool
T = TypeVar('T')
slots_true: Incomplete
PydanticPluginRecordValues: Incomplete
Expand Down Expand Up @@ -38,7 +37,6 @@ SERVICE_NAME: Incomplete
SERVICE_VERSION: Incomplete
SHOW_SUMMARY: Incomplete
CREDENTIALS_DIR: Incomplete
COLLECT_SYSTEM_METRICS: Incomplete
CONSOLE: Incomplete
CONSOLE_COLORS: Incomplete
CONSOLE_SPAN_STYLE: Incomplete
Expand Down
15 changes: 15 additions & 0 deletions logfire-api/logfire_api/_internal/integrations/system_metrics.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from _typeshed import Incomplete
from opentelemetry.metrics import MeterProvider
from typing import Any, Iterable

MetricName: Incomplete
alexmojaki marked this conversation as resolved.
Show resolved Hide resolved
ConfigString: Incomplete
ConfigDict = dict[MetricName, Iterable[str] | None]
Config: Incomplete
CPU_FIELDS: Incomplete
MEMORY_FIELDS: Incomplete
DEFAULT_CONFIG: ConfigDict
BASIC_METRICS: list[MetricName]

def parse_config(config: Config) -> ConfigDict: ...
def instrument_system_metrics(meter_provider: MeterProvider, config: Any = 'basic') -> None: ...
7 changes: 7 additions & 0 deletions logfire-api/logfire_api/_internal/main.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ from .integrations.pymongo import PymongoInstrumentKwargs as PymongoInstrumentKw
from .integrations.redis import RedisInstrumentKwargs as RedisInstrumentKwargs
from .integrations.sqlalchemy import SQLAlchemyInstrumentKwargs as SQLAlchemyInstrumentKwargs
from .integrations.starlette import StarletteInstrumentKwargs as StarletteInstrumentKwargs
from .integrations.system_metrics import Config as SystemMetricsConfig
from .json_encoder import logfire_json_dumps as logfire_json_dumps
from .json_schema import JsonSchemaProperties as JsonSchemaProperties, attributes_json_schema as attributes_json_schema, attributes_json_schema_properties as attributes_json_schema_properties, create_json_schema as create_json_schema
from .metrics import ProxyMeterProvider as ProxyMeterProvider
Expand Down Expand Up @@ -643,6 +644,12 @@ class Logfire:
If a connection is provided, returns the instrumented connection. If no connection is provided, returns None.

"""
def instrument_system_metrics(self, config: SystemMetricsConfig = 'basic'):
"""Instrument the system metrics.

Args:
config: The system metrics configuration.
"""
def metric_counter(self, name: str, *, unit: str = '', description: str = '') -> Counter:
"""Create a counter metric.

Expand Down
6 changes: 0 additions & 6 deletions logfire-api/logfire_api/_internal/metrics.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,6 @@ from typing import Any, Generic, Sequence, TypeVar
from weakref import WeakSet

Gauge: Incomplete
CPU_FIELDS: Incomplete
MEMORY_FIELDS: Incomplete
DEFAULT_CONFIG: Incomplete
INSTRUMENTOR: Incomplete

def configure_metrics(meter_provider: MeterProvider) -> None: ...

@dataclasses.dataclass
class ProxyMeterProvider(MeterProvider):
Expand Down
Loading
Loading