Skip to content

Commit d3bf790

Browse files
committed
feat: PrettyLogger enableColors option
1 parent 6d59e3a commit d3bf790

File tree

3 files changed

+108
-31
lines changed

3 files changed

+108
-31
lines changed

.changeset/silver-spoons-mix.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"effect-log": minor
3+
---
4+
5+
Add `enableColors` option for PrettyLogger.

readme.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ const logger = PrettyLog.layer({
2121
showFiberId: true,
2222
showTime: true,
2323
showSpans: true,
24+
enableColors: true,
2425
});
2526

2627
pipe(exampleEffect, Effect.provide(logger), Effect.runSync);

src/PrettyLogger.ts

Lines changed: 102 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { List, LogSpan } from "effect";
22
import * as Cause from "effect/Cause";
33
import * as FiberId from "effect/FiberId";
4-
import { pipe } from "effect/Function";
4+
import { identity, pipe } from "effect/Function";
55
import * as HashMap from "effect/HashMap";
66
import * as Layer from "effect/Layer";
77
import * as LogLevel from "effect/LogLevel";
@@ -10,6 +10,36 @@ import * as ReadonlyArray from "effect/ReadonlyArray";
1010

1111
import { serializeUnknown } from "effect-log/internal";
1212

13+
const SEVERITY_TO_COLOR: Record<
14+
LogLevel.LogLevel["_tag"],
15+
(c: ColorService) => (s: string) => string
16+
> = {
17+
All: (c: ColorService) => c.white,
18+
None: (c: ColorService) => c.white,
19+
Info: (c: ColorService) => c.green,
20+
Debug: (c: ColorService) => c.blue,
21+
Error: (c: ColorService) => c.red,
22+
Fatal: (c: ColorService) => c.boldRed,
23+
Trace: (c: ColorService) => c.dimWhite,
24+
Warning: (c: ColorService) => c.yellow,
25+
};
26+
27+
interface ColorService {
28+
bold(text: string): string;
29+
dim(text: string): string;
30+
italic(text: string): string;
31+
32+
red(text: string): string;
33+
green(text: string): string;
34+
yellow(text: string): string;
35+
blue(text: string): string;
36+
white(text: string): string;
37+
38+
dimItalic(text: string): string;
39+
dimWhite(text: string): string;
40+
boldRed(text: string): string;
41+
}
42+
1343
const RESET = "\x1b[0m";
1444
const BOLD = "\x1b[1m";
1545
const DIM = "\x1b[2m";
@@ -21,34 +51,57 @@ const YELLOW = "\x1b[33m";
2151
const BLUE = "\x1b[34m";
2252
const WHITE = "\x1b[37m";
2353

24-
const SEVERITY_TO_COLOR: Record<LogLevel.LogLevel["_tag"], string> = {
25-
All: WHITE,
26-
None: WHITE,
27-
Info: GREEN,
28-
Debug: BLUE,
29-
Error: RED,
30-
Fatal: BOLD + RED,
31-
Trace: DIM + WHITE,
32-
Warning: YELLOW,
54+
const enabledColorService: ColorService = {
55+
bold: (text: string) => `${BOLD}${text}${RESET}`,
56+
dim: (text: string) => `${DIM}${text}${RESET}`,
57+
italic: (text: string) => `${ITALIC}${text}${RESET}`,
58+
59+
red: (text: string) => `${RED}${text}${RESET}`,
60+
green: (text: string) => `${GREEN}${text}${RESET}`,
61+
yellow: (text: string) => `${YELLOW}${text}${RESET}`,
62+
blue: (text: string) => `${BLUE}${text}${RESET}`,
63+
white: (text: string) => `${WHITE}${text}${RESET}`,
64+
65+
dimItalic: (text: string) => `${DIM}${ITALIC}${text}${RESET}`,
66+
dimWhite: (text: string) => `${DIM}${WHITE}${text}${RESET}`,
67+
boldRed: (text: string) => `${BOLD}${RED}${text}${RESET}`,
68+
};
69+
70+
const disabledColorService: ColorService = {
71+
bold: identity,
72+
dim: identity,
73+
italic: identity,
74+
75+
red: identity,
76+
green: identity,
77+
yellow: identity,
78+
blue: identity,
79+
white: identity,
80+
81+
dimItalic: identity,
82+
dimWhite: identity,
83+
boldRed: identity,
3384
};
3485

3586
export interface PrettyLoggerOptions {
3687
showFiberId: boolean;
3788
showTime: boolean;
3889
showSpans: boolean;
90+
enableColors: boolean;
3991
}
4092

4193
const defaultOptions: PrettyLoggerOptions = {
4294
showFiberId: true,
4395
showTime: true,
4496
showSpans: true,
97+
enableColors: true,
4598
};
4699

47-
const createTimeString = (date: Date) => {
100+
const createTimeString = (colorService: ColorService, date: Date) => {
48101
const hoursText = date.getHours().toString().padStart(2, "0");
49102
const minutesText = date.getMinutes().toString().padStart(2, "0");
50103
const secondsText = date.getSeconds().toString().padStart(2, "0");
51-
return `${YELLOW}${hoursText}:${minutesText}:${secondsText}${RESET}`;
104+
return colorService.yellow(`${hoursText}:${minutesText}:${secondsText}`);
52105
};
53106

54107
const createCauseMessage = (cause: Cause.Cause<unknown>) => {
@@ -58,31 +111,40 @@ const createCauseMessage = (cause: Cause.Cause<unknown>) => {
58111
return Cause.pretty(cause);
59112
};
60113

61-
const createLogLevelString = (logLevel: LogLevel.LogLevel) => {
62-
const logLevelColor = SEVERITY_TO_COLOR[logLevel._tag];
63-
const logLevelText = logLevel.label.padEnd(5, " ");
64-
return `${logLevelColor}${logLevelText}${RESET}`;
114+
const createLogLevelString = (
115+
colorService: ColorService,
116+
logLevel: LogLevel.LogLevel,
117+
) => {
118+
const logLevelColor = SEVERITY_TO_COLOR[logLevel._tag](colorService);
119+
return logLevelColor(logLevel.label.padEnd(5, " "));
65120
};
66121

67-
const messageText = (message: unknown) => {
122+
const messageText = (colorService: ColorService, message: unknown) => {
68123
if (message === undefined) {
69-
return `${DIM}undefined${RESET}`;
124+
return colorService.dim("undefined");
70125
} else if (message === null) {
71-
return `${DIM}null${RESET}`;
126+
return colorService.dim("null");
72127
} else if (message === "") {
73-
return `${DIM}<empty message>${RESET}`;
128+
return colorService.dim("<empty message>");
74129
}
75130
return serializeUnknown(message);
76131
};
77132

78-
const createText = (message: unknown, cause: Cause.Cause<unknown>) =>
133+
const createText = (
134+
colorService: ColorService,
135+
message: unknown,
136+
cause: Cause.Cause<unknown>,
137+
) =>
79138
pipe(
80-
[createCauseMessage(cause), messageText(message)],
139+
[createCauseMessage(cause), messageText(colorService, message)],
81140
ReadonlyArray.filter((i) => i !== ""),
82141
ReadonlyArray.join(" "),
83142
);
84143

85-
const createSpanText = (spans: List.List<LogSpan.LogSpan>) => {
144+
const createSpanText = (
145+
colorService: ColorService,
146+
spans: List.List<LogSpan.LogSpan>,
147+
) => {
86148
if (List.isNil(spans)) {
87149
return "";
88150
}
@@ -93,23 +155,30 @@ const createSpanText = (spans: List.List<LogSpan.LogSpan>) => {
93155
(acc, span) => `${acc} -> ${span.label}`,
94156
);
95157

96-
return ` ${DIM}${ITALIC}${text}${RESET}`;
158+
return ` ${colorService.dimItalic(text)}`;
97159
};
98160

99161
export const make = (options?: Partial<PrettyLoggerOptions>) =>
100162
Logger.make(
101163
({ fiberId, logLevel, message, annotations, cause, date, spans }) => {
102164
const _options = { ...defaultOptions, ...options };
165+
const colorService = _options.enableColors
166+
? enabledColorService
167+
: disabledColorService;
103168

104-
const logLevelStr = createLogLevelString(logLevel);
105-
const timeText = _options.showTime ? `${createTimeString(date)} ` : "";
169+
const logLevelStr = createLogLevelString(colorService, logLevel);
170+
const timeText = _options.showTime
171+
? `${createTimeString(colorService, date)} `
172+
: "";
106173
const fiberText = _options.showFiberId
107-
? `${DIM}(Fiber ${FiberId.threadName(fiberId)})${RESET} `
174+
? colorService.dim(`(Fiber ${FiberId.threadName(fiberId)}) `)
108175
: "";
109176

110-
const text = createText(message, cause);
177+
const text = createText(colorService, message, cause);
111178

112-
const spansText = _options.showSpans ? createSpanText(spans) : "";
179+
const spansText = _options.showSpans
180+
? createSpanText(colorService, spans)
181+
: "";
113182

114183
console.log(`${timeText}${fiberText}${logLevelStr}${spansText} ${text}`);
115184

@@ -119,10 +188,12 @@ export const make = (options?: Partial<PrettyLoggerOptions>) =>
119188
[] as string[],
120189
(acc, v, k) => [
121190
...acc,
122-
`${WHITE}"${k}"${RESET}: ${serializeUnknown(v)}`,
191+
colorService.white(`"${k}"`) + `: ${serializeUnknown(v)}`,
123192
],
124193
);
125-
console.log(`ᐉ ${DIM}{${RESET} ${text.join(", ")} ${DIM}}${RESET}`);
194+
console.log(
195+
`ᐉ ${colorService.dim("{")} ${text.join(", ")} ${colorService.dim("}")}`,
196+
);
126197
}
127198
},
128199
);

0 commit comments

Comments
 (0)