Files
gh-hopeoverture-worldbuildi…/skills/sentry-and-otel-setup/assets/logger.ts
2025-11-29 18:46:44 +08:00

80 lines
1.9 KiB
TypeScript

import * as Sentry from '@sentry/nextjs';
type LogLevel = 'debug' | 'info' | 'warn' | 'error';
interface LogContext {
[key: string]: unknown;
}
class Logger {
private log(level: LogLevel, message: string, context?: LogContext) {
// Add context as Sentry breadcrumb
if (context) {
Sentry.addBreadcrumb({
category: 'log',
message,
level,
data: context,
});
}
// Also log to console in development
if (process.env.NODE_ENV === 'development') {
const logFn = console[level] || console.log;
logFn(`[${level.toUpperCase()}] ${message}`, context || '');
}
}
debug(message: string, context?: LogContext) {
this.log('debug', message, context);
}
info(message: string, context?: LogContext) {
this.log('info', message, context);
}
warn(message: string, context?: LogContext) {
this.log('warn', message, context);
// Set context for next error
if (context) {
Sentry.setContext('warning', context);
}
}
error(message: string, context?: LogContext & { error?: Error }) {
this.log('error', message, context);
// Capture as Sentry error with context
const error = context?.error || new Error(message);
Sentry.captureException(error, {
level: 'error',
contexts: {
custom: context,
},
});
}
// Set user context for all subsequent logs/errors
setUser(user: { id: string; email?: string; username?: string }) {
Sentry.setUser(user);
}
// Clear user context (e.g., on logout)
clearUser() {
Sentry.setUser(null);
}
// Add custom tags for filtering in Sentry
setTag(key: string, value: string) {
Sentry.setTag(key, value);
}
// Add context that persists across logs
setContext(key: string, context: LogContext) {
Sentry.setContext(key, context);
}
}
export const logger = new Logger();