The Logging Gap
You deployed your AI-generated app, and a user reported a bug. You try to diagnose it, but you cannot find any logs. Your app uses console.log for debugging, which is not captured in production, and there is no structured logging, no log levels, and no request correlation. You have no visibility into what happened, which means you cannot diagnose the bug. This is the logging gap, and it is one of the most common failures in AI-generated apps. AI assistants use console.log for debugging, which is sufficient for development but insufficient for production. Here are the 6 reasons AI assistants ship apps without proper logging, and the production checklist to fix them.
The direct answer is that logging is the practice of recording events that happen in your app, and it is essential for debugging production issues. AI assistants use console.log for debugging, which is not captured in production, does not support log levels, and does not provide structure. The 6 reasons are: console.log only, no log levels, no structured logs, no request correlation, no log aggregation, and no log retention. Each one has a known cause and a known fix, and applying all 6 fixes gives you a production-ready logging system. For more on production debugging, see our article on debugging from your IDE with deployxa doctor.
Reason 1: Console.log Only
The most common reason AI assistants ship apps without proper logging is the use of console.log. console.log is fine for development (it prints to the terminal), but it is insufficient for production, because it does not support log levels (you cannot filter by INFO, WARN, ERROR), it does not provide structure (the output is plain text, not JSON), and it is not captured by log aggregation tools. The fix is to use a structured logger (e.g., pino for Node.js, structlog for Python, slog for Go) that supports log levels, structured output, and log aggregation. For more on structured logging, see our article on AI error handling failures.
Reason 2: No Log Levels
The second reason is no log levels. Log levels (DEBUG, INFO, WARN, ERROR, FATAL) let you control the verbosity of your logs, which means you can filter by level when searching. Without log levels, all logs are the same priority, which makes it hard to find important events. AI assistants rarely use log levels, because console.log does not support them. The fix is to use a logger that supports log levels and to use the appropriate level for each event: DEBUG for detailed debugging, INFO for normal events, WARN for potential issues, ERROR for errors, FATAL for fatal errors.
Reason 3: No Structured Logs
The third reason is no structured logs. Structured logs (JSON format) are easier to search, filter, and analyze than plain-text logs. Without structured logs, you have to parse the plain text to find information, which is slow and error-prone. AI assistants rarely produce structured logs, because console.log outputs plain text. The fix is to use a logger that outputs JSON (e.g., pino for Node.js) and to include structured fields (e.g., userId, requestId, duration) in each log entry.
Reason 4: No Request Correlation
The fourth reason is no request correlation. In a production app, multiple requests are processed concurrently, and without a way to correlate log entries to a specific request, it is hard to trace the flow of a single request. AI assistants rarely implement request correlation, because it requires middleware that generates a unique request ID for each request. The fix is to generate a unique request ID for each request (via middleware) and to include it in every log entry, which lets you filter logs by request ID.
Reason 5: No Log Aggregation
The fifth reason is no log aggregation. In a production app with multiple containers, logs are scattered across containers, which makes it hard to search and analyze them. Without log aggregation, you have to SSH into each container to read its logs, which is tedious. The fix is to use a log aggregation service (e.g., Datadog, Logtail, Elasticsearch) that collects logs from all containers and provides a single interface for searching and analyzing them. Deployxa's dashboard includes a built-in log viewer that aggregates logs from all containers. For more on Deployxa's logging, see our article on how we built the logging pipeline.
Reason 6: No Log Retention
The sixth reason is no log retention. Logs accumulate over time, and without a retention policy, they consume unlimited storage. AI assistants rarely implement log retention, because it is an operational concern, not a code concern. The fix is to set a log retention policy (e.g., keep logs for 30 days, then delete them) and to use a log aggregation service that supports automatic retention.
Step-by-Step: Adding Production Logging to a Node.js App
Here is how to add production logging to a Node.js app using pino.
Step 1: Install pino
npm install pino pino-httpStep 2: Configure the logger
// logger.js
const pino = require('pino');
const logger = pino({
level: process.env.LOG_LEVEL || 'info',
redact: ['req.headers.authorization', 'req.body.password', 'req.body.creditCard'],
formatters: {
level: (label) => {
return { level: label };
},
},
timestamp: pino.stdTimeFunctions.isoTime,
});
module.exports = logger;Step 3: Add request correlation middleware
// server.js
const express = require('express');
const { v4: uuidv4 } = require('uuid');
const pinoHttp = require('pino-http');
const logger = require('./logger');
const app = express();
app.use(pinoHttp({
logger,
genReqId: (req, res) => {
const requestId = req.headers['x-request-id'] || uuidv4();
res.setHeader('X-Request-Id', requestId);
return requestId;
},
}));
// Log all requests
app.use((req, res, next) => {
req.log.info({ method: req.method, url: req.url }, 'Request received');
next();
});
// Example route with structured logging
app.get('/users/:id', async (req, res) => {
const userId = req.params.id;
req.log.info({ userId }, 'Fetching user');
try {
const user = await getUser(userId);
req.log.info({ userId, found: true }, 'User fetched');
res.json(user);
} catch (err) {
req.log.error({ userId, err: err.message }, 'Failed to fetch user');
res.status(500).json({ error: 'Failed to fetch user' });
}
});Step 4: Set environment variables
In the Deployxa dashboard, set:
- LOG_LEVEL: info (or debug for more verbose logging)
Step 5: Verify with deployxa doctor
Run deployxa doctor to verify your app's health. The 14-point readiness engine checks SSL, DNS, environment variables, health endpoints, and container status. You can also use deployxa get logs to view your structured logs in the Deployxa dashboard. For more on the MCP server, see our article on giving Cursor cloud superpowers.
Common Pitfalls and Troubleshooting
The first pitfall is logging sensitive information. Logs can contain passwords, tokens, and other secrets, which should never be logged. The fix is to use a logger that supports redaction (like pino) and to redact sensitive fields. The second pitfall is over-logging. Logging every event at DEBUG level produces a huge volume of logs, which makes it hard to find important events and increases storage costs. The fix is to use INFO level for normal events and to reserve DEBUG for detailed debugging (which can be enabled temporarily). The third pitfall is under-logging. Not logging enough means you have no visibility into production issues. The fix is to log all important events (requests, errors, state changes) at the appropriate level. The fourth pitfall is not testing log output. Logs that are not tested might not contain the expected information, which means they are useless for debugging. The fix is to write tests that verify log output for important events. The fifth pitfall is not monitoring log volume. A sudden spike in log volume can indicate a problem (e.g., a loop that logs repeatedly), which can fill up storage and cause issues. The fix is to monitor log volume and to alert on spikes.
Conclusion: Logs Are Your Eyes in Production
The logging gap is not a sign that your AI assistant did a bad job. It is a sign that console.log is sufficient for development but insufficient for production, and production logging requires additional work. By applying the 6 fixes above (use a structured logger, use log levels, output structured logs, implement request correlation, use log aggregation, set log retention), you can build a production-ready logging system that gives you visibility into your app's behavior. Stop shipping apps without logs and start logging properly.
Ready to ship a well-logged app? Drag your project to Deployxa Drop for an instant live preview, or install the CLI with npm i -g @deployxa/cli and deploy from your terminal. For more on AI coding patterns, see our articles on the i18n gap and the security headers gap. Learn about the monitoring gap and the database migration trap in our companion articles. Explore our free developer tools to speed up your workflow.