Skip to content

Commit e9e5608

Browse files
JoeyKhdwtfsayo
andauthored
feat: improvement to logger (elizaOS#2396)
* upd: initial updated logger * upd: remove test case * upd: improve some logs * upd: resolved issues with mix of left and right json * fix env and default mode * Update pnpm-lock.yaml --------- Co-authored-by: Sayo <82053242+wtfsayo@users.noreply.github.com>
1 parent 522481d commit e9e5608

File tree

5 files changed

+172
-270
lines changed

5 files changed

+172
-270
lines changed

.env.example

+3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ SUPABASE_ANON_KEY=
1818
# Comma separated list of remote character urls (optional)
1919
REMOTE_CHARACTER_URLS=
2020

21+
# Logging
22+
LOG_JSON_FORMAT= # Print everything in logger as json; false by default
23+
2124
###############################
2225
#### Client Configurations ####
2326
###############################

packages/core/package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
"@ai-sdk/openai": "1.0.5",
7272
"@anthropic-ai/sdk": "0.30.1",
7373
"@fal-ai/client": "1.2.0",
74+
"@tavily/core": "^0.0.2",
7475
"@types/uuid": "10.0.0",
7576
"ai": "3.4.33",
7677
"anthropic-vertex-ai": "1.0.2",
@@ -85,7 +86,8 @@
8586
"langchain": "0.3.6",
8687
"ollama-ai-provider": "0.16.1",
8788
"openai": "4.73.0",
88-
"@tavily/core": "^0.0.2",
89+
"pino": "^9.6.0",
90+
"pino-pretty": "^13.0.0",
8991
"tinyld": "1.3.4",
9092
"together-ai": "0.7.0",
9193
"unique-names-generator": "4.7.1",

packages/core/src/logger.ts

+57-262
Original file line numberDiff line numberDiff line change
@@ -1,271 +1,66 @@
1-
class ElizaLogger {
2-
constructor() {
3-
// Check if we're in Node.js environment
4-
this.isNode =
5-
typeof process !== "undefined" &&
6-
process.versions != null &&
7-
process.versions.node != null;
8-
9-
// Set verbose based on environment
10-
this.verbose = this.isNode ? process.env.VERBOSE === "true" : false;
11-
12-
// Add initialization logging
13-
console.log(`[ElizaLogger] Initializing with:
14-
isNode: ${this.isNode}
15-
verbose: ${this.verbose}
16-
VERBOSE env: ${process.env.VERBOSE}
17-
NODE_ENV: ${process.env.NODE_ENV}
18-
`);
19-
}
20-
21-
private isNode: boolean;
22-
verbose = false;
23-
closeByNewLine = true;
24-
useIcons = true;
25-
logsTitle = "LOGS";
26-
warningsTitle = "WARNINGS";
27-
errorsTitle = "ERRORS";
28-
informationsTitle = "INFORMATIONS";
29-
successesTitle = "SUCCESS";
30-
debugsTitle = "DEBUG";
31-
assertsTitle = "ASSERT";
32-
33-
#getColor(foregroundColor = "", backgroundColor = "") {
34-
if (!this.isNode) {
35-
// Browser console styling
36-
const colors: { [key: string]: string } = {
37-
black: "#000000",
38-
red: "#ff0000",
39-
green: "#00ff00",
40-
yellow: "#ffff00",
41-
blue: "#0000ff",
42-
magenta: "#ff00ff",
43-
cyan: "#00ffff",
44-
white: "#ffffff",
45-
};
46-
47-
const fg = colors[foregroundColor.toLowerCase()] || colors.white;
48-
const bg = colors[backgroundColor.toLowerCase()] || "transparent";
49-
return `color: ${fg}; background: ${bg};`;
50-
}
51-
52-
// Node.js console colors
53-
let fgc = "\x1b[37m";
54-
switch (foregroundColor.trim().toLowerCase()) {
55-
case "black":
56-
fgc = "\x1b[30m";
57-
break;
58-
case "red":
59-
fgc = "\x1b[31m";
60-
break;
61-
case "green":
62-
fgc = "\x1b[32m";
63-
break;
64-
case "yellow":
65-
fgc = "\x1b[33m";
66-
break;
67-
case "blue":
68-
fgc = "\x1b[34m";
69-
break;
70-
case "magenta":
71-
fgc = "\x1b[35m";
72-
break;
73-
case "cyan":
74-
fgc = "\x1b[36m";
75-
break;
76-
case "white":
77-
fgc = "\x1b[37m";
78-
break;
79-
}
80-
81-
let bgc = "";
82-
switch (backgroundColor.trim().toLowerCase()) {
83-
case "black":
84-
bgc = "\x1b[40m";
85-
break;
86-
case "red":
87-
bgc = "\x1b[44m";
88-
break;
89-
case "green":
90-
bgc = "\x1b[44m";
91-
break;
92-
case "yellow":
93-
bgc = "\x1b[43m";
94-
break;
95-
case "blue":
96-
bgc = "\x1b[44m";
97-
break;
98-
case "magenta":
99-
bgc = "\x1b[45m";
100-
break;
101-
case "cyan":
102-
bgc = "\x1b[46m";
103-
break;
104-
case "white":
105-
bgc = "\x1b[47m";
106-
break;
107-
}
108-
109-
return `${fgc}${bgc}`;
110-
}
111-
112-
#getColorReset() {
113-
return this.isNode ? "\x1b[0m" : "";
114-
}
115-
116-
clear() {
117-
console.clear();
1+
import pino, { LogFn } from "pino";
2+
import pretty from "pino-pretty";
3+
4+
const customLevels: Record<string, number> = {
5+
fatal: 60,
6+
error: 50,
7+
warn: 40,
8+
info: 30,
9+
log: 29,
10+
progress: 28,
11+
success: 27,
12+
debug: 20,
13+
trace: 10,
14+
};
15+
16+
const raw = process?.env?.LOG_JSON_FORMAT || false;
17+
18+
const createStream = () => {
19+
if (raw) {
20+
return undefined;
11821
}
119-
120-
print(foregroundColor = "white", backgroundColor = "black", ...strings) {
121-
// Convert objects to strings
122-
const processedStrings = strings.map((item) => {
123-
if (typeof item === "object") {
124-
return JSON.stringify(item, (key, value) =>
125-
typeof value === "bigint" ? value.toString() : value
22+
return pretty({
23+
colorize: true,
24+
translateTime: "yyyy-mm-dd HH:MM:ss",
25+
ignore: "pid,hostname",
26+
});
27+
};
28+
29+
const options = {
30+
customLevels,
31+
hooks: {
32+
logMethod(
33+
inputArgs: [string | Record<string, unknown>, ...unknown[]],
34+
method: LogFn
35+
): void {
36+
const [arg1, ...rest] = inputArgs;
37+
38+
if (typeof arg1 === "object") {
39+
const messageParts = rest.map((arg) =>
40+
typeof arg === "string" ? arg : JSON.stringify(arg)
12641
);
127-
}
128-
return item;
129-
});
130-
131-
if (this.isNode) {
132-
const c = this.#getColor(foregroundColor, backgroundColor);
133-
console.log(c, processedStrings.join(""), this.#getColorReset());
134-
} else {
135-
const style = this.#getColor(foregroundColor, backgroundColor);
136-
console.log(`%c${processedStrings.join("")}`, style);
137-
}
138-
139-
if (this.closeByNewLine) console.log("");
140-
}
141-
142-
#logWithStyle(
143-
strings: any[],
144-
options: {
145-
fg: string;
146-
bg: string;
147-
icon: string;
148-
groupTitle: string;
149-
}
150-
) {
151-
const { fg, bg, icon, groupTitle } = options;
152-
153-
if (strings.length > 1) {
154-
if (this.isNode) {
155-
const c = this.#getColor(fg, bg);
156-
console.group(c, (this.useIcons ? icon : "") + groupTitle);
42+
const message = messageParts.join(" ");
43+
return method.apply(this, [arg1, message]);
15744
} else {
158-
const style = this.#getColor(fg, bg);
159-
console.group(
160-
`%c${this.useIcons ? icon : ""}${groupTitle}`,
161-
style
45+
const context = {};
46+
const messageParts = [arg1, ...rest].map((arg) =>
47+
typeof arg === "string" ? arg : arg
48+
);
49+
const message = messageParts
50+
.filter((part) => typeof part === "string")
51+
.join(" ");
52+
const jsonParts = messageParts.filter(
53+
(part) => typeof part === "object"
16254
);
163-
}
164-
165-
const nl = this.closeByNewLine;
166-
this.closeByNewLine = false;
167-
strings.forEach((item) => {
168-
this.print(fg, bg, item);
169-
});
170-
this.closeByNewLine = nl;
171-
console.groupEnd();
172-
if (nl) console.log();
173-
} else {
174-
this.print(
175-
fg,
176-
bg,
177-
strings.map((item) => {
178-
return `${this.useIcons ? `${icon} ` : ""}${item}`;
179-
})
180-
);
181-
}
182-
}
183-
184-
log(...strings) {
185-
this.#logWithStyle(strings, {
186-
fg: "white",
187-
bg: "",
188-
icon: "\u25ce",
189-
groupTitle: ` ${this.logsTitle}`,
190-
});
191-
}
192-
193-
warn(...strings) {
194-
this.#logWithStyle(strings, {
195-
fg: "yellow",
196-
bg: "",
197-
icon: "\u26a0",
198-
groupTitle: ` ${this.warningsTitle}`,
199-
});
200-
}
201-
202-
error(...strings) {
203-
this.#logWithStyle(strings, {
204-
fg: "red",
205-
bg: "",
206-
icon: "\u26D4",
207-
groupTitle: ` ${this.errorsTitle}`,
208-
});
209-
}
210-
211-
info(...strings) {
212-
this.#logWithStyle(strings, {
213-
fg: "blue",
214-
bg: "",
215-
icon: "\u2139",
216-
groupTitle: ` ${this.informationsTitle}`,
217-
});
218-
}
219-
220-
debug(...strings) {
221-
if (!this.verbose) {
222-
// for diagnosing verbose logging issues
223-
// console.log(
224-
// "[ElizaLogger] Debug message suppressed (verbose=false):",
225-
// ...strings
226-
// );
227-
return;
228-
}
229-
this.#logWithStyle(strings, {
230-
fg: "magenta",
231-
bg: "",
232-
icon: "\u1367",
233-
groupTitle: ` ${this.debugsTitle}`,
234-
});
235-
}
236-
237-
success(...strings) {
238-
this.#logWithStyle(strings, {
239-
fg: "green",
240-
bg: "",
241-
icon: "\u2713",
242-
groupTitle: ` ${this.successesTitle}`,
243-
});
244-
}
24555

246-
assert(...strings) {
247-
this.#logWithStyle(strings, {
248-
fg: "cyan",
249-
bg: "",
250-
icon: "\u0021",
251-
groupTitle: ` ${this.assertsTitle}`,
252-
});
253-
}
56+
Object.assign(context, ...jsonParts);
25457

255-
progress(message: string) {
256-
if (this.isNode) {
257-
// Clear the current line and move cursor to beginning
258-
process.stdout.clearLine(0);
259-
process.stdout.cursorTo(0);
260-
process.stdout.write(message);
261-
} else {
262-
console.log(message);
263-
}
264-
}
265-
}
58+
return method.apply(this, [context, message]);
59+
}
60+
},
61+
},
62+
};
26663

267-
export const elizaLogger = new ElizaLogger();
268-
elizaLogger.closeByNewLine = true;
269-
elizaLogger.useIcons = true;
64+
export const elizaLogger = pino(options, createStream());
27065

27166
export default elizaLogger;

packages/core/src/runtime.ts

+7-7
Original file line numberDiff line numberDiff line change
@@ -371,19 +371,19 @@ export class AgentRuntime implements IAgentRuntime {
371371
this.imageModelProvider =
372372
this.character.imageModelProvider ?? this.modelProvider;
373373

374-
elizaLogger.info("Selected model provider:", this.modelProvider);
375374
elizaLogger.info(
376-
"Selected image model provider:",
377-
this.imageModelProvider
375+
`Selected model provider: ${this.modelProvider}`
376+
);
377+
378+
elizaLogger.info(
379+
`Selected image model provider: ${this.imageModelProvider}`
378380
);
379381

380382
this.imageVisionModelProvider =
381383
this.character.imageVisionModelProvider ?? this.modelProvider;
382384

383-
// elizaLogger.info("Selected model provider:", this.modelProvider); duplicated log ln: 343
384385
elizaLogger.info(
385-
"Selected image vision model provider:",
386-
this.imageVisionModelProvider
386+
`Selected image vision model provider: ${this.imageVisionModelProvider}`
387387
);
388388

389389
// Validate model provider
@@ -470,7 +470,7 @@ export class AgentRuntime implements IAgentRuntime {
470470
this.character.knowledge.length > 0
471471
) {
472472
elizaLogger.info(
473-
`[RAG Check] RAG Knowledge enabled: ${this.character.settings.ragKnowledge}`
473+
`[RAG Check] RAG Knowledge enabled: ${this.character.settings.ragKnowledge ? true : false}`
474474
);
475475
elizaLogger.info(
476476
`[RAG Check] Knowledge items:`,

0 commit comments

Comments
 (0)