traceSummary

tcmts.cli.main.traceSummary · #xliv5q7t · term · runs on the server

uses node:path

What tcm's traces say of one version of a definition (by hash), for where its code is read: in the last day, how often it ran as the server ran it (calls, renders, runs), its p50 and p95 and how many failed; how long a page waited for it, if a page called it; and how many errors were thrown in it. Undefined if nothing's recorded.

import type { Codebase } from "#codebase/tcmts/cli/codebase";
import { shownMs } from "#codebase/tcmts/cli/main";
import fs from "node:fs";
import path from "node:path";
import { DatabaseSync } from "node:sqlite";

export function traceSummary(
  cb: Codebase,
  hash: string,
  since = Date.now() - 86_400_000,
): string | undefined {
  const file = path.join(cb.lay.tcmDir, "data", "traces.sqlite");
  if (!fs.existsSync(file)) return undefined;
  let db: DatabaseSync;
  try {
    db = new DatabaseSync(file, { readOnly: true });
  } catch {
    return undefined;
  }
  try {
    const stats = (kinds: string) => {
      const where = `hash = ? AND kind ${kinds} AND start >= ?`;
      const s = db
        .prepare(
          `SELECT count(*) AS n, sum(error IS NOT NULL) AS errors, (SELECT kind FROM spans WHERE ${where} GROUP BY kind ORDER BY count(*) DESC LIMIT 1) AS kind FROM spans WHERE ${where}`,
        )
        .get(hash, since, hash, since) as { n: number; errors: number | null; kind: string | null };
      const at = (p: number) =>
        (
          db
            .prepare(`SELECT dur FROM spans WHERE ${where} ORDER BY dur LIMIT 1 OFFSET ?`)
            .get(hash, since, Math.min(s.n - 1, Math.floor(s.n * p))) as { dur: number }
        ).dur;
      return s.n
        ? { n: s.n, errors: s.errors ?? 0, kind: s.kind ?? "", p50: at(0.5), p95: at(0.95) }
        : undefined;
    };
    const ran = stats("NOT IN ('client', 'error')");
    const waited = stats("= 'client'");
    const thrown = (
      db
        .prepare(
          `SELECT count(DISTINCT trace) AS n FROM spans WHERE json_extract(attrs, '$."tcm.thrown_in"') = ? AND start >= ?`,
        )
        .get(hash, since) as { n: number }
    ).n;
    if (!ran && !waited && !thrown) return undefined;
    const what: Record<string, string> = {
      call: "call",
      fn: "call",
      render: "render",
      page: "page",
      http: "request",
      job: "run",
    };
    const said: string[] = [];
    if (ran)
      said.push(
        `${ran.n} ${what[ran.kind] ?? ran.kind}(s) in the last day, p50 ${shownMs(ran.p50)}, p95 ${shownMs(ran.p95)}${ran.errors ? `, ${ran.errors} failed` : ""}`,
      );
    if (waited) said.push(`pages waited p95 ${shownMs(waited.p95)} for it`);
    if (thrown) said.push(`${thrown} error(s) thrown in it`);
    return said.join("; ");
  } finally {
    db.close();
  }
}

uses

used by