tracksiy 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/tracksiy.mjs +79 -11
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -126,6 +126,7 @@ Labels: `bug`, `feature`, `question`, `blocker`. `npx tracksiy support` prints t
|
|
|
126
126
|
| `monitors declare` | Declare monitors for a project up front, idempotently: heartbeats for jobs, HTTP checks, TLS, ingest silence. | write | `monitors_declare` |
|
|
127
127
|
| `monitors delete <slug>` | Remove one of a project's monitors by the slug it was declared with. | **destructive** | `monitors_delete` |
|
|
128
128
|
| `performance` | Is this project slow, and did it get slower? Transactions compared with the previous window, plus uptime. | read | `performance` |
|
|
129
|
+
| `queries` | Which database queries and outbound HTTP calls make this project slow, with N+1 detection and the routes that run them. | read | `queries` |
|
|
129
130
|
| `issues list` | Recent issues of a project, newest activity first, with the frames that matter inlined. | read | `issues_list` |
|
|
130
131
|
| `issues view <id>` | One issue in enough depth to act on: latest event, stack frames, tags, recent volume. | read | `issues_view` |
|
|
131
132
|
| `issues resolve <ids...>` | Mark issues resolved, optionally fixed in a release so old clients do not reopen them. Records why. | write | `issues_resolve` |
|
package/dist/tracksiy.mjs
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { readFileSync as readFileSync2 } from "node:fs";
|
|
5
5
|
|
|
6
6
|
// src/version.ts
|
|
7
|
-
var VERSION = true ? "0.
|
|
7
|
+
var VERSION = true ? "0.4.0" : "0.0.0-dev";
|
|
8
8
|
var USER_AGENT = `tracksiy-cli/${VERSION} (node ${process.versions.node}; ${process.platform})`;
|
|
9
9
|
|
|
10
10
|
// src/core/errors.ts
|
|
@@ -851,10 +851,16 @@ var monitorsDeclare = {
|
|
|
851
851
|
ssl: { type: "list", value: "<slug>=<url>", description: "TLS certificate check (expiry is reported on every check)." },
|
|
852
852
|
ingest: { type: "list", value: "<slug>[:<surface>]", description: "Alert when this project (or surface) stops sending events." },
|
|
853
853
|
interval: { type: "integer", value: "<seconds>", description: "Interval for --get/--ping/--ssl/--ingest monitors." },
|
|
854
|
+
"expect-text": { type: "string", value: "<text>", description: "--get: down unless the body contains this (a 200 with an empty shell is down)." },
|
|
855
|
+
"expect-no-text": { type: "string", value: "<text>", description: "--get: down if the body contains this, e.g. Whoops or Exception." },
|
|
856
|
+
"user-agent": { type: "string", value: "<ua>", description: "--get/--ping: ask as this User-Agent, e.g. GPTBot/1.0, to see what crawlers get." },
|
|
857
|
+
"dry-run": { type: "boolean", description: "Show what would be created, adopted or changed; write nothing." },
|
|
854
858
|
body: { type: "json", value: "<json|@file|->", description: "Raw request body; overrides the shorthand flags." }
|
|
855
859
|
},
|
|
856
860
|
examples: [
|
|
857
|
-
{ command: "tracksiy monitors declare --heartbeat nightly-backup:93600 --get site=https://example.com", description: "A backup heartbeat and a homepage check." }
|
|
861
|
+
{ command: "tracksiy monitors declare --heartbeat nightly-backup:93600 --get site=https://example.com", description: "A backup heartbeat and a homepage check." },
|
|
862
|
+
{ command: "tracksiy monitors declare --get tr-landing=https://example.com/tr --expect-text '<h1' --expect-no-text Whoops --user-agent GPTBot/1.0", description: "The page as an answer engine gets it: real content, no error template." },
|
|
863
|
+
{ command: "tracksiy monitors declare --heartbeat tariff-sync:608400 --dry-run", description: "See the change before making it." }
|
|
858
864
|
],
|
|
859
865
|
output: "Server result per monitor, including check-in URLs for heartbeats.",
|
|
860
866
|
async run(ctx) {
|
|
@@ -870,7 +876,17 @@ var monitorsDeclare = {
|
|
|
870
876
|
for (const item of i[type] ?? []) {
|
|
871
877
|
const eq = String(item).indexOf("=");
|
|
872
878
|
if (eq < 1) throw usageError("bad_value", `--${type} expects <slug>=<url>, got ${JSON.stringify(item)}`);
|
|
873
|
-
monitors.push(
|
|
879
|
+
monitors.push(
|
|
880
|
+
compact({
|
|
881
|
+
slug: item.slice(0, eq),
|
|
882
|
+
type,
|
|
883
|
+
url: item.slice(eq + 1),
|
|
884
|
+
intervalSeconds: i.interval,
|
|
885
|
+
expectText: type === "get" ? i.expectText : void 0,
|
|
886
|
+
expectNoText: type === "get" ? i.expectNoText : void 0,
|
|
887
|
+
userAgent: type !== "ssl" ? i.userAgent : void 0
|
|
888
|
+
})
|
|
889
|
+
);
|
|
874
890
|
}
|
|
875
891
|
}
|
|
876
892
|
for (const item of i.ingest ?? []) {
|
|
@@ -880,6 +896,7 @@ var monitorsDeclare = {
|
|
|
880
896
|
if (!monitors.length) throw usageError("missing_flag", "Nothing to declare.", "Add --heartbeat, --get, --ping, --ssl, --ingest, or --body.");
|
|
881
897
|
body = { monitors };
|
|
882
898
|
}
|
|
899
|
+
if (i.dryRun) body = { ...body, dryRun: true };
|
|
883
900
|
return ctx.api.send("POST", await projectPath(ctx, "monitors"), body);
|
|
884
901
|
}
|
|
885
902
|
};
|
|
@@ -904,16 +921,26 @@ var performance = {
|
|
|
904
921
|
effect: "read",
|
|
905
922
|
endpoint: { method: "GET", path: "/api/agent/v1/projects/{org}/{project}/performance" },
|
|
906
923
|
flags: {
|
|
907
|
-
since: { type: "string", value: TIME, description: "Window start (default: server's, 24h)." },
|
|
908
|
-
op: { type: "string", value: "<op>", description: "Only this operation, e.g. http.server." },
|
|
909
|
-
sort: { type: "string",
|
|
910
|
-
limit: { type: "integer", value: "<n>", description: "How many transactions." }
|
|
924
|
+
since: { type: "string", value: TIME, description: "Window start (default: server's, 24h; 7d with --release)." },
|
|
925
|
+
op: { type: "string", value: "<op>", description: "Only this operation, e.g. http.server or pageload." },
|
|
926
|
+
sort: { type: "string", enum: ["slower", "duration", "p95", "failures"], description: "Order (default: slower first)." },
|
|
927
|
+
limit: { type: "integer", value: "<n>", description: "How many transactions." },
|
|
928
|
+
release: { type: "string", value: "<version>", description: "Compare this release's transactions with --against instead of two time windows." },
|
|
929
|
+
against: { type: "string", value: "<version>", description: "The release to compare with (default: the one before --release)." }
|
|
911
930
|
},
|
|
912
|
-
|
|
931
|
+
examples: [
|
|
932
|
+
{ command: "tracksiy performance --sort p95", description: "The slowest routes by p95." },
|
|
933
|
+
{ command: "tracksiy performance --release web@$(git rev-parse HEAD)", description: "Did this deploy make anything slower or failing?" },
|
|
934
|
+
{ command: "tracksiy performance --op pageload --select transactions.transaction,transactions.current.webVitals", description: "Core Web Vitals (p75) per page." }
|
|
935
|
+
],
|
|
936
|
+
output: "{since, until, release?, againstRelease?, transactions:[{transaction, op, current{count, avgDurationMs, p50Ms, p95Ms, p99Ms, failureRate, failed, status, webVitals}, previous{...}, changeRatio, slower}], uptime[...], blindSpots[...]}",
|
|
913
937
|
text: (d) => `${table(d.transactions ?? [], [
|
|
914
938
|
"transaction",
|
|
915
939
|
"op",
|
|
916
|
-
["
|
|
940
|
+
["p50", (r) => r.current?.p50Ms ?? "-"],
|
|
941
|
+
["p95", (r) => r.current?.p95Ms ?? "-"],
|
|
942
|
+
["p99", (r) => r.current?.p99Ms ?? "-"],
|
|
943
|
+
["fail", (r) => r.current?.failureRate == null ? "-" : `${(r.current.failureRate * 100).toFixed(1)}%`],
|
|
917
944
|
["count", (r) => r.current?.count ?? "-"],
|
|
918
945
|
["change", (r) => r.changeRatio == null ? "-" : `${r.changeRatio > 0 ? "+" : ""}${Math.round(r.changeRatio * 100)}%`],
|
|
919
946
|
["slower", (r) => r.slower]
|
|
@@ -926,11 +953,52 @@ ${table(d.uptime, ["name", "url", "upNow", "avgResponseMs", "downChecks"])}` : "
|
|
|
926
953
|
since: since(ctx.input.since),
|
|
927
954
|
op: ctx.input.op,
|
|
928
955
|
sort: ctx.input.sort,
|
|
956
|
+
limit: ctx.input.limit,
|
|
957
|
+
release: ctx.input.release,
|
|
958
|
+
against: ctx.input.against
|
|
959
|
+
});
|
|
960
|
+
}
|
|
961
|
+
};
|
|
962
|
+
var queries = {
|
|
963
|
+
path: ["queries"],
|
|
964
|
+
aliases: [["performance", "queries"]],
|
|
965
|
+
summary: "Which database queries and outbound HTTP calls make this project slow, with N+1 detection and the routes that run them.",
|
|
966
|
+
description: "Aggregated from the spans of sampled transactions (op db* and http.client), normalized so no literal is stored. Ranked by total time by default: the query that costs the most overall. nPlusOne marks a query one request ran 10+ times.",
|
|
967
|
+
context: "project",
|
|
968
|
+
effect: "read",
|
|
969
|
+
endpoint: { method: "GET", path: "/api/agent/v1/projects/{org}/{project}/queries" },
|
|
970
|
+
flags: {
|
|
971
|
+
since: { type: "string", value: TIME, description: "Window start (default 24h)." },
|
|
972
|
+
op: { type: "string", value: "<db|http.client|op>", description: "db (every db* op), http.client, or an exact op." },
|
|
973
|
+
transaction: { type: "string", value: "<route>", description: "Only queries run by this transaction, e.g. /orders." },
|
|
974
|
+
sort: { type: "string", enum: ["total", "avg", "max", "count", "perTransaction"], description: "Order (default total)." },
|
|
975
|
+
limit: { type: "integer", value: "<n>", description: "How many (max 100)." }
|
|
976
|
+
},
|
|
977
|
+
examples: [
|
|
978
|
+
{ command: "tracksiy queries --since 24h", description: "The queries that cost the most time today." },
|
|
979
|
+
{ command: "tracksiy queries --sort perTransaction --select queries.query,queries.maxPerTransaction,queries.routes", description: "N+1 candidates." }
|
|
980
|
+
],
|
|
981
|
+
output: "{since, until, queries:[{fingerprint, op, query, count, transactions, perTransaction, maxPerTransaction, totalMs, avgMs, maxMs, previous{count, avgMs}, changeRatio, nPlusOne, routes[{transaction, count, avgMs}]}], note}",
|
|
982
|
+
text: (d) => table(d.queries ?? [], [
|
|
983
|
+
["total ms", (r) => r.totalMs],
|
|
984
|
+
["avg", (r) => r.avgMs ?? "-"],
|
|
985
|
+
["max", (r) => r.maxMs],
|
|
986
|
+
["count", (r) => r.count],
|
|
987
|
+
["per req", (r) => r.perTransaction],
|
|
988
|
+
["n+1", (r) => r.nPlusOne ? "yes" : ""],
|
|
989
|
+
["query", (r) => String(r.query).slice(0, 90)]
|
|
990
|
+
]),
|
|
991
|
+
async run(ctx) {
|
|
992
|
+
return ctx.api.get(await projectPath(ctx, "queries"), {
|
|
993
|
+
since: since(ctx.input.since),
|
|
994
|
+
op: ctx.input.op,
|
|
995
|
+
transaction: ctx.input.transaction,
|
|
996
|
+
sort: ctx.input.sort,
|
|
929
997
|
limit: ctx.input.limit
|
|
930
998
|
});
|
|
931
999
|
}
|
|
932
1000
|
};
|
|
933
|
-
var fleet_default = [orgs, projects, overview, changes, health, monitorsList, monitorsDeclare, monitorsDelete, performance];
|
|
1001
|
+
var fleet_default = [orgs, projects, overview, changes, health, monitorsList, monitorsDeclare, monitorsDelete, performance, queries];
|
|
934
1002
|
|
|
935
1003
|
// src/commands/issues.ts
|
|
936
1004
|
var FILTERS = {
|
|
@@ -3101,7 +3169,7 @@ var COMMANDS = [
|
|
|
3101
3169
|
];
|
|
3102
3170
|
var GROUPS = [
|
|
3103
3171
|
["Start", "init auth onboarding describe"],
|
|
3104
|
-
["Look", "overview changes health orgs projects issues monitors performance releases alerts keys artifacts"],
|
|
3172
|
+
["Look", "overview changes health orgs projects issues monitors performance queries releases alerts keys artifacts"],
|
|
3105
3173
|
["Ship", "sourcemaps proguard"],
|
|
3106
3174
|
["Manage", "tokens"],
|
|
3107
3175
|
["Talk to us", "support"],
|