Agent skill
structlog
Structured logging for Python applications with context support and powerful processors
Install this agent skill to your Project
npx add-skill https://github.com/aiskillstore/marketplace/tree/main/skills/bossjones/structlog
SKILL.md
Structlog Skill
Quick Start
import structlog
# Basic usage
log = structlog.get_logger()
log.info("hello, %s!", "world", key="value", more_than_strings=[1, 2, 3])
Common Patterns
Basic Configuration
import structlog
structlog.configure(
processors=[
structlog.contextvars.merge_contextvars,
structlog.processors.add_log_level,
structlog.processors.StackInfoRenderer(),
structlog.dev.set_exc_info,
structlog.processors.TimeStamper(fmt="%Y-%m-%d %H:%M:%S", utc=False),
structlog.dev.ConsoleRenderer()
],
wrapper_class=structlog.make_filtering_bound_logger(logging.NOTSET),
context_class=dict,
logger_factory=structlog.PrintLoggerFactory(),
cache_logger_on_first_use=False
)
JSON Logging
import structlog
# Configure for JSON output
structlog.configure(
processors=[structlog.processors.JSONRenderer()]
)
log = structlog.get_logger()
log.info("Processing request", request_id="req-123", user_id=456)
# Output: {"event": "Processing request", "request_id": "req-123", "user_id": 456}
Standard Library Integration
import logging
import structlog
# Configure standard logging
logging.basicConfig(
format="%(message)s",
stream=sys.stdout,
level=logging.INFO
)
# Configure structlog to use standard library
structlog.configure(
processors=[
structlog.stdlib.filter_by_level,
structlog.stdlib.add_logger_name,
structlog.stdlib.add_log_level,
structlog.stdlib.PositionalArgumentsFormatter(),
structlog.processors.StackInfoRenderer(),
structlog.processors.format_exc_info,
structlog.stdlib.render_to_log_kwargs,
],
context_class=dict,
logger_factory=structlog.stdlib.LoggerFactory(),
wrapper_class=structlog.stdlib.BoundLogger,
cache_logger_on_first_use=True,
)
Context Binding
import structlog
log = structlog.get_logger()
# Bind context that persists across log calls
request_log = log.bind(request_id="req-789", user="alice")
request_log.info("Processing started")
request_log.info("Database query executed", query="SELECT * FROM users")
request_log.info("Processing completed")
# Output includes request_id and user in all log entries
Custom Processors
import time
def add_custom_context(logger, log_method, event_dict):
"""Add custom context to every log entry"""
event_dict["custom_field"] = "custom_value"
event_dict["timestamp"] = time.time()
return event_dict
structlog.configure(
processors=[
add_custom_context,
structlog.processors.JSONRenderer()
]
)
Exception Handling
import structlog
structlog.configure(
processors=[
structlog.processors.dict_tracebacks,
structlog.processors.JSONRenderer(),
],
)
log = structlog.get_logger()
try:
1 / 0
except ZeroDivisionError:
log.exception("Division error occurred")
Testing with Structlog
import pytest
import structlog
from structlog.testing import LogCapture
@pytest.fixture
def log_output():
return LogCapture()
@pytest.fixture(autouse=True)
def configure_structlog(log_output):
structlog.configure(
processors=[log_output]
)
def test_logging(log_output):
log = structlog.get_logger()
log.info("test message", key="value")
assert len(log_output.entries) == 1
assert log_output.entries[0]["event"] == "test message"
assert log_output.entries[0]["key"] == "value"
Performance-Optimized Configuration
import structlog
structlog.configure(
processors=[
structlog.stdlib.filter_by_level,
structlog.stdlib.add_logger_name,
structlog.stdlib.add_log_level,
structlog.stdlib.PositionalArgumentsFormatter(),
structlog.processors.TimeStamper(fmt="iso"),
structlog.processors.StackInfoRenderer(),
structlog.processors.format_exc_info,
structlog.processors.UnicodeDecoder(),
structlog.processors.JSONRenderer()
],
context_class=dict,
logger_factory=structlog.stdlib.LoggerFactory(),
wrapper_class=structlog.stdlib.BoundLogger,
cache_logger_on_first_use=True,
)
Advanced Console Output
import logging.config
import structlog
timestamper = structlog.processors.TimeStamper(fmt="%Y-%m-%d %H:%M:%S")
pre_chain = [
structlog.stdlib.add_log_level,
structlog.stdlib.ExtraAdder(),
timestamper,
]
logging.config.dictConfig({
"version": 1,
"disable_existing_loggers": False,
"formatters": {
"plain": {
"()": structlog.stdlib.ProcessorFormatter,
"processors": [
structlog.stdlib.ProcessorFormatter.remove_processors_meta,
structlog.dev.ConsoleRenderer(colors=False),
],
"foreign_pre_chain": pre_chain,
},
"colored": {
"()": structlog.stdlib.ProcessorFormatter,
"processors": [
structlog.stdlib.ProcessorFormatter.remove_processors_meta,
structlog.dev.ConsoleRenderer(colors=True),
],
"foreign_pre_chain": pre_chain,
},
},
"handlers": {
"default": {
"level": "DEBUG",
"class": "logging.StreamHandler",
"formatter": "colored",
},
"file": {
"level": "DEBUG",
"class": "logging.handlers.WatchedFileHandler",
"filename": "app.log",
"formatter": "plain",
},
},
"loggers": {
"": {
"handlers": ["default", "file"],
"level": "DEBUG",
}
}
})
Key Features
- Structured Logging: Log events as dictionaries with context
- Multiple Output Formats: Console, JSON, logfmt, and custom renderers
- Context Binding: Persistent context across log calls
- Standard Library Integration: Works seamlessly with Python's logging module
- Performance: Optimized for high-throughput applications
- Testing Support: Built-in testing utilities
- Exception Handling: Enhanced exception formatting and rendering
- Custom Processors: Flexible pipeline for log processing
Best Practices
- Configure Once: Set up structlog configuration at application startup
- Use Context: Bind relevant context (request_id, user_id) early in request handling
- Choose Right Renderer: Use ConsoleRenderer for development, JSONRenderer for production
- Test Logging: Use LogCapture for unit testing logging behavior
- Performance: Cache loggers and use efficient processors for production
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
perigon-backend
Perigon ASP.NET Core + EF Core + Aspire conventions
perigon-agent
Pointers for Copilot/agents to apply Perigon conventions
perigon-angular
Angular 21+ standalone/Material/signal conventions for Perigon WebApp
fastapi-mastery
Comprehensive FastAPI development skill covering REST API creation, routing, request/response handling, validation, authentication, database integration, middleware, and deployment. Use when working with FastAPI projects, building APIs, implementing CRUD operations, setting up authentication/authorization, integrating databases (SQL/NoSQL), adding middleware, handling WebSockets, or deploying FastAPI applications. Triggered by requests involving .py files with FastAPI code, API endpoint creation, Pydantic models, or FastAPI-specific features.
context7-efficient
Token-efficient library documentation fetcher using Context7 MCP with 86.8% token savings through intelligent shell pipeline filtering. Fetches code examples, API references, and best practices for JavaScript, Python, Go, Rust, and other libraries. Use when users ask about library documentation, need code examples, want API usage patterns, are learning a new framework, need syntax reference, or troubleshooting with library-specific information. Triggers include questions like "Show me React hooks", "How do I use Prisma", "What's the Next.js routing syntax", or any request for library/framework documentation.
browser-use
Browser automation using Playwright MCP. Navigate websites, fill forms, click elements, take screenshots, and extract data. Use when tasks require web browsing, form submission, web scraping, UI testing, or any browser interaction.
Didn't find tool you were looking for?