MCPcopy Create free account
hub / github.com/MemTensor/MemOS / getToolMetrics

Method getToolMetrics

packages/memos-core/src/storage/sqlite.ts:726–806  ·  view source on GitHub ↗
(minutes: number, fromMs?: number, toMs?: number)

Source from the content-addressed store, hash-verified

724 }
725
726 getToolMetrics(minutes: number, fromMs?: number, toMs?: number): {
727 tools: string[];
728 series: Array<{ minute: string; [tool: string]: number | string }>;
729 aggregated: Array<{ tool: string; totalCalls: number; avgMs: number; p95Ms: number; errorCount: number }>;
730 } {
731 const since = fromMs ?? (Date.now() - minutes * 60 * 1000);
732 const until = toMs ?? Date.now();
733
734 const rows = this.db.prepare(
735 `SELECT tool_name,
736 duration_ms,
737 success,
738 strftime('%Y-%m-%d %H:%M', called_at/1000, 'unixepoch', 'localtime') as minute_key
739 FROM tool_calls
740 WHERE called_at >= ? AND called_at <= ?
741 ORDER BY called_at`,
742 ).all(since, until) as Array<{ tool_name: string; duration_ms: number; success: number; minute_key: string }>;
743
744 const toolSet = new Set<string>();
745 const minuteMap = new Map<string, Map<string, { total: number; count: number }>>();
746 const aggMap = new Map<string, { durations: number[]; errors: number }>();
747
748 for (const r of rows) {
749 toolSet.add(r.tool_name);
750
751 if (!aggMap.has(r.tool_name)) aggMap.set(r.tool_name, { durations: [], errors: 0 });
752 const agg = aggMap.get(r.tool_name)!;
753 agg.durations.push(r.duration_ms);
754 if (!r.success) agg.errors++;
755
756 if (!minuteMap.has(r.minute_key)) minuteMap.set(r.minute_key, new Map());
757 const toolMap = minuteMap.get(r.minute_key)!;
758 if (!toolMap.has(r.tool_name)) toolMap.set(r.tool_name, { total: 0, count: 0 });
759 const entry = toolMap.get(r.tool_name)!;
760 entry.total += r.duration_ms;
761 entry.count++;
762 }
763
764 const tools = Array.from(toolSet).sort();
765
766 const allMinutes: string[] = [];
767 if (minutes > 0) {
768 const startMinute = new Date(since);
769 startMinute.setSeconds(0, 0);
770 const now = new Date();
771 for (let t = startMinute.getTime(); t <= now.getTime(); t += 60000) {
772 const d = new Date(t);
773 const pad = (n: number) => String(n).padStart(2, "0");
774 allMinutes.push(`${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`);
775 }
776 }
777
778 const series = allMinutes.map((m) => {
779 const entry: { minute: string; [tool: string]: number | string } = { minute: m };
780 const toolMap = minuteMap.get(m);
781 for (const t of tools) {
782 const data = toolMap?.get(t);
783 entry[t] = data ? Math.round(data.total / data.count) : 0;

Callers 1

serveToolMetricsMethod · 0.45

Calls 7

allMethod · 0.80
prepareMethod · 0.80
mapMethod · 0.80
hasMethod · 0.65
setMethod · 0.65
getMethod · 0.65
addMethod · 0.45

Tested by

no test coverage detected