Structured Logging: Making Logs Queryable and Actionable
February 16, 2026 · 7 min · 1406 words · Rob Washington
Table of Contents
Plain text logs are for humans. Structured logs are for machines. In production, machines need to read your logs before humans do.
When your service handles thousands of requests per second, grep stops working. You need logs that can be indexed, queried, aggregated, and alerted on. That means structure.
importstructloglogger=structlog.get_logger()# Configure once at startupstructlog.configure(processors=[structlog.processors.TimeStamper(fmt="iso"),structlog.processors.JSONRenderer()])# Usagelogger.info("user_login",user_id=user.id,email=user.email,ip=request.remote_addr)logger.error("payment_failed",order_id=order.id,user_id=user.id,reason=str(error),exc_info=True)
const{AsyncLocalStorage}=require('async_hooks');constasyncLocalStorage=newAsyncLocalStorage();functionrequestLogger(req,res,next){constcontext={requestId:req.headers['x-request-id']||uuid(),traceId:req.headers['x-trace-id'],userId:req.user?.id,path:req.path,method:req.method,};asyncLocalStorage.run(context,()=>next());}// Logger automatically includes context
constlogger={info(data,message){constcontext=asyncLocalStorage.getStore()||{};pino.info({...context,...data},message);},// ... other levels
};
Now every log in that request automatically includes requestId, userId, etc.
// Errors in the last hour
GET/logs/_search{"query":{"bool":{"must":[{"match":{"level":"error"}},{"range":{"timestamp":{"gte":"now-1h"}}}]}}}// Slow requests (>1s) by endpoint
GET/logs/_search{"query":{"range":{"duration_ms":{"gte":1000}}},"aggs":{"by_path":{"terms":{"field":"path.keyword"}}}}
// DON'T: Different names for same concept
logger.info({user_id:'123'});logger.info({userId:'123'});logger.info({uid:'123'});// DO: Standardize
logger.info({userId:'123'});
Think of structured logs as a time-series database of events:
Each log is a row
Each field is a column
You can query, aggregate, and alert
Plain text logs are like writing notes in a notebook. Structured logs are like entering data in a spreadsheet. The notebook is fine for personal use; the spreadsheet is what you need when you have to answer questions at scale.
Your future self debugging a production incident at 3 AM will thank you for the structure.
📬 Get the Newsletter
Weekly insights on DevOps, automation, and CLI mastery. No spam, unsubscribe anytime.