Skip to content

Commit 2c04e18

Browse files
committed
Extract functions from server roarr into shared logging module
1 parent a9ad5df commit 2c04e18

File tree

4 files changed

+97
-76
lines changed

4 files changed

+97
-76
lines changed

src/lib/server/roarr/client.ts

Lines changed: 27 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
11
import { Roarr, logLevels, type LogLevelName } from 'roarr';
2-
import callsites from 'callsites';
32
import { config } from '$lib/server/core/config';
43
import type {
5-
LoggerContext,
6-
LoggerContextWithError,
7-
LoggerLoggingMethodName,
4+
ServerLoggerContext,
5+
ServerLoggerContextWithError,
6+
ServerLoggerLoggingMethodName,
87
} from './types';
98
import { serializeError } from 'serialize-error';
109
import { sentry } from '$lib/shared/sentry';
11-
import { getTraceId } from '$lib/shared/sentry/utils';
1210
import type { SeverityLevel } from '$lib/shared/sentry/types';
11+
import {
12+
enrichContextWithDebugInfo,
13+
enrichLoggerContextWithSentryTraceId,
14+
} from '$lib/shared/logging/utils';
1315

1416
export const roarr = (function () {
15-
const createLogger = (methodName: LoggerLoggingMethodName) => {
17+
const createLogger = (methodName: ServerLoggerLoggingMethodName) => {
1618
return (
1719
message: string,
18-
context: LoggerContextWithError = {},
20+
context: ServerLoggerContextWithError = {},
1921
stackLevel: number = 3,
2022
) => {
2123
if (!shouldBeLogged(methodName)) {
@@ -24,11 +26,15 @@ export const roarr = (function () {
2426

2527
let contextClone = serializeErrorInContext(context);
2628
contextClone = enrichContextWithLogType(contextClone);
27-
contextClone = enrichContextWithSentryTraceId(contextClone);
29+
contextClone = enrichLoggerContextWithSentryTraceId(contextClone);
2830

2931
Roarr[methodName](
3032
config.roarr.isDebugContextShown
31-
? enrichContextWithDebugInfo(contextClone, stackLevel)
33+
? enrichContextWithDebugInfo(
34+
contextClone,
35+
config.folders.root,
36+
stackLevel,
37+
)
3238
: contextClone,
3339
message,
3440
);
@@ -44,9 +50,9 @@ export const roarr = (function () {
4450

4551
const roarrLoggingMethodNamesNoOnce = Object.keys(Roarr).filter((property) =>
4652
Object.keys(logLevels).includes(property),
47-
) as LoggerLoggingMethodName[];
53+
) as ServerLoggerLoggingMethodName[];
4854
const roarrLoggingMethodNamesOnce = roarrLoggingMethodNamesNoOnce.map(
49-
(methodName) => `${methodName}Once` as LoggerLoggingMethodName,
55+
(methodName) => `${methodName}Once` as ServerLoggerLoggingMethodName,
5056
);
5157
const roarrLoggingMethodNames = [
5258
...roarrLoggingMethodNamesNoOnce,
@@ -58,10 +64,10 @@ export const roarr = (function () {
5864
return acc;
5965
},
6066
{} as Record<
61-
LoggerLoggingMethodName,
67+
ServerLoggerLoggingMethodName,
6268
(
6369
message: string,
64-
context?: LoggerContextWithError,
70+
context?: ServerLoggerContextWithError,
6571
stackLevel?: number,
6672
) => void
6773
>,
@@ -70,7 +76,7 @@ export const roarr = (function () {
7076
return roarrLogger;
7177
})();
7278

73-
function shouldBeLogged(methodName: LoggerLoggingMethodName): boolean {
79+
function shouldBeLogged(methodName: ServerLoggerLoggingMethodName): boolean {
7480
const requestedLogLevelName = methodName.replace('Once', '') as LogLevelName;
7581
const requestedLogLevel = logLevels[requestedLogLevelName];
7682
const minLogLevel = logLevels[config.roarr.minLogLevel as LogLevelName];
@@ -79,11 +85,11 @@ function shouldBeLogged(methodName: LoggerLoggingMethodName): boolean {
7985
}
8086

8187
function serializeErrorInContext(
82-
context: LoggerContextWithError,
83-
): LoggerContext {
88+
context: ServerLoggerContextWithError,
89+
): ServerLoggerContext {
8490
const errorContext = context.error;
8591
if (!errorContext || !(errorContext instanceof Error)) {
86-
return { ...context } as LoggerContext;
92+
return { ...context } as ServerLoggerContext;
8793
}
8894

8995
return {
@@ -92,65 +98,17 @@ function serializeErrorInContext(
9298
};
9399
}
94100

95-
function enrichContextWithSentryTraceId(context: LoggerContext): LoggerContext {
96-
if (!sentry) {
97-
return { ...context };
98-
}
99-
100-
const traceId = getTraceId();
101-
if (!traceId) {
102-
return { ...context };
103-
}
104-
105-
return {
106-
...context,
107-
sentryTraceId: traceId,
108-
};
109-
}
110-
111-
function enrichContextWithDebugInfo(
112-
context: LoggerContext = {},
113-
stackLevel: number = 3,
114-
): LoggerContext {
115-
return {
116-
...context,
117-
callName: getCallName(stackLevel),
118-
fileName: getFileName(stackLevel),
119-
};
120-
}
121-
122-
function enrichContextWithLogType(context: LoggerContext): LoggerContext {
101+
function enrichContextWithLogType(
102+
context: ServerLoggerContext,
103+
): ServerLoggerContext {
123104
return {
124105
logType: 'app',
125106
...context,
126107
};
127108
}
128109

129-
function getCallName(stackLevel: number = 3): string {
130-
const typeName = callsites()[stackLevel]?.getTypeName() ?? '';
131-
const functionName =
132-
callsites()[3]?.getFunctionName() ??
133-
callsites()[stackLevel]?.getMethodName() ??
134-
'';
135-
136-
if (typeName) {
137-
return `${typeName}.${functionName}`;
138-
}
139-
140-
return functionName;
141-
}
142-
143-
function getFileName(stackLevel: number = 3): string {
144-
const fileName =
145-
callsites()[stackLevel]?.getFileName() ??
146-
callsites()[stackLevel]?.getEvalOrigin() ??
147-
'';
148-
149-
return fileName.replace(config.folders.root, '');
150-
}
151-
152110
function convertLogLevelNameRoarrToSentry(
153-
methodName: LoggerLoggingMethodName,
111+
methodName: ServerLoggerLoggingMethodName,
154112
): SeverityLevel {
155113
const methodNameWithoutOnce = methodName.replace('Once', '');
156114

src/lib/server/roarr/types/index.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
* Don't import from `node_modules/roarr/src/types.ts` directly to avoid type errors.
44
*/
55

6+
import type { LoggerContext } from '$lib/shared/logging/types';
67
import type { LogLevelName } from 'roarr';
78

8-
export type LoggerLoggingMethodName =
9-
| LoggerLoggingMethodNameNoOnce
10-
| LoggerLoggingMethodNameOnce;
9+
export type ServerLoggerLoggingMethodName =
10+
| ServerLoggerLoggingMethodNameNoOnce
11+
| ServerLoggerLoggingMethodNameOnce;
1112

1213
export type JsonObject = {
1314
[k: string]: JsonValue;
@@ -22,18 +23,19 @@ export type JsonValue =
2223
| null
2324
| undefined;
2425

25-
export interface LoggerContext extends JsonObject {
26+
export interface ServerLoggerContext extends JsonObject, LoggerContext {
2627
error?: JsonValue;
2728
sentryTraceId?: string;
2829
}
2930

30-
export interface LoggerContextWithError {
31+
export interface ServerLoggerContextWithError extends LoggerContext {
3132
error?: Error | JsonValue;
3233
sentryTraceId?: string;
3334
// WARN: Other properties should not have an `Error` type, but I don't know
3435
// how to enforce it in combination with the type of `error` property.
3536
[k: string]: Error | JsonValue;
3637
}
3738

38-
type LoggerLoggingMethodNameNoOnce = LogLevelName;
39-
type LoggerLoggingMethodNameOnce = `${LoggerLoggingMethodNameNoOnce}Once`;
39+
type ServerLoggerLoggingMethodNameNoOnce = LogLevelName;
40+
type ServerLoggerLoggingMethodNameOnce =
41+
`${ServerLoggerLoggingMethodNameNoOnce}Once`;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export interface LoggerContext {
2+
sentryTraceId?: string;
3+
[k: string]: any;
4+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { sentry } from '$lib/shared/sentry';
2+
import { getTraceId } from '$lib/shared/sentry/utils';
3+
import callsites from 'callsites';
4+
import type { LoggerContext } from '../types';
5+
6+
export function enrichLoggerContextWithSentryTraceId<T extends LoggerContext>(
7+
context: T,
8+
): T {
9+
if (!sentry) {
10+
return { ...context };
11+
}
12+
13+
const traceId = getTraceId();
14+
if (!traceId) {
15+
return { ...context };
16+
}
17+
18+
return {
19+
...context,
20+
sentryTraceId: traceId,
21+
};
22+
}
23+
24+
export function enrichContextWithDebugInfo(
25+
context: LoggerContext = {},
26+
rootFolder = '',
27+
stackLevel: number = 3,
28+
): LoggerContext {
29+
return {
30+
...context,
31+
callName: getCallName(stackLevel),
32+
fileName: getFileName(rootFolder, stackLevel),
33+
};
34+
}
35+
36+
function getCallName(stackLevel: number = 3): string {
37+
const typeName = callsites()[stackLevel]?.getTypeName() ?? '';
38+
const functionName =
39+
callsites()[3]?.getFunctionName() ??
40+
callsites()[stackLevel]?.getMethodName() ??
41+
'';
42+
43+
if (typeName) {
44+
return `${typeName}.${functionName}`;
45+
}
46+
47+
return functionName;
48+
}
49+
50+
function getFileName(rootFolder = '', stackLevel: number = 3): string {
51+
const fileName =
52+
callsites()[stackLevel]?.getFileName() ??
53+
callsites()[stackLevel]?.getEvalOrigin() ??
54+
'';
55+
56+
return fileName.replace(rootFolder, '');
57+
}

0 commit comments

Comments
 (0)