Top-Level Functions

Main entry points and utilities for fapilog.

get_logger (sync) {#get_logger}

def get_logger(
    name: str | None = None,
    *,
    preset: str | None = None,
    format: Literal["json", "pretty", "auto"] | None = None,
    settings: _Settings | None = None,
    reuse: bool = True,
) -> _SyncLoggerFacade

Return a ready-to-use synchronous logger facade wired to a container-scoped pipeline. Methods like info() and error() are synchronous (no await).

Parameters

Parameter

Type

Default

Description

name

str | None

None

Logger name for identification. If None, uses the module name.

preset

str | None

None

Built-in preset (dev, production, fastapi, minimal).

format

Literal[...]

None

Output format: json, pretty, auto (pretty in TTY).

settings

_Settings | None

None

Custom settings. If None, uses environment variables.

reuse

bool

True

If True, return cached instance for the same name. If False, create a new independent instance.

Returns

_SyncLoggerFacade - A logger instance ready for use (cached by name when reuse=True).

Examples

from fapilog import get_logger
import asyncio

# Zero-config usage (uses environment variables)
logger = get_logger()
logger.info("Application started")

# With custom name for better identification
service_logger = get_logger("user_service")
service_logger.info("User authentication successful")

# With custom settings
from fapilog import Settings
settings = Settings(core__enable_metrics=True)
logger = get_logger(settings=settings)
logger.info("Metrics-enabled logger ready")

# Force pretty output
logger = get_logger(format="pretty")
logger.info("Readable output", request_id="abc-123")

# Manual cleanup if you are not using runtime()
asyncio.run(logger.stop_and_drain())

Environment Variables

The following environment variables are automatically read:

  • FAPILOG_CORE__LOG_LEVEL - Log level hint (default: INFO)

  • FAPILOG_FILE__DIRECTORY - File sink directory (if set, enables file logging)

  • FAPILOG_CORE__ENABLE_METRICS - Enable metrics collection (default: false)

Notes

  • Sync API surface: debug, info, warning, error, exception, bind, unbind, clear_context

  • Worker lifecycle is managed automatically; call logger.stop_and_drain() if you need explicit shutdown.

  • Automatic sink selection: pretty in TTY, JSON when piped; file/http sink when configured via settings/env.

  • preset and settings are mutually exclusive; format and settings are mutually exclusive.

  • When settings is omitted, the default format behavior is auto.

  • Caching: By default, loggers are cached by name. Calling get_logger("foo") multiple times returns the same instance. Use reuse=False for independent instances (e.g., in tests).

get_async_logger (async) {#get_async_logger}

async def get_async_logger(
    name: str | None = None,
    *,
    preset: str | None = None,
    format: Literal["json", "pretty", "auto"] | None = None,
    settings: _Settings | None = None,
    reuse: bool = True,
) -> _AsyncLoggerFacade

Return a ready-to-use async logger facade with awaitable methods.

Parameters

Parameter

Type

Default

Description

name

str | None

None

Logger name for identification. If None, uses the module name.

preset

str | None

None

Built-in preset (dev, production, fastapi, minimal).

format

Literal[...]

None

Output format: json, pretty, auto (pretty in TTY).

settings

_Settings | None

None

Custom settings. If None, uses environment variables.

reuse

bool

True

If True, return cached instance for the same name. If False, create a new independent instance.

Returns

_AsyncLoggerFacade - A logger instance with awaitable methods (cached by name when reuse=True).

Examples

from fapilog import get_async_logger

logger = await get_async_logger("request")
await logger.info("Application started")
await logger.debug("Detailed event", request_id="req-1")
await logger.error("Something went wrong", exc_info=True)
await logger.drain()  # graceful shutdown

Notes

  • Async API surface: debug, info, warning, error, exception, drain, bind, unbind, clear_context

  • Uses the same settings/env vars as get_logger

  • Prefer runtime_async() for automatic lifecycle management

  • Caching: By default, loggers are cached by name. Calling get_async_logger("foo") multiple times returns the same instance. Use reuse=False for independent instances (e.g., in tests).

runtime {#runtime}

@contextmanager
def runtime(*, settings: _Settings | None = None) -> Iterator[_SyncLoggerFacade]

Context manager that initializes and drains a sync logger.

Examples

from fapilog import runtime

with runtime() as logger:
    logger.info("Processing started")
    # ... do work ...
    logger.info("Processing completed")
# Logger automatically drained on exit

runtime_async {#runtime_async}

@asynccontextmanager
async def runtime_async(
    *,
    settings: _Settings | None = None
) -> AsyncIterator[_AsyncLoggerFacade]

Async context manager that initializes and drains an async logger.

Examples

from fapilog import runtime_async

async with runtime_async() as logger:
    await logger.info("Batch processing started")
    await logger.debug("Item", index=1)
# Logger automatically drained on exit

register_level {#register_level}

def register_level(
    name: str,
    priority: int,
    *,
    add_method: bool = False,
) -> None

Register a custom log level for use throughout your application.

Custom levels allow you to define domain-specific severity levels beyond the standard DEBUG, INFO, WARNING, ERROR, and CRITICAL. Common use cases include:

  • TRACE (priority 5) - Verbose debugging below DEBUG

  • AUDIT (priority 25) - Compliance/security events between INFO and WARNING

  • NOTICE (priority 22) - Significant events that aren’t warnings

  • ALERT (priority 45) - Immediate attention needed, above ERROR

Parameters

Parameter

Type

Default

Description

name

str

-

Level name (e.g., “TRACE”, “AUDIT”). Automatically uppercased.

priority

int

-

Numeric priority 0-99. Lower = more verbose. Standard: DEBUG=10, INFO=20, WARNING=30, ERROR=40, CRITICAL=50.

add_method

bool

False

If True, adds a method to logger (e.g., logger.trace()).

Raises

  • ValueError - If level name already exists or priority is outside 0-99

  • RuntimeError - If called after a logger has been created

Examples

import fapilog

# Register custom levels BEFORE creating any loggers
fapilog.register_level("TRACE", priority=5, add_method=True)
fapilog.register_level("AUDIT", priority=25, add_method=True)

# Now create your logger
logger = fapilog.get_logger()

# Use the dynamic methods
logger.trace("entering function", func="process_order")
logger.audit("user accessed resource", user_id="123", resource="secrets")

# Standard methods still work
logger.info("order processed", order_id="456")

Level Filtering

Custom levels integrate with the level filter. Events below the configured minimum level are dropped:

import fapilog
from fapilog import Settings

fapilog.register_level("TRACE", priority=5, add_method=True)

# With min_level=INFO (priority 20), TRACE events (priority 5) are dropped
settings = Settings(core={"log_level": "INFO"})
logger = fapilog.get_logger(settings=settings)

logger.trace("this is dropped")  # priority 5 < 20
logger.info("this appears")       # priority 20 >= 20

Sink Routing

Custom levels work with sink routing rules:

# fapilog.yaml
sink_routing:
  rules:
    - match: { level: "AUDIT" }
      sink: "audit_file"
    - match: { level: "ERROR" }
      sink: "alerts"

Notes

  • Must be called before any logger is created - The registry freezes on first get_logger() or get_async_logger() call

  • Level names are case-insensitive and stored uppercase

  • Without add_method=True, you can still log via the level name but won’t have a dedicated method

  • Priority determines filtering order: lower priority = more verbose (filtered first when min_level is higher)

get_cached_loggers {#get_cached_loggers}

def get_cached_loggers() -> dict[str, str]

Return a snapshot of currently cached logger names and their types.

Returns

dict[str, str] - Mapping of logger names to their type ("async" or "sync").

Examples

from fapilog import get_logger, get_async_logger, get_cached_loggers

get_logger("service-a")
await get_async_logger("service-b")

cached = get_cached_loggers()
# {"service-a": "sync", "service-b": "async"}

clear_logger_cache {#clear_logger_cache}

async def clear_logger_cache() -> None

Drain all cached loggers and clear the cache. Useful for test cleanup.

Examples

from fapilog import clear_logger_cache

# Clear all cached loggers (drains them first)
await clear_logger_cache()

Notes

  • Drains all cached loggers before removing them from the cache

  • Thread-safe; can be called from any thread

  • Commonly used in test fixtures for isolation between tests


These top-level functions provide the main entry points for using fapilog.