Lightweight, production-ready logging package for Google Cloud Platform applications
Project description
GCLog
A lightweight, production-ready logging package for Google Cloud Platform applications. Built on top of loguru, it automatically detects GCP environments and provides structured JSON logging for cloud services while maintaining human-readable logs for local development.
Why?
I found that my logs in a fastapi app were using the Google Cloud Platforms' (GCP) default log level irrespective of the actual log level that was being emitted by the app itself. This meant my GCP logs were reporting things incorrectly, decreasing visibility and making it harder to debug issues. This issue came up time and again, and I didn't want to have to write a log formatter for every service, so I wrote this package to fix this problem once and for all.
Features
- 🚀 Auto-detection of all major GCP services (Cloud Run, Cloud Functions, App Engine, GKE, Compute Engine)
- 📊 Structured JSON logging for GCP with proper severity levels
- 🎨 Beautiful colored logs for local development
- ⚡ Thread-safe singleton pattern for consistent logging across your application
- 🛡️ Zero external dependencies beyond loguru and requests
- 🧪 Fully tested with comprehensive test coverage
Supported GCP Services
- Cloud Run - Detected via
K_REVISIONenvironment variable - Cloud Functions - Detected via
FUNCTION_NAMEenvironment variable - App Engine - Detected via
GAE_APPLICATIONenvironment variable - Cloud Run Jobs - Detected via
CLOUD_RUN_JOBenvironment variable - Google Kubernetes Engine (GKE) - Detected via
KUBERNETES_SERVICE_HOSTenvironment variable - Compute Engine - Detected via metadata server API
Installation
pip install gclog
Quick Start
from gclog import get_logger
# Get a configured logger instance
logger = get_logger()
# Use it like any loguru logger
logger.info("Application started")
logger.warning("This is a warning", extra={"user_id": "12345"})
logger.error("Something went wrong", extra={"error_code": "E001"})
# Exception logging with full traceback
try:
result = 1 / 0
except Exception:
logger.exception("Division by zero error")
Log Output
Local Development
2025-01-15 10:30:45.123 | INFO | myapp:main:15 - Application started | {}
2025-01-15 10:30:45.124 | WARNING | myapp:main:16 - This is a warning | {'user_id': '12345'}
2025-01-15 10:30:45.125 | ERROR | myapp:main:17 - Something went wrong | {'error_code': 'E001'}
GCP Cloud Environment
{
"severity": "INFO",
"message": "Application started",
"time": "2025-01-15T10:30:45.123000",
"extra": {},
"file": {"name": "main.py", "path": "/app/main.py"},
"function": "main",
"line": 15,
"module": "myapp",
"process": {"id": 1, "name": "python"},
"thread": {"id": 140567890, "name": "MainThread"},
"elapsed": 0.001
}
Configuration
Log Level
Set the log level using the LOG_LEVEL environment variable:
export LOG_LEVEL=INFO
Or pass it directly:
from gclog import GCPLogger
logger = GCPLogger(level="DEBUG")
Custom Labels
Add custom context to your logs:
logger.info("User action", extra={
"user_id": "user123",
"action": "login",
"ip_address": "192.168.1.1"
})
Advanced Usage
Manual Environment Detection
from gclog import is_running_on_cloud
if is_running_on_cloud():
print("Running on GCP!")
else:
print("Running locally")
Direct Logger Configuration
from gclog import GCPLogger
# This returns the global loguru logger instance
logger = GCPLogger(level="WARNING")
# All subsequent calls return the same configured instance
logger2 = GCPLogger() # Same as logger
Local Development
When not running on GCP, the logger:
- Uses colored output for better readability
- Sends INFO and below to stdout
- Sends WARNING and above to stderr
- Includes full diagnostic information
Error Handling
The logger includes robust error handling:
- Graceful fallback if GCP detection fails
- Automatic fallback to basic logging if configuration fails
- Thread-safe initialization prevents race conditions
Requirements
- Python 3.9+
- loguru
- requests (for GCP metadata server detection)
Testing
Run the test suite:
pytest tests/ -v
Contributing
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
License
MIT License - see LICENSE file for details.
Changelog
v0.1.1
- feat: Add conditional extra data formatting for cleaner logs
- improvement: Extra data section only appears when data is present
- docs: Update examples and documentation
v0.1.0
- Initial release
- Support for all major GCP services
- Structured JSON logging for cloud environments
- Beautiful local development logs
- Thread-safe singleton pattern
- Comprehensive test coverage
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 gclog-0.1.1.tar.gz.
File metadata
- Download URL: gclog-0.1.1.tar.gz
- Upload date:
- Size: 66.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3cbbe842df9642f74c4b14549dc2f993f5a2f32c09f10ea90ff94164223317fb
|
|
| MD5 |
22f0b38e9fbf398574fba291b27e8f49
|
|
| BLAKE2b-256 |
df0f97919924fb2391c2b9d0ac2d3a207f056c43005417e699423255a0da0a02
|
File details
Details for the file gclog-0.1.1-py3-none-any.whl.
File metadata
- Download URL: gclog-0.1.1-py3-none-any.whl
- Upload date:
- Size: 6.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7959b8685f4bac81b1eeb1865bb36dfcf9c4ed3ffb2eff8a32fb5909f5a6c280
|
|
| MD5 |
9b70ef6dda7a17b916babe3d723bb10d
|
|
| BLAKE2b-256 |
19ffb8f70a2150071cd693908dcadbbea5d4211c5fa361e579668336a441a2ba
|