@downtrace/agent 0.2.0 → 0.3.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 +31 -4
- package/dist/{config-K6GUM60m.js → config-Dai_3scM.js} +0 -0
- package/dist/index.d.ts +18 -9
- package/dist/index.js +1 -1
- package/dist/register.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -33,12 +33,39 @@ Without `DOWNTRACE_TOKEN` and `DOWNTRACE_URL` (or with a `DOWNTRACE_URL` that is
|
|
|
33
33
|
|
|
34
34
|
Only structural metadata: method, **route template** (`/products/:id`, never the actual URL), status, counts and a fixed-bucket latency histogram per route and interval, plus the process identity (random id, hostname, pid) and the deploy (version, environment). No bodies, no headers, no query strings. The exact contract is the JSON Schema in [`@downtrace/protocol`](https://www.npmjs.com/package/@downtrace/protocol).
|
|
35
35
|
|
|
36
|
+
### The health of your process
|
|
37
|
+
|
|
38
|
+
Every interval the agent also reports how late Node's event loop ran (median, p99 and worst), how much time went to
|
|
39
|
+
garbage collection, heap and resident memory, and the peak number of requests in flight. In Node many slowdowns are
|
|
40
|
+
neither the database nor the network but the process itself, and a diagnosis that does not measure it will blame
|
|
41
|
+
whatever it does measure. It all comes from Node's own instruments, which run whether anyone looks at them or not.
|
|
42
|
+
|
|
36
43
|
### Database work per request
|
|
37
44
|
|
|
38
|
-
When your application uses `pg`, the agent also counts the
|
|
39
|
-
|
|
40
|
-
endpoint went from 12 queries per request to 65". **It never reads the query text or its
|
|
41
|
-
durations.
|
|
45
|
+
When your application uses `pg`, the agent also counts the calls each request makes to it, how long they took in
|
|
46
|
+
total, the slowest one and how many failed, and reports that distribution per route. It is what turns "this endpoint
|
|
47
|
+
got slower" into "this endpoint went from 12 queries per request to 65". **It never reads the query text or its
|
|
48
|
+
values**, only counts and durations.
|
|
49
|
+
|
|
50
|
+
### Calls to other services
|
|
51
|
+
|
|
52
|
+
Outgoing HTTP is reported the same way, grouped by the host your application asked for: how many calls per request,
|
|
53
|
+
how long they took, the slowest one, and how many failed. A 5xx from a dependency counts as a failure of that
|
|
54
|
+
dependency, because for "is this service degraded?" a 500 and a timeout are the same answer.
|
|
55
|
+
|
|
56
|
+
`fetch` and the `node:http` client both publish on Node's `diagnostics_channel`, and the agent listens. There is one
|
|
57
|
+
exception: when a `fetch` cannot connect at all, undici publishes nothing, and that is exactly the case where a
|
|
58
|
+
dependency is down. For that, and only that, the agent wraps `globalThis.fetch`: if a call rejects and nothing was
|
|
59
|
+
recorded for it, it counts as a failed call. On every other path the wrapper does nothing.
|
|
60
|
+
|
|
61
|
+
### Redis
|
|
62
|
+
|
|
63
|
+
The commands each request issues are reported the same way, per server: how many per request, how long they took and
|
|
64
|
+
how many failed. ioredis publishes on a tracing channel, so nothing is patched.
|
|
65
|
+
|
|
66
|
+
Every dependency carries a **target** saying which instance of its kind it is, taken from the driver: the host for
|
|
67
|
+
outgoing HTTP, host and port for Postgres and Redis. A read replica and a primary are two dependencies, not one.
|
|
68
|
+
MySQL will appear the same way when it is added.
|
|
42
69
|
|
|
43
70
|
The agent loads before your application (`node --import`), so it wraps the driver before you import it and you write
|
|
44
71
|
no code. The wrapper passes arguments, results and errors through untouched, and a failure inside it runs your query
|
|
Binary file
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
|
-
import { AgentInfo, DeployInfo, Endpoint, InstanceInfo, Interval } from "@downtrace/protocol";
|
|
1
|
+
import { AgentInfo, Dependency, DeployInfo, Endpoint, InstanceInfo, Interval } from "@downtrace/protocol";
|
|
2
|
+
//#region src/context.d.ts
|
|
3
|
+
type DependencyKind = Dependency["kind"];
|
|
4
|
+
/** What one request did against one dependency. Counters only: never the query text, never the values. */
|
|
5
|
+
interface DependencyWork {
|
|
6
|
+
kind: DependencyKind;
|
|
7
|
+
target: string;
|
|
8
|
+
calls: number;
|
|
9
|
+
ms: number;
|
|
10
|
+
maxMs: number;
|
|
11
|
+
errors: number;
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
2
14
|
//#region src/routes.d.ts
|
|
3
15
|
type Method = Endpoint["method"];
|
|
4
16
|
/** Route used when the per-interval cardinality cap is hit. */
|
|
@@ -19,14 +31,8 @@ declare function routeOf(req: RouteSource): string;
|
|
|
19
31
|
declare function heuristicTemplate(url: string): string;
|
|
20
32
|
//#endregion
|
|
21
33
|
//#region src/aggregator.d.ts
|
|
22
|
-
/** What one finished request did in Postgres, as seen by the instrumented driver. */
|
|
23
|
-
interface QueryWork {
|
|
24
|
-
queries: number;
|
|
25
|
-
queryMs: number;
|
|
26
|
-
queryMaxMs: number;
|
|
27
|
-
}
|
|
28
34
|
interface Recorder {
|
|
29
|
-
record(method: Method, route: string, status: number, ms: number, work?:
|
|
35
|
+
record(method: Method, route: string, status: number, ms: number, work?: Map<string, DependencyWork> | undefined): void;
|
|
30
36
|
rotate(): Interval | null;
|
|
31
37
|
}
|
|
32
38
|
declare const DEFAULT_MAX_ROUTES = 500;
|
|
@@ -42,7 +48,7 @@ declare class IntervalAggregator implements Recorder {
|
|
|
42
48
|
private readonly now;
|
|
43
49
|
constructor(maxRoutes?: number, now?: () => number);
|
|
44
50
|
get size(): number;
|
|
45
|
-
record(method: Method, route: string, status: number, ms: number, work?:
|
|
51
|
+
record(method: Method, route: string, status: number, ms: number, work?: Map<string, DependencyWork> | undefined): void;
|
|
46
52
|
/** Closes the current interval and starts a new one. Returns null when nothing was recorded. */
|
|
47
53
|
rotate(): Interval | null;
|
|
48
54
|
}
|
|
@@ -148,7 +154,10 @@ declare class Agent {
|
|
|
148
154
|
private readonly handleSignals;
|
|
149
155
|
private readonly starts;
|
|
150
156
|
private readonly contexts;
|
|
157
|
+
private readonly runtime;
|
|
151
158
|
private instrumented;
|
|
159
|
+
private stopHttp;
|
|
160
|
+
private stopRedis;
|
|
152
161
|
private timer;
|
|
153
162
|
private started;
|
|
154
163
|
private recorded;
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as createAgent, c as Sender, d as IntervalAggregator, f as OTHER_ROUTE, h as routeOf, i as Agent, l as createLogger, m as normalizeMethod, n as configFromEnv, o as AGENT_VERSION, p as heuristicTemplate, r as detectVersion, s as DEFAULT_MAX_QUEUED, t as DEFAULT_INTERVAL_MS, u as DEFAULT_MAX_ROUTES } from "./config-
|
|
1
|
+
import { a as createAgent, c as Sender, d as IntervalAggregator, f as OTHER_ROUTE, h as routeOf, i as Agent, l as createLogger, m as normalizeMethod, n as configFromEnv, o as AGENT_VERSION, p as heuristicTemplate, r as detectVersion, s as DEFAULT_MAX_QUEUED, t as DEFAULT_INTERVAL_MS, u as DEFAULT_MAX_ROUTES } from "./config-Dai_3scM.js";
|
|
2
2
|
export { AGENT_VERSION, Agent, DEFAULT_INTERVAL_MS, DEFAULT_MAX_QUEUED, DEFAULT_MAX_ROUTES, IntervalAggregator, OTHER_ROUTE, Sender, configFromEnv, createAgent, createLogger, detectVersion, heuristicTemplate, normalizeMethod, routeOf };
|
package/dist/register.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as createAgent, l as createLogger, n as configFromEnv } from "./config-
|
|
1
|
+
import { a as createAgent, l as createLogger, n as configFromEnv } from "./config-Dai_3scM.js";
|
|
2
2
|
//#region src/register.ts
|
|
3
3
|
/**
|
|
4
4
|
* Entry point users load with `node --import @downtrace/agent/register`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@downtrace/agent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Downtrace agent for Node.js: a flight recorder for your backend. Observes HTTP requests, aggregates locally, ships compact batches, never in your request path.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"node": ">=20"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@downtrace/protocol": "0.
|
|
25
|
+
"@downtrace/protocol": "0.3.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@types/express": "^5.0.6",
|