Metadata Context
Metadata Context
Add rich contextual information to your logs to understand the state of your application when events occur. Metadata helps correlate related information and makes debugging easier.
Adding Context with with_context()
The with_context() method adds data to individual log entries:
from bytehide_logs import Log
# Single context value
Log.with_context("user_id", "user_123").info("User action performed")
# Multiple context values (chain multiple calls)
Log.with_context("user_id", "user_123") \
.with_context("action", "profile_update") \
.with_context("timestamp", "2026-03-02T14:30:00Z") \
.info("User profile updated")from bytehide_logs import Log
# Single context value
Log.with_context("user_id", "user_123").info("User action performed")
# Multiple context values (chain multiple calls)
Log.with_context("user_id", "user_123") \
.with_context("action", "profile_update") \
.with_context("timestamp", "2026-03-02T14:30:00Z") \
.info("User profile updated")Global Metadata Context
The add_meta_context() method adds metadata that applies to all subsequent logs:
from bytehide_logs import Log
# Set application-wide context
Log.add_meta_context("service", "payment-service")
Log.add_meta_context("environment", "production")
Log.add_meta_context("version", "2.1.0")
# All subsequent logs include this context
Log.info("Service started")
# Output includes: service=payment-service, environment=production, version=2.1.0
Log.info("Processing payment")
# Output includes: service=payment-service, environment=production, version=2.1.0from bytehide_logs import Log
# Set application-wide context
Log.add_meta_context("service", "payment-service")
Log.add_meta_context("environment", "production")
Log.add_meta_context("version", "2.1.0")
# All subsequent logs include this context
Log.info("Service started")
# Output includes: service=payment-service, environment=production, version=2.1.0
Log.info("Processing payment")
# Output includes: service=payment-service, environment=production, version=2.1.0Request-Level Context
Add context that applies to all logs within a request:
from bytehide_logs import Log
def handle_request(request):
"""Handle HTTP request with request context."""
# Add request-level context
Log.add_meta_context("request_id", request.id)
Log.add_meta_context("client_ip", request.remote_addr)
Log.add_meta_context("user_agent", request.headers.get("User-Agent"))
# All logs in this request include this context
Log.info("Request received")
Log.info("Validating request")
Log.info("Processing request")
# Clean up after request
Log.clear_meta_context()from bytehide_logs import Log
def handle_request(request):
"""Handle HTTP request with request context."""
# Add request-level context
Log.add_meta_context("request_id", request.id)
Log.add_meta_context("client_ip", request.remote_addr)
Log.add_meta_context("user_agent", request.headers.get("User-Agent"))
# All logs in this request include this context
Log.info("Request received")
Log.info("Validating request")
Log.info("Processing request")
# Clean up after request
Log.clear_meta_context()Application-Level Metadata
Set metadata once at application startup:
from bytehide_logs import Log
import os
def initialize_logging():
"""Initialize logging with application metadata."""
Log.add_meta_context("app_name", "ecommerce-api")
Log.add_meta_context("environment", os.environ.get("ENV", "development"))
Log.add_meta_context("region", os.environ.get("REGION", "us-east-1"))
Log.add_meta_context("version", "1.2.3")
Log.add_meta_context("start_time", get_current_timestamp())
# Call during application initialization
initialize_logging()
# Now all logs include this metadata
Log.info("Application started")from bytehide_logs import Log
import os
def initialize_logging():
"""Initialize logging with application metadata."""
Log.add_meta_context("app_name", "ecommerce-api")
Log.add_meta_context("environment", os.environ.get("ENV", "development"))
Log.add_meta_context("region", os.environ.get("REGION", "us-east-1"))
Log.add_meta_context("version", "1.2.3")
Log.add_meta_context("start_time", get_current_timestamp())
# Call during application initialization
initialize_logging()
# Now all logs include this metadata
Log.info("Application started")Context Types
Add different types of context data:
# Strings
Log.with_context("status", "active").info("User status")
# Numbers
Log.with_context("response_time_ms", 145).info("Request completed")
# Booleans
Log.with_context("is_cached", True).info("Response from cache")
# Lists
Log.with_context("tags", ["important", "urgent"]).info("Task created")
# Dictionaries (nested)
Log.with_context("metadata", {
"priority": "high",
"assigned_to": "team-backend"
}).info("Ticket created")
# None (absence of value)
Log.with_context("optional_field", None).info("Optional field not provided")# Strings
Log.with_context("status", "active").info("User status")
# Numbers
Log.with_context("response_time_ms", 145).info("Request completed")
# Booleans
Log.with_context("is_cached", True).info("Response from cache")
# Lists
Log.with_context("tags", ["important", "urgent"]).info("Task created")
# Dictionaries (nested)
Log.with_context("metadata", {
"priority": "high",
"assigned_to": "team-backend"
}).info("Ticket created")
# None (absence of value)
Log.with_context("optional_field", None).info("Optional field not provided")Request Tracking Context
Track requests through your system:
from bytehide_logs import Log
import uuid
import time
def middleware_before_request(request):
"""Track request context."""
request_id = str(uuid.uuid4())
start_time = time.time()
Log.add_meta_context("request_id", request_id)
Log.add_meta_context("start_time", start_time)
Log.add_meta_context("method", request.method)
Log.add_meta_context("path", request.path)
Log.info("Request started")
def middleware_after_request(response):
"""Log request completion with timing."""
elapsed_time = time.time() - get_start_time()
Log.with_context("status_code", response.status_code) \
.with_context("elapsed_time_ms", int(elapsed_time * 1000)) \
.info("Request completed")
Log.clear_meta_context()from bytehide_logs import Log
import uuid
import time
def middleware_before_request(request):
"""Track request context."""
request_id = str(uuid.uuid4())
start_time = time.time()
Log.add_meta_context("request_id", request_id)
Log.add_meta_context("start_time", start_time)
Log.add_meta_context("method", request.method)
Log.add_meta_context("path", request.path)
Log.info("Request started")
def middleware_after_request(response):
"""Log request completion with timing."""
elapsed_time = time.time() - get_start_time()
Log.with_context("status_code", response.status_code) \
.with_context("elapsed_time_ms", int(elapsed_time * 1000)) \
.info("Request completed")
Log.clear_meta_context()Database Operation Context
Add context for database queries:
from bytehide_logs import Log
def execute_query(query, params):
"""Execute database query with context."""
Log.with_context("query_type", query.type) \
.with_context("table", query.table) \
.with_context("param_count", len(params)) \
.with_context("query_id", generate_query_id()) \
.info("Executing database query")
try:
result = database.execute(query, params)
Log.with_context("rows_affected", len(result)).info("Query executed")
return result
except Exception as e:
Log.error("Query failed", exception=e)
raisefrom bytehide_logs import Log
def execute_query(query, params):
"""Execute database query with context."""
Log.with_context("query_type", query.type) \
.with_context("table", query.table) \
.with_context("param_count", len(params)) \
.with_context("query_id", generate_query_id()) \
.info("Executing database query")
try:
result = database.execute(query, params)
Log.with_context("rows_affected", len(result)).info("Query executed")
return result
except Exception as e:
Log.error("Query failed", exception=e)
raiseAPI Call Context
Track external API interactions:
from bytehide_logs import Log
import requests
def call_external_api(endpoint, method="GET", **kwargs):
"""Call external API with detailed context."""
request_id = generate_request_id()
Log.with_context("api_endpoint", endpoint) \
.with_context("http_method", method) \
.with_context("api_request_id", request_id) \
.info("Calling external API")
try:
headers = {**kwargs.get("headers", {}), "X-Request-ID": request_id}
response = requests.request(method, endpoint, headers=headers, **kwargs)
Log.with_context("status_code", response.status_code) \
.with_context("response_time_ms", response.elapsed.total_seconds() * 1000) \
.with_context("response_size_bytes", len(response.content)) \
.info("API call successful")
return response.json()
except Exception as e:
Log.error("API call failed", exception=e)
raisefrom bytehide_logs import Log
import requests
def call_external_api(endpoint, method="GET", **kwargs):
"""Call external API with detailed context."""
request_id = generate_request_id()
Log.with_context("api_endpoint", endpoint) \
.with_context("http_method", method) \
.with_context("api_request_id", request_id) \
.info("Calling external API")
try:
headers = {**kwargs.get("headers", {}), "X-Request-ID": request_id}
response = requests.request(method, endpoint, headers=headers, **kwargs)
Log.with_context("status_code", response.status_code) \
.with_context("response_time_ms", response.elapsed.total_seconds() * 1000) \
.with_context("response_size_bytes", len(response.content)) \
.info("API call successful")
return response.json()
except Exception as e:
Log.error("API call failed", exception=e)
raiseBusiness Logic Context
Add context specific to your business domain:
from bytehide_logs import Log
def process_order(order):
"""Process order with business context."""
Log.add_meta_context("order_id", order.id)
Log.add_meta_context("customer_id", order.customer_id)
Log.add_meta_context("order_total", order.total)
Log.info("Order processing started")
try:
# Validate inventory
Log.with_context("step", "inventory_check").info("Checking inventory")
validate_inventory(order)
# Process payment
Log.with_context("step", "payment") \
.with_context("payment_method", order.payment_method) \
.info("Processing payment")
process_payment(order)
# Create shipment
Log.with_context("step", "fulfillment").info("Creating shipment")
shipment = create_shipment(order)
Log.with_context("shipment_id", shipment.id).info("Shipment created")
Log.info("Order processing completed")
finally:
Log.clear_meta_context()from bytehide_logs import Log
def process_order(order):
"""Process order with business context."""
Log.add_meta_context("order_id", order.id)
Log.add_meta_context("customer_id", order.customer_id)
Log.add_meta_context("order_total", order.total)
Log.info("Order processing started")
try:
# Validate inventory
Log.with_context("step", "inventory_check").info("Checking inventory")
validate_inventory(order)
# Process payment
Log.with_context("step", "payment") \
.with_context("payment_method", order.payment_method) \
.info("Processing payment")
process_payment(order)
# Create shipment
Log.with_context("step", "fulfillment").info("Creating shipment")
shipment = create_shipment(order)
Log.with_context("shipment_id", shipment.id).info("Shipment created")
Log.info("Order processing completed")
finally:
Log.clear_meta_context()Performance Monitoring Context
Track performance metrics:
from bytehide_logs import Log
import time
class PerformanceMonitor:
"""Monitor operation performance with logging context."""
def __init__(self, operation_name):
self.operation_name = operation_name
self.start_time = time.time()
def __enter__(self):
Log.add_meta_context("operation", self.operation_name)
Log.add_meta_context("start_time", self.start_time)
return self
def __exit__(self, exc_type, exc_val, exc_tb):
elapsed = time.time() - self.start_time
Log.with_context("elapsed_ms", int(elapsed * 1000)).info(
f"Operation {self.operation_name} completed"
)
Log.clear_meta_context()
# Usage
with PerformanceMonitor("data_import"):
import_data_from_csv()from bytehide_logs import Log
import time
class PerformanceMonitor:
"""Monitor operation performance with logging context."""
def __init__(self, operation_name):
self.operation_name = operation_name
self.start_time = time.time()
def __enter__(self):
Log.add_meta_context("operation", self.operation_name)
Log.add_meta_context("start_time", self.start_time)
return self
def __exit__(self, exc_type, exc_val, exc_tb):
elapsed = time.time() - self.start_time
Log.with_context("elapsed_ms", int(elapsed * 1000)).info(
f"Operation {self.operation_name} completed"
)
Log.clear_meta_context()
# Usage
with PerformanceMonitor("data_import"):
import_data_from_csv()Combining Context Methods
Mix with_context() and add_meta_context():
from bytehide_logs import Log
# Global metadata (applies to all logs)
Log.add_meta_context("service", "user-service")
Log.add_meta_context("environment", "production")
# Request-specific context
Log.with_context("request_id", "req_123") \
.with_context("user_id", "user_456") \
.info("Processing user request")
# Output includes both global and request-specific context
# service=user-service, environment=production, request_id=req_123, user_id=user_456from bytehide_logs import Log
# Global metadata (applies to all logs)
Log.add_meta_context("service", "user-service")
Log.add_meta_context("environment", "production")
# Request-specific context
Log.with_context("request_id", "req_123") \
.with_context("user_id", "user_456") \
.info("Processing user request")
# Output includes both global and request-specific context
# service=user-service, environment=production, request_id=req_123, user_id=user_456Context Hierarchy
Context flows through your application hierarchy:
from bytehide_logs import Log
# Application level
Log.add_meta_context("app", "api-server")
def handle_request(request):
# Request level
Log.add_meta_context("request_id", request.id)
def process_item(item):
# Item level
Log.with_context("item_id", item.id) \
.with_context("item_type", item.type) \
.info("Processing item")
for item in request.items:
process_item(item)
Log.clear_meta_context()from bytehide_logs import Log
# Application level
Log.add_meta_context("app", "api-server")
def handle_request(request):
# Request level
Log.add_meta_context("request_id", request.id)
def process_item(item):
# Item level
Log.with_context("item_id", item.id) \
.with_context("item_type", item.type) \
.info("Processing item")
for item in request.items:
process_item(item)
Log.clear_meta_context()Clearing Context
Remove metadata context when no longer needed:
from bytehide_logs import Log
# Add context
Log.add_meta_context("request_id", "req_789")
Log.info("Processing request")
# Clear all metadata
Log.clear_meta_context()
# Clear specific metadata
Log.remove_meta_context("request_id")
# Subsequent logs don't include cleared context
Log.info("Processing complete")from bytehide_logs import Log
# Add context
Log.add_meta_context("request_id", "req_789")
Log.info("Processing request")
# Clear all metadata
Log.clear_meta_context()
# Clear specific metadata
Log.remove_meta_context("request_id")
# Subsequent logs don't include cleared context
Log.info("Processing complete")Complete Example
from bytehide_logs import Log, LogSettings
from datetime import timedelta
import uuid
# Initialize application logging
settings = LogSettings(
duplicate_suppression_window=timedelta(seconds=5),
mask_sensitive_data=["password", "token"]
)
Log.configure(settings)
# Application metadata
Log.add_meta_context("service", "payment-api")
Log.add_meta_context("version", "1.0.0")
Log.add_meta_context("environment", "production")
def handle_payment_request(request):
"""Handle payment request with comprehensive context."""
# Request context
request_id = str(uuid.uuid4())
Log.add_meta_context("request_id", request_id)
Log.add_meta_context("client_ip", request.remote_addr)
Log.info("Payment request received")
try:
# Identify user
user = authenticate(request)
Log.identify(user)
# Add business context
Log.add_meta_context("order_id", request.order_id)
Log.add_meta_context("amount_cents", request.amount)
# Validate request
Log.with_context("step", "validation").info("Validating payment details")
validate_payment(request)
# Process payment
Log.with_context("step", "processing") \
.with_context("gateway", "stripe") \
.info("Processing payment")
result = process_payment(request)
# Return result
Log.with_context("step", "complete") \
.with_context("transaction_id", result.id) \
.info("Payment processed successfully")
return result
except Exception as e:
Log.error("Payment processing failed", exception=e)
raise
finally:
# Clean up context
Log.clear_meta_context()from bytehide_logs import Log, LogSettings
from datetime import timedelta
import uuid
# Initialize application logging
settings = LogSettings(
duplicate_suppression_window=timedelta(seconds=5),
mask_sensitive_data=["password", "token"]
)
Log.configure(settings)
# Application metadata
Log.add_meta_context("service", "payment-api")
Log.add_meta_context("version", "1.0.0")
Log.add_meta_context("environment", "production")
def handle_payment_request(request):
"""Handle payment request with comprehensive context."""
# Request context
request_id = str(uuid.uuid4())
Log.add_meta_context("request_id", request_id)
Log.add_meta_context("client_ip", request.remote_addr)
Log.info("Payment request received")
try:
# Identify user
user = authenticate(request)
Log.identify(user)
# Add business context
Log.add_meta_context("order_id", request.order_id)
Log.add_meta_context("amount_cents", request.amount)
# Validate request
Log.with_context("step", "validation").info("Validating payment details")
validate_payment(request)
# Process payment
Log.with_context("step", "processing") \
.with_context("gateway", "stripe") \
.info("Processing payment")
result = process_payment(request)
# Return result
Log.with_context("step", "complete") \
.with_context("transaction_id", result.id) \
.info("Payment processed successfully")
return result
except Exception as e:
Log.error("Payment processing failed", exception=e)
raise
finally:
# Clean up context
Log.clear_meta_context()Next Steps
- Learn about user identification for tracking user actions
- Explore correlation IDs for request tracing
- Discover tags for categorizing log entries