@traffic-twin/sdk 0.0.0-stage → 0.1.1
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/LICENSE +202 -0
- package/README.md +171 -2
- package/dist/cjs/agent.d.ts +143 -0
- package/dist/cjs/agent.js +927 -0
- package/dist/cjs/capture/body.d.ts +11 -0
- package/dist/cjs/capture/body.js +73 -0
- package/dist/cjs/capture/common.d.ts +75 -0
- package/dist/cjs/capture/common.js +180 -0
- package/dist/cjs/capture/context.d.ts +28 -0
- package/dist/cjs/capture/context.js +92 -0
- package/dist/cjs/capture/inbound.d.ts +12 -0
- package/dist/cjs/capture/inbound.js +195 -0
- package/dist/cjs/capture/outbound-http.d.ts +4 -0
- package/dist/cjs/capture/outbound-http.js +200 -0
- package/dist/cjs/capture/outbound-undici.d.ts +2 -0
- package/dist/cjs/capture/outbound-undici.js +242 -0
- package/dist/cjs/capture/wire.d.ts +27 -0
- package/dist/cjs/capture/wire.js +68 -0
- package/dist/cjs/export/event.d.ts +46 -0
- package/dist/cjs/export/event.js +91 -0
- package/dist/cjs/export/exporter.d.ts +50 -0
- package/dist/cjs/export/exporter.js +192 -0
- package/dist/cjs/export/pipeline.d.ts +20 -0
- package/dist/cjs/export/pipeline.js +40 -0
- package/dist/cjs/fleet/asn1.d.ts +44 -0
- package/dist/cjs/fleet/asn1.js +150 -0
- package/dist/cjs/fleet/client.d.ts +84 -0
- package/dist/cjs/fleet/client.js +216 -0
- package/dist/cjs/fleet/http.d.ts +17 -0
- package/dist/cjs/fleet/http.js +80 -0
- package/dist/cjs/fleet/store.d.ts +18 -0
- package/dist/cjs/fleet/store.js +115 -0
- package/dist/cjs/index.d.ts +14 -0
- package/dist/cjs/index.js +69 -0
- package/dist/cjs/log.d.ts +4 -0
- package/dist/cjs/log.js +30 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/register.d.ts +1 -0
- package/dist/cjs/register.js +18 -0
- package/dist/cjs/sanitizer/bodies.d.ts +55 -0
- package/dist/cjs/sanitizer/bodies.js +710 -0
- package/dist/cjs/sanitizer/formats.d.ts +26 -0
- package/dist/cjs/sanitizer/formats.js +110 -0
- package/dist/cjs/sanitizer/graphql.d.ts +23 -0
- package/dist/cjs/sanitizer/graphql.js +478 -0
- package/dist/cjs/sanitizer/hostpat.d.ts +15 -0
- package/dist/cjs/sanitizer/hostpat.js +129 -0
- package/dist/cjs/sanitizer/json.d.ts +60 -0
- package/dist/cjs/sanitizer/json.js +460 -0
- package/dist/cjs/sanitizer/policy.d.ts +224 -0
- package/dist/cjs/sanitizer/policy.js +820 -0
- package/dist/cjs/sanitizer/sanitizer.d.ts +149 -0
- package/dist/cjs/sanitizer/sanitizer.js +1473 -0
- package/dist/cjs/sanitizer/utf8.d.ts +22 -0
- package/dist/cjs/sanitizer/utf8.js +180 -0
- package/dist/cjs/sanitizer/vectors.d.ts +22 -0
- package/dist/cjs/sanitizer/vectors.js +130 -0
- package/dist/cjs/version.d.ts +2 -0
- package/dist/cjs/version.js +5 -0
- package/dist/cjs/worker/dir.d.ts +1 -0
- package/dist/cjs/worker/dir.js +8 -0
- package/dist/cjs/worker/pool.d.ts +47 -0
- package/dist/cjs/worker/pool.js +179 -0
- package/dist/cjs/worker/protocol.d.ts +37 -0
- package/dist/cjs/worker/protocol.js +3 -0
- package/dist/cjs/worker/sanitizer-worker.d.ts +1 -0
- package/dist/cjs/worker/sanitizer-worker.js +53 -0
- package/dist/esm/agent.d.ts +143 -0
- package/dist/esm/agent.js +921 -0
- package/dist/esm/capture/body.d.ts +11 -0
- package/dist/esm/capture/body.js +69 -0
- package/dist/esm/capture/common.d.ts +75 -0
- package/dist/esm/capture/common.js +166 -0
- package/dist/esm/capture/context.d.ts +28 -0
- package/dist/esm/capture/context.js +84 -0
- package/dist/esm/capture/inbound.d.ts +12 -0
- package/dist/esm/capture/inbound.js +187 -0
- package/dist/esm/capture/outbound-http.d.ts +4 -0
- package/dist/esm/capture/outbound-http.js +193 -0
- package/dist/esm/capture/outbound-undici.d.ts +2 -0
- package/dist/esm/capture/outbound-undici.js +236 -0
- package/dist/esm/capture/wire.d.ts +27 -0
- package/dist/esm/capture/wire.js +65 -0
- package/dist/esm/export/event.d.ts +46 -0
- package/dist/esm/export/event.js +85 -0
- package/dist/esm/export/exporter.d.ts +50 -0
- package/dist/esm/export/exporter.js +188 -0
- package/dist/esm/export/pipeline.d.ts +20 -0
- package/dist/esm/export/pipeline.js +37 -0
- package/dist/esm/fleet/asn1.d.ts +44 -0
- package/dist/esm/fleet/asn1.js +128 -0
- package/dist/esm/fleet/client.d.ts +84 -0
- package/dist/esm/fleet/client.js +204 -0
- package/dist/esm/fleet/http.d.ts +17 -0
- package/dist/esm/fleet/http.js +73 -0
- package/dist/esm/fleet/store.d.ts +18 -0
- package/dist/esm/fleet/store.js +110 -0
- package/dist/esm/index.d.ts +14 -0
- package/dist/esm/index.js +48 -0
- package/dist/esm/log.d.ts +4 -0
- package/dist/esm/log.js +25 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/register.d.ts +1 -0
- package/dist/esm/register.js +16 -0
- package/dist/esm/sanitizer/bodies.d.ts +55 -0
- package/dist/esm/sanitizer/bodies.js +694 -0
- package/dist/esm/sanitizer/formats.d.ts +26 -0
- package/dist/esm/sanitizer/formats.js +101 -0
- package/dist/esm/sanitizer/graphql.d.ts +23 -0
- package/dist/esm/sanitizer/graphql.js +472 -0
- package/dist/esm/sanitizer/hostpat.d.ts +15 -0
- package/dist/esm/sanitizer/hostpat.js +122 -0
- package/dist/esm/sanitizer/json.d.ts +60 -0
- package/dist/esm/sanitizer/json.js +447 -0
- package/dist/esm/sanitizer/policy.d.ts +224 -0
- package/dist/esm/sanitizer/policy.js +800 -0
- package/dist/esm/sanitizer/sanitizer.d.ts +149 -0
- package/dist/esm/sanitizer/sanitizer.js +1459 -0
- package/dist/esm/sanitizer/utf8.d.ts +22 -0
- package/dist/esm/sanitizer/utf8.js +166 -0
- package/dist/esm/sanitizer/vectors.d.ts +22 -0
- package/dist/esm/sanitizer/vectors.js +125 -0
- package/dist/esm/version.d.ts +2 -0
- package/dist/esm/version.js +2 -0
- package/dist/esm/worker/dir.d.ts +1 -0
- package/dist/esm/worker/dir.js +5 -0
- package/dist/esm/worker/pool.d.ts +47 -0
- package/dist/esm/worker/pool.js +175 -0
- package/dist/esm/worker/protocol.d.ts +37 -0
- package/dist/esm/worker/protocol.js +2 -0
- package/dist/esm/worker/sanitizer-worker.d.ts +1 -0
- package/dist/esm/worker/sanitizer-worker.js +51 -0
- package/package.json +75 -4
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Sanitizer worker thread: receives wire exchanges, returns ready-made OTLP logRecords.
|
|
3
|
+
// It runs exactly the code the main thread would run inline (export/pipeline.ts), so the
|
|
4
|
+
// events are byte-identical. It holds the HMAC key like the main thread does and has no
|
|
5
|
+
// network, file or Fleet access of its own: it only reads messages and posts results.
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const node_worker_threads_1 = require("node:worker_threads");
|
|
8
|
+
const pipeline_js_1 = require("../export/pipeline.js");
|
|
9
|
+
const json_js_1 = require("../sanitizer/json.js");
|
|
10
|
+
const policy_js_1 = require("../sanitizer/policy.js");
|
|
11
|
+
const sanitizer_js_1 = require("../sanitizer/sanitizer.js");
|
|
12
|
+
const MAX_GENS = 16;
|
|
13
|
+
const sans = new Map();
|
|
14
|
+
const port = node_worker_threads_1.parentPort;
|
|
15
|
+
if (port) {
|
|
16
|
+
const send = (m) => port.postMessage(m);
|
|
17
|
+
port.on('message', (m) => {
|
|
18
|
+
try {
|
|
19
|
+
if (m.t === 'policy') {
|
|
20
|
+
const p = new policy_js_1.Policy((0, json_js_1.nodeToPlain)((0, json_js_1.parseJson)(m.body), true));
|
|
21
|
+
p.hash = m.hash;
|
|
22
|
+
sans.set(m.gen, new sanitizer_js_1.Sanitizer(p, { kid: m.kid, key: Buffer.from(m.key) }, { rateOverrideBp: m.rateOverrideBp }));
|
|
23
|
+
while (sans.size > MAX_GENS)
|
|
24
|
+
sans.delete(sans.keys().next().value);
|
|
25
|
+
}
|
|
26
|
+
else if (m.t === 'run') {
|
|
27
|
+
const recs = [];
|
|
28
|
+
const errs = [];
|
|
29
|
+
const now = Date.now();
|
|
30
|
+
for (const j of m.jobs) {
|
|
31
|
+
const san = sans.get(j.gen);
|
|
32
|
+
const r = san ? (0, pipeline_js_1.sanitizeToRecord)(san, j.wire, j.decision, j.meta, m.sourceId, now) : { err: 'sanitizer_error' };
|
|
33
|
+
if (r === null)
|
|
34
|
+
continue;
|
|
35
|
+
if ('record' in r)
|
|
36
|
+
recs.push(r.record);
|
|
37
|
+
else
|
|
38
|
+
errs.push(r.err);
|
|
39
|
+
}
|
|
40
|
+
send({ t: 'out', epoch: m.epoch, recs, errs });
|
|
41
|
+
}
|
|
42
|
+
else if (m.t === 'sync') {
|
|
43
|
+
send({ t: 'synced', seq: m.seq });
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
// A malformed message must not kill the worker; the jobs it carried are lost.
|
|
48
|
+
if (m.t === 'run')
|
|
49
|
+
send({ t: 'out', epoch: m.epoch, recs: [], errs: m.jobs.map(() => 'sanitizer_error') });
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
send({ t: 'ready' });
|
|
53
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import type { CaptureHost, RawExchange } from './capture/common.js';
|
|
2
|
+
import { Sanitizer } from './sanitizer/sanitizer.js';
|
|
3
|
+
export type SourceState = 'starting' | 'capturing' | 'no_policy' | 'policy_rejected' | 'expired_policy' | 'key_missing' | 'key_mismatch' | 'killed';
|
|
4
|
+
export interface AgentOptions {
|
|
5
|
+
/** Fleet base URL used for enrollment (TT_ENROLL_URL). */
|
|
6
|
+
enrollUrl?: string;
|
|
7
|
+
/** Enrollment token `tte_<secret>.<pin>` (TT_ENROLL_TOKEN). */
|
|
8
|
+
enrollToken?: string;
|
|
9
|
+
/** Content of the HMAC key (TT_HMAC_KEY). */
|
|
10
|
+
hmacKey?: string;
|
|
11
|
+
/** File holding the HMAC key (TT_HMAC_KEY_FILE). */
|
|
12
|
+
hmacKeyFile?: string;
|
|
13
|
+
/** Service name requested at enrollment (TT_SERVICE_NAME, else OTEL_SERVICE_NAME). */
|
|
14
|
+
serviceName?: string;
|
|
15
|
+
/** Where certificates, keys and the policy cache are kept (TT_STATE_DIR). */
|
|
16
|
+
stateDir?: string;
|
|
17
|
+
/** Informational instance name (TT_INSTANCE, default hostname). */
|
|
18
|
+
instance?: string;
|
|
19
|
+
/** Send a CSR at enrollment so the private key never leaves the process (default true). */
|
|
20
|
+
useCsr?: boolean;
|
|
21
|
+
debug?: boolean;
|
|
22
|
+
/** Overrides for tests and benchmarks. */
|
|
23
|
+
heartbeatIntervalMs?: number;
|
|
24
|
+
policyPollIntervalMs?: number;
|
|
25
|
+
exportFlushMs?: number;
|
|
26
|
+
/** Sanitizer worker threads: 0 = always inline, default min(2, cores - 1) (TT_SANITIZER_THREADS). */
|
|
27
|
+
sanitizerThreads?: number;
|
|
28
|
+
/** Sampling rate (basis points) from which sanitization moves to the workers (default 200 = 2%). */
|
|
29
|
+
workerMinBp?: number;
|
|
30
|
+
}
|
|
31
|
+
export declare function serviceNameFromEnv(env: NodeJS.ProcessEnv): string | undefined;
|
|
32
|
+
export declare function optionsFromEnv(env?: NodeJS.ProcessEnv): AgentOptions;
|
|
33
|
+
export declare class Agent implements CaptureHost {
|
|
34
|
+
readonly opts: AgentOptions;
|
|
35
|
+
readonly counters: {
|
|
36
|
+
exchanges_seen: number;
|
|
37
|
+
exchanges_sampled: number;
|
|
38
|
+
events_sent: number;
|
|
39
|
+
events_dropped_queue: number;
|
|
40
|
+
events_rejected: number;
|
|
41
|
+
send_errors: number;
|
|
42
|
+
sanitizer_errors: number;
|
|
43
|
+
};
|
|
44
|
+
state: SourceState;
|
|
45
|
+
private san;
|
|
46
|
+
private policy;
|
|
47
|
+
private policyKid;
|
|
48
|
+
private rejected;
|
|
49
|
+
private ring;
|
|
50
|
+
private keyState;
|
|
51
|
+
private heartbeatOk;
|
|
52
|
+
private lastContact;
|
|
53
|
+
private persisted;
|
|
54
|
+
private overrideBp;
|
|
55
|
+
private decisionNames;
|
|
56
|
+
private readonly overhead;
|
|
57
|
+
private overheadN;
|
|
58
|
+
private lastErrors;
|
|
59
|
+
private pending;
|
|
60
|
+
private pendingBytes;
|
|
61
|
+
private drainScheduled;
|
|
62
|
+
private pool;
|
|
63
|
+
/** The last drain handed its work to the workers: the next one is batched on a timer. */
|
|
64
|
+
private workerMode;
|
|
65
|
+
private inflight;
|
|
66
|
+
private inflightBytes;
|
|
67
|
+
private uninstall;
|
|
68
|
+
private timers;
|
|
69
|
+
private stopped;
|
|
70
|
+
private store;
|
|
71
|
+
private enrollment;
|
|
72
|
+
private keyPem;
|
|
73
|
+
private httpsAgent;
|
|
74
|
+
private fleet;
|
|
75
|
+
private exporter;
|
|
76
|
+
private etag;
|
|
77
|
+
private switching;
|
|
78
|
+
private acceptedHashes;
|
|
79
|
+
private polling;
|
|
80
|
+
private pollAgain;
|
|
81
|
+
constructor(opts: AgentOptions);
|
|
82
|
+
active(): Sanitizer | null;
|
|
83
|
+
serviceName(): string;
|
|
84
|
+
decisionHeaders(): ReadonlySet<string>;
|
|
85
|
+
propagates(): boolean;
|
|
86
|
+
mayPropagate(urlBase: string): boolean;
|
|
87
|
+
private propMemoFor;
|
|
88
|
+
private readonly propMemo;
|
|
89
|
+
private mayPropagateUncached;
|
|
90
|
+
noteSeen(): void;
|
|
91
|
+
noteSampled(): void;
|
|
92
|
+
noteOverhead(ns: number): void;
|
|
93
|
+
noteError(code: string): void;
|
|
94
|
+
submit(raw: RawExchange): void;
|
|
95
|
+
private threads;
|
|
96
|
+
/** Worker threads pay off only when many exchanges are sampled (high rate). */
|
|
97
|
+
private wantWorkers;
|
|
98
|
+
private onWorkerOut;
|
|
99
|
+
/**
|
|
100
|
+
* Inline sanitization runs right after the response (setImmediate). With worker threads
|
|
101
|
+
* the exchanges are collected for a few milliseconds and posted as one batch: one message
|
|
102
|
+
* and one thread wake-up for many exchanges instead of one each.
|
|
103
|
+
*/
|
|
104
|
+
private scheduleDrain;
|
|
105
|
+
private drain;
|
|
106
|
+
/** Posts up to WORKER_BATCH pending exchanges to a worker. False when none could be posted. */
|
|
107
|
+
private drainToWorkers;
|
|
108
|
+
private process;
|
|
109
|
+
/** Installs the hooks and runs the first Fleet cycle. Never throws. */
|
|
110
|
+
start(): Promise<void>;
|
|
111
|
+
stop(): Promise<void>;
|
|
112
|
+
/** Sanitizes what is pending and sends everything queued (tests, graceful shutdown). */
|
|
113
|
+
flush(): Promise<void>;
|
|
114
|
+
status(): {
|
|
115
|
+
state: SourceState;
|
|
116
|
+
counters: Agent['counters'];
|
|
117
|
+
queue: {
|
|
118
|
+
events: number;
|
|
119
|
+
bytes: number;
|
|
120
|
+
};
|
|
121
|
+
};
|
|
122
|
+
private enrollWithRetry;
|
|
123
|
+
private connect;
|
|
124
|
+
private schedule;
|
|
125
|
+
private loadKeys;
|
|
126
|
+
/** Said once per cause, whatever TT_DEBUG: without the key nothing is captured. Never prints key material or paths. */
|
|
127
|
+
private keyWarned;
|
|
128
|
+
private warnKeyMissing;
|
|
129
|
+
private signingKeys;
|
|
130
|
+
private persist;
|
|
131
|
+
private tryAccept;
|
|
132
|
+
private pollPolicy;
|
|
133
|
+
private pollOnce;
|
|
134
|
+
private overheadUs;
|
|
135
|
+
private heartbeat;
|
|
136
|
+
private applyHeartbeat;
|
|
137
|
+
private addSigningKeys;
|
|
138
|
+
private renew;
|
|
139
|
+
private revoke;
|
|
140
|
+
private dropQueues;
|
|
141
|
+
/** Recomputes the state and the capture gate. */
|
|
142
|
+
private recompute;
|
|
143
|
+
}
|