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.5.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.5-py3-none-any.whl (17.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: urbalurba_logging-1.0.5.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.5.tar.gz
Algorithm Hash digest
SHA256 2cf5d9d5ee8515808440260ddfafd4811343ac6a3cccd0c8e8cafe8ad884043c
MD5 e24d4ce655509be1570a224ef5940545
BLAKE2b-256 5023955476971b27817830629d696cf524b329eeb9402a801d6e42495a431c09

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for urbalurba_logging-1.0.5-py3-none-any.whl
Algorithm Hash digest
SHA256 5f6e1d4ee95b175deff9a8d47be51104b2fe514351a0c4f78dc22f6f7b6143e4
MD5 3560fc2b3cdd56a348f81877fdb1cbc5
BLAKE2b-256 1857ce8c82ea3c9fbca13df58660ad2da2a58ee1c36c48d08280d9154c1227fe

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