← Back to README · Documentation index
SharedCache provides a comprehensive logging system with structured output for monitoring and debugging cache operations.
interface Logger {
info(message?: unknown, ...optionalParams: unknown[]): void;
warn(message?: unknown, ...optionalParams: unknown[]): void;
debug(message?: unknown, ...optionalParams: unknown[]): void;
error(message?: unknown, ...optionalParams: unknown[]): void;
}import { createLogger, LogLevel } from '@web-widget/shared-cache';
// Create a simple console logger
const logger = {
info: console.info.bind(console),
warn: console.warn.bind(console),
debug: console.debug.bind(console),
error: console.error.bind(console),
};
// Create SharedCache with logger
const cache = new SharedCache(storage, {
logger,
});- Purpose: Detailed operational information for development and troubleshooting
- Content: Cache lookups, key generation, policy decisions
- Example Output:
SharedCache: Cache miss { url: 'https://api.com/data', cacheKey: 'api:data', method: 'GET' } SharedCache: Cache item found { url: 'https://api.com/data', cacheKey: 'api:data', method: 'GET' }
- Purpose: Normal operational messages about successful operations
- Content: Cache hits, revalidation results, stale responses
- Example Output:
SharedCache: Cache hit { url: 'https://api.com/data', cacheKey: 'api:data', cacheStatus: 'HIT' } SharedCache: Serving stale response - Revalidating in background { url: 'https://api.com/data', cacheKey: 'api:data', cacheStatus: 'UPDATING' }
- Purpose: Potentially problematic situations that don't prevent operation
- Content: Network errors with fallback, deprecated usage
- Example Output:
SharedCache: Revalidation network error - Using fallback 500 response { url: 'https://api.com/data', cacheKey: 'api:data', error: [NetworkError] }
- Purpose: Critical issues that prevent normal operation
- Content: Storage failures, revalidation failures, validation errors
- Example Output:
SharedCache: Put operation failed { url: 'https://api.com/data', error: [StorageError] } SharedCache: Revalidation failed - Server returned 5xx status { url: 'https://api.com/data', status: 503, cacheKey: 'api:data' }
const productionLogger = {
info: (msg, ctx) =>
console.log(JSON.stringify({ level: 'INFO', message: msg, ...ctx })),
warn: (msg, ctx) =>
console.warn(JSON.stringify({ level: 'WARN', message: msg, ...ctx })),
debug: () => {}, // No debug in production
error: (msg, ctx) =>
console.error(JSON.stringify({ level: 'ERROR', message: msg, ...ctx })),
};
const cache = new SharedCache(storage, {
logger: productionLogger,
});const devLogger = {
info: console.info.bind(console),
warn: console.warn.bind(console),
debug: console.debug.bind(console),
error: console.error.bind(console),
};
const cache = new SharedCache(storage, {
logger: devLogger,
});import { createLogger, LogLevel } from '@web-widget/shared-cache';
class CustomLogger {
info(message: unknown, ...params: unknown[]) {
this.log('INFO', message, ...params);
}
warn(message: unknown, ...params: unknown[]) {
this.log('WARN', message, ...params);
}
debug(message: unknown, ...params: unknown[]) {
this.log('DEBUG', message, ...params);
}
error(message: unknown, ...params: unknown[]) {
this.log('ERROR', message, ...params);
}
private log(level: string, message: unknown, ...params: unknown[]) {
const timestamp = new Date().toISOString();
const context = params[0] || {};
console.log(
JSON.stringify({
timestamp,
level,
service: 'shared-cache',
message,
...context,
})
);
}
}
const customLogger = new CustomLogger();
const structuredLogger = createLogger(customLogger, LogLevel.DEBUG);
const cache = new SharedCache(storage, {
logger: customLogger,
});All log messages include structured context data:
interface CacheLogContext {
url?: string; // Request URL
cacheKey?: string; // Generated cache key
status?: number; // HTTP status code
duration?: number; // Operation duration (ms)
error?: unknown; // Error object
cacheStatus?: string; // Cache result status
ttl?: number; // Time to live (seconds)
method?: string; // HTTP method
[key: string]: unknown; // Additional context
}- Use appropriate log levels: Don't log normal operations at ERROR level
- Include relevant context: URL, cache key, and timing information help with debugging
- Filter by environment: Use DEBUG level in development, INFO+ in production
- Monitor error logs: Set up alerts for ERROR level messages
- Structure your data: Use consistent context object structures for easier parsing
- DEBUG level: Can be verbose in high-traffic scenarios. Use sparingly in production
- Structured data: Context objects are not deeply cloned. Avoid modifying context after logging
- Async operations: Background revalidation errors are properly caught and logged without blocking responses
import { createLogger, LogLevel } from '@web-widget/shared-cache';
let hitCount = 0;
let totalCount = 0;
const monitoringLogger = {
info: (message, context) => {
if (context?.cacheStatus) {
totalCount++;
if (context.cacheStatus === 'HIT') hitCount++;
// Log hit rate every 100 requests
if (totalCount % 100 === 0) {
console.log(
`Cache hit rate: ${((hitCount / totalCount) * 100).toFixed(2)}%`
);
}
}
console.log(message, context);
},
warn: console.warn,
debug: console.debug,
error: console.error,
};
const cache = new SharedCache(storage, {
logger: createLogger(monitoringLogger, LogLevel.INFO),
});const performanceLogger = {
info: (message, context) => {
if (context?.duration) {
console.log(`${message} - Duration: ${context.duration}ms`, context);
} else {
console.log(message, context);
}
},
warn: console.warn,
debug: console.debug,
error: console.error,
};const alertingLogger = {
info: console.log,
warn: console.warn,
debug: console.debug,
error: (message, context) => {
console.error(message, context);
// Send alerts for critical cache errors
if (context?.error && message.includes('Put operation failed')) {
sendAlert(`Cache storage error: ${context.error.message}`);
}
},
};