@fougere/observability 0.9.2-alpha.0 → 0.10.0-alpha.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.
Files changed (69) hide show
  1. package/dist/OtlpExporter.d.ts +12 -0
  2. package/dist/OtlpExporter.d.ts.map +1 -0
  3. package/dist/{otlp.js → OtlpExporter.js} +9 -4
  4. package/dist/OtlpExporter.js.map +1 -0
  5. package/dist/{otlp.d.ts → OtlpOptions.d.ts} +2 -12
  6. package/dist/OtlpOptions.d.ts.map +1 -0
  7. package/dist/OtlpOptions.js +2 -0
  8. package/dist/OtlpOptions.js.map +1 -0
  9. package/dist/extension.d.ts +19 -0
  10. package/dist/extension.d.ts.map +1 -1
  11. package/dist/extension.js +32 -9
  12. package/dist/extension.js.map +1 -1
  13. package/dist/index.d.ts +90 -6
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +106 -13
  16. package/dist/index.js.map +1 -1
  17. package/dist/logs/CapturedLog.d.ts +7 -0
  18. package/dist/logs/CapturedLog.d.ts.map +1 -0
  19. package/dist/logs/CapturedLog.js +2 -0
  20. package/dist/logs/CapturedLog.js.map +1 -0
  21. package/dist/logs/LogExporter.d.ts +12 -0
  22. package/dist/logs/LogExporter.d.ts.map +1 -0
  23. package/dist/{logs.js → logs/LogExporter.js} +4 -5
  24. package/dist/logs/LogExporter.js.map +1 -0
  25. package/dist/logs/LogsOptions.d.ts +13 -0
  26. package/dist/logs/LogsOptions.d.ts.map +1 -0
  27. package/dist/logs/LogsOptions.js +2 -0
  28. package/dist/logs/LogsOptions.js.map +1 -0
  29. package/dist/metrics/Bucketed.d.ts +16 -0
  30. package/dist/metrics/Bucketed.d.ts.map +1 -0
  31. package/dist/metrics/Bucketed.js +2 -0
  32. package/dist/metrics/Bucketed.js.map +1 -0
  33. package/dist/metrics/Metrics.d.ts +42 -0
  34. package/dist/metrics/Metrics.d.ts.map +1 -0
  35. package/dist/{metrics.js → metrics/Metrics.js} +97 -28
  36. package/dist/metrics/Metrics.js.map +1 -0
  37. package/dist/metrics/MetricsSnapshot.d.ts +14 -0
  38. package/dist/metrics/MetricsSnapshot.d.ts.map +1 -0
  39. package/dist/metrics/MetricsSnapshot.js +2 -0
  40. package/dist/metrics/MetricsSnapshot.js.map +1 -0
  41. package/dist/otlp/OtlpExporter.d.ts +12 -0
  42. package/dist/otlp/OtlpExporter.d.ts.map +1 -0
  43. package/dist/otlp/OtlpExporter.js +64 -0
  44. package/dist/otlp/OtlpExporter.js.map +1 -0
  45. package/dist/otlp/OtlpOptions.d.ts +16 -0
  46. package/dist/otlp/OtlpOptions.d.ts.map +1 -0
  47. package/dist/otlp/OtlpOptions.js +2 -0
  48. package/dist/otlp/OtlpOptions.js.map +1 -0
  49. package/package.json +14 -7
  50. package/src/{otlp.ts → OtlpExporter.ts} +12 -18
  51. package/src/OtlpOptions.ts +16 -0
  52. package/src/extension.ts +53 -9
  53. package/src/index.ts +189 -14
  54. package/src/logs/CapturedLog.ts +7 -0
  55. package/src/{logs.ts → logs/LogExporter.ts} +5 -23
  56. package/src/logs/LogsOptions.ts +12 -0
  57. package/src/metrics/Bucketed.ts +15 -0
  58. package/src/{metrics.ts → metrics/Metrics.ts} +100 -53
  59. package/src/metrics/MetricsSnapshot.ts +14 -0
  60. package/src/otlp/OtlpExporter.ts +87 -0
  61. package/src/otlp/OtlpOptions.ts +16 -0
  62. package/dist/logs.d.ts +0 -28
  63. package/dist/logs.d.ts.map +0 -1
  64. package/dist/logs.js.map +0 -1
  65. package/dist/metrics.d.ts +0 -59
  66. package/dist/metrics.d.ts.map +0 -1
  67. package/dist/metrics.js.map +0 -1
  68. package/dist/otlp.d.ts.map +0 -1
  69. package/dist/otlp.js.map +0 -1
@@ -0,0 +1,12 @@
1
+ import type { SpanSink } from './index.js';
2
+ import type { OtlpOptions } from './OtlpOptions.js';
3
+ export interface OtlpExporter {
4
+ /** Hand to `onSpan`. */
5
+ sink: SpanSink;
6
+ /** Send what is buffered now — a process about to exit has to call this. */
7
+ flush(): Promise<void>;
8
+ /** Stop the timer and send what is left. */
9
+ stop(): Promise<void>;
10
+ }
11
+ export declare function otlp(options: OtlpOptions): OtlpExporter;
12
+ //# sourceMappingURL=OtlpExporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OtlpExporter.d.ts","sourceRoot":"","sources":["../src/OtlpExporter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAgB,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,WAAW,YAAY;IAC3B,wBAAwB;IACxB,IAAI,EAAE,QAAQ,CAAC;IACf,4EAA4E;IAC5E,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,4CAA4C;IAC5C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAYD,wBAAgB,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,YAAY,CA2BvD"}
@@ -1,10 +1,12 @@
1
- /** OTLP export — the spans this process finished, in the one shape every collector reads. */
2
1
  import { Beat } from './Beat.js';
3
2
  import { Endpoint } from './Endpoint.js';
4
- import { metricsPayload } from './metrics.js';
3
+ import { metricsPayload } from './metrics/Metrics.js';
5
4
  /** OTLP status codes: 0 unset, 1 ok, 2 error. */
6
5
  const OK = 1;
7
6
  const ERROR = 2;
7
+ /** OTLP span kinds, of the six only these two are ours. */
8
+ const INTERNAL = 1;
9
+ const CLIENT = 3;
8
10
  export function otlp(options) {
9
11
  const url = options.url ?? 'http://localhost:4318/v1/traces';
10
12
  const traces = Endpoint.at(url, options.onError);
@@ -41,7 +43,10 @@ function payload(service, spans) {
41
43
  spanId: span.spanId,
42
44
  ...(span.parentId ? { parentSpanId: span.parentId } : {}),
43
45
  name: `${span.entity}.${span.operation}`,
44
- kind: 1,
46
+ // 1 INTERNAL, 3 CLIENT: a statement left this process for an engine, and a
47
+ // viewer draws the two differently. `selfMs` is NOT sent — a collector
48
+ // derives it from the tree it already holds.
49
+ kind: span.kind === 'statement' ? CLIENT : INTERNAL,
45
50
  startTimeUnixNano: nanos(span.startedAt),
46
51
  endTimeUnixNano: nanos(span.startedAt + span.ms),
47
52
  status: span.error ? { code: ERROR, message: span.error } : { code: OK },
@@ -56,4 +61,4 @@ function payload(service, spans) {
56
61
  function nanos(ms) {
57
62
  return `${Math.round(ms * 1e6)}`;
58
63
  }
59
- //# sourceMappingURL=otlp.js.map
64
+ //# sourceMappingURL=OtlpExporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OtlpExporter.js","sourceRoot":"","sources":["../src/OtlpExporter.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,4 @@
1
- import type { SpanSink } from './index.js';
2
- import { type Metrics } from './metrics.js';
1
+ import { type Metrics } from './metrics/Metrics.js';
3
2
  export interface OtlpOptions {
4
3
  /** Which service these spans belong to — what a dashboard groups by. */
5
4
  service: string;
@@ -14,13 +13,4 @@ export interface OtlpOptions {
14
13
  /** Where metrics go when it is not the same collector as traces. */
15
14
  metricsUrl?: string;
16
15
  }
17
- export interface OtlpExporter {
18
- /** Hand to `onSpan`. */
19
- sink: SpanSink;
20
- /** Send what is buffered now — a process about to exit has to call this. */
21
- flush(): Promise<void>;
22
- /** Stop the timer and send what is left. */
23
- stop(): Promise<void>;
24
- }
25
- export declare function otlp(options: OtlpOptions): OtlpExporter;
26
- //# sourceMappingURL=otlp.d.ts.map
16
+ //# sourceMappingURL=OtlpOptions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OtlpOptions.d.ts","sourceRoot":"","sources":["../src/OtlpOptions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD,MAAM,WAAW,WAAW;IAC1B,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+FAA+F;IAC/F,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;IACjC,8CAA8C;IAC9C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=OtlpOptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OtlpOptions.js","sourceRoot":"","sources":["../src/OtlpOptions.ts"],"names":[],"mappings":""}
@@ -16,6 +16,25 @@ export interface ObservabilityOptions {
16
16
  * extension took.
17
17
  */
18
18
  onSpan?: SpanSink;
19
+ /**
20
+ * A span of its own for every statement, beside the count every operation already carries.
21
+ * Off by default — see `TracingOptions.spanPerStatement`.
22
+ */
23
+ spanPerStatement?: boolean;
24
+ /**
25
+ * What share of the operations that stay in this process are traced, `0` to `1`. Default `1`.
26
+ *
27
+ * A rate is a budget, which no reading of the code answers. What the code does answer is
28
+ * which spans a budget may not touch — see `TracingOptions.sample`.
29
+ */
30
+ sample?: number;
31
+ /**
32
+ * Bucket bounds in SECONDS for the duration histograms. Default: the OpenTelemetry
33
+ * recommendation for request durations, which assumes a healthy op lives under 100 ms.
34
+ *
35
+ * One list for the whole process, deliberately — see `metrics.ts`.
36
+ */
37
+ bounds?: readonly number[];
19
38
  }
20
39
  /** Observe this process — one member of the ascent. */
21
40
  export declare function observability(options?: ObservabilityOptions): Extension;
@@ -1 +1 @@
1
- {"version":3,"file":"extension.d.ts","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,OAAO,EAAsD,KAAK,SAAS,EAAgB,MAAM,eAAe,CAAC;AAIjH,OAAO,EAAS,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAKlD,MAAM,WAAW,oBAAoB;IACnC,gFAAgF;IAChF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kFAAkF;IAClF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC;;;;;OAKG;IACH,MAAM,CAAC,EAAE,QAAQ,CAAC;CACnB;AAED,uDAAuD;AACvD,wBAAgB,aAAa,CAAC,OAAO,GAAE,oBAAyB,GAAG,SAAS,CAqG3E"}
1
+ {"version":3,"file":"extension.d.ts","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,OAAO,EAAsD,KAAK,SAAS,EAAgB,MAAM,eAAe,CAAC;AAGjH,OAAO,EAA2C,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAKpF,MAAM,WAAW,oBAAoB;IACnC,gFAAgF;IAChF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kFAAkF;IAClF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC;;;;;OAKG;IACH,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B;AAsBD,uDAAuD;AACvD,wBAAgB,aAAa,CAAC,OAAO,GAAE,oBAAyB,GAAG,SAAS,CA2G3E"}
package/dist/extension.js CHANGED
@@ -2,11 +2,28 @@
2
2
  import { frond, loggerMiddleware, LogLine } from '@fougere/core';
3
3
  import ExportHandler from './ExportHandler.js';
4
4
  import { traceContext } from '#trace-context';
5
- import { registerFlush } from './index.js';
6
- import { trace } from './index.js';
7
- import { metrics, serveTopology } from './metrics.js';
8
- import { otlp } from './otlp.js';
9
- import { logs } from './logs.js';
5
+ import { registerFlush, statementsUnder, tracing } from './index.js';
6
+ import { metrics, serveTopology } from './metrics/Metrics.js';
7
+ import { otlp } from './otlp/OtlpExporter.js';
8
+ import { logs } from './logs/LogExporter.js';
9
+ /**
10
+ * How far each operation's work goes, read off the model ONCE at boot.
11
+ *
12
+ * `EffectiveOperation.reach` is resolved when the app is built, so the middleware does not
13
+ * recompute it per call — it looks one name up. An address the model does not hold answers zero,
14
+ * which is what `rpc` and a brought frond's own ops are.
15
+ */
16
+ function hopsIn(app) {
17
+ const hops = new Map();
18
+ for (const frond of app.fronds) {
19
+ for (const handler of frond.handlers) {
20
+ for (const [name, op] of app.operationsFor(handler.address) ?? []) {
21
+ hops.set(`${handler.address}.${name}`, op.reach.hops);
22
+ }
23
+ }
24
+ }
25
+ return (entity, operation) => hops.get(`${entity}.${operation}`) ?? 0;
26
+ }
10
27
  /** Observe this process — one member of the ascent. */
11
28
  export function observability(options = {}) {
12
29
  const service = options.service ?? 'fougere';
@@ -32,17 +49,23 @@ export function observability(options = {}) {
32
49
  },
33
50
  }],
34
51
  })],
35
- up(app) {
52
+ async up(app) {
36
53
  // Held across the ascent: the exporter exists only when `otlp` is declared, and the
37
54
  // handler resolves this either way.
38
55
  app.container.registerValue('LogExport', exporting);
39
56
  const undo = [];
40
57
  undoing.set(app, undo);
41
- // Order matters: `trace()` opens the span that every log line written inside the
58
+ // Order matters: `tracing()` opens the span that every log line written inside the
42
59
  // call will carry. Installed the other way round, the lines leave uncorrelated.
43
60
  const spans = options.onSpan ? [options.onSpan] : [];
44
61
  takers.set(app, spans);
45
- app.use(trace(spans));
62
+ const tracer = tracing(spans, {
63
+ spanPerStatement: options.spanPerStatement ?? false,
64
+ ...(options.sample === undefined ? {} : { sample: options.sample }),
65
+ hopsOf: hopsIn(app),
66
+ });
67
+ app.use(tracer.middleware);
68
+ undo.push(await statementsUnder(tracer));
46
69
  // The app's own logger, named — NOT `new Logger(service)`: a logger built here has
47
70
  // no `Carry`, so its lines printed and announced nothing. 20 on the console, 0 in
48
71
  // the ring, measured on `demos/observability`.
@@ -57,7 +80,7 @@ export function observability(options = {}) {
57
80
  + 'An arriving call and a call to a frond behind `remotes:` are unaffected — both carry '
58
81
  + 'traceparent on the invocation. Add "nodejs_als" to compatibility_flags to restore the rest.');
59
82
  }
60
- const measured = metrics(app);
83
+ const measured = metrics(app, options.bounds);
61
84
  spans.push(measured.sink);
62
85
  serveTopology(app, measured);
63
86
  if (!options.otlp)
@@ -1 +1 @@
1
- {"version":3,"file":"extension.js","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"extension.js","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,10 @@
1
1
  import { type AppMiddleware } from '@fougere/core';
2
2
  import { type SpanContext } from './traceparent.js';
3
+ /**
4
+ * What a span is a span OF. An operation was dispatched and has an address; a statement ran
5
+ * underneath one and has a table. A reader that counts operations has to say which it takes.
6
+ */
7
+ export type SpanKind = 'operation' | 'statement';
3
8
  /** A step that has finished, and what it did. */
4
9
  export interface FinishedSpan extends SpanContext {
5
10
  parentId: string | undefined;
@@ -10,15 +15,75 @@ export interface FinishedSpan extends SpanContext {
10
15
  callerFrond: string | undefined;
11
16
  /** Which frond owned the op — the deployment unit, so the first thing a reader groups by. */
12
17
  frond: string | undefined;
18
+ kind: SpanKind;
13
19
  entity: string;
14
20
  operation: string;
15
21
  /** When it started, in epoch milliseconds — an INSTANT, not an offset. */
16
22
  startedAt: number;
17
23
  ms: number;
24
+ /**
25
+ * `ms` minus what its OBSERVED children account for — the time this step spent itself. An op
26
+ * that delegates everything reports a duration and almost no self, which is how a report
27
+ * names the step that is actually slow instead of the one that waited for it.
28
+ *
29
+ * Never below zero, and that is not a guard: children running TOGETHER — the four queries
30
+ * behind one `Promise.all` — add up to more than the step that holds them. What is
31
+ * measured is the time nothing else accounts for, and there is no less of it than none.
32
+ *
33
+ * A child that finishes AFTER its parent is not deducted either: nothing was observed when
34
+ * the subtraction ran. The figure stays true, it is only cleaner than it should be.
35
+ */
36
+ selfMs: number;
37
+ /** How many statements ran under this step — one per row is the shape of an N+1. */
38
+ statements: number;
18
39
  /** The FougereError code when it refused, absent when it answered. */
19
40
  error: string | undefined;
20
41
  }
21
42
  export type SpanSink = (span: FinishedSpan) => void;
43
+ /** A statement as its producer describes it — never the values it was given. */
44
+ export interface Statement {
45
+ /** What it read or wrote: the table, or the source when the statement names none. */
46
+ subject: string;
47
+ /** `select`, `insert`, `update`, `delete`. */
48
+ verb: string;
49
+ ms: number;
50
+ failed: boolean;
51
+ }
52
+ /** What an app's tracer answers for. */
53
+ export interface Tracing {
54
+ /** One span per operation — handed to `app.use`. */
55
+ middleware: AppMiddleware;
56
+ /** A statement that ran under the operation in flight: its time charged upward, and its own span when asked. */
57
+ statement(ran: Statement): void;
58
+ }
59
+ export interface TracingOptions {
60
+ /**
61
+ * A span of its OWN for every statement, and not only the time charged to the operation
62
+ * above it. Off by default, and the default is not prudence: `selfMs` and `statements` are
63
+ * counted either way, so what this adds is WHICH queries ran — a diagnosis, against a
64
+ * volume that multiplies by however many rows the page held. A backend charges per span.
65
+ *
66
+ * The pair splits the way profiling splits from monitoring: the count DETECTS, and it runs
67
+ * always; the detail EXPLAINS, and it is turned on over the operation the count named.
68
+ */
69
+ spanPerStatement?: boolean;
70
+ /**
71
+ * What share of the operations that stay in this process are traced, `0` to `1`.
72
+ *
73
+ * A rate is a BUDGET — how much a backend is worth per day — and no reading of the code
74
+ * answers it, so it is the operator's to set. What the code does answer is which spans the
75
+ * budget may not touch: an operation that crosses a process produces the one signal nothing
76
+ * else carries, since the difference between the caller's span and the callee's IS the wire
77
+ * cost, and neither process can measure it alone. So a rate below one thins what is already
78
+ * described by its own histogram, and never what only a trace can show.
79
+ *
80
+ * Default `1`, which is what a process did before this existed. The gain is not the default:
81
+ * it is that turning the rate down no longer drops the traces that matter most.
82
+ */
83
+ sample?: number;
84
+ /** How far an operation's work goes, by `entity.op` — the boot reads it off the model. */
85
+ hopsOf?: (entity: string, operation: string) => number;
86
+ }
22
87
  /** The step running here and now. */
23
88
  /** The step running right now, if any. */
24
89
  export declare function currentSpan(): SpanContext | undefined;
@@ -28,17 +93,36 @@ export declare function flushTelemetry(): Promise<void>;
28
93
  /** Declare an exporter's flush, and answer the way to withdraw it — like `onSpan`. */
29
94
  export declare function registerFlush(send: () => Promise<void>): () => void;
30
95
  /**
31
- * The middleware, and it is HANDED who takes the spans it finishes.
96
+ * The tracer of ONE app, and it is HANDED who takes the spans it finishes.
32
97
  *
33
98
  * The list belongs to the app the middleware was installed on, never to the process: a
34
99
  * discarded app went on feeding the takers of the app that replaced it, so every metric
35
100
  * counted twice. A module-level array made that a leak you had to remember to undo; a list
36
101
  * held beside the app cannot outlive it. Read at every end, so a taker added later counts.
102
+ *
103
+ * Two facades and not one, because a statement is not dispatched: nothing calls a middleware
104
+ * around a query. What both need is the same table — the time a step's children accounted
105
+ * for — so the two sit in one closure rather than reaching for each other.
106
+ *
107
+ * Documented: [observability](https://fougere.dev/docs/infra/observability).
108
+ */
109
+ export declare function tracing(takers: readonly SpanSink[], options?: TracingOptions): Tracing;
110
+ /**
111
+ * The join this package exists to make: a statement runs SYNCHRONOUSLY inside the async
112
+ * context `tracing()` opened around the operation, so the sink finds the step it belongs to
113
+ * without the app ever holding its sources — which is what made the two ends of `onQuery`
114
+ * unable to see each other.
115
+ *
116
+ * `@fougere/adapter-sql` is optional, and dynamic for the reason `@fougere/calls` states:
117
+ * this package declares no dependency on it. An app on another storage observes no
118
+ * statement and every operation still reports its own time.
37
119
  */
38
- export declare function trace(takers: readonly SpanSink[]): AppMiddleware;
39
- export { otlp } from './otlp.js';
40
- export { metrics } from './metrics.js';
41
- export type { Metrics, TopologyReport, FrondPlacement, Edge } from './metrics.js';
42
- export { logs } from './logs.js';
120
+ export declare function statementsUnder(tracer: Tracing): Promise<() => void>;
121
+ export { otlp } from './otlp/OtlpExporter.js';
122
+ export { metrics } from './metrics/Metrics.js';
123
+ export type { Metrics } from './metrics/Metrics.js';
124
+ export type { TopologyReport } from '@fougere/core';
125
+ export type { FrondPlacement, Edge } from '@fougere/core';
126
+ export { logs } from './logs/LogExporter.js';
43
127
  export { observability } from './extension.js';
44
128
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAA8C,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAOhG,iDAAiD;AACjD,MAAM,WAAW,YAAa,SAAQ,WAAW;IAC/C,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B;;;OAGG;IACH,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,6FAA6F;IAC7F,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,SAAS,EAAE,MAAM,CAAC;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,sEAAsE;IACtE,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B;AAED,MAAM,MAAM,QAAQ,GAAG,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;AAEpD,qCAAqC;AAErC,0CAA0C;AAC1C,wBAAgB,WAAW,IAAI,WAAW,GAAG,SAAS,CAErD;AAQD,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAKD,kCAAkC;AAClC,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAMpD;AAED,sFAAsF;AACtF,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,CAMnE;AAED;;;;;;;GAOG;AACH,wBAAgB,KAAK,CAAC,MAAM,EAAE,SAAS,QAAQ,EAAE,GAAG,aAAa,CAgEhE;AAOD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAClF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAA8C,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAiBhG;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,WAAW,GAAG,WAAW,CAAC;AAEjD,iDAAiD;AACjD,MAAM,WAAW,YAAa,SAAQ,WAAW;IAC/C,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B;;;OAGG;IACH,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,6FAA6F;IAC7F,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,SAAS,EAAE,MAAM,CAAC;IAClB,EAAE,EAAE,MAAM,CAAC;IACX;;;;;;;;;;;OAWG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,oFAAoF;IACpF,UAAU,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B;AAED,MAAM,MAAM,QAAQ,GAAG,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;AAEpD,gFAAgF;AAChF,MAAM,WAAW,SAAS;IACxB,qFAAqF;IACrF,OAAO,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,wCAAwC;AACxC,MAAM,WAAW,OAAO;IACtB,oDAAoD;IACpD,UAAU,EAAE,aAAa,CAAC;IAC1B,gHAAgH;IAChH,SAAS,CAAC,GAAG,EAAE,SAAS,GAAG,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,cAAc;IAC7B;;;;;;;;OAQG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0FAA0F;IAC1F,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC;CACxD;AAED,qCAAqC;AAErC,0CAA0C;AAC1C,wBAAgB,WAAW,IAAI,WAAW,GAAG,SAAS,CAErD;AAQD,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAKD,kCAAkC;AAClC,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAMpD;AAED,sFAAsF;AACtF,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,CAMnE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,OAAO,CAAC,MAAM,EAAE,SAAS,QAAQ,EAAE,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CA+H1F;AAED;;;;;;;;;GASG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAa1E;AAOD,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,YAAY,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACpD,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,YAAY,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/index.js CHANGED
@@ -36,15 +36,30 @@ export function registerFlush(send) {
36
36
  };
37
37
  }
38
38
  /**
39
- * The middleware, and it is HANDED who takes the spans it finishes.
39
+ * The tracer of ONE app, and it is HANDED who takes the spans it finishes.
40
40
  *
41
41
  * The list belongs to the app the middleware was installed on, never to the process: a
42
42
  * discarded app went on feeding the takers of the app that replaced it, so every metric
43
43
  * counted twice. A module-level array made that a leak you had to remember to undo; a list
44
44
  * held beside the app cannot outlive it. Read at every end, so a taker added later counts.
45
+ *
46
+ * Two facades and not one, because a statement is not dispatched: nothing calls a middleware
47
+ * around a query. What both need is the same table — the time a step's children accounted
48
+ * for — so the two sit in one closure rather than reaching for each other.
49
+ *
50
+ * Documented: [observability](https://fougere.dev/docs/infra/observability).
45
51
  */
46
- export function trace(takers) {
47
- return (ctx, next) => {
52
+ export function tracing(takers, options = {}) {
53
+ /** What a step's children have accounted for, by the step they ran under. */
54
+ const charged = new Map();
55
+ const rate = options.sample ?? 1;
56
+ const hopsOf = options.hopsOf ?? (() => 0);
57
+ /**
58
+ * Whether a root span is kept. An operation that leaves the process always is — the budget is
59
+ * for the ones a histogram already describes.
60
+ */
61
+ const keeps = (entity, operation) => rate >= 1 || hopsOf(entity, operation) > 0 || Math.random() < rate;
62
+ const middleware = (ctx, next) => {
48
63
  if (takers.length === 0)
49
64
  return next();
50
65
  // An op that CARRIES a line is not a call this process made: counting it puts the
@@ -57,11 +72,20 @@ export function trace(takers) {
57
72
  const inherited = parseTraceparent(ctx.invocation?.trace);
58
73
  const ambient = traceContext.current();
59
74
  const parent = inherited ?? ambient;
75
+ // Both, and they are not the same measurement: the wall clock says WHEN so two
76
+ // processes land on one timeline, the monotonic one says HOW LONG without being
77
+ // moved by an NTP correction mid-call.
78
+ const startedAt = Date.now();
79
+ const start = performance.now();
60
80
  const span = {
61
81
  traceId: parent?.traceId ?? randomHex(16),
62
82
  spanId: randomHex(8),
63
- sampled: parent?.sampled ?? true,
83
+ // A trace is whole or it is nothing: a call under a sampled parent is sampled, whatever
84
+ // this process would have decided on its own. Only a root is decided here.
85
+ sampled: parent?.sampled ?? keeps(ctx.entity, ctx.operation),
64
86
  frond: ctx.frond,
87
+ startedAt,
88
+ start,
65
89
  };
66
90
  // An edge exists only when the parent is IN this process and belongs to another frond.
67
91
  // `inherited` won means the parent is across a wire, and it did not name its frond.
@@ -72,23 +96,26 @@ export function trace(takers) {
72
96
  // carries the invocation.
73
97
  if (ctx.invocation)
74
98
  ctx.invocation = { ...ctx.invocation, trace: traceparentOf(span) };
75
- // Both, and they are not the same measurement: the wall clock says WHEN so two
76
- // processes land on one timeline, the monotonic one says HOW LONG without being
77
- // moved by an NTP correction mid-call.
78
- const startedAt = Date.now();
79
- const start = performance.now();
80
99
  active += 1;
81
100
  const finish = (error) => {
82
101
  active -= 1;
102
+ const ms = performance.now() - start;
103
+ // Read and dropped in one gesture: a step ends once, and what its children owed it
104
+ // is of no use to anyone after that.
105
+ const owed = charged.get(span.spanId);
106
+ charged.delete(span.spanId);
83
107
  const done = {
84
108
  ...span,
85
109
  parentId: parent?.spanId,
86
110
  callerFrond,
87
111
  frond: ctx.frond,
112
+ kind: 'operation',
88
113
  entity: ctx.entity,
89
114
  operation: ctx.operation,
90
115
  startedAt,
91
- ms: performance.now() - start,
116
+ ms,
117
+ selfMs: Math.max(0, ms - (owed?.ms ?? 0)),
118
+ statements: owed?.statements ?? 0,
92
119
  error,
93
120
  };
94
121
  // A taker that throws is a broken exporter, never a broken call.
@@ -111,13 +138,79 @@ export function trace(takers) {
111
138
  }
112
139
  });
113
140
  };
141
+ return {
142
+ middleware,
143
+ statement(ran) {
144
+ if (takers.length === 0)
145
+ return;
146
+ // A statement with no operation above it — a migration, a seed — belongs to no step,
147
+ // and inventing a trace for it would put a root span in the viewer per row planted.
148
+ const under = traceContext.current();
149
+ if (!under)
150
+ return;
151
+ const owed = charged.get(under.spanId) ?? { ms: 0, statements: 0 };
152
+ owed.ms += ran.ms;
153
+ owed.statements += 1;
154
+ charged.set(under.spanId, owed);
155
+ // The op above now reports what it waited for and how many times, which is the whole
156
+ // of what a dashboard reads. WHICH queries ran leaves only when someone asks.
157
+ if (!options.spanPerStatement)
158
+ return;
159
+ const done = {
160
+ traceId: under.traceId,
161
+ spanId: randomHex(8),
162
+ sampled: under.sampled,
163
+ parentId: under.spanId,
164
+ callerFrond: undefined,
165
+ frond: under.frond,
166
+ kind: 'statement',
167
+ entity: ran.subject,
168
+ operation: ran.verb,
169
+ startedAt: under.startedAt + Math.max(0, performance.now() - under.start - ran.ms),
170
+ ms: ran.ms,
171
+ selfMs: ran.ms,
172
+ statements: 0,
173
+ error: ran.failed ? 'STATEMENT_FAILED' : undefined,
174
+ };
175
+ for (const take of takers) {
176
+ try {
177
+ take(done);
178
+ }
179
+ catch { /* observing never refuses */ }
180
+ }
181
+ },
182
+ };
183
+ }
184
+ /**
185
+ * The join this package exists to make: a statement runs SYNCHRONOUSLY inside the async
186
+ * context `tracing()` opened around the operation, so the sink finds the step it belongs to
187
+ * without the app ever holding its sources — which is what made the two ends of `onQuery`
188
+ * unable to see each other.
189
+ *
190
+ * `@fougere/adapter-sql` is optional, and dynamic for the reason `@fougere/calls` states:
191
+ * this package declares no dependency on it. An app on another storage observes no
192
+ * statement and every operation still reports its own time.
193
+ */
194
+ export async function statementsUnder(tracer) {
195
+ try {
196
+ const { onQuery } = await import('@fougere/adapter-sql');
197
+ return onQuery((event) => tracer.statement({
198
+ subject: event.subject,
199
+ verb: event.verb,
200
+ ms: event.ms,
201
+ failed: event.failed,
202
+ }));
203
+ }
204
+ catch {
205
+ return () => { };
206
+ }
114
207
  }
115
208
  function codeOf(err) {
116
209
  const code = err?.code;
117
210
  return typeof code === 'string' ? code : (err?.name ?? 'error');
118
211
  }
119
- export { otlp } from './otlp.js';
120
- export { metrics } from './metrics.js';
121
- export { logs } from './logs.js';
212
+ export { otlp } from './otlp/OtlpExporter.js';
213
+ export { metrics } from './metrics/Metrics.js';
214
+ export { logs } from './logs/LogExporter.js';
122
215
  export { observability } from './extension.js';
123
216
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { LogRecord } from '@fougere/core';
2
+ /** A record, plus what it could only be told at the moment it was written. */
3
+ export interface CapturedLog extends LogRecord {
4
+ traceId: string | undefined;
5
+ spanId: string | undefined;
6
+ }
7
+ //# sourceMappingURL=CapturedLog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CapturedLog.d.ts","sourceRoot":"","sources":["../../src/logs/CapturedLog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE/C,8EAA8E;AAC9E,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC5C,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=CapturedLog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CapturedLog.js","sourceRoot":"","sources":["../../src/logs/CapturedLog.ts"],"names":[],"mappings":""}
@@ -0,0 +1,12 @@
1
+ import type { LogRecord } from '@fougere/core';
2
+ import type { LogsOptions } from './LogsOptions.js';
3
+ export interface LogExporter {
4
+ /** Hand to `onLog`. */
5
+ sink: (record: LogRecord) => void;
6
+ /** Send what is buffered now. */
7
+ flush(): Promise<void>;
8
+ /** Stop the timer and send what is left. */
9
+ stop(): Promise<void>;
10
+ }
11
+ export declare function logs(options: LogsOptions): LogExporter;
12
+ //# sourceMappingURL=LogExporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LogExporter.d.ts","sourceRoot":"","sources":["../../src/logs/LogExporter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAUpD,MAAM,WAAW,WAAW;IAC1B,uBAAuB;IACvB,IAAI,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,CAAC;IAClC,iCAAiC;IACjC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,4CAA4C;IAC5C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAED,wBAAgB,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,WAAW,CA2BtD"}
@@ -1,7 +1,6 @@
1
- /** Log export — the third signal, and the only one whose value is entirely in its links. */
2
- import { Beat } from './Beat.js';
3
- import { Endpoint } from './Endpoint.js';
4
- import { currentSpan } from './index.js';
1
+ import { Beat } from '../Beat.js';
2
+ import { Endpoint } from '../Endpoint.js';
3
+ import { currentSpan } from '../index.js';
5
4
  /** OTLP severity numbers — the scale is 1–24, these are the canonical rungs. */
6
5
  const SEVERITY = {
7
6
  debug: { number: 5, text: 'DEBUG' },
@@ -88,4 +87,4 @@ function readable(value) {
88
87
  return String(value);
89
88
  }
90
89
  }
91
- //# sourceMappingURL=logs.js.map
90
+ //# sourceMappingURL=LogExporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LogExporter.js","sourceRoot":"","sources":["../../src/logs/LogExporter.ts"],"names":[],"mappings":"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"}