TheBird

Stats.jsx

1.9 kB · jsx · 42 lines

1import { Code, Rows, Waiting, ago, bytes, useMirror } from "../components/Mirror.jsx";23function Cloud({ data }) {4  return (5    <>6      <Rows7        list={[8          ["Stats", `${ago(data.at)}, last ${data.hours} h`],9          ["CDN", data.cdn.requests == null ? "no distribution" : `${data.cdn.requests} requests, ${bytes(data.cdn.bytes)}, ${data.cdn.error_4xx}% 4xx, ${data.cdn.error_5xx}% 5xx`],10          ["Bucket", `${data.bucket.site_objects} site files (${bytes(data.bucket.site_bytes)}), ${data.bucket.data_objects} data files (${bytes(data.bucket.data_bytes)})`],11          ["Shop", `${data.bucket.products} live products, ${data.bucket.designs} designs on the CDN, ${data.bucket.posts} posts`],12        ]}13      />14      <Rows list={Object.entries(data.lambdas).map(([name, one]) => [name, `${one.invocations} runs, ${one.errors} errors, ${one.throttles} throttles, ${Math.round(one.duration_ms)} ms avg`])} />15    </>16  );17}1819export function Stats() {20  const seen = useMirror("/stats/stats.json");21  const data = seen?.data ?? null;22  const found = Object.entries(data?.errors ?? {}).flatMap(([name, list]) => list.map((one) => `${one.at ?? "sometime"} ${one.level} ${name} ${one.message}`));2324  return (25    <div className="wrap">26      <article className="doc status narrow">27        <h1>Stats</h1>28        <p className="lead">29          The CDN, the Lambdas and the bucket, read from the bucket every minute. Raw: <a href="/stats/stats.json">stats.json</a>, <a href="/cdn/feed/index.json">feed</a>. The shop's own tick lives on <a href="/automator/">automator</a>.30        </p>31        <section>32          <h2>Cloud</h2>33          {data ? <Cloud data={data} /> : <Waiting seen={seen} />}34        </section>35        <section>36          <h2>Errors</h2>37          {found.length ? <Code lines={found} /> : data ? <p className="fine">None in the window.</p> : <Waiting seen={seen} />}38        </section>39      </article>40    </div>41  );42}