@descryy/runtime-database-observation 0.5.2 → 0.5.4
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/index.d.ts +8 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -4
- package/dist/index.js.map +1 -1
- package/dist/mysql-row-collector.d.ts +33 -19
- package/dist/mysql-row-collector.d.ts.map +1 -1
- package/dist/mysql-row-collector.js +480 -26
- package/dist/mysql-row-collector.js.map +1 -1
- package/dist/postgres-log-parser.d.ts +15 -29
- package/dist/postgres-log-parser.d.ts.map +1 -1
- package/dist/postgres-log-parser.js +103 -32
- package/dist/postgres-log-parser.js.map +1 -1
- package/dist/postgres-log-source.d.ts +4 -0
- package/dist/postgres-log-source.d.ts.map +1 -1
- package/dist/postgres-log-source.js +196 -36
- package/dist/postgres-log-source.js.map +1 -1
- package/dist/postgres-query-collector.d.ts.map +1 -1
- package/dist/postgres-query-collector.js +43 -13
- package/dist/postgres-query-collector.js.map +1 -1
- package/dist/postgres-row-collector.d.ts +7 -0
- package/dist/postgres-row-collector.d.ts.map +1 -1
- package/dist/postgres-row-collector.js +112 -17
- package/dist/postgres-row-collector.js.map +1 -1
- package/dist/prisma-instrumentation.d.ts +20 -0
- package/dist/prisma-instrumentation.d.ts.map +1 -0
- package/dist/prisma-instrumentation.js +99 -0
- package/dist/prisma-instrumentation.js.map +1 -0
- package/dist/query-collector.d.ts +2 -0
- package/dist/query-collector.d.ts.map +1 -1
- package/dist/query-collector.js +38 -13
- package/dist/query-collector.js.map +1 -1
- package/dist/query-line-parser.d.ts.map +1 -1
- package/dist/query-line-parser.js +2 -1
- package/dist/query-line-parser.js.map +1 -1
- package/dist/query-marker.d.ts +10 -1
- package/dist/query-marker.d.ts.map +1 -1
- package/dist/query-marker.js +2 -0
- package/dist/query-marker.js.map +1 -1
- package/dist/row-capture-policy.d.ts +31 -0
- package/dist/row-capture-policy.d.ts.map +1 -0
- package/dist/row-capture-policy.js +95 -0
- package/dist/row-capture-policy.js.map +1 -0
- package/dist/smoke.d.ts.map +1 -1
- package/dist/smoke.js +2 -0
- package/dist/smoke.js.map +1 -1
- package/dist/sqlite-instrumentation.js +9 -2
- package/dist/sqlite-instrumentation.js.map +1 -1
- package/dist/sqlite-row-snapshot.d.ts +4 -0
- package/dist/sqlite-row-snapshot.d.ts.map +1 -1
- package/dist/sqlite-row-snapshot.js +153 -25
- package/dist/sqlite-row-snapshot.js.map +1 -1
- package/dist/table-extraction.d.ts.map +1 -1
- package/dist/table-extraction.js +124 -5
- package/dist/table-extraction.js.map +1 -1
- package/package.json +9 -8
|
@@ -1,49 +1,120 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* RG-5(b): Postgres needs no preload — its own server-side statement log is
|
|
3
3
|
* the capture mechanism, the way the plan calls for ("its logging path
|
|
4
|
-
* needs no preload"). This reads
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* concern), and recognises exactly two shapes `log_statement = 'all'`
|
|
8
|
-
* produces:
|
|
9
|
-
*
|
|
10
|
-
* - `LOG: statement: <sql>` — the simple-query protocol.
|
|
11
|
-
* - `LOG: execute <name>: <sql>` — the extended/prepared-statement
|
|
12
|
-
* protocol (`<name>` is `<unnamed>` for an unnamed prepared statement, or
|
|
13
|
-
* a real name).
|
|
4
|
+
* needs no preload"). This reads that log line by line, whatever
|
|
5
|
+
* `log_line_prefix` a deployment configured (timestamp, pid, database name
|
|
6
|
+
* — all deployment-specific and none of them this parser's concern).
|
|
14
7
|
*
|
|
15
8
|
* Verified against PostgreSQL's own documented log format (`log_statement`,
|
|
16
9
|
* `log_line_prefix`), not guessed, and now also **live-tested against a
|
|
17
10
|
* real `postgres:16` Docker container** producing real `LOG: statement:`
|
|
18
11
|
* lines (`postgres-query-collector.ts`'s `test/postgres-live.test.ts`) —
|
|
19
12
|
* not just doc-verified syntax fed in by hand.
|
|
20
|
-
*
|
|
21
|
-
* **Disclosed, deliberate scope, same "refuse rather than guess" rule
|
|
22
|
-
* `query-line-parser.ts` and `table-extraction.ts` already apply:**
|
|
23
|
-
* - A statement split across multiple log lines (a long query Postgres
|
|
24
|
-
* wraps) is read as written on its own line only — refused, not
|
|
25
|
-
* reassembled, same as this package's other parsers stay bounded readers.
|
|
26
|
-
* - `duration` is always `null` here: Postgres logs it on a **separate**
|
|
27
|
-
* `LOG: duration: N ms` line, joined to the statement line only via
|
|
28
|
-
* `log_duration`/`log_min_duration_statement` and the same backend pid —
|
|
29
|
-
* a real correlation this parser does not attempt, so it reports what it
|
|
30
|
-
* does not know rather than a fabricated duration.
|
|
31
|
-
* - `success` is always `true` here: a failed statement logs as `ERROR:`,
|
|
32
|
-
* a different prefix this parser does not recognise — refused (`null`),
|
|
33
|
-
* not misread as a successful query.
|
|
34
13
|
*/
|
|
14
|
+
export const MAX_STATEMENT_CHARS = 256 * 1024;
|
|
35
15
|
const STATEMENT_PATTERN = /\bLOG:\s+statement:\s+(.*)$/;
|
|
36
16
|
const EXECUTE_PATTERN = /\bLOG:\s+execute\s+\S+:\s+(.*)$/;
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
17
|
+
const DURATION_PATTERN = /\bLOG:\s+duration:\s+(\d+(?:\.\d+)?)\s+ms\s+(statement|execute\s+\S+|parse\s+\S+|bind\s+\S+):\s+(.*)$/;
|
|
18
|
+
const ERROR_PATTERN = /\b(?:ERROR|FATAL|PANIC):\s+(.*)$/;
|
|
19
|
+
const ERROR_STATEMENT_PATTERN = /\bSTATEMENT:\s+(.*)$/;
|
|
20
|
+
const ERROR_ATTACHMENT_PATTERN = /\b(?:DETAIL|HINT|CONTEXT|QUERY|LOCATION|WHERE):\s/;
|
|
21
|
+
function bounded(sql) {
|
|
22
|
+
return sql.length <= MAX_STATEMENT_CHARS ? { sql, truncated: false } : { sql: sql.slice(0, MAX_STATEMENT_CHARS), truncated: true };
|
|
23
|
+
}
|
|
24
|
+
function startOf(line, pendingError) {
|
|
25
|
+
const duration = DURATION_PATTERN.exec(line);
|
|
26
|
+
if (duration !== null) {
|
|
27
|
+
const kind = duration[2];
|
|
28
|
+
if (kind.startsWith("parse") || kind.startsWith("bind"))
|
|
29
|
+
return null;
|
|
30
|
+
const { sql, truncated } = bounded(duration[3].trim());
|
|
31
|
+
return {
|
|
32
|
+
method: kind === "statement" ? "statement" : "execute",
|
|
33
|
+
durationMs: Number(duration[1]),
|
|
34
|
+
success: true,
|
|
35
|
+
outcomeKnown: true,
|
|
36
|
+
error: null,
|
|
37
|
+
sql,
|
|
38
|
+
sqlTruncated: truncated,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
const statement = STATEMENT_PATTERN.exec(line) ?? EXECUTE_PATTERN.exec(line);
|
|
42
|
+
if (statement !== null) {
|
|
43
|
+
const { sql, truncated } = bounded(statement[1].trim());
|
|
44
|
+
return {
|
|
45
|
+
method: STATEMENT_PATTERN.test(line) ? "statement" : "execute",
|
|
46
|
+
durationMs: null,
|
|
47
|
+
success: null,
|
|
48
|
+
outcomeKnown: false,
|
|
49
|
+
error: null,
|
|
50
|
+
sql,
|
|
51
|
+
sqlTruncated: truncated,
|
|
52
|
+
};
|
|
42
53
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
54
|
+
if (pendingError !== null) {
|
|
55
|
+
const failed = ERROR_STATEMENT_PATTERN.exec(line);
|
|
56
|
+
if (failed !== null) {
|
|
57
|
+
const { sql, truncated } = bounded(failed[1].trim());
|
|
58
|
+
return { method: "failed-statement", durationMs: null, success: false, outcomeKnown: true, error: pendingError, sql, sqlTruncated: truncated };
|
|
59
|
+
}
|
|
46
60
|
}
|
|
47
61
|
return null;
|
|
48
62
|
}
|
|
63
|
+
function finished(pending) {
|
|
64
|
+
return {
|
|
65
|
+
sql: pending.sql,
|
|
66
|
+
method: pending.method,
|
|
67
|
+
durationMs: pending.durationMs,
|
|
68
|
+
success: pending.success,
|
|
69
|
+
outcomeKnown: pending.outcomeKnown,
|
|
70
|
+
error: pending.error,
|
|
71
|
+
sqlTruncated: pending.sqlTruncated,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
export function createPostgresLogReader() {
|
|
75
|
+
let pending = null;
|
|
76
|
+
let pendingError = null;
|
|
77
|
+
function close() {
|
|
78
|
+
if (pending === null)
|
|
79
|
+
return [];
|
|
80
|
+
const done = finished(pending);
|
|
81
|
+
pending = null;
|
|
82
|
+
return [done];
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
push(line) {
|
|
86
|
+
if (line.startsWith("\t")) {
|
|
87
|
+
if (pending !== null && !pending.sqlTruncated) {
|
|
88
|
+
const { sql, truncated } = bounded(`${pending.sql}\n${line.slice(1)}`);
|
|
89
|
+
pending.sql = sql;
|
|
90
|
+
pending.sqlTruncated = truncated;
|
|
91
|
+
}
|
|
92
|
+
return [];
|
|
93
|
+
}
|
|
94
|
+
const out = close();
|
|
95
|
+
const started = startOf(line, pendingError);
|
|
96
|
+
if (started !== null) {
|
|
97
|
+
pending = started;
|
|
98
|
+
pendingError = null;
|
|
99
|
+
return out;
|
|
100
|
+
}
|
|
101
|
+
const error = ERROR_PATTERN.exec(line);
|
|
102
|
+
if (error !== null) {
|
|
103
|
+
pendingError = error[1].trim();
|
|
104
|
+
return out;
|
|
105
|
+
}
|
|
106
|
+
if (pendingError !== null && !ERROR_ATTACHMENT_PATTERN.test(line))
|
|
107
|
+
pendingError = null;
|
|
108
|
+
return out;
|
|
109
|
+
},
|
|
110
|
+
flush() {
|
|
111
|
+
pendingError = null;
|
|
112
|
+
return close();
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
export function parsePostgresLogLine(line) {
|
|
117
|
+
const reader = createPostgresLogReader();
|
|
118
|
+
return [...reader.push(line), ...reader.flush()][0] ?? null;
|
|
119
|
+
}
|
|
49
120
|
//# sourceMappingURL=postgres-log-parser.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres-log-parser.js","sourceRoot":"","sources":["../src/postgres-log-parser.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"postgres-log-parser.js","sourceRoot":"","sources":["../src/postgres-log-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -43,6 +43,8 @@ export type PostgresStatementLogSource = {
|
|
|
43
43
|
readonly kind: "dockerContainer";
|
|
44
44
|
readonly container: string;
|
|
45
45
|
};
|
|
46
|
+
export declare function invalidDockerContainerName(container: string): string | null;
|
|
47
|
+
export declare const DEFAULT_STATEMENT_LOG_MAX_BYTES_PER_READ: number;
|
|
46
48
|
/**
|
|
47
49
|
* Builds the `ProcessOutputSource` `createPostgresQueryCollector` consumes,
|
|
48
50
|
* over whichever statement-log shape a caller configured. `serviceName`
|
|
@@ -51,5 +53,7 @@ export type PostgresStatementLogSource = {
|
|
|
51
53
|
*/
|
|
52
54
|
export declare function createPostgresLogSource(logSource: PostgresStatementLogSource, processId: string, serviceName: string | null, options?: {
|
|
53
55
|
readonly signal?: AbortSignal;
|
|
56
|
+
readonly fileAppearTimeoutMs?: number;
|
|
57
|
+
readonly maxBytesPerRead?: number;
|
|
54
58
|
}): ProcessOutputSource;
|
|
55
59
|
//# sourceMappingURL=postgres-log-source.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres-log-source.d.ts","sourceRoot":"","sources":["../src/postgres-log-source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;
|
|
1
|
+
{"version":3,"file":"postgres-log-source.d.ts","sourceRoot":"","sources":["../src/postgres-log-source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAKH,OAAO,EAA2D,KAAK,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAEzI,MAAM,MAAM,0BAA0B,GAClC;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAWrE,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI3E;AAeD,eAAO,MAAM,wCAAwC,QAAkB,CAAC;AAmPxE;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,0BAA0B,EACrC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAAG,IAAI,EAC1B,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,GACpH,mBAAmB,CAUrB"}
|
|
@@ -36,41 +36,181 @@
|
|
|
36
36
|
* run forever); the file branch checks the signal between polls.
|
|
37
37
|
*/
|
|
38
38
|
import { spawn } from "node:child_process";
|
|
39
|
-
import {
|
|
40
|
-
import {
|
|
39
|
+
import { open, stat } from "node:fs/promises";
|
|
40
|
+
import { StringDecoder } from "node:string_decoder";
|
|
41
|
+
import { GapResynchronizer, LineSplitter } from "@descryy/runtime-backend-observation";
|
|
41
42
|
const FILE_POLL_INTERVAL_MS = 200;
|
|
43
|
+
const FILE_APPEAR_TIMEOUT_MS = 10_000;
|
|
44
|
+
const DOCKER_CONTAINER_NAME = /^[A-Za-z0-9][A-Za-z0-9_.-]*$/;
|
|
45
|
+
function errnoOf(error) {
|
|
46
|
+
const code = typeof error === "object" && error !== null ? error.code : undefined;
|
|
47
|
+
return code ?? String(error);
|
|
48
|
+
}
|
|
49
|
+
export function invalidDockerContainerName(container) {
|
|
50
|
+
return DOCKER_CONTAINER_NAME.test(container)
|
|
51
|
+
? null
|
|
52
|
+
: `"${container}" is not a valid Docker container name (letters, digits, "_", "." and "-", not starting with "-")`;
|
|
53
|
+
}
|
|
54
|
+
function validatedMaxBytesPerRead(requested) {
|
|
55
|
+
if (requested === undefined)
|
|
56
|
+
return DEFAULT_STATEMENT_LOG_MAX_BYTES_PER_READ;
|
|
57
|
+
if (!Number.isSafeInteger(requested) || requested < 1) {
|
|
58
|
+
throw new RangeError(`maxBytesPerRead must be a positive integer, got ${String(requested)}`);
|
|
59
|
+
}
|
|
60
|
+
return requested;
|
|
61
|
+
}
|
|
42
62
|
function sleep(ms) {
|
|
43
63
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
44
64
|
}
|
|
45
|
-
|
|
46
|
-
|
|
65
|
+
const FILE_READ_CHUNK_BYTES = 1024 * 1024;
|
|
66
|
+
export const DEFAULT_STATEMENT_LOG_MAX_BYTES_PER_READ = 8 * 1024 * 1024;
|
|
67
|
+
async function statFile(path) {
|
|
47
68
|
try {
|
|
48
|
-
|
|
69
|
+
const stats = await stat(path);
|
|
70
|
+
return { ok: true, size: stats.size, ino: stats.ino };
|
|
49
71
|
}
|
|
50
|
-
catch {
|
|
51
|
-
|
|
72
|
+
catch (error) {
|
|
73
|
+
return { ok: false, code: errnoOf(error) };
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async function readFrom(path, offset, maxBytes) {
|
|
77
|
+
let handle;
|
|
78
|
+
try {
|
|
79
|
+
handle = await open(path, "r");
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
if (errnoOf(error) === "ENOENT")
|
|
83
|
+
return null;
|
|
84
|
+
throw new Error(`the Postgres statement log file ${path} cannot be read (${errnoOf(error)})`);
|
|
85
|
+
}
|
|
86
|
+
try {
|
|
87
|
+
const { ino, size } = await handle.stat();
|
|
88
|
+
const skippedBytes = size - offset > maxBytes ? size - maxBytes - offset : 0;
|
|
89
|
+
const chunks = [];
|
|
90
|
+
let position = offset + skippedBytes;
|
|
91
|
+
while (position < size) {
|
|
92
|
+
const buffer = Buffer.alloc(Math.min(FILE_READ_CHUNK_BYTES, size - position));
|
|
93
|
+
const { bytesRead } = await handle.read(buffer, 0, buffer.length, position);
|
|
94
|
+
if (bytesRead === 0)
|
|
95
|
+
break;
|
|
96
|
+
chunks.push(buffer.subarray(0, bytesRead));
|
|
97
|
+
position += bytesRead;
|
|
98
|
+
}
|
|
99
|
+
return { bytes: Buffer.concat(chunks), ino, skippedBytes };
|
|
100
|
+
}
|
|
101
|
+
finally {
|
|
102
|
+
await handle.close();
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
const HEAD_FINGERPRINT_BYTES = 64;
|
|
106
|
+
async function readHead(path, length) {
|
|
107
|
+
if (length === 0)
|
|
108
|
+
return Buffer.alloc(0);
|
|
109
|
+
let handle;
|
|
110
|
+
try {
|
|
111
|
+
handle = await open(path, "r");
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
if (errnoOf(error) === "ENOENT")
|
|
115
|
+
return null;
|
|
116
|
+
throw new Error(`the Postgres statement log file ${path} cannot be read (${errnoOf(error)})`);
|
|
117
|
+
}
|
|
118
|
+
try {
|
|
119
|
+
const buffer = Buffer.alloc(length);
|
|
120
|
+
const { bytesRead } = await handle.read(buffer, 0, length, 0);
|
|
121
|
+
return buffer.subarray(0, bytesRead);
|
|
122
|
+
}
|
|
123
|
+
finally {
|
|
124
|
+
await handle.close();
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
async function* tailFile(path, signal, appearTimeoutMs, maxBytesPerRead) {
|
|
128
|
+
const initial = await statFile(path);
|
|
129
|
+
if (!initial.ok && initial.code !== "ENOENT") {
|
|
130
|
+
throw new Error(`the Postgres statement log file ${path} cannot be read (${initial.code}); no queries can be observed from it`);
|
|
52
131
|
}
|
|
132
|
+
let missingSince = initial.ok ? null : Date.now();
|
|
133
|
+
let hasExisted = initial.ok;
|
|
134
|
+
let offset = initial.ok ? initial.size : 0;
|
|
135
|
+
let inode = initial.ok ? initial.ino : null;
|
|
136
|
+
let head = (await readHead(path, Math.min(offset, HEAD_FINGERPRINT_BYTES))) ?? Buffer.alloc(0);
|
|
137
|
+
let decoder = new StringDecoder("utf8");
|
|
53
138
|
const splitter = new LineSplitter();
|
|
139
|
+
let resync = new GapResynchronizer();
|
|
140
|
+
const rotated = () => {
|
|
141
|
+
splitter.discardPartial();
|
|
142
|
+
decoder = new StringDecoder("utf8");
|
|
143
|
+
resync = new GapResynchronizer();
|
|
144
|
+
offset = 0;
|
|
145
|
+
head = Buffer.alloc(0);
|
|
146
|
+
return { text: "", stream: "combined", observedAt: new Date().toISOString(), gap: { droppedChars: 0, cause: "source-rotated" } };
|
|
147
|
+
};
|
|
54
148
|
while (signal?.aborted !== true) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
149
|
+
const current = await statFile(path);
|
|
150
|
+
if (!current.ok) {
|
|
151
|
+
if (current.code !== "ENOENT") {
|
|
152
|
+
throw new Error(`the Postgres statement log file ${path} cannot be read (${current.code}); no further queries can be observed from it`);
|
|
153
|
+
}
|
|
154
|
+
missingSince ??= Date.now();
|
|
155
|
+
if (Date.now() - missingSince > appearTimeoutMs) {
|
|
156
|
+
throw new Error(`the Postgres statement log file ${path} ${hasExisted ? "disappeared" : "did not appear"} and stayed missing for more than ${String(appearTimeoutMs)} ms (ENOENT); ` +
|
|
157
|
+
"an empty result here would be indistinguishable from an application that issued no queries");
|
|
158
|
+
}
|
|
62
159
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
160
|
+
else {
|
|
161
|
+
missingSince = null;
|
|
162
|
+
hasExisted = true;
|
|
163
|
+
if (inode !== null && current.ino !== inode) {
|
|
164
|
+
yield rotated();
|
|
165
|
+
}
|
|
166
|
+
else if (current.size < offset) {
|
|
167
|
+
yield rotated();
|
|
168
|
+
}
|
|
169
|
+
else if (head.length > 0) {
|
|
170
|
+
const now = await readHead(path, head.length);
|
|
171
|
+
if (now !== null && !now.equals(head))
|
|
172
|
+
yield rotated();
|
|
173
|
+
}
|
|
174
|
+
const read = await readFrom(path, offset, maxBytesPerRead);
|
|
175
|
+
if (read !== null) {
|
|
176
|
+
if (inode !== null && read.ino !== inode && offset !== 0) {
|
|
177
|
+
yield rotated();
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
inode = read.ino;
|
|
181
|
+
if (read.bytes.length > 0 || read.skippedBytes > 0) {
|
|
182
|
+
if (head.length < HEAD_FINGERPRINT_BYTES && offset < HEAD_FINGERPRINT_BYTES && read.skippedBytes === 0) {
|
|
183
|
+
head = Buffer.concat([head, read.bytes.subarray(0, HEAD_FINGERPRINT_BYTES - offset)]);
|
|
184
|
+
}
|
|
185
|
+
offset += read.skippedBytes + read.bytes.length;
|
|
186
|
+
if (read.skippedBytes > 0) {
|
|
187
|
+
resync.recordGap(read.skippedBytes, splitter);
|
|
188
|
+
decoder = new StringDecoder("utf8");
|
|
189
|
+
}
|
|
190
|
+
const observedAt = new Date().toISOString();
|
|
191
|
+
const lines = splitter.push(resync.admit(decoder.write(read.bytes)));
|
|
192
|
+
if (lines.length > 0) {
|
|
193
|
+
const gap = resync.take();
|
|
194
|
+
if (gap !== null)
|
|
195
|
+
yield { text: "", stream: "combined", observedAt, gap };
|
|
196
|
+
}
|
|
197
|
+
for (const text of lines) {
|
|
198
|
+
yield { text, stream: "combined", observedAt };
|
|
199
|
+
}
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
70
203
|
}
|
|
71
204
|
}
|
|
72
205
|
await sleep(FILE_POLL_INTERVAL_MS);
|
|
73
206
|
}
|
|
207
|
+
const observedAt = new Date().toISOString();
|
|
208
|
+
const closingLines = [...splitter.push(resync.admit(decoder.end())), ...splitter.flush()];
|
|
209
|
+
const closingGap = resync.take();
|
|
210
|
+
if (closingGap !== null)
|
|
211
|
+
yield { text: "", stream: "combined", observedAt, gap: closingGap };
|
|
212
|
+
for (const text of closingLines)
|
|
213
|
+
yield { text, stream: "combined", observedAt };
|
|
74
214
|
}
|
|
75
215
|
/**
|
|
76
216
|
* Merges `docker logs -f`'s own stdout and stderr into one line stream.
|
|
@@ -90,7 +230,11 @@ async function* tailFile(path, signal) {
|
|
|
90
230
|
* `process-output.ts`'s own header already states for `ManagedProcess`.
|
|
91
231
|
*/
|
|
92
232
|
async function* tailDockerContainer(container, since, signal) {
|
|
93
|
-
const
|
|
233
|
+
const invalidName = invalidDockerContainerName(container);
|
|
234
|
+
if (invalidName !== null) {
|
|
235
|
+
throw new Error(`could not follow the logs of a container: ${invalidName}`);
|
|
236
|
+
}
|
|
237
|
+
const child = spawn("docker", ["logs", "-f", "--since", since.toISOString(), "--", container], {
|
|
94
238
|
stdio: ["ignore", "pipe", "pipe"],
|
|
95
239
|
...(signal === undefined ? {} : { signal }),
|
|
96
240
|
});
|
|
@@ -98,6 +242,9 @@ async function* tailDockerContainer(container, since, signal) {
|
|
|
98
242
|
const queue = [];
|
|
99
243
|
let waiter = null;
|
|
100
244
|
let done = false;
|
|
245
|
+
let spawnError = null;
|
|
246
|
+
let exit = null;
|
|
247
|
+
let recent = "";
|
|
101
248
|
function wake() {
|
|
102
249
|
if (waiter !== null) {
|
|
103
250
|
const resolve = waiter;
|
|
@@ -106,22 +253,24 @@ async function* tailDockerContainer(container, since, signal) {
|
|
|
106
253
|
}
|
|
107
254
|
}
|
|
108
255
|
function onChunk(chunk) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
function onDone() {
|
|
113
|
-
done = true;
|
|
256
|
+
const text = chunk.toString("utf8");
|
|
257
|
+
recent = (recent + text).slice(-600);
|
|
258
|
+
queue.push(text);
|
|
114
259
|
wake();
|
|
115
260
|
}
|
|
116
261
|
child.stdout.on("data", onChunk);
|
|
117
262
|
child.stderr.on("data", onChunk);
|
|
118
|
-
child.once("close",
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
263
|
+
child.once("close", (code, exitSignal) => {
|
|
264
|
+
exit = { code, signal: exitSignal };
|
|
265
|
+
done = true;
|
|
266
|
+
wake();
|
|
267
|
+
});
|
|
268
|
+
child.on("error", (error) => {
|
|
269
|
+
if (signal?.aborted !== true)
|
|
270
|
+
spawnError = error;
|
|
271
|
+
done = true;
|
|
272
|
+
wake();
|
|
273
|
+
});
|
|
125
274
|
try {
|
|
126
275
|
for (;;) {
|
|
127
276
|
while (queue.length > 0) {
|
|
@@ -131,8 +280,19 @@ async function* tailDockerContainer(container, since, signal) {
|
|
|
131
280
|
yield { text, stream: "combined", observedAt };
|
|
132
281
|
}
|
|
133
282
|
}
|
|
134
|
-
if (done)
|
|
283
|
+
if (done) {
|
|
284
|
+
if (signal?.aborted === true)
|
|
285
|
+
return;
|
|
286
|
+
if (spawnError !== null) {
|
|
287
|
+
throw new Error(`could not follow the logs of container "${container}": docker did not start (${spawnError.message})`);
|
|
288
|
+
}
|
|
289
|
+
const ended = exit;
|
|
290
|
+
if (ended !== null && ended.code !== 0) {
|
|
291
|
+
throw new Error(`following the logs of container "${container}" stopped: docker logs exited ` +
|
|
292
|
+
`${ended.code === null ? `on ${String(ended.signal)}` : String(ended.code)}: ${recent.trim().split("\n").slice(-3).join(" | ")}`);
|
|
293
|
+
}
|
|
135
294
|
return;
|
|
295
|
+
}
|
|
136
296
|
await new Promise((resolve) => {
|
|
137
297
|
waiter = resolve;
|
|
138
298
|
});
|
|
@@ -157,7 +317,7 @@ export function createPostgresLogSource(logSource, processId, serviceName, optio
|
|
|
157
317
|
// exists to close.
|
|
158
318
|
const startedAt = new Date();
|
|
159
319
|
const lines = logSource.kind === "file"
|
|
160
|
-
? tailFile(logSource.path, options?.signal)
|
|
320
|
+
? tailFile(logSource.path, options?.signal, options?.fileAppearTimeoutMs ?? FILE_APPEAR_TIMEOUT_MS, validatedMaxBytesPerRead(options?.maxBytesPerRead))
|
|
161
321
|
: tailDockerContainer(logSource.container, startedAt, options?.signal);
|
|
162
322
|
return { processId, serviceName, lines };
|
|
163
323
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres-log-source.js","sourceRoot":"","sources":["../src/postgres-log-source.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"postgres-log-source.js","sourceRoot":"","sources":["../src/postgres-log-source.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres-query-collector.d.ts","sourceRoot":"","sources":["../src/postgres-query-collector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAmF,MAAM,4BAA4B,CAAC;AAC7I,OAAO,
|
|
1
|
+
{"version":3,"file":"postgres-query-collector.d.ts","sourceRoot":"","sources":["../src/postgres-query-collector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAmF,MAAM,4BAA4B,CAAC;AAC7I,OAAO,EAA0E,KAAK,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAMxJ,MAAM,WAAW,6BAA6B;IAC5C,+HAA+H;IAC/H,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC;IACrC,mHAAmH;IACnH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AA6BD,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,6BAA6B,GAAG,SAAS,CAyH9F"}
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
* relays on its own stderr fd — a stdout-only tail captured nothing against
|
|
30
30
|
* the real thing. Skips with a named reason when Docker is unavailable.
|
|
31
31
|
*/
|
|
32
|
-
import { extractCorrelationIds } from "@descryy/runtime-backend-observation";
|
|
33
|
-
import {
|
|
32
|
+
import { outputGapReason, outputGapEvidence, isOutputGap, extractCorrelationIds } from "@descryy/runtime-backend-observation";
|
|
33
|
+
import { createPostgresLogReader } from "./postgres-log-parser.js";
|
|
34
34
|
import { extractTargetTable } from "./table-extraction.js";
|
|
35
35
|
import { COLLECTOR_VERSION } from "./collector-version.js";
|
|
36
36
|
const EVENT_TYPE = "DATABASE_QUERY";
|
|
@@ -50,8 +50,9 @@ function computeCapabilities() {
|
|
|
50
50
|
stackCapture: status,
|
|
51
51
|
processLifecycle: status,
|
|
52
52
|
databaseObservation: {
|
|
53
|
-
availability: "
|
|
54
|
-
reason: "queries only — the server statement log is a text stream, not a row-change feed; no before/after row state (RG-5(c) disclosure)."
|
|
53
|
+
availability: "degraded",
|
|
54
|
+
reason: "queries only — the server statement log is a text stream, not a row-change feed; no before/after row state (RG-5(c) disclosure). " +
|
|
55
|
+
"It sees only what the server's log settings write (log_statement, log_min_duration_statement, log_min_error_statement).",
|
|
55
56
|
},
|
|
56
57
|
externalServiceObservation: { availability: "unavailable", reason: "PostgresQueryCollector instruments the Postgres statement log only." },
|
|
57
58
|
};
|
|
@@ -60,6 +61,8 @@ export function createPostgresQueryCollector(options) {
|
|
|
60
61
|
const capabilities = computeCapabilities();
|
|
61
62
|
let consumeLoopDone;
|
|
62
63
|
let consumptionFailure = null;
|
|
64
|
+
let droppedCharsTotal = 0;
|
|
65
|
+
let rotations = 0;
|
|
63
66
|
function emitCapturedQuery(query, context) {
|
|
64
67
|
const { traceId, requestId } = extractCorrelationIds(query.sql);
|
|
65
68
|
context.emit({
|
|
@@ -74,6 +77,8 @@ export function createPostgresQueryCollector(options) {
|
|
|
74
77
|
durationMs: query.durationMs,
|
|
75
78
|
success: query.success,
|
|
76
79
|
error: query.error,
|
|
80
|
+
...(query.outcomeKnown ? {} : { outcomeKnown: false }),
|
|
81
|
+
...(query.sqlTruncated ? { sqlTruncated: true } : {}),
|
|
77
82
|
table: extractTargetTable(query.sql),
|
|
78
83
|
},
|
|
79
84
|
traceId,
|
|
@@ -88,11 +93,30 @@ export function createPostgresQueryCollector(options) {
|
|
|
88
93
|
});
|
|
89
94
|
}
|
|
90
95
|
async function consume(context) {
|
|
96
|
+
const reader = createPostgresLogReader();
|
|
91
97
|
for await (const line of options.source.lines) {
|
|
92
|
-
|
|
93
|
-
|
|
98
|
+
if (isOutputGap(line)) {
|
|
99
|
+
for (const query of reader.flush())
|
|
100
|
+
emitCapturedQuery(query, context);
|
|
101
|
+
if (line.gap.cause === "source-rotated")
|
|
102
|
+
rotations += 1;
|
|
103
|
+
else
|
|
104
|
+
droppedCharsTotal += line.gap.droppedChars;
|
|
105
|
+
context.emit(outputGapEvidence({
|
|
106
|
+
collectorId: `postgres-query-collector:${options.source.processId}`,
|
|
107
|
+
collectorVersion: COLLECTOR_VERSION,
|
|
108
|
+
service: options.source.serviceName ?? options.service ?? null,
|
|
109
|
+
processId: options.source.processId,
|
|
110
|
+
droppedChars: line.gap.droppedChars,
|
|
111
|
+
...(line.gap.cause === undefined ? {} : { cause: line.gap.cause }),
|
|
112
|
+
}));
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
for (const query of reader.push(line.text))
|
|
94
116
|
emitCapturedQuery(query, context);
|
|
95
117
|
}
|
|
118
|
+
for (const query of reader.flush())
|
|
119
|
+
emitCapturedQuery(query, context);
|
|
96
120
|
}
|
|
97
121
|
return {
|
|
98
122
|
collectorId: `postgres-query-collector:${options.source.processId}`,
|
|
@@ -133,15 +157,21 @@ export function createPostgresQueryCollector(options) {
|
|
|
133
157
|
await consumeLoopDone;
|
|
134
158
|
},
|
|
135
159
|
capabilities() {
|
|
136
|
-
if (consumptionFailure
|
|
137
|
-
|
|
138
|
-
return {
|
|
139
|
-
...capabilities,
|
|
140
|
-
distributedTrace: {
|
|
160
|
+
if (consumptionFailure !== null) {
|
|
161
|
+
const stopped = {
|
|
141
162
|
availability: "unavailable",
|
|
142
163
|
reason: `consumption stopped early after an error (${consumptionFailure}); output after that point was never observed.`,
|
|
143
|
-
}
|
|
144
|
-
|
|
164
|
+
};
|
|
165
|
+
return { ...capabilities, distributedTrace: stopped, databaseObservation: stopped };
|
|
166
|
+
}
|
|
167
|
+
const gapReasons = [
|
|
168
|
+
...(droppedCharsTotal > 0 ? [outputGapReason(droppedCharsTotal)] : []),
|
|
169
|
+
...(rotations > 0 ? [`${outputGapReason(0, "source-rotated")} (${String(rotations)} rotation(s))`] : []),
|
|
170
|
+
];
|
|
171
|
+
if (gapReasons.length > 0) {
|
|
172
|
+
return { ...capabilities, databaseObservation: { availability: "degraded", reason: gapReasons.join(" ") } };
|
|
173
|
+
}
|
|
174
|
+
return capabilities;
|
|
145
175
|
},
|
|
146
176
|
};
|
|
147
177
|
}
|