# 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"
}