@catsle/caretta v1.0.3
Caretta Logger
A powerful, extensible logging system for JavaScript applications with support for federated analytics and plugin architecture.
Quick Start
import { createLogger, LogLevel, Logger } from '@catsle/caretta';
// Set global log level
Logger.setGlobalLevel(LogLevel.WARN);
// Create a logger for your component
const logger = createLogger('MyComponent');
// This won't log (below global level)
logger.debug('Debug information');
// Set instance-specific level
logger.setLevel(LogLevel.DEBUG);
// This will log now!
logger.debug('Debug information'); // showsWhy Caretta?
Modern applications need more than just console logs. You need structured logging that works across environments, integrates with monitoring systems, and scales with your architecture. Most logging libraries either:
- Do too little - just wrapping console.log with minimal features
- Do too much - forcing specific backends or workflows
- Aren't designed for today's federated systems and analytics needs
Caretta solves these problems with a flexible, plugin-based architecture that:
- Puts you in control of where your logs go
- Works consistently across browsers, Node.js, and other JavaScript environments
- Enables federated analytics without vendor lock-in
- Provides powerful developer tools without sacrificing performance
Table of Contents
- Installation
- Core Concepts
- Global vs. Instance Configuration
- Plugins
- Federated Analytics
- Advanced Usage
- Recipes
- API Reference
- Contributing
Documentation
For comprehensive documentation, visit:
Installation
# Using npm
npm install @catsle/caretta
# Using pnpm (recommended)
pnpm add @catsle/caretta
# Using yarn
yarn add @catsle/carettaCore Concepts
Loggers
Loggers are the main interface you'll interact with. Each logger has:
- A unique context name to identify its source
- Level-based methods (.debug(), .info(), .warn(), .error())
- Metadata support
- Instance-specific configuration
import { createLogger } from '@catsle/caretta';
// Create a named logger
const logger = createLogger('AuthService');
// Basic logging
logger.info('User login attempt');
// With metadata
logger.info('Login successful', { userId: '123', method: 'oauth' });
// With error objects
logger.error('Authentication failed', new Error('Invalid credentials'));Log Levels
Caretta provides standard log levels with symbolic values and a overridable method that enables numeric comparison of log leves to support custom log levels.
import { LogLevel } from '@catsle/caretta';
// Available levels (from most to least verbose)
LogLevel.DEBUG // Detailed debugging information
LogLevel.INFO // Interesting runtime events
LogLevel.WARN // Warning conditions
LogLevel.ERROR // Error conditions
LogLevel.ALWAYS // Critical information, never filteredMetadata
Add context to your logs with metadata at multiple levels:
import { Logger, createLogger } from '@catsle/caretta';
// Global metadata (applied to all loggers)
Logger.setGlobalMetadata('version', '2.3.0');
Logger.setGlobalMetadata('environment', 'production');
// Instance metadata (applied to all logs from this instance)
const userLogger = createLogger('UserService');
userLogger.setMetadata('component', 'Authentication');
// Log-specific metadata (just for this log entry)
userLogger.info('Operation completed', {
duration: 127,
cacheHit: true
});Global vs. Instance Configuration
Caretta lets you configure logging at both global and instance levels:
import { Logger, LogLevel, createLogger } from '@catsle/caretta';
// === Global Configuration ===
// Set the global minimum log level
Logger.setGlobalLevel(LogLevel.INFO);
// Register plugins for all loggers
import { ConsolePlugin } from '@catsle/caretta-console-plugin';
Logger.registerPlugin(new ConsolePlugin({ colors: true }));
// === Instance Configuration ===
const apiLogger = createLogger('APIClient');
const dbLogger = createLogger('Database');
// Override global level for specific loggers
apiLogger.setLevel(LogLevel.DEBUG); // More verbose for API debugging
dbLogger.setLevel(LogLevel.WARN); // Less noise from database
// Add logger-specific metadata
apiLogger.setMetadata('module', 'external-api');Plugins
Caretta's power comes from its plugin architecture. Plugins receive log entries and can:
- Format and output logs to different destinations
- Filter or transform log data
- Integrate with monitoring and analytics systems
- Provide developer tools
Official Plugins
import { Logger } from '@catsle/caretta';
// Console output with formatting
import { ConsolePlugin } from '@catsle/caretta-console-plugin';
Logger.registerPlugin(new ConsolePlugin({
colors: true,
timestamp: true
}));
// Error tracking with Sentry
import { SentryPlugin } from '@catsle/caretta-sentry-plugin';
import * as Sentry from '@sentry/browser';
Logger.registerPlugin(new SentryPlugin({ sentry: Sentry }));
// In-browser log viewer
import { BrowserLogViewerPlugin } from '@catsle/caretta-browser-viewer';
Logger.registerPlugin(new BrowserLogViewerPlugin());Creating Your Own Plugin
import { LoggerPlugin, LogEntry } from '@catsle/caretta';
class MetricsPlugin implements LoggerPlugin {
name = 'metricsPlugin';
initialize() {
// Setup connections, initialize storage, etc.
}
process(entry: LogEntry) {
if (entry.level === LogLevel.ERROR) {
// Track error metrics
trackErrorMetric(entry.context, entry.message);
}
// Process log-specific metadata
if (entry.metadata?.duration) {
trackDurationMetric(entry.context, entry.metadata.duration);
}
}
cleanup() {
// Close connections, flush buffers, etc.
}
}
// Register your plugin
Logger.registerPlugin(new MetricsPlugin());Federated Analytics
Caretta supports federated analytics, allowing you to collect insights across your application ecosystem without centralized dependencies.
import { Logger } from '@catsle/caretta';
import { AnalyticsPlugin } from '@catsle/caretta-analytics';
// Setup federated analytics
Logger.registerPlugin(new AnalyticsPlugin({
endpoint: 'https://analytics.example.com/collect',
sampleRate: 0.1, // Sample 10% of events
consent: () => userHasOptedIn(), // Respect user preferences
eventMapping: (entry) => {
// Map log entries to analytics events
return {
eventName: `${entry.context}:${entry.levelName}`,
properties: entry.metadata || {}
};
}
}));
// Now regular logs can trigger analytics when appropriate
const checkoutLogger = createLogger('Checkout');
checkoutLogger.info('Purchase completed', {
amount: 99.99,
productId: 'PRD-123',
currency: 'USD'
});Benefits of federated analytics with Caretta:
- Unified logging and analytics instrumentation
- Consistent sampling and filtering across services
- Privacy controls built-in
- No vendor lock-in
Advanced Usage
Environment Detection
import { Logger, LogLevel, createLogger } from '@catsle/caretta';
// Configure based on environment
const isDevelopment = process.env.NODE_ENV !== 'production';
Logger.setGlobalLevel(isDevelopment ? LogLevel.DEBUG : LogLevel.INFO);
// Add environment-specific plugins
if (isDevelopment) {
const { DevToolsPlugin } = require('@catsle/caretta-devtools');
Logger.registerPlugin(new DevToolsPlugin());
} else {
const { CloudWatchPlugin } = require('@catsle/caretta-cloudwatch');
Logger.registerPlugin(new CloudWatchPlugin({ region: 'us-west-2' }));
}Log Management
import { Logger, createLogger } from '@catsle/caretta';
// Create loggers for different components
const authLogger = createLogger('Auth');
const apiLogger = createLogger('API');
const uiLogger = createLogger('UI');
// List all registered loggers (useful for debugging)
Logger.listFormatted();
// Output:
// | Context | Level | Enabled | Instance Level |
// |---------|-------|---------|---------------|
// | Auth | INFO | Yes | (Global) |
// | API | INFO | Yes | DEBUG |
// | UI | INFO | Yes | (Global) |
// Disable noisy loggers temporarily
Logger.disableByContext('API');
// Later, re-enable with specific level
Logger.enableByContext('API', LogLevel.WARN);Global Access
// After importing and setting up @catsle/caretta
import { setupGlobalAccess } from '@catsle/caretta';
// Make logger available globally
await setupGlobalAccess();
// Now you can access logger anywhere, even in imported scripts
console.log('Global logger available:', typeof globalThis.log !== 'undefined');
// Create new loggers
const logger = globalThis.log.create('GlobalExample');
// Use global helpers
globalThis.log.setLevel(globalThis.log.levels.DEBUG);Recipes
React Application Setup
// src/logging/setup.ts
import { Logger, LogLevel, createLogger } from '@catsle/caretta';
import { ConsolePlugin } from '@catsle/caretta-console-plugin';
import { ReactLoggerPlugin } from '@catsle/caretta-react';
export function setupLogging() {
// Configure based on environment
const isDev = process.env.NODE_ENV === 'development';
Logger.setGlobalLevel(isDev ? LogLevel.DEBUG : LogLevel.INFO);
// Add application metadata
Logger.setGlobalMetadata('appVersion', process.env.APP_VERSION);
Logger.setGlobalMetadata('environment', process.env.NODE_ENV);
// Register plugins
Logger.registerPlugin(new ConsolePlugin({ colors: isDev }));
Logger.registerPlugin(new ReactLoggerPlugin());
// Production-only plugins
if (!isDev) {
import('@catsle/caretta-sentry-plugin').then(({ SentryPlugin }) => {
Logger.registerPlugin(new SentryPlugin({ dsn: process.env.SENTRY_DSN }));
});
}
// Return root logger
return createLogger('App');
}
// In your React components:
import { createLogger } from '@catsle/caretta';
function UserProfile({ userId }) {
const logger = createLogger('UserProfile');
useEffect(() => {
logger.info('Component mounted', { userId });
return () => {
logger.debug('Component unmounted');
};
}, [userId]);
// Rest of component...
}Node.js API Server
// src/logger.ts
import { Logger, LogLevel, createLogger } from '@catsle/caretta';
import { ConsolePlugin } from '@catsle/caretta-console-plugin';
import { PinoPlugin } from '@catsle/caretta-pino';
export function initializeLogging() {
// Set up global configuration
Logger.setGlobalLevel(process.env.LOG_LEVEL || LogLevel.INFO);
// Add server metadata
Logger.setGlobalMetadata('serverId', process.env.SERVER_ID);
Logger.setGlobalMetadata('region', process.env.AWS_REGION);
// Register plugins
Logger.registerPlugin(new ConsolePlugin({
format: 'json',
timestamp: true
}));
// Use Pino for production logging
if (process.env.NODE_ENV === 'production') {
Logger.registerPlugin(new PinoPlugin({
destination: pino.destination({
dest: process.env.LOG_FILE || '/var/log/app.log',
sync: false
})
}));
}
}
// In your API routes:
import { createLogger } from '@catsle/caretta';
const apiLogger = createLogger('API');
app.get('/users/:id', (req, res) => {
apiLogger.info('User request', {
userId: req.params.id,
ip: req.ip,
route: '/users/:id'
});
// Rest of handler...
});API Reference
See the full API documentation for complete details.
Contributing
We welcome contributions! See CONTRIBUTING.md for details.
License
MIT