Skip to content

szmyty/visionlog

Visionlog πŸš€

A high-performance, structured logging library for analytics tracking.

Features

  • πŸš€ Structured JSON Logging
  • πŸ”Ž Easy Integration with OpenTelemetry
  • 🎨 Pretty Console Output with Loguru
  • ⚑ Ultra-Fast JSON Serialization using orjson
  • πŸ›  Command-Line Logging Tool

Installation

Install via pip

pip install visionlog

Install via Poetry

poetry add visionlog

Install with OpenTelemetry tracing support

pip install visionlog[tracing]
# or
poetry add visionlog --extras tracing

Install with device detection support

pip install visionlog[device]
# or
poetry add visionlog --extras device

πŸš€ Usage

1. Basic Example

from visionlog import get_logger

logger = get_logger("my-app")

logger.info("User login event", user="john_doe", action="login")
logger.warning("Suspicious activity detected", ip="192.168.1.1")
logger.error("Server crashed!", error_code=500)

2. Config-Based Usage

Group all logger options into a reusable LoggerConfig object and pass it to get_logger:

from visionlog import get_logger, LoggerConfig

config = LoggerConfig(
    service_name="my-app",
    user_id="user_42",
    session_id="sess_001",
    environment="production",
)

logger = get_logger(config=config)

logger.info("User login event", action="login")

LoggerConfig supports the same options as the individual keyword arguments. Keyword arguments are still fully supported when config is not provided.

3. CLI Usage

You can also log messages directly from the command line:

visionlog-cli --message "Quick log example"

🎯 Advanced Usage

Using Visionlog with OpenTelemetry

Install the tracing extra first:

pip install visionlog[tracing]

Enable tracing when creating your logger.
Visionlog will automatically inject trace_id and span_id into every log record emitted inside an active span:

from visionlog import get_logger
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider

# Configure the OTel SDK (use your preferred exporter in production)
trace.set_tracer_provider(TracerProvider())
tracer = trace.get_tracer("my-app")

logger = get_logger("my-app", enable_tracing=True)

with tracer.start_as_current_span("http_request"):
    # trace_id and span_id are added automatically
    logger.info("Tracking request event", endpoint="/api/data", status=200)

When no span is active the trace_id/span_id fields are simply omitted, so the logger works identically to the non-tracing configuration.
The opentelemetry-api and opentelemetry-sdk packages are optional β€” if they are not installed, enable_tracing=True is silently ignored.


πŸ” Privacy Considerations

visionlog can enrich logs with IP, geo, and device metadata.

These may be considered Personally Identifiable Information (PII) under regulations such as GDPR, CCPA, LGPD, and others.

By default, privacy_mode is enabled and disables all PII enrichment features (IP lookup, geo-location lookup, and device detection).

To enable enrichment, opt out of privacy mode explicitly:

from visionlog import get_logger

logger = get_logger(
    "my-app",
    ip_address=True,
    geo_info=True,
    device_info=True,
    privacy_mode=False,
)

⚠️ Warning: Only set privacy_mode=False when you have a lawful basis for collecting this data, have notified your users, and have reviewed your compliance obligations.


πŸ“‘ Network Control

visionlog performs external HTTP calls for IP lookup and geo-location lookup. This can cause issues in CI environments, air-gapped systems, or restricted networks.

Use disable_network=True to skip all HTTP calls and receive fallback values instead (None for IP, {} for geo info):

from visionlog import get_logger

logger = get_logger(
    "my-app",
    ip_address=True,
    geo_info=True,
    privacy_mode=False,
    disable_network=True,  # no external HTTP calls are made
)

disable_network is compatible with privacy_mode. When privacy_mode=True (the default) network calls are already prevented, so disable_network is most useful when privacy_mode=False but you still need to suppress network activity.


⚑ Why Use Visionlog?

βœ… Super fast JSON serialization using orjson
βœ… Structured, formatted logs for analytics
βœ… Extensible with OpenTelemetry for tracing
βœ… Command-line logging for quick debugging


🧰 Development Tasks

This project uses Taskfile for development workflows.

Install Task:

macOS / Linux (Homebrew):

brew install go-task/tap/go-task

Windows (Chocolatey):

choco install go-task

Windows (Scoop):

scoop install task

Linux (snap):

snap install task --classic

Or download a binary directly from the Taskfile releases page.

List available tasks:

task --list

🐳 Development Environment

This project supports Dev Containers for a reproducible setup.

Open in VS Code, then open the Command Palette (Ctrl+Shift+P / Cmd+Shift+P) and select:

Remote-Containers: Reopen in Container


πŸ›  Development & Contribution

  1. Clone the repository:

    git clone https://github.com/szmyty/visionlog.git
    cd visionlog
  2. Install dependencies:

    poetry install
  3. Run the example:

    python examples/basic_usage.py

πŸ“ API Stability & Versioning Policy

Public API

The public API of Visionlog consists of everything exported in __all__ from the top-level visionlog package:

Symbol Kind Description
get_logger Function Creates and returns a configured logger instance
configure_visionlog Function Configures the global structlog pipeline
LoggerConfig Dataclass Structured configuration object for get_logger
Enricher Protocol Interface for custom log enrichers
Processor Protocol Interface for custom structlog processors
NetworkEnricher Class Built-in IP/geo enrichment
DeviceEnricher Class Built-in device-detection enrichment
get_public_ip Function Utility β€” fetches the public IP address
get_geo_info Function Utility β€” fetches geo-location data for an IP
get_device_info Function Utility β€” parses a User-Agent string
serialize_json Function Utility β€” serialises a value to JSON bytes via orjson
add_common_fields Function Built-in structlog processor β€” adds common metadata fields
add_otel_context Function Built-in structlog processor β€” injects OpenTelemetry trace context

Any symbol not listed above (e.g. internal helpers inside sub-modules) is considered private and may change without notice.

Stability guarantees

⚠️ Visionlog is currently in Alpha (0.x.y).
The public API is stabilising but breaking changes may still occur in minor version bumps while the project is pre-1.0.

Phase Guarantee
0.x.y β€” Alpha/Beta The public API surface above is defined and intentional, but signatures and behaviour may change in any 0.x release. Migration notes are always included in CHANGELOG.md.
1.0.0 β€” Stable Full semantic versioning guarantees apply (see below). No breaking changes without a major version bump.

Semantic versioning

Visionlog follows Semantic Versioning 2.0.0 (MAJOR.MINOR.PATCH):

Version component When it is incremented
MAJOR (X.y.z) Backwards-incompatible changes to the public API (e.g. removing or renaming exported symbols, changing function signatures in a breaking way).
MINOR (x.Y.z) New backwards-compatible functionality added to the public API (e.g. new exported symbols, new optional parameters with default values).
PATCH (x.y.Z) Backwards-compatible bug fixes that do not alter the public API contract.

Version numbers are managed automatically by Commitizen using Conventional Commits:

  • fix: commits trigger a patch bump.
  • feat: commits trigger a minor bump.
  • Commits with a BREAKING CHANGE: footer, or a ! suffix (e.g. feat!:), trigger a major bump.

Releases are tagged as vMAJOR.MINOR.PATCH (e.g. v1.0.0) and every release is accompanied by an entry in CHANGELOG.md.


πŸ“œ License

Visionlog is released under the MIT License.

About

πŸ‘οΈβ€πŸ—¨οΈ Visionlog: Next-level structured logging for Python. Fast, scalable, and analytics-friendly.

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors