-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.ts
121 lines (103 loc) · 2.59 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// NOTE: log4js appenders must be written in CommonJS
import * as Sentry from "@sentry/node";
// @ts-ignore: missing type definitions
import { dummyLayout } from "log4js/lib/layouts";
import type {
SeverityLevel,
User,
} from "@sentry/node";
import type { NodeClientOptions } from "@sentry/node/build/types/types";
import type {
AppenderFunction,
LayoutFunction,
LayoutsParam,
Levels,
Log4js,
LoggingEvent,
} from "log4js";
export interface Config extends Partial<NodeClientOptions> {
/**
* The Data Source Name (DSN) for connecting to the Sentry server.
*
* @see https://<project_name>.sentry.io/settings/projects/node/keys/
* @see https://docs.sentry.io/product/sentry-basics/dsn-explainer/#the-parts-of-the-dsn
*/
dsn: string;
/**
* Sentry user data for scope setting
*/
user?: User;
/**
* Levels to be reported to Sentry.
*/
levels?: SentryAppenderLevels[];
}
declare module "log4js" {
interface Appenders {
SentryAppender: {
type: "log4js-appender-sentry";
} & Config;
}
}
export type SentryAppenderLevels = keyof Pick<
Levels,
| "WARN"
| "ERROR"
| "FATAL"
>;
/**
* Map log4js string log levels to their corresponding Sentry levels.
*/
const levelMap = {
WARN: "warning",
ERROR: "error",
FATAL: "fatal",
} satisfies Record<SentryAppenderLevels, SeverityLevel | undefined>;
export function sentry(
config: Config,
levels: Levels,
layout: LayoutFunction,
): AppenderFunction {
Sentry.init(config);
function appender(loggingEvent: LoggingEvent) {
const eventLevel = levels.getLevel(loggingEvent.level.levelStr);
/**
* Sentry is mainly used to report application errors.
*/
if (eventLevel.isGreaterThanOrEqualTo(levels.WARN) === false) {
return;
}
Sentry.withScope((scope) => {
const level = eventLevel.levelStr as SentryAppenderLevels;
scope.setLevel(levelMap[level]);
scope.setExtra("category", loggingEvent.categoryName);
if (config.user) {
scope.setUser(config.user);
}
const msg = layout(loggingEvent);
const eventId = Sentry.captureMessage(msg);
// const eventId = Sentry.captureException(msg);
});
}
// @ts-ignore
(appender.shutdown as Log4js["shutdown"]) = (_error) => {
Sentry.close();
};
return appender;
}
export class ConfigError extends Error {
constructor(msg: string, cause?: unknown) {
super(msg);
this.name = this.constructor.name;
this.cause = cause;
}
}
export function configure(
config: Config,
layouts: LayoutsParam,
_findAppender: () => AppenderFunction,
levels: Levels,
): AppenderFunction {
const layout = layouts?.basicLayout ?? dummyLayout;
return sentry(config, levels, layout);
}