Python SDK for Platform Observability log ingestion and analytics
Project description
Platform Observability Python SDK
A Python SDK for ingesting logs and interacting with the Platform Observability service by Red Duck Labs.
Installation
From PyPI (after publishing)
pip install redducklabs-platform-observability-sdk
From Source (Development)
cd sdks/python
pip install -e .
Quick Start
Basic Usage
from platform_observability import ObservabilityClient, LogEntry, LogLevel
# Initialize client
client = ObservabilityClient(
api_key="YOUR_API_KEY",
base_url="https://observability.redducklabs.com/api/v1"
)
# Send a single log
client.ingest_log(
message="Application started",
level=LogLevel.INFO,
source="my-application",
labels={"app": "my-app", "environment": "production"},
fields={"version": "1.0.0", "user_id": "user123"}
)
Using the ObservabilityLogger (Recommended)
The ObservabilityLogger provides a higher-level interface with automatic batching and Python logging integration:
from platform_observability import ObservabilityLogger
# Initialize logger with labels for Grafana filtering
logger = ObservabilityLogger(
api_key="YOUR_API_KEY",
name="my-logger",
base_url="https://observability.redducklabs.com/api/v1",
source="my-application",
labels={
"app": "my-app",
"environment": "production",
"version": "1.0.0"
},
batch_size=100, # Batch up to 100 logs
flush_interval=5 # Auto-flush every 5 seconds
)
# Log messages with different levels
logger.info("User logged in", user_id="user123", ip="192.168.1.1")
logger.warning("High memory usage", memory_percent=85.5)
logger.error("Failed to connect to database", error_code="DB_CONN_FAILED")
# Ensure all logs are sent before exit
logger.flush()
logger.close()
Configuration
Environment Variables
You can configure the SDK using environment variables:
# Required
export RDL_API_KEY="your_api_key_here"
# Optional
export RDL_LOG_ENDPOINT="https://observability.redducklabs.com/api/v1"
export RDL_BATCH_SIZE="100"
export RDL_FLUSH_INTERVAL="5.0"
Then use them in your code:
import os
from platform_observability import ObservabilityLogger
logger = ObservabilityLogger(
api_key=os.getenv('RDL_API_KEY'),
base_url=os.getenv('RDL_LOG_ENDPOINT', 'https://observability.redducklabs.com/api/v1'),
source="my-app",
labels={"app": "my-app", "environment": os.getenv('ENVIRONMENT', 'dev')}
)
Important Concepts
Labels vs Fields
Labels (low-cardinality, indexed):
- Used for filtering and querying in Grafana
- Should have limited unique values
- Examples:
app,environment,version,region
Fields (high-cardinality, not indexed):
- Additional context for debugging
- Can have many unique values
- Examples:
user_id,request_id,duration_ms
Log Format
Logs are sent in this format:
{
"message": "User action completed",
"level": "info",
"source": "my-app",
"labels": {
"app": "my-app",
"environment": "production"
},
"fields": {
"user_id": "user123",
"action": "purchase",
"amount": 99.99
},
"timestamp": "2024-01-25T10:30:00Z"
}
Querying Logs in Grafana
Once logs are ingested, query them in Grafana using LogQL:
# All logs from your app
{app="my-app"}
# Filter by environment
{app="my-app", environment="production"}
# Search for errors
{app="my-app"} |= "error"
# Parse JSON and filter
{app="my-app"} | json | user_id="user123"
Advanced Usage
Custom Batching
client = ObservabilityClient(
api_key="YOUR_API_KEY",
base_url="https://observability.redducklabs.com/api/v1",
batch_size=200, # Larger batches
batch_timeout=10.0, # Wait longer before sending
enable_batching=True # Enable automatic batching
)
# Add logs to batch queue
for i in range(100):
client.add_to_batch(
message=f"Log entry {i}",
level=LogLevel.INFO,
source="batch-test"
)
# Manually flush when needed
client.flush_batch()
Error Handling
from platform_observability import ObservabilityClient
from platform_observability.exceptions import (
AuthenticationError,
RateLimitError,
ValidationError
)
client = ObservabilityClient(
api_key="YOUR_API_KEY",
skip_connection_check=True # Skip initial health check
)
try:
client.ingest_log("Test message", level="info")
except AuthenticationError:
print("Invalid API key")
except RateLimitError:
print("Rate limit exceeded, retry later")
except ValidationError as e:
print(f"Invalid log format: {e}")
Integration with Python Logging
import logging
from platform_observability import ObservabilityHandler
# Create custom handler
handler = ObservabilityHandler(
api_key="YOUR_API_KEY",
base_url="https://observability.redducklabs.com/api/v1",
source="my-app",
labels={"app": "my-app", "environment": "dev"}
)
# Add to Python logger
logger = logging.getLogger(__name__)
logger.addHandler(handler)
logger.setLevel(logging.INFO)
# Now regular Python logging will be sent to Platform Observability
logger.info("This goes to Platform Observability")
logger.error("This error too", extra={"user_id": "user123"})
API Key Management
# List API keys
keys = client.list_api_keys()
for key in keys:
print(f"{key.name}: {key.masked_key}")
# Create new API key
new_key = client.create_api_key(
name="ci-pipeline",
description="API key for CI/CD pipeline"
)
print(f"New key created: {new_key.key}")
# Rotate API key
rotated = client.rotate_api_key(key_id="key_123")
print(f"New key value: {rotated['key']}")
# Delete API key
client.delete_api_key(key_id="key_123")
Usage Analytics
from datetime import datetime, timedelta
# Get usage metrics
end_time = datetime.now()
start_time = end_time - timedelta(days=7)
metrics = client.get_usage_analytics(
start_time=start_time,
end_time=end_time
)
print(f"Total logs ingested: {metrics.total_logs_ingested}")
print(f"Data volume: {metrics.total_data_volume_gb:.2f} GB")
print(f"Average logs per request: {metrics.average_logs_per_request:.1f}")
CLI Tool
After installation, use the obs-cli command-line tool:
# Set up configuration
obs-cli config set api_key YOUR_API_KEY
obs-cli config set endpoint https://observability.redducklabs.com/api/v1
# Send a log
obs-cli log "Application deployed" --level info --label app=my-app
# List API keys
obs-cli keys list
# Get usage statistics
obs-cli usage --days 7
Development
Requirements
- Python >= 3.8
- pip
Setup Development Environment
# Clone repository
git clone https://github.com/redducklabs/platform-observability.git
cd platform-observability/sdks/python
# Install in development mode with dependencies
pip install -e .[dev]
Running Tests
# Run all tests
pytest
# Run with coverage
pytest --cov=platform_observability
# Run specific test file
pytest tests/test_client.py
Building Package
# Install build tools
pip install build
# Build wheel and source distribution
python -m build
# Output will be in dist/
ls dist/
Code Quality
# Format code
black platform_observability tests
# Lint code
flake8 platform_observability tests
# Type checking
mypy platform_observability
Troubleshooting
Logs Not Appearing in Grafana?
- Verify API Key: Ensure your API key is valid and active
- Check Endpoint: Confirm you're using the correct endpoint URL
- Validate Labels: Ensure labels are properly set (required for Grafana queries)
- Flush Logs: Call
logger.flush()to ensure batched logs are sent - Check Errors: Enable debug logging to see any errors:
import logging logging.basicConfig(level=logging.DEBUG)
Connection Errors?
If you're getting connection errors during initialization:
client = ObservabilityClient(
api_key="YOUR_API_KEY",
base_url="https://observability.redducklabs.com/api/v1",
skip_connection_check=True # Skip initial health check
)
Rate Limiting?
The SDK automatically retries on rate limit errors. You can also check rate limit status:
# After making requests
rate_limit_info = client.get_rate_limit_info()
print(f"Remaining requests: {rate_limit_info.get('remaining')}")
print(f"Reset time: {rate_limit_info.get('reset')}")
Examples
See the examples/ directory for complete working examples:
examples/sample-application/sdk_only_example.py- Basic SDK usageexamples/sample-application/sdk_continuous_example.py- Continuous log generationexamples/sample-application/app.py- FastAPI integration example
Support
For issues, questions, or contributions:
- GitHub Issues: https://github.com/redducklabs/platform-observability/issues
- Documentation: https://docs.redducklabs.com/observability
License
MIT License - see LICENSE file for details
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file redducklabs_platform_observability_sdk-1.0.2.tar.gz.
File metadata
- Download URL: redducklabs_platform_observability_sdk-1.0.2.tar.gz
- Upload date:
- Size: 19.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b1a9a51d55f8d6aa4c2a424a5ef351f7604963c606997641c20b3492ace32d99
|
|
| MD5 |
87f6c381a94f426a1631ee29644bb4cc
|
|
| BLAKE2b-256 |
a4ca33f3a82dfd3cc827cc96924cc61e9a7da675e02627e35d8f4ca5be1a4337
|
Provenance
The following attestation bundles were made for redducklabs_platform_observability_sdk-1.0.2.tar.gz:
Publisher:
publish-python-sdk.yml on redducklabs/platform-observability
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
redducklabs_platform_observability_sdk-1.0.2.tar.gz -
Subject digest:
b1a9a51d55f8d6aa4c2a424a5ef351f7604963c606997641c20b3492ace32d99 - Sigstore transparency entry: 430171841
- Sigstore integration time:
-
Permalink:
redducklabs/platform-observability@15a33204a5bb8175722e5fa676febd4093673037 -
Branch / Tag:
refs/heads/development - Owner: https://github.com/redducklabs
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
self-hosted -
Publication workflow:
publish-python-sdk.yml@15a33204a5bb8175722e5fa676febd4093673037 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file redducklabs_platform_observability_sdk-1.0.2-py3-none-any.whl.
File metadata
- Download URL: redducklabs_platform_observability_sdk-1.0.2-py3-none-any.whl
- Upload date:
- Size: 17.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2789826e4729cf95789a76741e84c6169bd66771fa6f8c5f4a807ee26eb056a3
|
|
| MD5 |
70dec06a6139660337704923e9de5577
|
|
| BLAKE2b-256 |
26b33aed9b9204569722f62c37fde65e52a3fbd0d26ab0d32dd98ccacce2103a
|
Provenance
The following attestation bundles were made for redducklabs_platform_observability_sdk-1.0.2-py3-none-any.whl:
Publisher:
publish-python-sdk.yml on redducklabs/platform-observability
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
redducklabs_platform_observability_sdk-1.0.2-py3-none-any.whl -
Subject digest:
2789826e4729cf95789a76741e84c6169bd66771fa6f8c5f4a807ee26eb056a3 - Sigstore transparency entry: 430171852
- Sigstore integration time:
-
Permalink:
redducklabs/platform-observability@15a33204a5bb8175722e5fa676febd4093673037 -
Branch / Tag:
refs/heads/development - Owner: https://github.com/redducklabs
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
self-hosted -
Publication workflow:
publish-python-sdk.yml@15a33204a5bb8175722e5fa676febd4093673037 -
Trigger Event:
workflow_dispatch
-
Statement type: