@tonbo/cli 0.23.0 → 0.25.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 +361 -4
- package/package.json +1 -1
package/dist/bin/tonbo.js
CHANGED
|
@@ -613,6 +613,22 @@ var managementOperations = {
|
|
|
613
613
|
"idempotencyKey": false,
|
|
614
614
|
"cli": "tonbo database activity"
|
|
615
615
|
},
|
|
616
|
+
"getDatabaseMetrics": {
|
|
617
|
+
"method": "GET",
|
|
618
|
+
"path": "/databases/{name}/metrics",
|
|
619
|
+
"pathParams": [
|
|
620
|
+
"name"
|
|
621
|
+
],
|
|
622
|
+
"query": [
|
|
623
|
+
"series",
|
|
624
|
+
"window",
|
|
625
|
+
"granularity",
|
|
626
|
+
"from",
|
|
627
|
+
"to"
|
|
628
|
+
],
|
|
629
|
+
"idempotencyKey": false,
|
|
630
|
+
"cli": "tonbo database metrics"
|
|
631
|
+
},
|
|
616
632
|
"listDatabaseUsage": {
|
|
617
633
|
"method": "GET",
|
|
618
634
|
"path": "/usage/databases",
|
|
@@ -752,6 +768,34 @@ var managementOperations = {
|
|
|
752
768
|
"idempotencyKey": false,
|
|
753
769
|
"cli": "tonbo metrics machines"
|
|
754
770
|
},
|
|
771
|
+
"getAccountDatabaseMetrics": {
|
|
772
|
+
"method": "GET",
|
|
773
|
+
"path": "/metrics/databases",
|
|
774
|
+
"pathParams": [],
|
|
775
|
+
"query": [
|
|
776
|
+
"series",
|
|
777
|
+
"window",
|
|
778
|
+
"granularity",
|
|
779
|
+
"from",
|
|
780
|
+
"to"
|
|
781
|
+
],
|
|
782
|
+
"idempotencyKey": false,
|
|
783
|
+
"cli": "tonbo metrics databases"
|
|
784
|
+
},
|
|
785
|
+
"getAccountStreamMetrics": {
|
|
786
|
+
"method": "GET",
|
|
787
|
+
"path": "/metrics/streams",
|
|
788
|
+
"pathParams": [],
|
|
789
|
+
"query": [
|
|
790
|
+
"series",
|
|
791
|
+
"window",
|
|
792
|
+
"granularity",
|
|
793
|
+
"from",
|
|
794
|
+
"to"
|
|
795
|
+
],
|
|
796
|
+
"idempotencyKey": false,
|
|
797
|
+
"cli": "tonbo metrics streams"
|
|
798
|
+
},
|
|
755
799
|
"listMachineShapes": {
|
|
756
800
|
"method": "GET",
|
|
757
801
|
"path": "/machine-shapes",
|
|
@@ -1018,6 +1062,22 @@ var managementOperations = {
|
|
|
1018
1062
|
"idempotencyKey": false,
|
|
1019
1063
|
"cli": "tonbo volume delete"
|
|
1020
1064
|
},
|
|
1065
|
+
"getVolumeNameMetrics": {
|
|
1066
|
+
"method": "GET",
|
|
1067
|
+
"path": "/volumes/{name}/metrics",
|
|
1068
|
+
"pathParams": [
|
|
1069
|
+
"name"
|
|
1070
|
+
],
|
|
1071
|
+
"query": [
|
|
1072
|
+
"series",
|
|
1073
|
+
"window",
|
|
1074
|
+
"granularity",
|
|
1075
|
+
"from",
|
|
1076
|
+
"to"
|
|
1077
|
+
],
|
|
1078
|
+
"idempotencyKey": false,
|
|
1079
|
+
"cli": "tonbo volume metrics"
|
|
1080
|
+
},
|
|
1021
1081
|
"listStreams": {
|
|
1022
1082
|
"method": "GET",
|
|
1023
1083
|
"path": "/streams",
|
|
@@ -1083,6 +1143,22 @@ var managementOperations = {
|
|
|
1083
1143
|
"idempotencyKey": false,
|
|
1084
1144
|
"cli": "tonbo stream activity"
|
|
1085
1145
|
},
|
|
1146
|
+
"getStreamMetrics": {
|
|
1147
|
+
"method": "GET",
|
|
1148
|
+
"path": "/streams/{name}/metrics",
|
|
1149
|
+
"pathParams": [
|
|
1150
|
+
"name"
|
|
1151
|
+
],
|
|
1152
|
+
"query": [
|
|
1153
|
+
"series",
|
|
1154
|
+
"window",
|
|
1155
|
+
"granularity",
|
|
1156
|
+
"from",
|
|
1157
|
+
"to"
|
|
1158
|
+
],
|
|
1159
|
+
"idempotencyKey": false,
|
|
1160
|
+
"cli": "tonbo stream metrics"
|
|
1161
|
+
},
|
|
1086
1162
|
"listStreamUsage": {
|
|
1087
1163
|
"method": "GET",
|
|
1088
1164
|
"path": "/usage/streams",
|
|
@@ -2335,10 +2411,19 @@ var ManagementApi = class {
|
|
|
2335
2411
|
deleteDatabase(key, name) {
|
|
2336
2412
|
return this.call("deleteDatabase", key, { params: { name } });
|
|
2337
2413
|
}
|
|
2338
|
-
/**
|
|
2414
|
+
/** Deprecated (`getDatabaseMetrics`): a database's writes per hour or day
|
|
2415
|
+
* and its size at each step's end, for `tonbo database activity`. */
|
|
2339
2416
|
getDatabaseActivity(key, name, query = {}) {
|
|
2340
2417
|
return this.call("getDatabaseActivity", key, { params: { name }, query });
|
|
2341
2418
|
}
|
|
2419
|
+
/** A live database's metrics per UTC hour or day. */
|
|
2420
|
+
getDatabaseMetrics(key, name, query = {}) {
|
|
2421
|
+
return this.call("getDatabaseMetrics", key, { params: { name }, query });
|
|
2422
|
+
}
|
|
2423
|
+
/** The account's databases' metrics, each and summed. */
|
|
2424
|
+
getAccountDatabaseMetrics(key, query = {}) {
|
|
2425
|
+
return this.call("getAccountDatabaseMetrics", key, { query });
|
|
2426
|
+
}
|
|
2342
2427
|
/** The whole usage page: its rows, `other`, prices and checkpoint. */
|
|
2343
2428
|
listDatabaseUsage(key, page, query = {}) {
|
|
2344
2429
|
return this.page("listDatabaseUsage", key, page, query);
|
|
@@ -2363,10 +2448,19 @@ var ManagementApi = class {
|
|
|
2363
2448
|
deleteStream(key, name) {
|
|
2364
2449
|
return this.call("deleteStream", key, { params: { name } });
|
|
2365
2450
|
}
|
|
2366
|
-
/**
|
|
2451
|
+
/** Deprecated (`getStreamMetrics`): a stream's appends per hour or day and
|
|
2452
|
+
* its size at each step's end, for `tonbo stream activity`. */
|
|
2367
2453
|
getStreamActivity(key, name, query = {}) {
|
|
2368
2454
|
return this.call("getStreamActivity", key, { params: { name }, query });
|
|
2369
2455
|
}
|
|
2456
|
+
/** A live stream's metrics per UTC hour or day. */
|
|
2457
|
+
getStreamMetrics(key, name, query = {}) {
|
|
2458
|
+
return this.call("getStreamMetrics", key, { params: { name }, query });
|
|
2459
|
+
}
|
|
2460
|
+
/** The account's streams' metrics, each and summed. */
|
|
2461
|
+
getAccountStreamMetrics(key, query = {}) {
|
|
2462
|
+
return this.call("getAccountStreamMetrics", key, { query });
|
|
2463
|
+
}
|
|
2370
2464
|
/** The whole usage page: its rows, `other`, prices and checkpoint. */
|
|
2371
2465
|
listStreamUsage(key, page, query = {}) {
|
|
2372
2466
|
return this.page("listStreamUsage", key, page, query);
|
|
@@ -2381,6 +2475,10 @@ var ManagementApi = class {
|
|
|
2381
2475
|
getVolumeMetrics(key, query = {}) {
|
|
2382
2476
|
return this.call("getVolumeMetrics", key, { query });
|
|
2383
2477
|
}
|
|
2478
|
+
/** One Volume's guest I/O and stored bytes per UTC hour or day. */
|
|
2479
|
+
getVolumeNameMetrics(key, name, query = {}) {
|
|
2480
|
+
return this.call("getVolumeNameMetrics", key, { params: { name }, query });
|
|
2481
|
+
}
|
|
2384
2482
|
/** The account's writes of yesterday and today, hourly, per lane. */
|
|
2385
2483
|
getUsageToday(key) {
|
|
2386
2484
|
return this.call("getUsageToday", key);
|
|
@@ -5234,6 +5332,128 @@ async function databaseActivityCommand(deps, name, options = {}) {
|
|
|
5234
5332
|
);
|
|
5235
5333
|
printActivity(deps, options.json, activity, "Database");
|
|
5236
5334
|
}
|
|
5335
|
+
var REGISTRY_COLUMNS = {
|
|
5336
|
+
stored_bytes: ["STORED", (value) => bytes(value)],
|
|
5337
|
+
log_bytes: ["LOG", (value) => bytes(value)],
|
|
5338
|
+
snapshot_bytes: ["SNAPSHOT", (value) => bytes(value)],
|
|
5339
|
+
write_units: ["WRITE UNITS", String],
|
|
5340
|
+
write_bytes: ["WRITTEN", (value) => bytes(value)],
|
|
5341
|
+
records: ["RECORDS", String],
|
|
5342
|
+
reads: ["READS", String],
|
|
5343
|
+
read_bytes: ["READ", (value) => bytes(value)],
|
|
5344
|
+
live_reads: ["LIVE READS", String],
|
|
5345
|
+
live_read_bytes: ["LIVE READ", (value) => bytes(value)],
|
|
5346
|
+
server_write_latency_p50_ms: ["WRITE P50", (value) => `${value} ms`],
|
|
5347
|
+
server_write_latency_p99_ms: ["WRITE P99", (value) => `${value} ms`],
|
|
5348
|
+
server_read_latency_p50_ms: ["READ P50", (value) => `${value} ms`],
|
|
5349
|
+
server_read_latency_p99_ms: ["READ P99", (value) => `${value} ms`]
|
|
5350
|
+
};
|
|
5351
|
+
var SERVER_LATENCY = "Latency is server latency: measured at Tonbo's servers, from request to response headers; your network adds to this.";
|
|
5352
|
+
function registryMetricsTable(granularity, points) {
|
|
5353
|
+
const series = Object.keys(REGISTRY_COLUMNS).filter(
|
|
5354
|
+
(name) => points.some((point) => name in point)
|
|
5355
|
+
);
|
|
5356
|
+
return {
|
|
5357
|
+
latency: series.some((name) => name.startsWith("server_")),
|
|
5358
|
+
text: table(
|
|
5359
|
+
[
|
|
5360
|
+
granularity === "hour" ? "HOUR (UTC)" : "DAY (UTC)",
|
|
5361
|
+
...series.map((name) => REGISTRY_COLUMNS[name][0])
|
|
5362
|
+
],
|
|
5363
|
+
points.map((point) => [
|
|
5364
|
+
granularity === "hour" ? point.start.slice(0, 16).replace("T", " ") : point.start.slice(0, 10),
|
|
5365
|
+
...series.map((name) => {
|
|
5366
|
+
const value = point[name];
|
|
5367
|
+
if (value === null || value === void 0)
|
|
5368
|
+
return Date.parse(point.start) > Date.now() ? "" : "-";
|
|
5369
|
+
return REGISTRY_COLUMNS[name][1](value);
|
|
5370
|
+
})
|
|
5371
|
+
])
|
|
5372
|
+
)
|
|
5373
|
+
};
|
|
5374
|
+
}
|
|
5375
|
+
function printRegistryMetrics(deps, noun, metrics, options) {
|
|
5376
|
+
const rendered = registryMetricsTable(metrics.granularity, metrics.points);
|
|
5377
|
+
print(
|
|
5378
|
+
deps,
|
|
5379
|
+
options.json,
|
|
5380
|
+
metrics,
|
|
5381
|
+
[
|
|
5382
|
+
`${noun} ${metrics.name} in ${metrics.region} from ${metrics.from} to ${metrics.to} (UTC; metered up to ${when(metrics.as_of, "not yet metered")})`,
|
|
5383
|
+
rendered.text,
|
|
5384
|
+
...rendered.latency ? [SERVER_LATENCY] : []
|
|
5385
|
+
].join("\n")
|
|
5386
|
+
);
|
|
5387
|
+
}
|
|
5388
|
+
async function databaseMetricsCommand(deps, name, options = {}) {
|
|
5389
|
+
const metrics = await deps.api.getDatabaseMetrics(
|
|
5390
|
+
await deps.auth.apiKey(),
|
|
5391
|
+
name,
|
|
5392
|
+
metricsQuery(options)
|
|
5393
|
+
);
|
|
5394
|
+
printRegistryMetrics(deps, "Database", metrics, options);
|
|
5395
|
+
}
|
|
5396
|
+
async function streamMetricsCommand(deps, name, options = {}) {
|
|
5397
|
+
const metrics = await deps.api.getStreamMetrics(
|
|
5398
|
+
await deps.auth.apiKey(),
|
|
5399
|
+
name,
|
|
5400
|
+
metricsQuery(options)
|
|
5401
|
+
);
|
|
5402
|
+
printRegistryMetrics(deps, "Stream", metrics, options);
|
|
5403
|
+
}
|
|
5404
|
+
function printAccountRegistryMetrics(deps, noun, metrics, options) {
|
|
5405
|
+
const rendered = registryMetricsTable(metrics.granularity, metrics.total.points);
|
|
5406
|
+
const lines = [
|
|
5407
|
+
`The account's ${noun} from ${metrics.from} to ${metrics.to} (UTC; metered up to ${when(metrics.as_of, "not yet metered")})`,
|
|
5408
|
+
rendered.text
|
|
5409
|
+
];
|
|
5410
|
+
const counted = ["write_units", "write_bytes", "records", "reads", "read_bytes"].filter((name) => metrics.total.points.some((point) => name in point));
|
|
5411
|
+
const sized = metrics.total.points.some((point) => "stored_bytes" in point);
|
|
5412
|
+
if (metrics.resources.length > 0 && (counted.length > 0 || sized)) {
|
|
5413
|
+
lines.push(
|
|
5414
|
+
"",
|
|
5415
|
+
table(
|
|
5416
|
+
[
|
|
5417
|
+
noun === "databases" ? "DATABASE" : "STREAM",
|
|
5418
|
+
"REGION",
|
|
5419
|
+
...sized ? ["STORED"] : [],
|
|
5420
|
+
...counted.map((name) => REGISTRY_COLUMNS[name][0])
|
|
5421
|
+
],
|
|
5422
|
+
metrics.resources.map((resource) => {
|
|
5423
|
+
const stored = [...resource.points].reverse().find((point) => point.stored_bytes !== null && point.stored_bytes !== void 0);
|
|
5424
|
+
return [
|
|
5425
|
+
resource.name,
|
|
5426
|
+
resource.region,
|
|
5427
|
+
...sized ? [stored ? bytes(stored.stored_bytes ?? 0) : "-"] : [],
|
|
5428
|
+
...counted.map(
|
|
5429
|
+
(name) => REGISTRY_COLUMNS[name][1](
|
|
5430
|
+
resource.points.reduce((total, point) => total + (point[name] ?? 0), 0)
|
|
5431
|
+
)
|
|
5432
|
+
)
|
|
5433
|
+
];
|
|
5434
|
+
})
|
|
5435
|
+
)
|
|
5436
|
+
);
|
|
5437
|
+
}
|
|
5438
|
+
if (rendered.latency) lines.push(SERVER_LATENCY);
|
|
5439
|
+
if (metrics.unavailable_regions.length > 0)
|
|
5440
|
+
lines.push(`Not read: ${metrics.unavailable_regions.join(", ")}`);
|
|
5441
|
+
print(deps, options.json, metrics, lines.join("\n"));
|
|
5442
|
+
}
|
|
5443
|
+
async function metricsDatabasesCommand(deps, options = {}) {
|
|
5444
|
+
const metrics = await deps.api.getAccountDatabaseMetrics(
|
|
5445
|
+
await deps.auth.apiKey(),
|
|
5446
|
+
metricsQuery(options)
|
|
5447
|
+
);
|
|
5448
|
+
printAccountRegistryMetrics(deps, "databases", metrics, options);
|
|
5449
|
+
}
|
|
5450
|
+
async function metricsStreamsCommand(deps, options = {}) {
|
|
5451
|
+
const metrics = await deps.api.getAccountStreamMetrics(
|
|
5452
|
+
await deps.auth.apiKey(),
|
|
5453
|
+
metricsQuery(options)
|
|
5454
|
+
);
|
|
5455
|
+
printAccountRegistryMetrics(deps, "streams", metrics, options);
|
|
5456
|
+
}
|
|
5237
5457
|
function streamFields(stream) {
|
|
5238
5458
|
return fields([
|
|
5239
5459
|
["Name", stream.name],
|
|
@@ -5409,14 +5629,14 @@ async function metricsVolumesCommand(deps, options = {}) {
|
|
|
5409
5629
|
["DAY", "STORED", ""],
|
|
5410
5630
|
points.map((point) => [
|
|
5411
5631
|
point.start.slice(0, 10),
|
|
5412
|
-
bytes(point.stored_bytes),
|
|
5632
|
+
bytes(point.stored_bytes ?? 0),
|
|
5413
5633
|
point.partial ? "so far" : ""
|
|
5414
5634
|
])
|
|
5415
5635
|
)
|
|
5416
5636
|
];
|
|
5417
5637
|
const complete = points.filter((point) => !point.partial);
|
|
5418
5638
|
if (complete.length > 1) {
|
|
5419
|
-
const change = complete[complete.length - 1].stored_bytes - complete[0].stored_bytes;
|
|
5639
|
+
const change = (complete[complete.length - 1].stored_bytes ?? 0) - (complete[0].stored_bytes ?? 0);
|
|
5420
5640
|
lines.push(
|
|
5421
5641
|
`Change over its complete days: ${change < 0 ? "-" : "+"}${bytes(Math.abs(change))}`
|
|
5422
5642
|
);
|
|
@@ -5809,6 +6029,44 @@ async function resolveVolumeBinding(deps, key, spec) {
|
|
|
5809
6029
|
region: volume.region
|
|
5810
6030
|
};
|
|
5811
6031
|
}
|
|
6032
|
+
var VOLUME_COLUMNS = {
|
|
6033
|
+
stored_bytes: ["STORED", (value) => bytes(value)],
|
|
6034
|
+
read_bytes: ["READ", (value) => bytes(value)],
|
|
6035
|
+
write_bytes: ["WRITTEN", (value) => bytes(value)],
|
|
6036
|
+
read_ops: ["READ OPS", String],
|
|
6037
|
+
write_ops: ["WRITE OPS", String],
|
|
6038
|
+
trim_ops: ["TRIMS", String]
|
|
6039
|
+
};
|
|
6040
|
+
async function volumeMetricsCommand(deps, name, options = {}) {
|
|
6041
|
+
const metrics = await deps.api.getVolumeNameMetrics(
|
|
6042
|
+
await deps.auth.apiKey(),
|
|
6043
|
+
name,
|
|
6044
|
+
metricsQuery(options)
|
|
6045
|
+
);
|
|
6046
|
+
const series = Object.keys(VOLUME_COLUMNS).filter(
|
|
6047
|
+
(key) => metrics.points.some((point) => key in point)
|
|
6048
|
+
);
|
|
6049
|
+
const hourly = metrics.granularity === "hour";
|
|
6050
|
+
print(
|
|
6051
|
+
deps,
|
|
6052
|
+
options.json,
|
|
6053
|
+
metrics,
|
|
6054
|
+
[
|
|
6055
|
+
`Volume ${metrics.name} in ${metrics.region} from ${metrics.from} to ${metrics.to} (UTC)`,
|
|
6056
|
+
table(
|
|
6057
|
+
[hourly ? "HOUR (UTC)" : "DAY (UTC)", ...series.map((key) => VOLUME_COLUMNS[key][0]), ""],
|
|
6058
|
+
metrics.points.map((point) => [
|
|
6059
|
+
hourly ? point.start.slice(0, 16).replace("T", " ") : point.start.slice(0, 10),
|
|
6060
|
+
...series.map((key) => {
|
|
6061
|
+
const value = point[key];
|
|
6062
|
+
return value === null || value === void 0 ? "-" : VOLUME_COLUMNS[key][1](value);
|
|
6063
|
+
}),
|
|
6064
|
+
point.partial ? "so far" : ""
|
|
6065
|
+
])
|
|
6066
|
+
)
|
|
6067
|
+
].join("\n")
|
|
6068
|
+
);
|
|
6069
|
+
}
|
|
5812
6070
|
|
|
5813
6071
|
// src/machine.ts
|
|
5814
6072
|
var MACHINE_ERROR_HINTS = {
|
|
@@ -7263,6 +7521,18 @@ var COMMAND_HELP = {
|
|
|
7263
7521
|
arguments: NAME("database"),
|
|
7264
7522
|
defaults: ACTIVITY_DEFAULTS
|
|
7265
7523
|
},
|
|
7524
|
+
"tonbo database metrics": {
|
|
7525
|
+
about: [
|
|
7526
|
+
"Prints the database's metrics, one row per UTC hour or day: its stored size at the step's end (the log and snapshots it keeps), the write units, bytes and records written, the successful reads and live (long-poll or SSE) reads and the bytes they streamed, and the median and 99th percentile server latency of its appends and catch-up reads. Server latency is measured at Tonbo's servers, from request to response headers; your network adds to this. A dash is a value not measured (a size before the meter's first sample, a latency with no request); the current step is still growing.",
|
|
7527
|
+
"Give `--window`, or `--from` and `--to` with `--granularity` (at most 31 days hourly, 92 days daily; server latency is kept 8 days hourly). `--series` prints only the series it names. It carries no money: `tonbo database usage` says what it cost."
|
|
7528
|
+
],
|
|
7529
|
+
examples: [
|
|
7530
|
+
"tonbo database metrics notes --window 7d",
|
|
7531
|
+
"tonbo database metrics notes --series server_write_latency_p50_ms,server_write_latency_p99_ms"
|
|
7532
|
+
],
|
|
7533
|
+
arguments: NAME("database"),
|
|
7534
|
+
defaults: { "--window": "24h" }
|
|
7535
|
+
},
|
|
7266
7536
|
"tonbo database usage": {
|
|
7267
7537
|
about: [
|
|
7268
7538
|
"Prints each database's usage of one calendar month in UTC at list price, before the monthly allowance and credit: its write units, log and snapshot GiB-months and list value, then the account's other metered usage (its streams and everything else). The charges after allowance and credit are in `tonbo usage show`."
|
|
@@ -7321,6 +7591,18 @@ var COMMAND_HELP = {
|
|
|
7321
7591
|
arguments: NAME("stream"),
|
|
7322
7592
|
defaults: ACTIVITY_DEFAULTS
|
|
7323
7593
|
},
|
|
7594
|
+
"tonbo stream metrics": {
|
|
7595
|
+
about: [
|
|
7596
|
+
"Prints the stream's metrics, one row per UTC hour or day: its stored size at the step's end (the log and snapshots it keeps), the write units, bytes and records written, the successful reads and live (long-poll or SSE) reads and the bytes they streamed, and the median and 99th percentile server latency of its appends and catch-up reads. Server latency is measured at Tonbo's servers, from request to response headers; your network adds to this. A dash is a value not measured (a size before the meter's first sample, a latency with no request); the current step is still growing.",
|
|
7597
|
+
"Give `--window`, or `--from` and `--to` with `--granularity` (at most 31 days hourly, 92 days daily; server latency is kept 8 days hourly). `--series` prints only the series it names. It carries no money: `tonbo stream usage` says what it cost."
|
|
7598
|
+
],
|
|
7599
|
+
examples: [
|
|
7600
|
+
"tonbo stream metrics events --window 7d",
|
|
7601
|
+
"tonbo stream metrics events --series server_write_latency_p50_ms,server_write_latency_p99_ms"
|
|
7602
|
+
],
|
|
7603
|
+
arguments: NAME("stream"),
|
|
7604
|
+
defaults: { "--window": "24h" }
|
|
7605
|
+
},
|
|
7324
7606
|
"tonbo stream usage": {
|
|
7325
7607
|
about: [
|
|
7326
7608
|
"Prints each stream's usage of one calendar month in UTC at list price, before the monthly allowance and credit, then the account's other metered usage (its databases and everything else). The charges after allowance and credit are in `tonbo usage show`."
|
|
@@ -7642,6 +7924,18 @@ var COMMAND_HELP = {
|
|
|
7642
7924
|
examples: ["tonbo volume show data"],
|
|
7643
7925
|
arguments: NAME("Volume")
|
|
7644
7926
|
},
|
|
7927
|
+
"tonbo volume metrics": {
|
|
7928
|
+
about: [
|
|
7929
|
+
"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`.",
|
|
7930
|
+
"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."
|
|
7931
|
+
],
|
|
7932
|
+
examples: [
|
|
7933
|
+
"tonbo volume metrics data --window 24h",
|
|
7934
|
+
"tonbo volume metrics data --series read_bytes,write_bytes --window 7d"
|
|
7935
|
+
],
|
|
7936
|
+
arguments: NAME("Volume"),
|
|
7937
|
+
defaults: { "--window": "30d" }
|
|
7938
|
+
},
|
|
7645
7939
|
"tonbo volume move": {
|
|
7646
7940
|
about: [
|
|
7647
7941
|
"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.",
|
|
@@ -7681,6 +7975,22 @@ var COMMAND_HELP = {
|
|
|
7681
7975
|
examples: ["tonbo metrics machines --window 30d"],
|
|
7682
7976
|
defaults: { "--window": "7d" }
|
|
7683
7977
|
},
|
|
7978
|
+
"tonbo metrics databases": {
|
|
7979
|
+
about: [
|
|
7980
|
+
"Prints the account's databases 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 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 database's row over the window: its stored size at the last measured step and its counts summed.",
|
|
7981
|
+
"Give `--window`, or `--from` and `--to` with `--granularity` (at most 31 days hourly, 92 days daily)."
|
|
7982
|
+
],
|
|
7983
|
+
examples: ["tonbo metrics databases --window 30d --series stored_bytes,write_units"],
|
|
7984
|
+
defaults: { "--window": "7d" }
|
|
7985
|
+
},
|
|
7986
|
+
"tonbo metrics streams": {
|
|
7987
|
+
about: [
|
|
7988
|
+
"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.",
|
|
7989
|
+
"Give `--window`, or `--from` and `--to` with `--granularity` (at most 31 days hourly, 92 days daily)."
|
|
7990
|
+
],
|
|
7991
|
+
examples: ["tonbo metrics streams --window 30d --series stored_bytes,write_units"],
|
|
7992
|
+
defaults: { "--window": "7d" }
|
|
7993
|
+
},
|
|
7684
7994
|
"tonbo metrics volumes": {
|
|
7685
7995
|
about: [
|
|
7686
7996
|
"Prints what the account's Volumes stored, one line per UTC day of the window: the average bytes their files held that day, compressed, summed over every region, which is what they are billed for. Today, and a day not fully rated yet, is marked `so far`. Then the change between the window's first and last complete days.",
|
|
@@ -9323,6 +9633,15 @@ function createProgram(makeDependencies = createDependencies) {
|
|
|
9323
9633
|
).action(
|
|
9324
9634
|
async (name, options) => databaseActivityCommand(dependencies(), name, options)
|
|
9325
9635
|
);
|
|
9636
|
+
operationOptions(
|
|
9637
|
+
database.command("metrics <name>").description("show a database's writes, reads, stored size and server latency over time").option("--window <window>", "24h or 7d hourly, 30d or 90d daily; 24h when omitted").option(
|
|
9638
|
+
"--series <series>",
|
|
9639
|
+
"the series to print, comma-separated; every series when omitted"
|
|
9640
|
+
).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"),
|
|
9641
|
+
"getDatabaseMetrics"
|
|
9642
|
+
).action(
|
|
9643
|
+
async (name, options) => databaseMetricsCommand(dependencies(), name, options)
|
|
9644
|
+
);
|
|
9326
9645
|
operationOptions(
|
|
9327
9646
|
database.command("usage").description("each database's usage of one month at list price, before allowance and credit").option("--period <month>", "the calendar month in UTC, as YYYY-MM").option("--sort <order>", "list_value (highest first) or name", parseUsageSort).option("--prefix <prefix>", "only databases whose name starts with this").option("--names <names>", "only these databases, up to 100 names, comma-separated"),
|
|
9328
9647
|
"listDatabaseUsage"
|
|
@@ -9384,6 +9703,15 @@ function createProgram(makeDependencies = createDependencies) {
|
|
|
9384
9703
|
).action(
|
|
9385
9704
|
async (name, options) => streamActivityCommand(dependencies(), name, options)
|
|
9386
9705
|
);
|
|
9706
|
+
operationOptions(
|
|
9707
|
+
stream.command("metrics <name>").description("show a stream's writes, reads, stored size and server latency over time").option("--window <window>", "24h or 7d hourly, 30d or 90d daily; 24h when omitted").option(
|
|
9708
|
+
"--series <series>",
|
|
9709
|
+
"the series to print, comma-separated; every series when omitted"
|
|
9710
|
+
).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"),
|
|
9711
|
+
"getStreamMetrics"
|
|
9712
|
+
).action(
|
|
9713
|
+
async (name, options) => streamMetricsCommand(dependencies(), name, options)
|
|
9714
|
+
);
|
|
9387
9715
|
operationOptions(
|
|
9388
9716
|
stream.command("usage").description("each stream's usage of one month at list price, before allowance and credit").option("--period <month>", "the calendar month in UTC, as YYYY-MM").option("--sort <order>", "list_value (highest first) or name", parseUsageSort).option("--prefix <prefix>", "only streams whose name starts with this").option("--names <names>", "only these streams, up to 100 names, comma-separated"),
|
|
9389
9717
|
"listStreamUsage"
|
|
@@ -9642,6 +9970,17 @@ function createProgram(makeDependencies = createDependencies) {
|
|
|
9642
9970
|
).action(
|
|
9643
9971
|
async (name, options) => volumeShowCommand(dependencies(), name, options)
|
|
9644
9972
|
);
|
|
9973
|
+
operationOptions(
|
|
9974
|
+
volume.command("metrics <name>").description(
|
|
9975
|
+
"show what a Volume's Machine read, wrote and trimmed, and what it held, over time"
|
|
9976
|
+
).option("--window <window>", "24h hourly, or 7d, 30d or 90d daily; 30d when omitted").option(
|
|
9977
|
+
"--series <series>",
|
|
9978
|
+
"the series to print, comma-separated; every series when omitted"
|
|
9979
|
+
).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"),
|
|
9980
|
+
"getVolumeNameMetrics"
|
|
9981
|
+
).action(
|
|
9982
|
+
async (name, options) => volumeMetricsCommand(dependencies(), name, options)
|
|
9983
|
+
);
|
|
9645
9984
|
operationOptions(
|
|
9646
9985
|
volume.command("move <name>").description(
|
|
9647
9986
|
"move a Volume to another Machine of its region, taking it from the asleep Machine that has it in the same write"
|
|
@@ -9692,6 +10031,24 @@ function createProgram(makeDependencies = createDependencies) {
|
|
|
9692
10031
|
).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"),
|
|
9693
10032
|
"getAccountMachineMetrics"
|
|
9694
10033
|
).action(async (options) => metricsMachinesCommand(dependencies(), options));
|
|
10034
|
+
operationOptions(
|
|
10035
|
+
metrics.command("databases").description(
|
|
10036
|
+
"show the account's databases' writes, reads, stored size and server latency over time"
|
|
10037
|
+
).option("--window <window>", "24h or 7d hourly, 30d or 90d daily; 7d when omitted").option(
|
|
10038
|
+
"--series <series>",
|
|
10039
|
+
"the series to print, comma-separated; every series when omitted"
|
|
10040
|
+
).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"),
|
|
10041
|
+
"getAccountDatabaseMetrics"
|
|
10042
|
+
).action(async (options) => metricsDatabasesCommand(dependencies(), options));
|
|
10043
|
+
operationOptions(
|
|
10044
|
+
metrics.command("streams").description(
|
|
10045
|
+
"show the account's streams' writes, reads, stored size and server latency over time"
|
|
10046
|
+
).option("--window <window>", "24h or 7d hourly, 30d or 90d daily; 7d when omitted").option(
|
|
10047
|
+
"--series <series>",
|
|
10048
|
+
"the series to print, comma-separated; every series when omitted"
|
|
10049
|
+
).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"),
|
|
10050
|
+
"getAccountStreamMetrics"
|
|
10051
|
+
).action(async (options) => metricsStreamsCommand(dependencies(), options));
|
|
9695
10052
|
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));
|
|
9696
10053
|
ssh.command("config").description(
|
|
9697
10054
|
"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.25.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": {
|