80 lines
1.9 KiB
TypeScript
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();
|