Skip to main content

Professional structured logging library following 'Loggeloven av 2025' requirements

Project description

Urbalurba Logging - Python Implementation

Professional Python implementation of Urbalurba structured logging following "Loggeloven av 2025" requirements. Provides consistent API across all programming languages with full OpenTelemetry integration and production-ready OTLP export capabilities.

✅ Current Status: PRODUCTION READY

  • 🎉 Complete Feature Parity: Matches TypeScript Winston → OpenTelemetry architecture
  • 📡 OTLP Export: Fully functional logs + traces export to observability stack
  • 🔄 Multiple Transports: Simultaneous console + file + OTLP logging
  • 🧪 Comprehensive Testing: Demo, library tests, and real-world validation complete
  • 📊 Live Verification: Successfully integrated with Loki + Grafana observability stack

Repository

This package is part of the multi-language Urbalurba logging system:

Installation

From Source (Current Method)

git clone https://github.com/terchris/urbalurba-logging.git
cd urbalurba-logging/python
pip install -e .

From PyPI

pip install urbalurba-logging

From Test PyPI

pip install -i https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ urbalurba-logging

Quick Start

1. Initialize Logger (Required)

from urbalurba_logging import urbinitializelogger, urblog, LOGLEVELS

# Initialize once at application startup
urbinitializelogger("your-system-id")

2. Basic Logging

FUNCTIONNAME = "MyFunction"

# Simple logging
urblog(LOGLEVELS.INFO, FUNCTIONNAME, "Processing completed", None)

# With context data
urblog(LOGLEVELS.INFO, FUNCTIONNAME, "User created", None, 
       {"userId": "12345"}, {"status": "success"})

# Error logging with exception
try:
    # some operation
    pass
except Exception as error:
    urblog(LOGLEVELS.ERROR, FUNCTIONNAME, "Operation failed", error)

3. Job Tracking

from urbalurba_logging import urblogjobstatus, urblogjobprogress

FUNCTIONNAME = "ProcessData"

# Job lifecycle tracking
urblogjobstatus(LOGLEVELS.INFO, FUNCTIONNAME, "DataImport", "Started")
urblogjobprogress(LOGLEVELS.INFO, FUNCTIONNAME, "item-1", 1, 100)
urblogjobstatus(LOGLEVELS.INFO, FUNCTIONNAME, "DataImport", "Completed")

4. Graceful Shutdown

from urbalurba_logging import urbflushlog

# Flush all logs before application exit
urbflushlog()

Running the Demo

The demo demonstrates real-world usage with API calls and comprehensive logging patterns.

Step 1: Clone and Navigate

git clone https://github.com/terchris/urbalurba-logging.git
cd urbalurba-logging/python/examples/demo

Step 2: Install Dependencies

# Install demo dependencies
pip install -r requirements.txt

# Install main package in development mode
pip install -e ../../

Step 3: Configure Environment

# Run interactive setup (choose logging destination)
./setup-dev-env.sh

Choose from three options:

  1. Console Output - JSON logs to terminal (good for development)
  2. File Logging - Logs to ./logs/dev.log (good for analysis)
  3. OTLP Collector - Export to observability stack (requires Docker)

Step 4: Run Demo

python demo.py

Project Structure

python/
├── src/
│   └── urbalurba_logging/
│       ├── __init__.py          # Package exports
│       ├── urblogger.py         # Core logging implementation  
│       └── log_levels.py        # Log level constants
├── examples/
│   └── demo/
│       ├── demo.py              # Complete working example
│       ├── requirements.txt     # Demo dependencies
│       ├── setup-dev-env.sh     # Development environment setup
│       └── .env                 # Environment template
├── setup.py                     # PyPI package configuration
├── requirements.txt             # Main dependencies
└── README-python.md            # This documentation

API Reference

Initialization

urbinitializelogger(system_id: str)

  • Required: Must be called once at application startup
  • Purpose: Initialize logger with unique system identifier
  • Example: urbinitializelogger("payment-service")

Core Logging

urblog(level, function_name, message, exception, input_json=None, response_json=None)

  • Purpose: General purpose structured logging
  • Parameters:
    • level: Use LOGLEVELS constants (INFO, ERROR, etc.)
    • function_name: Name of calling function (use constant)
    • message: Human-readable description
    • exception: Exception object or None
    • input_json: Input parameters/context (optional)
    • response_json: Output/response data (optional)

Job Tracking

urblogjobstatus(level, function_name, job_name, status, input_json=None)

  • Purpose: Track job lifecycle (Started, Completed, Failed)
  • Example: urblogjobstatus(LOGLEVELS.INFO, "ProcessPayments", "MonthlyBatch", "Started")

urblogjobprogress(level, function_name, item_id, current, total, input_json=None)

  • Purpose: Track progress through collections/batches
  • Example: urblogjobprogress(LOGLEVELS.INFO, "ProcessPayments", "payment-123", 5, 100)

Log Levels

Level Purpose Usage Example
LOGLEVELS.TRACE Detailed debugging Successful operations with full context
LOGLEVELS.DEBUG Development info Function entry/exit, data flow
LOGLEVELS.INFO Important events Business logic, progress tracking
LOGLEVELS.WARN Potential issues Missing optional parameters, retries
LOGLEVELS.ERROR Actual failures API errors, validation failures
LOGLEVELS.FATAL Critical failures System crashes, data corruption

Output Format

All logs are structured JSON with consistent fields:

{
  "timestamp": "2025-07-04T12:54:34.447Z",
  "level": "info",
  "systemId": "payment-service", 
  "functionName": "ProcessPayment",
  "correlationId": "e804d7c4-4592-42e6-9923-ab4dad45f41f",
  "message": "Payment processed successfully",
  "inputJSON": {"userId": "12345", "amount": 100.00},
  "responseJSON": {"transactionId": "tx-789", "status": "completed"}
}

Environment Configuration

Create .env.development (or use setup script):

# Logging configuration
LOG_TO_FILE=true
LOG_FILE_PATH=./logs/dev.log
LOG_LEVEL=INFO

# OpenTelemetry OTLP Export (production-ready)
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://localhost:4318/v1/traces
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=http://localhost:4318/v1/logs
OTEL_ENVIRONMENT=development

# Environment
PYTHON_ENV=development

Dependencies

Core dependencies installed automatically:

  • structlog ≥23.1.0 - Structured logging framework
  • opentelemetry-api ≥1.21.0 - OpenTelemetry API for tracing
  • opentelemetry-sdk ≥1.21.0 - OpenTelemetry SDK
  • opentelemetry-exporter-otlp-proto-http ≥1.21.0 - OTLP HTTP exporter
  • opentelemetry-sdk-logs ≥1.21.0 - OpenTelemetry logs SDK
  • opentelemetry-api-logs ≥1.21.0 - OpenTelemetry logs API
  • opentelemetry-instrumentation-auto ≥1.21.0 - Auto-instrumentation
  • requests ≥2.31.0 - HTTP client library

Production Usage

OTLP Export (Recommended)

import os
# Configure OTLP endpoints for production observability stack
os.environ['OTEL_EXPORTER_OTLP_TRACES_ENDPOINT'] = 'https://your-otel-collector.com/v1/traces'
os.environ['OTEL_EXPORTER_OTLP_LOGS_ENDPOINT'] = 'https://your-otel-collector.com/v1/logs'
os.environ['OTEL_ENVIRONMENT'] = 'production'

from urbalurba_logging import urbinitializelogger, urbflushlog
urbinitializelogger("production-service")

# Your application code here...

# Graceful shutdown
urbflushlog()

Multiple Transports (Console + File + OTLP)

import os
# Enable all transports simultaneously
os.environ['LOG_TO_FILE'] = 'true'
os.environ['LOG_FILE_PATH'] = '/var/log/myapp/app.log'
os.environ['OTEL_EXPORTER_OTLP_TRACES_ENDPOINT'] = 'https://your-otel-collector.com/v1/traces'
os.environ['OTEL_EXPORTER_OTLP_LOGS_ENDPOINT'] = 'https://your-otel-collector.com/v1/logs'

from urbalurba_logging import urbinitializelogger, urbflushlog
urbinitializelogger("production-service")

File Logging Only

import os
os.environ['LOG_TO_FILE'] = 'true'
os.environ['LOG_FILE_PATH'] = '/var/log/myapp/app.log'

from urbalurba_logging import urbinitializelogger, urbflushlog
urbinitializelogger("production-service")

Best Practices

  1. Function Names: Use constants for consistent identification

    FUNCTIONNAME = "ProcessPayment"  # Use PascalCase
    
  2. Context Data: Include relevant input/output for debugging

    urblog(LOGLEVELS.INFO, FUNCTIONNAME, "User authenticated", None,
           {"userId": user_id}, {"sessionId": session.id})
    
  3. Error Handling: Always include exception objects

    except Exception as error:
        urblog(LOGLEVELS.ERROR, FUNCTIONNAME, "Authentication failed", error)
    
  4. Job Processing: Track lifecycle and progress

    urblogjobstatus(LOGLEVELS.INFO, FUNCTIONNAME, "DataExport", "Started")
    for item in items:
        urblogjobprogress(LOGLEVELS.INFO, FUNCTIONNAME, item.id, current, total)
    urblogjobstatus(LOGLEVELS.INFO, FUNCTIONNAME, "DataExport", "Completed")
    
  5. Graceful Shutdown: Always flush logs before exit

    from urbalurba_logging import urbflushlog
    
    try:
        # Application code here
        pass
    finally:
        urbflushlog()  # Ensures all logs are sent to OTLP collector
    

Architecture

The Python implementation uses the same architecture as TypeScript:

structlog → OpenTelemetry → OTLP (logs + traces)

Key Components:

  • structlog: Primary logging framework (like Winston in TypeScript)
  • OpenTelemetry Processor: Custom processor for OpenTelemetry integration
  • Multiple Transports: Console, file, and OTLP export simultaneous operation
  • Full SDK Configuration: Traces, logs, and auto-instrumentation
  • Graceful Shutdown: urbflushlog() ensures data delivery

Testing

The implementation includes comprehensive testing:

  1. Demo Application: Real-world Norwegian Brreg API integration
  2. Library Tests: All logging scenarios and error handling
  3. Setup Scripts: Interactive environment configuration
  4. Integration Tests: OTLP export verified with live observability stack

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

urbalurba_logging-1.0.1.tar.gz (19.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

urbalurba_logging-1.0.1-py3-none-any.whl (17.8 kB view details)

Uploaded Python 3

File details

Details for the file urbalurba_logging-1.0.1.tar.gz.

File metadata

  • Download URL: urbalurba_logging-1.0.1.tar.gz
  • Upload date:
  • Size: 19.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.11.13

File hashes

Hashes for urbalurba_logging-1.0.1.tar.gz
Algorithm Hash digest
SHA256 30447e32471be377c5f3019e2d8747446a4bdcb87a35be77d1088feac0907cdf
MD5 d1db6bfab2f88875a03e314c682955d3
BLAKE2b-256 6df6eb017483b7178a916324eb429f20d3dfa8e4f4138aef517e10ac38ee8185

See more details on using hashes here.

File details

Details for the file urbalurba_logging-1.0.1-py3-none-any.whl.

File metadata

File hashes

Hashes for urbalurba_logging-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 7d54af4075f6537e76fdd3e5634b532588f1700f46a53cf72c8b6854f18b48ff
MD5 27cb96bdabd542fb424259100e24f690
BLAKE2b-256 d1d01d537eeea3fc55bb2a1b8c85392c38c7940b982550212caae242d8b0d8b5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page