otel-observability


Nameotel-observability JSON
Version 0.1.5 PyPI version JSON
download
home_pagehttps://github.com/Touzi-Mortadha/otel-observability
SummaryA unified OpenTelemetry observability package for Python applications
upload_time2025-10-26 19:51:22
maintainerNone
docs_urlNone
authorMortada Touzi
requires_python>=3.8
licenseAGPL-3.0
keywords opentelemetry observability logging metrics tracing monitoring
VCS
bugtrack_url
requirements opentelemetry-api opentelemetry-sdk opentelemetry-exporter-otlp setuptools pytest pytest-cov pylint
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # OTEL Observability Package
[![Pytest](https://github.com/Touzi-Mortadha/otel-observability/actions/workflows/pytest.yml/badge.svg)](https://github.com/Touzi-Mortadha/otel-observability/actions/workflows/pytest.yml)
[![Pylint](https://github.com/Touzi-Mortadha/otel-observability/actions/workflows/pylint.yml/badge.svg)](https://github.com/Touzi-Mortadha/otel-observability/actions/workflows/pylint.yml)
[![Upload Python Package](https://github.com/Touzi-Mortadha/otel-observability/actions/workflows/python-publish.yml/badge.svg)](https://github.com/Touzi-Mortadha/otel-observability/actions/workflows/python-publish.yml)

A unified OpenTelemetry observability package for Python applications that provides easy-to-use logging, metrics, and tracing with best practices.

## Features

- **Unified Configuration**: Configure all observability components through environment variables or programmatic configuration
- **Multiple Exporters**: Support for OTLP (gRPC), HTTP, and Console exporters
- **Thread-Safe**: Singleton pattern ensures thread-safe initialization
- **Easy Integration**: Simple API for logging, metrics, and tracing
- **Decorators**: Built-in decorators for automatic tracing, logging, and trace propagation

## Installation

### From PyPI

```bash
pip install otel-observability
```

### From Source

```bash
git clone https://github.com/Touzi-Mortadha/otel-observability.git
cd otel-observability
pip install -e .
```

## Quick Start

### Basic Usage with Environment Variables

```python
from otel_observability import initialize_observability, get_logger, get_metrics, get_traces

# Initialize observability (reads from environment variables)
manager = initialize_observability()

# Get a logger
logger = get_logger(__name__)
logger.info("Application started")

# Get a meter for metrics
meter = get_metrics("my_app")
request_counter = meter.create_counter("requests_total", description="Total requests")
request_counter.add(1, {"endpoint": "/api"})

# Get a tracer for distributed tracing
tracer = get_traces("my_app")
with tracer.start_as_current_span("process_request") as span:
    span.set_attribute("user.id", "123")
    logger.info("Processing request")
```

### Programmatic Configuration

```python
from otel_observability import ObservabilityManager, ObservabilityConfig

# Create custom configuration
config = ObservabilityConfig(
    app_name="my-app",
    component="test-component",
    otlp_endpoint="localhost:4317",  # OTLP gRPC endpoint
    log_level=LogLevel.INFO,
    insecure=True,
)

# Initialize with custom config
manager = ObservabilityManager(config)
manager.initialize_all()

# Use the manager directly
logger = manager.get_logger(__name__)
meter = manager.get_meter("my_app")
tracer = manager.get_tracer("my_app")
```

### Using Decorators

```python
from otel_observability import ObservabilityDecorators

@ObservabilityDecorators.trace_method()
@ObservabilityDecorators.log_execution()
def process_data(data):
    """Process data with automatic tracing and logging."""
    logger.info(f"Processing data: {data}")
    return {"processed": True, **data}

result = process_data({"input": "test"})
```

### Trace Propagation

The `@trace_propagator()` decorator is useful for propagating trace context from incoming requests (e.g., HTTP headers, message queues) and creating child spans:

```python
from otel_observability import ObservabilityDecorators
from opentelemetry.propagate import inject

@ObservabilityDecorators.trace_propagator()
def handle_incoming_request(carrier, payload):
    """
    Handle incoming request with trace context propagation.
    
    Args:
        carrier: Dictionary containing trace context (e.g., HTTP headers)
        payload: The actual request payload
    """
    # This function will automatically:
    # 1. Extract trace context from the carrier dictionary
    # 2. Create a new span as part of the existing trace
    # 3. Execute the function within the trace context
    # 4. Clean up the context after execution
    
    logger.info(f"Processing payload: {payload}")
    return {"status": "success", "data": payload}

# Example usage with W3C trace context
trace_carrier = {}
inject(carrier=trace_carrier)

payload = {"user_id": 123, "action": "login"}

result = handle_incoming_request(trace_carrier, payload)
```

You can also use multiple decorators together:

```python
@ObservabilityDecorators.trace_propagator()
@ObservabilityDecorators.log_execution(logger_name="api_handler")
def api_endpoint_handler(headers, body):
    """Handle API endpoint with trace propagation and logging."""
    # The trace_propagator will extract context from headers
    # The log_execution will log method entry and exit
    return process_business_logic(body)
```

## Configuration

### Environment Variables

| Variable | Description | Default |
|----------|-------------|---------|
| `OTEL_APP_NAME` | App name for resource attributes | `unknown-service` |
| `OTEL_COMPONENT_NAME` | service name for resource attributes | `unknown-component` |
| `OTEL_GRPC_URL` | OTLP gRPC endpoint URL | None |
| `OTEL_HTTP_URL` | Base HTTP URL for OTLP HTTP exporters | None |
| `OTEL_HTTP_LOGS_URL` | Specific HTTP URL for logs | `{OTEL_HTTP_URL}/v1/logs` |
| `OTEL_HTTP_TRACES_URL` | Specific HTTP URL for traces | `{OTEL_HTTP_URL}/v1/traces` |
| `OTEL_HTTP_METRICS_URL` | Specific HTTP URL for metrics | `{OTEL_HTTP_URL}/v1/metrics` |
| `OTEL_INSECURE` | Use insecure connection for gRPC | `true` |
| `LOG_LEVEL` | Log level (DEBUG, INFO, WARNING, ERROR, CRITICAL) | `INFO` |
| `OTEL_METRIC_EXPORT_INTERVAL_MS` | Metrics export interval in milliseconds | `60000` |
| `ENABLE_CONSOLE_DEBUG` | Enable console output for debugging | `false` |

### Programmatic Configuration

Create an `ObservabilityConfig` instance with the following parameters:

- `app_name`: Your app name (required)
- `component`: Your service name (required)
- `otlp_endpoint`: OTLP gRPC endpoint URL
- `http_logs_url`: HTTP endpoint for logs
- `http_traces_url`: HTTP endpoint for traces  
- `http_metrics_url`: HTTP endpoint for metrics
- `insecure`: Use insecure connection (default: True)
- `log_level`: Log level (default: LogLevel.INFO)
- `metric_export_interval_ms`: Metrics export interval (default: 60000)
- `enable_console_debug`: Enable console debugging (default: False)

## API Reference

### Core Functions

- `initialize_observability()`: Initialize all components and return manager
- `get_logger(name)`: Get a configured logger instance
- `get_metrics(name, version)`: Get a meter for creating metrics
- `get_traces(name, version)`: Get a tracer for creating spans

### ObservabilityManager

The main manager class providing:

- `get_logger(name)`: Get logger by name
- `get_meter(name, version)`: Get meter by name and version
- `get_tracer(name, version)`: Get tracer by name and version
- `create_counter()`: Create a counter metric
- `create_histogram()`: Create a histogram metric
- `shutdown()`: Gracefully shutdown all providers

### ObservabilityDecorators

- `@trace_method()`: Automatically trace method execution
- `@log_execution()`: Automatically log method execution
- `@trace_propagator()`: Propagate trace context from carrier and create spans

## Examples

### Flask Application

```python
from flask import Flask
from otel_observability import initialize_observability, get_logger, ObservabilityDecorators

app = Flask(__name__)
manager = initialize_observability()
logger = get_logger(__name__)

@app.route('/')
@ObservabilityDecorators.trace_method()
def hello():
    logger.info("Hello endpoint called")
    return "Hello World!"

if __name__ == '__main__':
    app.run()
```

### FastAPI Application

```python
from fastapi import FastAPI
from otel_observability import initialize_observability, get_logger, get_traces

app = FastAPI()
manager = initialize_observability()
logger = get_logger(__name__)
tracer = get_traces("fastapi_app")

@app.get("/")
async def read_root():
    with tracer.start_as_current_span("read_root"):
        logger.info("Root endpoint called")
        return {"Hello": "World"}

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/Touzi-Mortadha/otel-observability",
    "name": "otel-observability",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": "opentelemetry, observability, logging, metrics, tracing, monitoring",
    "author": "Mortada Touzi",
    "author_email": "Mortada Touzi <mortada.touzi@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/b3/60/0e4b41681bf011a8baf0530b0e3b8cee684ec0dd7696ba819577e3d7d792/otel_observability-0.1.5.tar.gz",
    "platform": null,
    "description": "# OTEL Observability Package\n[![Pytest](https://github.com/Touzi-Mortadha/otel-observability/actions/workflows/pytest.yml/badge.svg)](https://github.com/Touzi-Mortadha/otel-observability/actions/workflows/pytest.yml)\n[![Pylint](https://github.com/Touzi-Mortadha/otel-observability/actions/workflows/pylint.yml/badge.svg)](https://github.com/Touzi-Mortadha/otel-observability/actions/workflows/pylint.yml)\n[![Upload Python Package](https://github.com/Touzi-Mortadha/otel-observability/actions/workflows/python-publish.yml/badge.svg)](https://github.com/Touzi-Mortadha/otel-observability/actions/workflows/python-publish.yml)\n\nA unified OpenTelemetry observability package for Python applications that provides easy-to-use logging, metrics, and tracing with best practices.\n\n## Features\n\n- **Unified Configuration**: Configure all observability components through environment variables or programmatic configuration\n- **Multiple Exporters**: Support for OTLP (gRPC), HTTP, and Console exporters\n- **Thread-Safe**: Singleton pattern ensures thread-safe initialization\n- **Easy Integration**: Simple API for logging, metrics, and tracing\n- **Decorators**: Built-in decorators for automatic tracing, logging, and trace propagation\n\n## Installation\n\n### From PyPI\n\n```bash\npip install otel-observability\n```\n\n### From Source\n\n```bash\ngit clone https://github.com/Touzi-Mortadha/otel-observability.git\ncd otel-observability\npip install -e .\n```\n\n## Quick Start\n\n### Basic Usage with Environment Variables\n\n```python\nfrom otel_observability import initialize_observability, get_logger, get_metrics, get_traces\n\n# Initialize observability (reads from environment variables)\nmanager = initialize_observability()\n\n# Get a logger\nlogger = get_logger(__name__)\nlogger.info(\"Application started\")\n\n# Get a meter for metrics\nmeter = get_metrics(\"my_app\")\nrequest_counter = meter.create_counter(\"requests_total\", description=\"Total requests\")\nrequest_counter.add(1, {\"endpoint\": \"/api\"})\n\n# Get a tracer for distributed tracing\ntracer = get_traces(\"my_app\")\nwith tracer.start_as_current_span(\"process_request\") as span:\n    span.set_attribute(\"user.id\", \"123\")\n    logger.info(\"Processing request\")\n```\n\n### Programmatic Configuration\n\n```python\nfrom otel_observability import ObservabilityManager, ObservabilityConfig\n\n# Create custom configuration\nconfig = ObservabilityConfig(\n    app_name=\"my-app\",\n    component=\"test-component\",\n    otlp_endpoint=\"localhost:4317\",  # OTLP gRPC endpoint\n    log_level=LogLevel.INFO,\n    insecure=True,\n)\n\n# Initialize with custom config\nmanager = ObservabilityManager(config)\nmanager.initialize_all()\n\n# Use the manager directly\nlogger = manager.get_logger(__name__)\nmeter = manager.get_meter(\"my_app\")\ntracer = manager.get_tracer(\"my_app\")\n```\n\n### Using Decorators\n\n```python\nfrom otel_observability import ObservabilityDecorators\n\n@ObservabilityDecorators.trace_method()\n@ObservabilityDecorators.log_execution()\ndef process_data(data):\n    \"\"\"Process data with automatic tracing and logging.\"\"\"\n    logger.info(f\"Processing data: {data}\")\n    return {\"processed\": True, **data}\n\nresult = process_data({\"input\": \"test\"})\n```\n\n### Trace Propagation\n\nThe `@trace_propagator()` decorator is useful for propagating trace context from incoming requests (e.g., HTTP headers, message queues) and creating child spans:\n\n```python\nfrom otel_observability import ObservabilityDecorators\nfrom opentelemetry.propagate import inject\n\n@ObservabilityDecorators.trace_propagator()\ndef handle_incoming_request(carrier, payload):\n    \"\"\"\n    Handle incoming request with trace context propagation.\n    \n    Args:\n        carrier: Dictionary containing trace context (e.g., HTTP headers)\n        payload: The actual request payload\n    \"\"\"\n    # This function will automatically:\n    # 1. Extract trace context from the carrier dictionary\n    # 2. Create a new span as part of the existing trace\n    # 3. Execute the function within the trace context\n    # 4. Clean up the context after execution\n    \n    logger.info(f\"Processing payload: {payload}\")\n    return {\"status\": \"success\", \"data\": payload}\n\n# Example usage with W3C trace context\ntrace_carrier = {}\ninject(carrier=trace_carrier)\n\npayload = {\"user_id\": 123, \"action\": \"login\"}\n\nresult = handle_incoming_request(trace_carrier, payload)\n```\n\nYou can also use multiple decorators together:\n\n```python\n@ObservabilityDecorators.trace_propagator()\n@ObservabilityDecorators.log_execution(logger_name=\"api_handler\")\ndef api_endpoint_handler(headers, body):\n    \"\"\"Handle API endpoint with trace propagation and logging.\"\"\"\n    # The trace_propagator will extract context from headers\n    # The log_execution will log method entry and exit\n    return process_business_logic(body)\n```\n\n## Configuration\n\n### Environment Variables\n\n| Variable | Description | Default |\n|----------|-------------|---------|\n| `OTEL_APP_NAME` | App name for resource attributes | `unknown-service` |\n| `OTEL_COMPONENT_NAME` | service name for resource attributes | `unknown-component` |\n| `OTEL_GRPC_URL` | OTLP gRPC endpoint URL | None |\n| `OTEL_HTTP_URL` | Base HTTP URL for OTLP HTTP exporters | None |\n| `OTEL_HTTP_LOGS_URL` | Specific HTTP URL for logs | `{OTEL_HTTP_URL}/v1/logs` |\n| `OTEL_HTTP_TRACES_URL` | Specific HTTP URL for traces | `{OTEL_HTTP_URL}/v1/traces` |\n| `OTEL_HTTP_METRICS_URL` | Specific HTTP URL for metrics | `{OTEL_HTTP_URL}/v1/metrics` |\n| `OTEL_INSECURE` | Use insecure connection for gRPC | `true` |\n| `LOG_LEVEL` | Log level (DEBUG, INFO, WARNING, ERROR, CRITICAL) | `INFO` |\n| `OTEL_METRIC_EXPORT_INTERVAL_MS` | Metrics export interval in milliseconds | `60000` |\n| `ENABLE_CONSOLE_DEBUG` | Enable console output for debugging | `false` |\n\n### Programmatic Configuration\n\nCreate an `ObservabilityConfig` instance with the following parameters:\n\n- `app_name`: Your app name (required)\n- `component`: Your service name (required)\n- `otlp_endpoint`: OTLP gRPC endpoint URL\n- `http_logs_url`: HTTP endpoint for logs\n- `http_traces_url`: HTTP endpoint for traces  \n- `http_metrics_url`: HTTP endpoint for metrics\n- `insecure`: Use insecure connection (default: True)\n- `log_level`: Log level (default: LogLevel.INFO)\n- `metric_export_interval_ms`: Metrics export interval (default: 60000)\n- `enable_console_debug`: Enable console debugging (default: False)\n\n## API Reference\n\n### Core Functions\n\n- `initialize_observability()`: Initialize all components and return manager\n- `get_logger(name)`: Get a configured logger instance\n- `get_metrics(name, version)`: Get a meter for creating metrics\n- `get_traces(name, version)`: Get a tracer for creating spans\n\n### ObservabilityManager\n\nThe main manager class providing:\n\n- `get_logger(name)`: Get logger by name\n- `get_meter(name, version)`: Get meter by name and version\n- `get_tracer(name, version)`: Get tracer by name and version\n- `create_counter()`: Create a counter metric\n- `create_histogram()`: Create a histogram metric\n- `shutdown()`: Gracefully shutdown all providers\n\n### ObservabilityDecorators\n\n- `@trace_method()`: Automatically trace method execution\n- `@log_execution()`: Automatically log method execution\n- `@trace_propagator()`: Propagate trace context from carrier and create spans\n\n## Examples\n\n### Flask Application\n\n```python\nfrom flask import Flask\nfrom otel_observability import initialize_observability, get_logger, ObservabilityDecorators\n\napp = Flask(__name__)\nmanager = initialize_observability()\nlogger = get_logger(__name__)\n\n@app.route('/')\n@ObservabilityDecorators.trace_method()\ndef hello():\n    logger.info(\"Hello endpoint called\")\n    return \"Hello World!\"\n\nif __name__ == '__main__':\n    app.run()\n```\n\n### FastAPI Application\n\n```python\nfrom fastapi import FastAPI\nfrom otel_observability import initialize_observability, get_logger, get_traces\n\napp = FastAPI()\nmanager = initialize_observability()\nlogger = get_logger(__name__)\ntracer = get_traces(\"fastapi_app\")\n\n@app.get(\"/\")\nasync def read_root():\n    with tracer.start_as_current_span(\"read_root\"):\n        logger.info(\"Root endpoint called\")\n        return {\"Hello\": \"World\"}\n",
    "bugtrack_url": null,
    "license": "AGPL-3.0",
    "summary": "A unified OpenTelemetry observability package for Python applications",
    "version": "0.1.5",
    "project_urls": {
        "Bug Tracker": "https://github.com/Touzi-Mortadha/otel-observability/issues",
        "Homepage": "https://github.com/Touzi-Mortadha/otel-observability"
    },
    "split_keywords": [
        "opentelemetry",
        " observability",
        " logging",
        " metrics",
        " tracing",
        " monitoring"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "893a7320c95420c241cc4280022e0d6180d012e3d341377b162f2ea644e5d673",
                "md5": "32e99d0bfbdaae1764103ffab0c4055a",
                "sha256": "7b2e9d31ab4d8edc307f5575f8bdff195b3d9e3c2f8cbe80bd774c66018aaf15"
            },
            "downloads": -1,
            "filename": "otel_observability-0.1.5-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "32e99d0bfbdaae1764103ffab0c4055a",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 25362,
            "upload_time": "2025-10-26T19:51:21",
            "upload_time_iso_8601": "2025-10-26T19:51:21.054426Z",
            "url": "https://files.pythonhosted.org/packages/89/3a/7320c95420c241cc4280022e0d6180d012e3d341377b162f2ea644e5d673/otel_observability-0.1.5-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "b3600e4b41681bf011a8baf0530b0e3b8cee684ec0dd7696ba819577e3d7d792",
                "md5": "ad09a859a66323f9cafb705d61c0a554",
                "sha256": "6b15b87f67490d2a6f1a5fe94a0733773e4cc4b89f2eb0f8530796904abbbe40"
            },
            "downloads": -1,
            "filename": "otel_observability-0.1.5.tar.gz",
            "has_sig": false,
            "md5_digest": "ad09a859a66323f9cafb705d61c0a554",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 30491,
            "upload_time": "2025-10-26T19:51:22",
            "upload_time_iso_8601": "2025-10-26T19:51:22.610069Z",
            "url": "https://files.pythonhosted.org/packages/b3/60/0e4b41681bf011a8baf0530b0e3b8cee684ec0dd7696ba819577e3d7d792/otel_observability-0.1.5.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-10-26 19:51:22",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "Touzi-Mortadha",
    "github_project": "otel-observability",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [
        {
            "name": "opentelemetry-api",
            "specs": [
                [
                    "==",
                    "1.38.0"
                ]
            ]
        },
        {
            "name": "opentelemetry-sdk",
            "specs": [
                [
                    "==",
                    "1.38.0"
                ]
            ]
        },
        {
            "name": "opentelemetry-exporter-otlp",
            "specs": [
                [
                    "==",
                    "1.38.0"
                ]
            ]
        },
        {
            "name": "setuptools",
            "specs": [
                [
                    "==",
                    "80.9.0"
                ]
            ]
        },
        {
            "name": "pytest",
            "specs": [
                [
                    "==",
                    "8.4.2"
                ]
            ]
        },
        {
            "name": "pytest-cov",
            "specs": [
                [
                    "==",
                    "7.0.0"
                ]
            ]
        },
        {
            "name": "pylint",
            "specs": [
                [
                    "==",
                    "4.0.2"
                ]
            ]
        }
    ],
    "lcname": "otel-observability"
}
        
Elapsed time: 3.07890s