@tonbo/cli 0.24.0 → 0.26.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/dist/bin/tonbo.js +131 -4
- package/package.json +1 -1
package/dist/bin/tonbo.js
CHANGED
|
@@ -796,6 +796,20 @@ var managementOperations = {
|
|
|
796
796
|
"idempotencyKey": false,
|
|
797
797
|
"cli": "tonbo metrics streams"
|
|
798
798
|
},
|
|
799
|
+
"getAccountDatabaseAndStreamMetrics": {
|
|
800
|
+
"method": "GET",
|
|
801
|
+
"path": "/metrics/databases-and-streams",
|
|
802
|
+
"pathParams": [],
|
|
803
|
+
"query": [
|
|
804
|
+
"series",
|
|
805
|
+
"window",
|
|
806
|
+
"granularity",
|
|
807
|
+
"from",
|
|
808
|
+
"to"
|
|
809
|
+
],
|
|
810
|
+
"idempotencyKey": false,
|
|
811
|
+
"cli": "tonbo metrics databases-and-streams"
|
|
812
|
+
},
|
|
799
813
|
"listMachineShapes": {
|
|
800
814
|
"method": "GET",
|
|
801
815
|
"path": "/machine-shapes",
|
|
@@ -1062,6 +1076,22 @@ var managementOperations = {
|
|
|
1062
1076
|
"idempotencyKey": false,
|
|
1063
1077
|
"cli": "tonbo volume delete"
|
|
1064
1078
|
},
|
|
1079
|
+
"getVolumeNameMetrics": {
|
|
1080
|
+
"method": "GET",
|
|
1081
|
+
"path": "/volumes/{name}/metrics",
|
|
1082
|
+
"pathParams": [
|
|
1083
|
+
"name"
|
|
1084
|
+
],
|
|
1085
|
+
"query": [
|
|
1086
|
+
"series",
|
|
1087
|
+
"window",
|
|
1088
|
+
"granularity",
|
|
1089
|
+
"from",
|
|
1090
|
+
"to"
|
|
1091
|
+
],
|
|
1092
|
+
"idempotencyKey": false,
|
|
1093
|
+
"cli": "tonbo volume metrics"
|
|
1094
|
+
},
|
|
1065
1095
|
"listStreams": {
|
|
1066
1096
|
"method": "GET",
|
|
1067
1097
|
"path": "/streams",
|
|
@@ -2445,6 +2475,10 @@ var ManagementApi = class {
|
|
|
2445
2475
|
getAccountStreamMetrics(key, query = {}) {
|
|
2446
2476
|
return this.call("getAccountStreamMetrics", key, { query });
|
|
2447
2477
|
}
|
|
2478
|
+
/** The account's databases and streams together, with one server latency for both. */
|
|
2479
|
+
getAccountDatabaseAndStreamMetrics(key, query = {}) {
|
|
2480
|
+
return this.call("getAccountDatabaseAndStreamMetrics", key, { query });
|
|
2481
|
+
}
|
|
2448
2482
|
/** The whole usage page: its rows, `other`, prices and checkpoint. */
|
|
2449
2483
|
listStreamUsage(key, page, query = {}) {
|
|
2450
2484
|
return this.page("listStreamUsage", key, page, query);
|
|
@@ -2459,6 +2493,10 @@ var ManagementApi = class {
|
|
|
2459
2493
|
getVolumeMetrics(key, query = {}) {
|
|
2460
2494
|
return this.call("getVolumeMetrics", key, { query });
|
|
2461
2495
|
}
|
|
2496
|
+
/** One Volume's guest I/O and stored bytes per UTC hour or day. */
|
|
2497
|
+
getVolumeNameMetrics(key, name, query = {}) {
|
|
2498
|
+
return this.call("getVolumeNameMetrics", key, { params: { name }, query });
|
|
2499
|
+
}
|
|
2462
2500
|
/** The account's writes of yesterday and today, hourly, per lane. */
|
|
2463
2501
|
getUsageToday(key) {
|
|
2464
2502
|
return this.call("getUsageToday", key);
|
|
@@ -5394,7 +5432,7 @@ function printAccountRegistryMetrics(deps, noun, metrics, options) {
|
|
|
5394
5432
|
"",
|
|
5395
5433
|
table(
|
|
5396
5434
|
[
|
|
5397
|
-
noun === "databases" ? "DATABASE" : "STREAM",
|
|
5435
|
+
noun === "databases" ? "DATABASE" : noun === "streams" ? "STREAM" : "NAME",
|
|
5398
5436
|
"REGION",
|
|
5399
5437
|
...sized ? ["STORED"] : [],
|
|
5400
5438
|
...counted.map((name) => REGISTRY_COLUMNS[name][0])
|
|
@@ -5402,7 +5440,7 @@ function printAccountRegistryMetrics(deps, noun, metrics, options) {
|
|
|
5402
5440
|
metrics.resources.map((resource) => {
|
|
5403
5441
|
const stored = [...resource.points].reverse().find((point) => point.stored_bytes !== null && point.stored_bytes !== void 0);
|
|
5404
5442
|
return [
|
|
5405
|
-
resource.name,
|
|
5443
|
+
resource.kind ? `${resource.name} (${resource.kind})` : resource.name,
|
|
5406
5444
|
resource.region,
|
|
5407
5445
|
...sized ? [stored ? bytes(stored.stored_bytes ?? 0) : "-"] : [],
|
|
5408
5446
|
...counted.map(
|
|
@@ -5434,6 +5472,13 @@ async function metricsStreamsCommand(deps, options = {}) {
|
|
|
5434
5472
|
);
|
|
5435
5473
|
printAccountRegistryMetrics(deps, "streams", metrics, options);
|
|
5436
5474
|
}
|
|
5475
|
+
async function metricsDatabasesAndStreamsCommand(deps, options = {}) {
|
|
5476
|
+
const metrics = await deps.api.getAccountDatabaseAndStreamMetrics(
|
|
5477
|
+
await deps.auth.apiKey(),
|
|
5478
|
+
metricsQuery(options)
|
|
5479
|
+
);
|
|
5480
|
+
printAccountRegistryMetrics(deps, "databases and streams", metrics, options);
|
|
5481
|
+
}
|
|
5437
5482
|
function streamFields(stream) {
|
|
5438
5483
|
return fields([
|
|
5439
5484
|
["Name", stream.name],
|
|
@@ -5609,14 +5654,14 @@ async function metricsVolumesCommand(deps, options = {}) {
|
|
|
5609
5654
|
["DAY", "STORED", ""],
|
|
5610
5655
|
points.map((point) => [
|
|
5611
5656
|
point.start.slice(0, 10),
|
|
5612
|
-
bytes(point.stored_bytes),
|
|
5657
|
+
bytes(point.stored_bytes ?? 0),
|
|
5613
5658
|
point.partial ? "so far" : ""
|
|
5614
5659
|
])
|
|
5615
5660
|
)
|
|
5616
5661
|
];
|
|
5617
5662
|
const complete = points.filter((point) => !point.partial);
|
|
5618
5663
|
if (complete.length > 1) {
|
|
5619
|
-
const change = complete[complete.length - 1].stored_bytes - complete[0].stored_bytes;
|
|
5664
|
+
const change = (complete[complete.length - 1].stored_bytes ?? 0) - (complete[0].stored_bytes ?? 0);
|
|
5620
5665
|
lines.push(
|
|
5621
5666
|
`Change over its complete days: ${change < 0 ? "-" : "+"}${bytes(Math.abs(change))}`
|
|
5622
5667
|
);
|
|
@@ -6009,6 +6054,44 @@ async function resolveVolumeBinding(deps, key, spec) {
|
|
|
6009
6054
|
region: volume.region
|
|
6010
6055
|
};
|
|
6011
6056
|
}
|
|
6057
|
+
var VOLUME_COLUMNS = {
|
|
6058
|
+
stored_bytes: ["STORED", (value) => bytes(value)],
|
|
6059
|
+
read_bytes: ["READ", (value) => bytes(value)],
|
|
6060
|
+
write_bytes: ["WRITTEN", (value) => bytes(value)],
|
|
6061
|
+
read_ops: ["READ OPS", String],
|
|
6062
|
+
write_ops: ["WRITE OPS", String],
|
|
6063
|
+
trim_ops: ["TRIMS", String]
|
|
6064
|
+
};
|
|
6065
|
+
async function volumeMetricsCommand(deps, name, options = {}) {
|
|
6066
|
+
const metrics = await deps.api.getVolumeNameMetrics(
|
|
6067
|
+
await deps.auth.apiKey(),
|
|
6068
|
+
name,
|
|
6069
|
+
metricsQuery(options)
|
|
6070
|
+
);
|
|
6071
|
+
const series = Object.keys(VOLUME_COLUMNS).filter(
|
|
6072
|
+
(key) => metrics.points.some((point) => key in point)
|
|
6073
|
+
);
|
|
6074
|
+
const hourly = metrics.granularity === "hour";
|
|
6075
|
+
print(
|
|
6076
|
+
deps,
|
|
6077
|
+
options.json,
|
|
6078
|
+
metrics,
|
|
6079
|
+
[
|
|
6080
|
+
`Volume ${metrics.name} in ${metrics.region} from ${metrics.from} to ${metrics.to} (UTC)`,
|
|
6081
|
+
table(
|
|
6082
|
+
[hourly ? "HOUR (UTC)" : "DAY (UTC)", ...series.map((key) => VOLUME_COLUMNS[key][0]), ""],
|
|
6083
|
+
metrics.points.map((point) => [
|
|
6084
|
+
hourly ? point.start.slice(0, 16).replace("T", " ") : point.start.slice(0, 10),
|
|
6085
|
+
...series.map((key) => {
|
|
6086
|
+
const value = point[key];
|
|
6087
|
+
return value === null || value === void 0 ? "-" : VOLUME_COLUMNS[key][1](value);
|
|
6088
|
+
}),
|
|
6089
|
+
point.partial ? "so far" : ""
|
|
6090
|
+
])
|
|
6091
|
+
)
|
|
6092
|
+
].join("\n")
|
|
6093
|
+
);
|
|
6094
|
+
}
|
|
6012
6095
|
|
|
6013
6096
|
// src/machine.ts
|
|
6014
6097
|
var MACHINE_ERROR_HINTS = {
|
|
@@ -7866,6 +7949,18 @@ var COMMAND_HELP = {
|
|
|
7866
7949
|
examples: ["tonbo volume show data"],
|
|
7867
7950
|
arguments: NAME("Volume")
|
|
7868
7951
|
},
|
|
7952
|
+
"tonbo volume metrics": {
|
|
7953
|
+
about: [
|
|
7954
|
+
"Prints the Volume's metrics, one row per UTC hour or day: the bytes and requests its Machine read, wrote and trimmed, as the Volume served them, and what its files held at the step's last sample, compressed. The I/O updates about every 30 seconds while the Volume is attached; the current step is marked `so far`.",
|
|
7955
|
+
"Give `--window` (24h hourly; 7d, 30d or 90d daily, 7d also hourly with `--granularity hour`), or `--from` and `--to` with `--granularity` (at most 8 days hourly, 92 days daily). `--series` prints only the series it names. It carries no money: `tonbo usage show` says what the Volume cost."
|
|
7956
|
+
],
|
|
7957
|
+
examples: [
|
|
7958
|
+
"tonbo volume metrics data --window 24h",
|
|
7959
|
+
"tonbo volume metrics data --series read_bytes,write_bytes --window 7d"
|
|
7960
|
+
],
|
|
7961
|
+
arguments: NAME("Volume"),
|
|
7962
|
+
defaults: { "--window": "30d" }
|
|
7963
|
+
},
|
|
7869
7964
|
"tonbo volume move": {
|
|
7870
7965
|
about: [
|
|
7871
7966
|
"Moves the Volume to the Machine `--to`, taking it from the Machine that has it now in one write: the Volume is unbound there (that Machine's ETag changes and it boots without it) and bound to `--to`, which may be awake and gets it at its next boot. The CLI reads both Machines' ETags first, so a Machine changed since is refused, never overwritten. Without `--path` the Volume keeps the path it has now, or stays a whole disk; a whole disk moves only to a Machine on the same image.",
|
|
@@ -7913,6 +8008,16 @@ var COMMAND_HELP = {
|
|
|
7913
8008
|
examples: ["tonbo metrics databases --window 30d --series stored_bytes,write_units"],
|
|
7914
8009
|
defaults: { "--window": "7d" }
|
|
7915
8010
|
},
|
|
8011
|
+
"tonbo metrics databases-and-streams": {
|
|
8012
|
+
about: [
|
|
8013
|
+
"Prints the account's databases and streams together, per UTC hour or day, summed over every region, with the same series as `tonbo database metrics`: the total's server latency comes from every database's and stream's merged histograms, one figure for both kinds, never an average of percentiles. Server latency is measured at Tonbo's servers, from request to response headers; your network adds to this. Then each one's row over the window, named with its kind.",
|
|
8014
|
+
"Give `--window`, or `--from` and `--to` with `--granularity` (at most 31 days hourly, 92 days daily)."
|
|
8015
|
+
],
|
|
8016
|
+
examples: [
|
|
8017
|
+
"tonbo metrics databases-and-streams --window 30d --series server_read_latency_p50_ms"
|
|
8018
|
+
],
|
|
8019
|
+
defaults: { "--window": "7d" }
|
|
8020
|
+
},
|
|
7916
8021
|
"tonbo metrics streams": {
|
|
7917
8022
|
about: [
|
|
7918
8023
|
"Prints the account's streams per UTC hour or day, summed over every region, with the same series as `tonbo stream metrics`: the total's server latency comes from every stream's merged histograms, never an average of percentiles. Server latency is measured at Tonbo's servers, from request to response headers; your network adds to this. Then each stream's row over the window: its stored size at the last measured step and its counts summed.",
|
|
@@ -9900,6 +10005,17 @@ function createProgram(makeDependencies = createDependencies) {
|
|
|
9900
10005
|
).action(
|
|
9901
10006
|
async (name, options) => volumeShowCommand(dependencies(), name, options)
|
|
9902
10007
|
);
|
|
10008
|
+
operationOptions(
|
|
10009
|
+
volume.command("metrics <name>").description(
|
|
10010
|
+
"show what a Volume's Machine read, wrote and trimmed, and what it held, over time"
|
|
10011
|
+
).option("--window <window>", "24h hourly, or 7d, 30d or 90d daily; 30d when omitted").option(
|
|
10012
|
+
"--series <series>",
|
|
10013
|
+
"the series to print, comma-separated; every series when omitted"
|
|
10014
|
+
).option("--granularity <step>", "hour or day: with --from and --to, or with --window 7d").option("--from <time>", "with --to, the window's start, on a UTC hour or day").option("--to <time>", "with --from, the window's end, exclusive"),
|
|
10015
|
+
"getVolumeNameMetrics"
|
|
10016
|
+
).action(
|
|
10017
|
+
async (name, options) => volumeMetricsCommand(dependencies(), name, options)
|
|
10018
|
+
);
|
|
9903
10019
|
operationOptions(
|
|
9904
10020
|
volume.command("move <name>").description(
|
|
9905
10021
|
"move a Volume to another Machine of its region, taking it from the asleep Machine that has it in the same write"
|
|
@@ -9968,6 +10084,17 @@ function createProgram(makeDependencies = createDependencies) {
|
|
|
9968
10084
|
).option("--granularity <step>", "with --from and --to, hour or day").option("--from <time>", "with --to, the window's start, on a UTC hour or day").option("--to <time>", "with --from, the window's end, exclusive"),
|
|
9969
10085
|
"getAccountStreamMetrics"
|
|
9970
10086
|
).action(async (options) => metricsStreamsCommand(dependencies(), options));
|
|
10087
|
+
operationOptions(
|
|
10088
|
+
metrics.command("databases-and-streams").description(
|
|
10089
|
+
"show the account's databases and streams together, with one server latency for both"
|
|
10090
|
+
).option("--window <window>", "24h or 7d hourly, 30d or 90d daily; 7d when omitted").option(
|
|
10091
|
+
"--series <series>",
|
|
10092
|
+
"the series to print, comma-separated; every series when omitted"
|
|
10093
|
+
).option("--granularity <step>", "with --from and --to, hour or day").option("--from <time>", "with --to, the window's start, on a UTC hour or day").option("--to <time>", "with --from, the window's end, exclusive"),
|
|
10094
|
+
"getAccountDatabaseAndStreamMetrics"
|
|
10095
|
+
).action(
|
|
10096
|
+
async (options) => metricsDatabasesAndStreamsCommand(dependencies(), options)
|
|
10097
|
+
);
|
|
9971
10098
|
const ssh = program.command("ssh").description("open a terminal on a Machine, or run a command there, over SSH").argument("<machine>", "the Machine's name").argument("[command...]", "a command to run instead of a shell, after --").action(async (name, command) => sshCommand(dependencies(), name, command));
|
|
9972
10099
|
ssh.command("config").description(
|
|
9973
10100
|
"print the ssh_config block that lets ssh, scp, sftp and Remote-SSH reach every Machine"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tonbo/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.26.0",
|
|
4
4
|
"description": "The Tonbo CLI. Compute, disks, databases and streams for AI agents: your agent picks what it needs, sets it up, and knows what it costs, from the command line.",
|
|
5
5
|
"homepage": "https://tonbo.dev",
|
|
6
6
|
"bugs": {
|