forked from yunus-0x/meridian
-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathlogger.js
More file actions
91 lines (75 loc) · 3.13 KB
/
Copy pathlogger.js
File metadata and controls
91 lines (75 loc) · 3.13 KB
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
import fs from "fs";
import path from "path";
const LOG_DIR = "./logs";
const LOG_LEVEL = process.env.LOG_LEVEL || "info";
const LEVELS = { debug: 0, info: 1, warn: 2, error: 3 };
const currentLevel = LEVELS[LOG_LEVEL] || 1;
// Ensure log directory exists
if (!fs.existsSync(LOG_DIR)) {
fs.mkdirSync(LOG_DIR, { recursive: true });
}
/**
* General log function.
*/
export function log(category, message) {
const level = category.includes("error") ? "error"
: category.includes("warn") ? "warn"
: "info";
if (LEVELS[level] < currentLevel) return;
const timestamp = new Date().toISOString();
const line = `[${timestamp}] [${category.toUpperCase()}] ${message}`;
// Console output
console.log(line);
// File output (daily rotation)
const dateStr = timestamp.split("T")[0];
const logFile = path.join(LOG_DIR, `agent-${dateStr}.log`);
fs.appendFileSync(logFile, line + "\n");
}
/**
* Log a tool action with full details (for audit trail).
*/
function actionHint(action) {
const a = action.args || {};
const r = action.result || {};
switch (action.tool) {
case "deploy_position": return ` ${a.pool_name || a.pool_address?.slice(0,8)} ${a.amount_sol} SOL`;
case "close_position": return ` ${a.position_address?.slice(0,8)}${r.pnl_pct != null ? ` | PnL ${r.pnl_pct}%${r.pnl_sol != null ? ` (${r.pnl_sol} SOL)` : r.pnl_usd != null ? ` ($${r.pnl_usd})` : ""}` : ""}`;
case "claim_fees": return ` ${a.position_address?.slice(0,8)}`;
case "get_active_bin": return ` bin ${r.binId ?? ""}`;
case "get_pool_detail": return ` ${r.name || a.pool_address?.slice(0,8) || ""}`;
case "get_my_positions": return ` ${r.total_positions ?? ""} positions`;
case "get_wallet_balance":return ` ${r.sol ?? ""} SOL`;
case "get_top_candidates":return ` ${r?.candidates?.length ?? ""} pools`;
case "swap_token": return ` ${a.amount} ${a.input_mint?.slice(0,6)}→SOL`;
case "update_config": return ` ${Object.keys(r.applied || {}).join(", ")}`;
case "add_lesson": return ` saved`;
case "clear_lessons": return ` cleared ${r.cleared ?? ""}`;
default: return "";
}
}
export function logAction(action) {
const timestamp = new Date().toISOString();
const entry = { timestamp, ...action };
// Console: single clean line, no raw JSON
const status = action.success ? "✓" : "✗";
const dur = action.duration_ms != null ? ` (${action.duration_ms}ms)` : "";
const hint = actionHint(action);
console.log(`[${action.tool}] ${status}${hint}${dur}`);
// File: full JSON for audit trail
const dateStr = timestamp.split("T")[0];
const actionsFile = path.join(LOG_DIR, `actions-${dateStr}.jsonl`);
fs.appendFileSync(actionsFile, JSON.stringify(entry) + "\n");
}
/**
* Log a portfolio snapshot (for tracking performance over time).
*/
export function logSnapshot(snapshot) {
const timestamp = new Date().toISOString();
const entry = {
timestamp,
...snapshot,
};
const dateStr = timestamp.split("T")[0];
const snapshotFile = path.join(LOG_DIR, `snapshots-${dateStr}.jsonl`);
fs.appendFileSync(snapshotFile, JSON.stringify(entry) + "\n");
}