urbalurba-logging


Nameurbalurba-logging JSON
Version 1.0.0 PyPI version JSON
download
home_pagehttps://github.com/terchris/urbalurba-logging
SummaryProfessional structured logging library following 'Loggeloven av 2025' requirements
upload_time2025-08-26 07:06:51
maintainerNone
docs_urlNone
authorTerje Christensen
requires_python>=3.8
licenseNone
keywords logging structured-logging json opentelemetry azure-monitor observability
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # 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:
- **Repository**: https://github.com/terchris/urbalurba-logging  
- **Python Package**: https://github.com/terchris/urbalurba-logging/tree/main/python

## Installation

### From Source (Current Method)
```bash
git clone https://github.com/terchris/urbalurba-logging.git
cd urbalurba-logging/python
pip install -e .
```

### From PyPI
```bash
pip install urbalurba-logging
```

## Quick Start

### 1. Initialize Logger (Required)
```python
from urbalurba_logging import urbinitializelogger, urblog, LOGLEVELS

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

### 2. Basic Logging
```python
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
```python
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
```python
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
```bash
git clone https://github.com/terchris/urbalurba-logging.git
cd urbalurba-logging/python/examples/demo
```

### Step 2: Install Dependencies
```bash
# Install demo dependencies
pip install -r requirements.txt

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

### Step 3: Configure Environment
```bash
# 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
```bash
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:

```json
{
  "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):

```bash
# 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)
```python
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)
```python
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
```python
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
   ```python
   FUNCTIONNAME = "ProcessPayment"  # Use PascalCase
   ```

2. **Context Data**: Include relevant input/output for debugging
   ```python
   urblog(LOGLEVELS.INFO, FUNCTIONNAME, "User authenticated", None,
          {"userId": user_id}, {"sessionId": session.id})
   ```

3. **Error Handling**: Always include exception objects
   ```python
   except Exception as error:
       urblog(LOGLEVELS.ERROR, FUNCTIONNAME, "Authentication failed", error)
   ```

4. **Job Processing**: Track lifecycle and progress
   ```python
   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
   ```python
   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

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/terchris/urbalurba-logging",
    "name": "urbalurba-logging",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": "logging, structured-logging, json, opentelemetry, azure-monitor, observability",
    "author": "Terje Christensen",
    "author_email": "Terje Christensen <integration-platform@redcross.no>",
    "download_url": "https://files.pythonhosted.org/packages/cf/16/fd7fb687e8df840ca735db2ca85b9db5d333a69d995dd9ce6cdb55239712/urbalurba_logging-1.0.0.tar.gz",
    "platform": null,
    "description": "# Urbalurba Logging - Python Implementation\n\nProfessional 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.\n\n## \u2705 Current Status: **PRODUCTION READY**\n\n- **\ud83c\udf89 Complete Feature Parity**: Matches TypeScript Winston \u2192 OpenTelemetry architecture\n- **\ud83d\udce1 OTLP Export**: Fully functional logs + traces export to observability stack\n- **\ud83d\udd04 Multiple Transports**: Simultaneous console + file + OTLP logging\n- **\ud83e\uddea Comprehensive Testing**: Demo, library tests, and real-world validation complete\n- **\ud83d\udcca Live Verification**: Successfully integrated with Loki + Grafana observability stack\n\n## Repository\n\nThis package is part of the multi-language Urbalurba logging system:\n- **Repository**: https://github.com/terchris/urbalurba-logging  \n- **Python Package**: https://github.com/terchris/urbalurba-logging/tree/main/python\n\n## Installation\n\n### From Source (Current Method)\n```bash\ngit clone https://github.com/terchris/urbalurba-logging.git\ncd urbalurba-logging/python\npip install -e .\n```\n\n### From PyPI\n```bash\npip install urbalurba-logging\n```\n\n## Quick Start\n\n### 1. Initialize Logger (Required)\n```python\nfrom urbalurba_logging import urbinitializelogger, urblog, LOGLEVELS\n\n# Initialize once at application startup\nurbinitializelogger(\"your-system-id\")\n```\n\n### 2. Basic Logging\n```python\nFUNCTIONNAME = \"MyFunction\"\n\n# Simple logging\nurblog(LOGLEVELS.INFO, FUNCTIONNAME, \"Processing completed\", None)\n\n# With context data\nurblog(LOGLEVELS.INFO, FUNCTIONNAME, \"User created\", None, \n       {\"userId\": \"12345\"}, {\"status\": \"success\"})\n\n# Error logging with exception\ntry:\n    # some operation\n    pass\nexcept Exception as error:\n    urblog(LOGLEVELS.ERROR, FUNCTIONNAME, \"Operation failed\", error)\n```\n\n### 3. Job Tracking\n```python\nfrom urbalurba_logging import urblogjobstatus, urblogjobprogress\n\nFUNCTIONNAME = \"ProcessData\"\n\n# Job lifecycle tracking\nurblogjobstatus(LOGLEVELS.INFO, FUNCTIONNAME, \"DataImport\", \"Started\")\nurblogjobprogress(LOGLEVELS.INFO, FUNCTIONNAME, \"item-1\", 1, 100)\nurblogjobstatus(LOGLEVELS.INFO, FUNCTIONNAME, \"DataImport\", \"Completed\")\n```\n\n### 4. Graceful Shutdown\n```python\nfrom urbalurba_logging import urbflushlog\n\n# Flush all logs before application exit\nurbflushlog()\n```\n\n## Running the Demo\n\nThe demo demonstrates real-world usage with API calls and comprehensive logging patterns.\n\n### Step 1: Clone and Navigate\n```bash\ngit clone https://github.com/terchris/urbalurba-logging.git\ncd urbalurba-logging/python/examples/demo\n```\n\n### Step 2: Install Dependencies\n```bash\n# Install demo dependencies\npip install -r requirements.txt\n\n# Install main package in development mode\npip install -e ../../\n```\n\n### Step 3: Configure Environment\n```bash\n# Run interactive setup (choose logging destination)\n./setup-dev-env.sh\n```\n\nChoose from three options:\n1. **Console Output** - JSON logs to terminal (good for development)\n2. **File Logging** - Logs to `./logs/dev.log` (good for analysis)  \n3. **OTLP Collector** - Export to observability stack (requires Docker)\n\n### Step 4: Run Demo\n```bash\npython demo.py\n```\n\n## Project Structure\n\n```\npython/\n\u251c\u2500\u2500 src/\n\u2502   \u2514\u2500\u2500 urbalurba_logging/\n\u2502       \u251c\u2500\u2500 __init__.py          # Package exports\n\u2502       \u251c\u2500\u2500 urblogger.py         # Core logging implementation  \n\u2502       \u2514\u2500\u2500 log_levels.py        # Log level constants\n\u251c\u2500\u2500 examples/\n\u2502   \u2514\u2500\u2500 demo/\n\u2502       \u251c\u2500\u2500 demo.py              # Complete working example\n\u2502       \u251c\u2500\u2500 requirements.txt     # Demo dependencies\n\u2502       \u251c\u2500\u2500 setup-dev-env.sh     # Development environment setup\n\u2502       \u2514\u2500\u2500 .env                 # Environment template\n\u251c\u2500\u2500 setup.py                     # PyPI package configuration\n\u251c\u2500\u2500 requirements.txt             # Main dependencies\n\u2514\u2500\u2500 README-python.md            # This documentation\n```\n\n## API Reference\n\n### Initialization\n\n**`urbinitializelogger(system_id: str)`**\n- **Required**: Must be called once at application startup\n- **Purpose**: Initialize logger with unique system identifier\n- **Example**: `urbinitializelogger(\"payment-service\")`\n\n### Core Logging\n\n**`urblog(level, function_name, message, exception, input_json=None, response_json=None)`**\n- **Purpose**: General purpose structured logging\n- **Parameters**:\n  - `level`: Use `LOGLEVELS` constants (INFO, ERROR, etc.)\n  - `function_name`: Name of calling function (use constant)\n  - `message`: Human-readable description\n  - `exception`: Exception object or None\n  - `input_json`: Input parameters/context (optional)\n  - `response_json`: Output/response data (optional)\n\n### Job Tracking\n\n**`urblogjobstatus(level, function_name, job_name, status, input_json=None)`**\n- **Purpose**: Track job lifecycle (Started, Completed, Failed)\n- **Example**: `urblogjobstatus(LOGLEVELS.INFO, \"ProcessPayments\", \"MonthlyBatch\", \"Started\")`\n\n**`urblogjobprogress(level, function_name, item_id, current, total, input_json=None)`**\n- **Purpose**: Track progress through collections/batches\n- **Example**: `urblogjobprogress(LOGLEVELS.INFO, \"ProcessPayments\", \"payment-123\", 5, 100)`\n\n### Log Levels\n\n| Level | Purpose | Usage Example |\n|-------|---------|---------------|\n| `LOGLEVELS.TRACE` | Detailed debugging | Successful operations with full context |\n| `LOGLEVELS.DEBUG` | Development info | Function entry/exit, data flow |\n| `LOGLEVELS.INFO` | Important events | Business logic, progress tracking |\n| `LOGLEVELS.WARN` | Potential issues | Missing optional parameters, retries |\n| `LOGLEVELS.ERROR` | Actual failures | API errors, validation failures |\n| `LOGLEVELS.FATAL` | Critical failures | System crashes, data corruption |\n\n## Output Format\n\nAll logs are structured JSON with consistent fields:\n\n```json\n{\n  \"timestamp\": \"2025-07-04T12:54:34.447Z\",\n  \"level\": \"info\",\n  \"systemId\": \"payment-service\", \n  \"functionName\": \"ProcessPayment\",\n  \"correlationId\": \"e804d7c4-4592-42e6-9923-ab4dad45f41f\",\n  \"message\": \"Payment processed successfully\",\n  \"inputJSON\": {\"userId\": \"12345\", \"amount\": 100.00},\n  \"responseJSON\": {\"transactionId\": \"tx-789\", \"status\": \"completed\"}\n}\n```\n\n## Environment Configuration\n\nCreate `.env.development` (or use setup script):\n\n```bash\n# Logging configuration\nLOG_TO_FILE=true\nLOG_FILE_PATH=./logs/dev.log\nLOG_LEVEL=INFO\n\n# OpenTelemetry OTLP Export (production-ready)\nOTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://localhost:4318/v1/traces\nOTEL_EXPORTER_OTLP_LOGS_ENDPOINT=http://localhost:4318/v1/logs\nOTEL_ENVIRONMENT=development\n\n# Environment\nPYTHON_ENV=development\n```\n\n## Dependencies\n\nCore dependencies installed automatically:\n\n- **structlog** \u226523.1.0 - Structured logging framework\n- **opentelemetry-api** \u22651.21.0 - OpenTelemetry API for tracing  \n- **opentelemetry-sdk** \u22651.21.0 - OpenTelemetry SDK\n- **opentelemetry-exporter-otlp-proto-http** \u22651.21.0 - OTLP HTTP exporter\n- **opentelemetry-sdk-logs** \u22651.21.0 - OpenTelemetry logs SDK\n- **opentelemetry-api-logs** \u22651.21.0 - OpenTelemetry logs API\n- **opentelemetry-instrumentation-auto** \u22651.21.0 - Auto-instrumentation\n- **requests** \u22652.31.0 - HTTP client library\n\n## Production Usage\n\n### OTLP Export (Recommended)\n```python\nimport os\n# Configure OTLP endpoints for production observability stack\nos.environ['OTEL_EXPORTER_OTLP_TRACES_ENDPOINT'] = 'https://your-otel-collector.com/v1/traces'\nos.environ['OTEL_EXPORTER_OTLP_LOGS_ENDPOINT'] = 'https://your-otel-collector.com/v1/logs'\nos.environ['OTEL_ENVIRONMENT'] = 'production'\n\nfrom urbalurba_logging import urbinitializelogger, urbflushlog\nurbinitializelogger(\"production-service\")\n\n# Your application code here...\n\n# Graceful shutdown\nurbflushlog()\n```\n\n### Multiple Transports (Console + File + OTLP)\n```python\nimport os\n# Enable all transports simultaneously\nos.environ['LOG_TO_FILE'] = 'true'\nos.environ['LOG_FILE_PATH'] = '/var/log/myapp/app.log'\nos.environ['OTEL_EXPORTER_OTLP_TRACES_ENDPOINT'] = 'https://your-otel-collector.com/v1/traces'\nos.environ['OTEL_EXPORTER_OTLP_LOGS_ENDPOINT'] = 'https://your-otel-collector.com/v1/logs'\n\nfrom urbalurba_logging import urbinitializelogger, urbflushlog\nurbinitializelogger(\"production-service\")\n```\n\n### File Logging Only\n```python\nimport os\nos.environ['LOG_TO_FILE'] = 'true'\nos.environ['LOG_FILE_PATH'] = '/var/log/myapp/app.log'\n\nfrom urbalurba_logging import urbinitializelogger, urbflushlog\nurbinitializelogger(\"production-service\")\n```\n\n## Best Practices\n\n1. **Function Names**: Use constants for consistent identification\n   ```python\n   FUNCTIONNAME = \"ProcessPayment\"  # Use PascalCase\n   ```\n\n2. **Context Data**: Include relevant input/output for debugging\n   ```python\n   urblog(LOGLEVELS.INFO, FUNCTIONNAME, \"User authenticated\", None,\n          {\"userId\": user_id}, {\"sessionId\": session.id})\n   ```\n\n3. **Error Handling**: Always include exception objects\n   ```python\n   except Exception as error:\n       urblog(LOGLEVELS.ERROR, FUNCTIONNAME, \"Authentication failed\", error)\n   ```\n\n4. **Job Processing**: Track lifecycle and progress\n   ```python\n   urblogjobstatus(LOGLEVELS.INFO, FUNCTIONNAME, \"DataExport\", \"Started\")\n   for item in items:\n       urblogjobprogress(LOGLEVELS.INFO, FUNCTIONNAME, item.id, current, total)\n   urblogjobstatus(LOGLEVELS.INFO, FUNCTIONNAME, \"DataExport\", \"Completed\")\n   ```\n\n5. **Graceful Shutdown**: Always flush logs before exit\n   ```python\n   from urbalurba_logging import urbflushlog\n   \n   try:\n       # Application code here\n       pass\n   finally:\n       urbflushlog()  # Ensures all logs are sent to OTLP collector\n   ```\n\n## Architecture\n\nThe Python implementation uses the same architecture as TypeScript:\n\n```\nstructlog \u2192 OpenTelemetry \u2192 OTLP (logs + traces)\n```\n\n**Key Components:**\n- **structlog**: Primary logging framework (like Winston in TypeScript)\n- **OpenTelemetry Processor**: Custom processor for OpenTelemetry integration\n- **Multiple Transports**: Console, file, and OTLP export simultaneous operation\n- **Full SDK Configuration**: Traces, logs, and auto-instrumentation\n- **Graceful Shutdown**: `urbflushlog()` ensures data delivery\n\n## Testing\n\nThe implementation includes comprehensive testing:\n\n1. **Demo Application**: Real-world Norwegian Brreg API integration\n2. **Library Tests**: All logging scenarios and error handling\n3. **Setup Scripts**: Interactive environment configuration\n4. **Integration Tests**: OTLP export verified with live observability stack\n\n## License\n\nMIT\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Professional structured logging library following 'Loggeloven av 2025' requirements",
    "version": "1.0.0",
    "project_urls": {
        "Bug Tracker": "https://github.com/terchris/urbalurba-logging/issues",
        "Documentation": "https://github.com/terchris/urbalurba-logging/blob/main/python/README-python.md",
        "Homepage": "https://github.com/terchris/urbalurba-logging",
        "Source Code": "https://github.com/terchris/urbalurba-logging/tree/main/python"
    },
    "split_keywords": [
        "logging",
        " structured-logging",
        " json",
        " opentelemetry",
        " azure-monitor",
        " observability"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "66eebcc710fdd54730f48ae675803b47b2dc604b98ee17ff2af5edd3d13596f0",
                "md5": "1269422f84042209f442ee5e0da171f1",
                "sha256": "9af340c04f26c9005622a646bec15e867e87e4280fe927775426f31dc066e386"
            },
            "downloads": -1,
            "filename": "urbalurba_logging-1.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "1269422f84042209f442ee5e0da171f1",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 17808,
            "upload_time": "2025-08-26T07:06:50",
            "upload_time_iso_8601": "2025-08-26T07:06:50.596177Z",
            "url": "https://files.pythonhosted.org/packages/66/ee/bcc710fdd54730f48ae675803b47b2dc604b98ee17ff2af5edd3d13596f0/urbalurba_logging-1.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "cf16fd7fb687e8df840ca735db2ca85b9db5d333a69d995dd9ce6cdb55239712",
                "md5": "f2a8fbbcf6ca39a90088139ca739abf3",
                "sha256": "f77b286bab65f53e121e4c37019121e0b12075174668a16b81350de998ceb612"
            },
            "downloads": -1,
            "filename": "urbalurba_logging-1.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "f2a8fbbcf6ca39a90088139ca739abf3",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 20343,
            "upload_time": "2025-08-26T07:06:51",
            "upload_time_iso_8601": "2025-08-26T07:06:51.833104Z",
            "url": "https://files.pythonhosted.org/packages/cf/16/fd7fb687e8df840ca735db2ca85b9db5d333a69d995dd9ce6cdb55239712/urbalurba_logging-1.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-26 07:06:51",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "terchris",
    "github_project": "urbalurba-logging",
    "github_not_found": true,
    "lcname": "urbalurba-logging"
}
        
Elapsed time: 0.71046s