@descryy/runtime-database-observation 0.5.2 → 0.5.3

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.
Files changed (55) hide show
  1. package/dist/index.d.ts +7 -5
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +4 -3
  4. package/dist/index.js.map +1 -1
  5. package/dist/mysql-row-collector.d.ts +33 -19
  6. package/dist/mysql-row-collector.d.ts.map +1 -1
  7. package/dist/mysql-row-collector.js +480 -26
  8. package/dist/mysql-row-collector.js.map +1 -1
  9. package/dist/postgres-log-parser.d.ts +15 -29
  10. package/dist/postgres-log-parser.d.ts.map +1 -1
  11. package/dist/postgres-log-parser.js +103 -32
  12. package/dist/postgres-log-parser.js.map +1 -1
  13. package/dist/postgres-log-source.d.ts +2 -0
  14. package/dist/postgres-log-source.d.ts.map +1 -1
  15. package/dist/postgres-log-source.js +171 -35
  16. package/dist/postgres-log-source.js.map +1 -1
  17. package/dist/postgres-query-collector.d.ts.map +1 -1
  18. package/dist/postgres-query-collector.js +43 -13
  19. package/dist/postgres-query-collector.js.map +1 -1
  20. package/dist/postgres-row-collector.d.ts +7 -0
  21. package/dist/postgres-row-collector.d.ts.map +1 -1
  22. package/dist/postgres-row-collector.js +112 -17
  23. package/dist/postgres-row-collector.js.map +1 -1
  24. package/dist/prisma-instrumentation.d.ts +20 -0
  25. package/dist/prisma-instrumentation.d.ts.map +1 -0
  26. package/dist/prisma-instrumentation.js +99 -0
  27. package/dist/prisma-instrumentation.js.map +1 -0
  28. package/dist/query-collector.d.ts +2 -0
  29. package/dist/query-collector.d.ts.map +1 -1
  30. package/dist/query-collector.js +38 -13
  31. package/dist/query-collector.js.map +1 -1
  32. package/dist/query-line-parser.d.ts.map +1 -1
  33. package/dist/query-line-parser.js +2 -1
  34. package/dist/query-line-parser.js.map +1 -1
  35. package/dist/query-marker.d.ts +10 -1
  36. package/dist/query-marker.d.ts.map +1 -1
  37. package/dist/query-marker.js +2 -0
  38. package/dist/query-marker.js.map +1 -1
  39. package/dist/row-capture-policy.d.ts +31 -0
  40. package/dist/row-capture-policy.d.ts.map +1 -0
  41. package/dist/row-capture-policy.js +95 -0
  42. package/dist/row-capture-policy.js.map +1 -0
  43. package/dist/smoke.d.ts.map +1 -1
  44. package/dist/smoke.js +2 -0
  45. package/dist/smoke.js.map +1 -1
  46. package/dist/sqlite-instrumentation.js +9 -2
  47. package/dist/sqlite-instrumentation.js.map +1 -1
  48. package/dist/sqlite-row-snapshot.d.ts +4 -0
  49. package/dist/sqlite-row-snapshot.d.ts.map +1 -1
  50. package/dist/sqlite-row-snapshot.js +153 -25
  51. package/dist/sqlite-row-snapshot.js.map +1 -1
  52. package/dist/table-extraction.d.ts.map +1 -1
  53. package/dist/table-extraction.js +124 -5
  54. package/dist/table-extraction.js.map +1 -1
  55. 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 one line of that log, already stripped of
5
- * whatever `log_line_prefix` a deployment configured (timestamp, pid,
6
- * database name — all deployment-specific and none of them this parser's
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
- /** `null` for anything not one of the two recognised `log_statement = 'all'` shapes — never a guessed reassembly. */
38
- export function parsePostgresLogLine(line) {
39
- const statementMatch = STATEMENT_PATTERN.exec(line);
40
- if (statementMatch !== null) {
41
- return { sql: statementMatch[1].trim(), method: "statement", durationMs: null, success: true, error: null };
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
- const executeMatch = EXECUTE_PATTERN.exec(line);
44
- if (executeMatch !== null) {
45
- return { sql: executeMatch[1].trim(), method: "execute", durationMs: null, success: true, error: null };
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAUH,MAAM,iBAAiB,GAAG,6BAA6B,CAAC;AACxD,MAAM,eAAe,GAAG,iCAAiC,CAAC;AAE1D,qHAAqH;AACrH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,MAAM,cAAc,GAAG,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpD,IAAI,cAAc,KAAK,IAAI,EAAE,CAAC;QAC5B,OAAO,EAAE,GAAG,EAAE,cAAc,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAC/G,CAAC;IACD,MAAM,YAAY,GAAG,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChD,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;QAC1B,OAAO,EAAE,GAAG,EAAE,YAAY,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAC3G,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
1
+ {"version":3,"file":"postgres-log-parser.js","sourceRoot":"","sources":["../src/postgres-log-parser.ts"],"names":[],"mappings":"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"}
@@ -43,6 +43,7 @@ export type PostgresStatementLogSource = {
43
43
  readonly kind: "dockerContainer";
44
44
  readonly container: string;
45
45
  };
46
+ export declare function invalidDockerContainerName(container: string): string | null;
46
47
  /**
47
48
  * Builds the `ProcessOutputSource` `createPostgresQueryCollector` consumes,
48
49
  * over whichever statement-log shape a caller configured. `serviceName`
@@ -51,5 +52,6 @@ export type PostgresStatementLogSource = {
51
52
  */
52
53
  export declare function createPostgresLogSource(logSource: PostgresStatementLogSource, processId: string, serviceName: string | null, options?: {
53
54
  readonly signal?: AbortSignal;
55
+ readonly fileAppearTimeoutMs?: number;
54
56
  }): ProcessOutputSource;
55
57
  //# 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;AAIH,OAAO,EAAwC,KAAK,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAEtH,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;AA+GrE;;;;;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,CAAA;CAAE,GAC1C,mBAAmB,CAUrB"}
1
+ {"version":3,"file":"postgres-log-source.d.ts","sourceRoot":"","sources":["../src/postgres-log-source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAKH,OAAO,EAAwC,KAAK,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAEtH,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;AAqOD;;;;;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,CAAA;CAAE,GACjF,mBAAmB,CAUrB"}
@@ -36,41 +36,157 @@
36
36
  * run forever); the file branch checks the signal between polls.
37
37
  */
38
38
  import { spawn } from "node:child_process";
39
- import { readFile, stat } from "node:fs/promises";
39
+ import { open, stat } from "node:fs/promises";
40
+ import { StringDecoder } from "node:string_decoder";
40
41
  import { 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
+ }
42
54
  function sleep(ms) {
43
55
  return new Promise((resolve) => setTimeout(resolve, ms));
44
56
  }
45
- async function* tailFile(path, signal) {
46
- let offset;
57
+ const FILE_READ_CHUNK_BYTES = 1024 * 1024;
58
+ async function statFile(path) {
47
59
  try {
48
- offset = (await stat(path)).size;
60
+ const stats = await stat(path);
61
+ return { ok: true, size: stats.size, ino: stats.ino };
49
62
  }
50
- catch {
51
- offset = 0;
63
+ catch (error) {
64
+ return { ok: false, code: errnoOf(error) };
65
+ }
66
+ }
67
+ async function readFrom(path, offset) {
68
+ let handle;
69
+ try {
70
+ handle = await open(path, "r");
71
+ }
72
+ catch (error) {
73
+ if (errnoOf(error) === "ENOENT")
74
+ return null;
75
+ throw new Error(`the Postgres statement log file ${path} cannot be read (${errnoOf(error)})`);
76
+ }
77
+ try {
78
+ const ino = (await handle.stat()).ino;
79
+ const chunks = [];
80
+ let position = offset;
81
+ for (;;) {
82
+ const buffer = Buffer.alloc(FILE_READ_CHUNK_BYTES);
83
+ const { bytesRead } = await handle.read(buffer, 0, buffer.length, position);
84
+ if (bytesRead === 0)
85
+ break;
86
+ chunks.push(buffer.subarray(0, bytesRead));
87
+ position += bytesRead;
88
+ }
89
+ return { bytes: Buffer.concat(chunks), ino };
90
+ }
91
+ finally {
92
+ await handle.close();
93
+ }
94
+ }
95
+ const HEAD_FINGERPRINT_BYTES = 64;
96
+ async function readHead(path, length) {
97
+ if (length === 0)
98
+ return Buffer.alloc(0);
99
+ let handle;
100
+ try {
101
+ handle = await open(path, "r");
102
+ }
103
+ catch (error) {
104
+ if (errnoOf(error) === "ENOENT")
105
+ return null;
106
+ throw new Error(`the Postgres statement log file ${path} cannot be read (${errnoOf(error)})`);
107
+ }
108
+ try {
109
+ const buffer = Buffer.alloc(length);
110
+ const { bytesRead } = await handle.read(buffer, 0, length, 0);
111
+ return buffer.subarray(0, bytesRead);
112
+ }
113
+ finally {
114
+ await handle.close();
115
+ }
116
+ }
117
+ async function* tailFile(path, signal, appearTimeoutMs) {
118
+ const initial = await statFile(path);
119
+ if (!initial.ok && initial.code !== "ENOENT") {
120
+ throw new Error(`the Postgres statement log file ${path} cannot be read (${initial.code}); no queries can be observed from it`);
52
121
  }
122
+ let missingSince = initial.ok ? null : Date.now();
123
+ let hasExisted = initial.ok;
124
+ let offset = initial.ok ? initial.size : 0;
125
+ let inode = initial.ok ? initial.ino : null;
126
+ let head = (await readHead(path, Math.min(offset, HEAD_FINGERPRINT_BYTES))) ?? Buffer.alloc(0);
127
+ let decoder = new StringDecoder("utf8");
53
128
  const splitter = new LineSplitter();
129
+ const rotated = () => {
130
+ splitter.discardPartial();
131
+ decoder = new StringDecoder("utf8");
132
+ offset = 0;
133
+ head = Buffer.alloc(0);
134
+ return { text: "", stream: "combined", observedAt: new Date().toISOString(), gap: { droppedChars: 0, cause: "source-rotated" } };
135
+ };
54
136
  while (signal?.aborted !== true) {
55
- let size;
56
- try {
57
- size = (await stat(path)).size;
58
- }
59
- catch {
60
- await sleep(FILE_POLL_INTERVAL_MS);
61
- continue;
137
+ const current = await statFile(path);
138
+ if (!current.ok) {
139
+ if (current.code !== "ENOENT") {
140
+ throw new Error(`the Postgres statement log file ${path} cannot be read (${current.code}); no further queries can be observed from it`);
141
+ }
142
+ missingSince ??= Date.now();
143
+ if (Date.now() - missingSince > appearTimeoutMs) {
144
+ throw new Error(`the Postgres statement log file ${path} ${hasExisted ? "disappeared" : "did not appear"} and stayed missing for more than ${String(appearTimeoutMs)} ms (ENOENT); ` +
145
+ "an empty result here would be indistinguishable from an application that issued no queries");
146
+ }
62
147
  }
63
- if (size > offset) {
64
- const buffer = await readFile(path);
65
- const chunk = buffer.subarray(offset).toString("utf8");
66
- offset = size;
67
- const observedAt = new Date().toISOString();
68
- for (const text of splitter.push(chunk)) {
69
- yield { text, stream: "combined", observedAt };
148
+ else {
149
+ missingSince = null;
150
+ hasExisted = true;
151
+ if (inode !== null && current.ino !== inode) {
152
+ yield rotated();
153
+ }
154
+ else if (current.size < offset) {
155
+ yield rotated();
156
+ }
157
+ else if (head.length > 0) {
158
+ const now = await readHead(path, head.length);
159
+ if (now !== null && !now.equals(head))
160
+ yield rotated();
161
+ }
162
+ const read = await readFrom(path, offset);
163
+ if (read !== null) {
164
+ if (inode !== null && read.ino !== inode && offset !== 0) {
165
+ yield rotated();
166
+ }
167
+ else {
168
+ inode = read.ino;
169
+ if (read.bytes.length > 0) {
170
+ if (head.length < HEAD_FINGERPRINT_BYTES && offset < HEAD_FINGERPRINT_BYTES) {
171
+ head = Buffer.concat([head, read.bytes.subarray(0, HEAD_FINGERPRINT_BYTES - offset)]);
172
+ }
173
+ offset += read.bytes.length;
174
+ const observedAt = new Date().toISOString();
175
+ for (const text of splitter.push(decoder.write(read.bytes))) {
176
+ yield { text, stream: "combined", observedAt };
177
+ }
178
+ continue;
179
+ }
180
+ }
70
181
  }
71
182
  }
72
183
  await sleep(FILE_POLL_INTERVAL_MS);
73
184
  }
185
+ const observedAt = new Date().toISOString();
186
+ for (const text of splitter.push(decoder.end()))
187
+ yield { text, stream: "combined", observedAt };
188
+ for (const text of splitter.flush())
189
+ yield { text, stream: "combined", observedAt };
74
190
  }
75
191
  /**
76
192
  * Merges `docker logs -f`'s own stdout and stderr into one line stream.
@@ -90,7 +206,11 @@ async function* tailFile(path, signal) {
90
206
  * `process-output.ts`'s own header already states for `ManagedProcess`.
91
207
  */
92
208
  async function* tailDockerContainer(container, since, signal) {
93
- const child = spawn("docker", ["logs", "-f", "--since", since.toISOString(), container], {
209
+ const invalidName = invalidDockerContainerName(container);
210
+ if (invalidName !== null) {
211
+ throw new Error(`could not follow the logs of a container: ${invalidName}`);
212
+ }
213
+ const child = spawn("docker", ["logs", "-f", "--since", since.toISOString(), "--", container], {
94
214
  stdio: ["ignore", "pipe", "pipe"],
95
215
  ...(signal === undefined ? {} : { signal }),
96
216
  });
@@ -98,6 +218,9 @@ async function* tailDockerContainer(container, since, signal) {
98
218
  const queue = [];
99
219
  let waiter = null;
100
220
  let done = false;
221
+ let spawnError = null;
222
+ let exit = null;
223
+ let recent = "";
101
224
  function wake() {
102
225
  if (waiter !== null) {
103
226
  const resolve = waiter;
@@ -106,22 +229,24 @@ async function* tailDockerContainer(container, since, signal) {
106
229
  }
107
230
  }
108
231
  function onChunk(chunk) {
109
- queue.push(chunk.toString("utf8"));
110
- wake();
111
- }
112
- function onDone() {
113
- done = true;
232
+ const text = chunk.toString("utf8");
233
+ recent = (recent + text).slice(-600);
234
+ queue.push(text);
114
235
  wake();
115
236
  }
116
237
  child.stdout.on("data", onChunk);
117
238
  child.stderr.on("data", onChunk);
118
- child.once("close", onDone);
119
- // An aborted signal kills the child, which surfaces as an 'error' event on
120
- // the ChildProcess itself (not either stream) -- swallowed here, because
121
- // `onDone` (via 'close', which always follows) is this generator's real
122
- // end signal, and an unhandled 'error' event would otherwise crash the
123
- // process.
124
- child.on("error", () => undefined);
239
+ child.once("close", (code, exitSignal) => {
240
+ exit = { code, signal: exitSignal };
241
+ done = true;
242
+ wake();
243
+ });
244
+ child.on("error", (error) => {
245
+ if (signal?.aborted !== true)
246
+ spawnError = error;
247
+ done = true;
248
+ wake();
249
+ });
125
250
  try {
126
251
  for (;;) {
127
252
  while (queue.length > 0) {
@@ -131,8 +256,19 @@ async function* tailDockerContainer(container, since, signal) {
131
256
  yield { text, stream: "combined", observedAt };
132
257
  }
133
258
  }
134
- if (done)
259
+ if (done) {
260
+ if (signal?.aborted === true)
261
+ return;
262
+ if (spawnError !== null) {
263
+ throw new Error(`could not follow the logs of container "${container}": docker did not start (${spawnError.message})`);
264
+ }
265
+ const ended = exit;
266
+ if (ended !== null && ended.code !== 0) {
267
+ throw new Error(`following the logs of container "${container}" stopped: docker logs exited ` +
268
+ `${ended.code === null ? `on ${String(ended.signal)}` : String(ended.code)}: ${recent.trim().split("\n").slice(-3).join(" | ")}`);
269
+ }
135
270
  return;
271
+ }
136
272
  await new Promise((resolve) => {
137
273
  waiter = resolve;
138
274
  });
@@ -157,7 +293,7 @@ export function createPostgresLogSource(logSource, processId, serviceName, optio
157
293
  // exists to close.
158
294
  const startedAt = new Date();
159
295
  const lines = logSource.kind === "file"
160
- ? tailFile(logSource.path, options?.signal)
296
+ ? tailFile(logSource.path, options?.signal, options?.fileAppearTimeoutMs ?? FILE_APPEAR_TIMEOUT_MS)
161
297
  : tailDockerContainer(logSource.container, startedAt, options?.signal);
162
298
  return { processId, serviceName, lines };
163
299
  }
@@ -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,EAAyB,KAAK,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAMvG,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;AA2BD,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,6BAA6B,GAAG,SAAS,CA6F9F"}
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 { parsePostgresLogLine } from "./postgres-log-parser.js";
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: "available",
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
- const query = parsePostgresLogLine(line.text);
93
- if (query !== null)
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 === null)
137
- return capabilities;
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
  }
@@ -1 +1 @@
1
- {"version":3,"file":"postgres-query-collector.js","sourceRoot":"","sources":["../src/postgres-query-collector.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"postgres-query-collector.js","sourceRoot":"","sources":["../src/postgres-query-collector.ts"],"names":[],"mappings":"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"}