imexs-audit-trail-plugin
v1.0.0
Published
Production-ready Audit Trail Plugin for Node.js with TypeScript - Performance Monitoring, System Integration Audit, Data Accountability & User Activity Tracking
Downloads
2
Maintainers
Readme
@imexs/audit-trail-plugin
Production-ready Audit Trail Plugin for Node.js + TypeScript with Performance Monitoring, System Integration Audit, Data Accountability & User Activity Tracking
🚀 Features
- ✅ Performance Monitoring - Track query execution times, memory usage, and CPU utilization
- ✅ System Integration Audit - Log external API calls and third-party service interactions
- ✅ Data Accountability & Compliance - Track data access and policy enforcement
- ✅ User Activity Tracking - Monitor user actions and behavior
- ✅ Clean Architecture - Modular, dependency injection, TypeScript strict mode
- ✅ Event-Driven - Built-in pub/sub event bus for extensibility
- ✅ PII Protection - Automatic masking of sensitive fields
- ✅ Express Middleware - Easy HTTP request/response logging
- ✅ Axios Interceptor - Automatic API call logging
- ✅ Method Decorators - Track method execution with @TrackMethod
- ✅ PostgreSQL - Full migration support with Knex.js
📦 Installation
npm install @imexs/audit-trail-pluginPeer Dependencies
npm install knex pg uuid
npm install --save-dev @types/node @types/uuid
# Optional (if using middleware/interceptors)
npm install express axios
npm install --save-dev @types/express🗄️ Database Setup
1. Configure Database Connection
Create a .env file:
DB_HOST=localhost
DB_PORT=5432
DB_NAME=audit_trail_db
DB_USER=postgres
DB_PASSWORD=postgres
DB_SSL=false
APP_NAME=my-app
AUDIT_ENABLED=true
AUDIT_TABLE_PREFIX=2. Run Migrations
# Run migrations
npx knex migrate:latest
# Seed default categories
npx knex seed:runThis creates the following tables:
audit_trail_categories- Category definitionsaudit_trail- Main audit log table
🎯 Quick Start
Basic Usage
import { AuditTrail, ConfigManager } from '@imexs/audit-trail-plugin';
// Initialize configuration (optional - uses env vars by default)
ConfigManager.getInstance({
appName: 'my-app',
enabled: true,
database: {
host: 'localhost',
port: 5432,
database: 'audit_trail_db',
user: 'postgres',
password: 'postgres'
}
});
// Get audit trail instance
const auditTrail = AuditTrail.getInstance();
// Log user activity
await auditTrail.logUserActivity({
user_id: 'user-123',
action: 'CREATE',
entity: 'product',
before: null,
after: { id: 'prod-1', name: 'New Product', price: 99.99 },
ip_address: '192.168.1.1',
metadata: { source: 'web-app' }
});
// Log performance
await auditTrail.logPerformance({
query: 'SELECT * FROM products WHERE category = ?',
duration: 45,
memory_usage: 1024,
cpu_usage: 15,
user_id: 'user-123'
});
// Log integration
await auditTrail.logIntegration({
integration_name: 'stripe_api',
request: {
url: 'https://api.stripe.com/v1/charges',
method: 'POST',
body: { amount: 1000, currency: 'usd' }
},
response: {
status: 200,
data: { id: 'ch_123', status: 'succeeded' }
},
status_code: 200,
latency: 234,
user_id: 'user-123'
});
// Log compliance/data access
await auditTrail.logCompliance({
user_id: 'user-123',
data_access: 'customer_pii',
policy_name: 'GDPR_ACCESS_POLICY',
field_accessed: ['email', 'phone', 'address'],
is_allowed: true,
ip_address: '192.168.1.1'
});🔌 Express Middleware
Setup HTTP Logger
import express from 'express';
import { createHttpLogger } from '@imexs/audit-trail-plugin';
const app = express();
// Add audit middleware
app.use(createHttpLogger({
captureBody: true,
captureHeaders: false,
excludePaths: ['/health', '/metrics'],
getUserId: (req) => req.user?.id // Extract user ID from request
}));
// Your routes
app.post('/api/products', (req, res) => {
res.json({ success: true });
});
app.listen(3000);Simple Usage
import { httpLogger } from '@imexs/audit-trail-plugin';
app.use(httpLogger); // Uses default options🌐 Axios Interceptor
Setup Axios Logging
import axios from 'axios';
import { setupAxiosInterceptor } from '@imexs/audit-trail-plugin';
const apiClient = axios.create({
baseURL: 'https://api.example.com'
});
setupAxiosInterceptor(apiClient, {
integrationName: 'external_api',
captureRequestBody: true,
captureResponseBody: true,
captureHeaders: false,
getUserId: () => getCurrentUserId(), // Your user context function
getIpAddress: () => getCurrentUserIp()
});
// All requests are now automatically logged
const response = await apiClient.get('/users');Create Audited Instance
import axios from 'axios';
import { createAuditedAxiosInstance } from '@imexs/audit-trail-plugin';
const apiClient = createAuditedAxiosInstance(
axios.create({ baseURL: 'https://api.example.com' }),
{ integrationName: 'payment_gateway' }
);🎨 Method Decorators
@TrackMethod Decorator
import { TrackMethod, TrackUserActivity, TrackPerformance } from '@imexs/audit-trail-plugin';
class UserService {
@TrackUserActivity('CREATE_USER', 'user')
async createUser(userData: any) {
// Your implementation
return { id: '123', ...userData };
}
@TrackPerformance('database')
async fetchUsers() {
// Automatically tracks execution time
return await db.query('SELECT * FROM users');
}
@TrackMethod({
action: 'UPDATE_USER',
entity: 'user',
captureArgs: true,
captureResult: true,
maskFields: ['password', 'ssn']
})
async updateUser(userId: string, updates: any) {
// Implementation
return { id: userId, ...updates };
}
}Available Decorators
@TrackMethod(options)- General purpose method tracking@TrackPerformance(entity?)- Performance monitoring@TrackUserActivity(action?, entity?)- User activity tracking@TrackDataAccess(entity?)- Data access tracking
⚙️ Configuration
Override Default Config
import { ConfigManager } from '@imexs/audit-trail-plugin';
const config = ConfigManager.getInstance();
config.updateConfig({
maskedFields: ['password', 'token', 'ssn', 'credit_card'],
categories: {
performance_monitoring: true,
system_integration: true,
data_accountability: true,
user_activity: true
},
defaultSeverity: 'INFO',
autoFlush: true,
flushInterval: 5000 // 5 seconds
});Configuration Options
interface AuditConfig {
appName: string;
enabled: boolean;
database: {
host: string;
port: number;
database: string;
user: string;
password: string;
ssl?: boolean;
pool?: { min: number; max: number };
};
tablePrefix?: string; // Prefix for audit tables
maskedFields: string[]; // Fields to mask in logs
categories: {
performance_monitoring?: boolean;
system_integration?: boolean;
data_accountability?: boolean;
user_activity?: boolean;
};
defaultSeverity: 'INFO' | 'WARN' | 'ERROR' | 'CRITICAL';
autoFlush?: boolean; // Auto-flush pending logs
flushInterval?: number; // Flush interval in ms
}🔍 Querying Audit Logs
import { AuditTrail } from '@imexs/audit-trail-plugin';
const auditTrail = AuditTrail.getInstance();
// Query by user
const userLogs = await auditTrail.query({
actor_user_id: 'user-123'
}, 50);
// Query by action
const createLogs = await auditTrail.query({
action: 'CREATE',
entity: 'product'
}, 100);
// Query by severity
const criticalLogs = await auditTrail.query({
severity: 'CRITICAL'
}, 20);🛡️ Data Sanitization
Automatic PII Masking
import { DataSanitizer } from '@imexs/audit-trail-plugin';
const sanitizer = new DataSanitizer(['ssn', 'credit_card']);
const data = {
name: 'John Doe',
email: '[email protected]',
password: 'secret123',
ssn: '123-45-6789',
credit_card: '4111111111111111'
};
const sanitized = sanitizer.sanitize(data);
// {
// name: 'John Doe',
// email: '[email protected]',
// password: '***MASKED***',
// ssn: '***MASKED***',
// credit_card: '***MASKED***'
// }Custom Masked Fields
sanitizer.addMaskedFields(['custom_field', 'sensitive_data']);📊 Event Bus
Subscribe to Audit Events
import { AuditEventBus } from '@imexs/audit-trail-plugin';
const eventBus = AuditEventBus.getInstance();
// Listen to all audit logs
eventBus.on('audit:log', (record) => {
console.log('New audit log:', record);
// Send to external monitoring service
});
// Listen once
eventBus.once('audit:log', (record) => {
console.log('First audit log:', record);
});
// Emit custom events
eventBus.emit('custom:event', { data: 'value' });🔧 Advanced Usage
Manual Flush
const auditTrail = AuditTrail.getInstance();
// Manually flush pending logs
await auditTrail.flush();Graceful Shutdown
process.on('SIGTERM', async () => {
const auditTrail = AuditTrail.getInstance();
await auditTrail.shutdown(); // Flushes logs and closes DB connection
process.exit(0);
});Custom Table Prefix
// In .env
AUDIT_TABLE_PREFIX=myapp
// Creates tables: myapp_audit_trail, myapp_audit_trail_categories📝 Database Schema
audit_trail_categories
| Column | Type | Description | |--------|------|-------------| | category_id | UUID | Primary key | | category_name | TEXT | Category name (unique) | | description | TEXT | Category description | | created_at | TIMESTAMP | Creation timestamp | | updated_at | TIMESTAMP | Update timestamp |
audit_trail
| Column | Type | Description | |--------|------|-------------| | audit_id | UUID | Primary key | | timestamp | TIMESTAMP | Event timestamp | | category_id | UUID | Foreign key to categories | | severity | ENUM | INFO, WARN, ERROR, CRITICAL | | actor_user_id | TEXT | User who performed action | | ip_address | TEXT | IP address | | action | TEXT | Action performed | | entity | TEXT | Entity affected | | before_data | JSONB | State before change | | after_data | JSONB | State after change | | metadata | JSONB | Additional metadata | | integration_name | TEXT | Integration name | | processing_time_ms | INTEGER | Processing time | | status_code | INTEGER | HTTP status code | | error_message | TEXT | Error message if any | | created_at | TIMESTAMP | Creation timestamp | | updated_at | TIMESTAMP | Update timestamp |
🧪 Testing
import { DatabaseManager } from '@imexs/audit-trail-plugin';
// Test database connection
const db = DatabaseManager.getInstance();
const isConnected = await db.testConnection();
console.log('Database connected:', isConnected);📚 TypeScript Support
Full TypeScript support with strict mode enabled. All types are exported:
import {
AuditTrailRecord,
PerformanceLogInput,
IntegrationLogInput,
UserActivityLogInput,
ComplianceLogInput,
SeverityLevel,
AuditCategory
} from '@imexs/audit-trail-plugin';🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
📄 License
MIT © IMEXS
🔗 Links
💡 Examples
Check out the /examples directory for more usage examples:
- Express.js integration
- NestJS integration
- Microservices setup
- Custom event handlers
🐛 Troubleshooting
Database Connection Issues
// Test connection
const db = DatabaseManager.getInstance();
const connected = await db.testConnection();
if (!connected) {
console.error('Failed to connect to database');
}Logs Not Appearing
// Check if audit trail is enabled
const config = ConfigManager.getInstance();
console.log('Enabled:', config.isEnabled());
// Manually flush logs
await auditTrail.flush();Performance Issues
// Increase flush interval
config.updateConfig({
flushInterval: 10000 // 10 seconds
});
// Or disable auto-flush and flush manually
config.updateConfig({
autoFlush: false
});📞 Support
For issues and questions:
- GitHub Issues: Create an issue
- Email: [email protected]
Built with ❤️ by IMEXS Team
