@getstrata/core 2.2.9 → 2.2.11
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/CHANGELOG.md +12 -0
- package/dist/core/database/acquisitionMetrics.d.ts +23 -0
- package/dist/core/database/baseRepository.d.ts +5 -0
- package/dist/core/database/isolatedReadOnlyObservation.d.ts +15 -0
- package/dist/core/database/mysqlConnection.d.ts +3 -0
- package/dist/core/database/readOnlyCollector.d.ts +7 -0
- package/dist/core/database/sqliteConnection.d.ts +3 -0
- package/dist/core/database/transaction.d.ts +5 -0
- package/dist/core/events/outbox/metrics.d.ts +1 -1
- package/dist/core/queue/failedJobMetrics.d.ts +17 -0
- package/dist/core/queue/queueMetrics.d.ts +4 -0
- package/dist/core/tracing/health.d.ts +27 -0
- package/dist/core/tracing/otel.d.ts +2 -0
- package/dist/core/tracing/tracingMiddleware.d.ts +2 -0
- package/dist/entries/audit/exportAuditLogs.js +61 -3
- package/dist/entries/auth/scimAuthMiddleware.js +61 -3
- package/dist/entries/database/sqliteConnection.js +137 -1
- package/dist/entries/http/response.js +3 -0
- package/dist/entries/jobs/exportAuditLogsJob.js +61 -3
- package/dist/entries/queue/queueMetrics.js +1052 -7
- package/dist/entries/tenant/databaseTenantContext.js +61 -3
- package/dist/entries/tenant/tenantDatabaseScope.js +61 -3
- package/dist/entries/tracing/tracingMiddleware.js +188 -5
- package/dist/framework/public-api.d.ts +6 -0
- package/dist/index.js +704 -105
- package/package.json +2 -1
|
@@ -129,6 +129,9 @@ function unwrapTransactionRollback(error, depth = 0) {
|
|
|
129
129
|
}
|
|
130
130
|
return unwrapTransactionRollback(error.cause, depth + 1);
|
|
131
131
|
}
|
|
132
|
+
function hasActiveTransaction() {
|
|
133
|
+
return hasActiveDatabaseConnection() && (transactionScopes.getStore()?.rollback.length ?? 0) > 0;
|
|
134
|
+
}
|
|
132
135
|
function requestTransactionRollback() {
|
|
133
136
|
const state = transactionScopes.getStore();
|
|
134
137
|
const index = state ? state.rollback.length - 1 : -1;
|
|
@@ -344,6 +347,55 @@ var init_deferredModelEvents = __esm(() => {
|
|
|
344
347
|
deferredModelEvents = createAsyncContextStore("@getstrata/deferredModelEvents");
|
|
345
348
|
});
|
|
346
349
|
|
|
350
|
+
// ../../src/core/database/acquisitionMetrics.ts
|
|
351
|
+
async function observeTransactionAcquisition(metrics, acquire, signal) {
|
|
352
|
+
const state = states.get(metrics);
|
|
353
|
+
if (!state)
|
|
354
|
+
throw new TypeError("Transaction acquisition metrics must be created by the framework factory.");
|
|
355
|
+
const started = performance.now();
|
|
356
|
+
state.inflight++;
|
|
357
|
+
let outcome = "acquired";
|
|
358
|
+
try {
|
|
359
|
+
return await acquire();
|
|
360
|
+
} catch (error) {
|
|
361
|
+
outcome = signal?.aborted ? "aborted" : "failed";
|
|
362
|
+
throw error;
|
|
363
|
+
} finally {
|
|
364
|
+
state.inflight--;
|
|
365
|
+
const elapsed = Math.max(0, performance.now() - started) / 1000;
|
|
366
|
+
const histogram = state.outcomes[outcomes.indexOf(outcome)];
|
|
367
|
+
if (histogram) {
|
|
368
|
+
histogram.count++;
|
|
369
|
+
histogram.sumSeconds += elapsed;
|
|
370
|
+
for (let index = 0;index < ACQUISITION_BUCKETS_SECONDS.length; index++) {
|
|
371
|
+
const bound = ACQUISITION_BUCKETS_SECONDS[index];
|
|
372
|
+
if (bound !== undefined && elapsed <= bound)
|
|
373
|
+
histogram.buckets[index] = (histogram.buckets[index] ?? 0) + 1;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
var ACQUISITION_BUCKETS_SECONDS, outcomes, metricsBrand, states;
|
|
379
|
+
var init_acquisitionMetrics = __esm(() => {
|
|
380
|
+
ACQUISITION_BUCKETS_SECONDS = [
|
|
381
|
+
0.001,
|
|
382
|
+
0.005,
|
|
383
|
+
0.01,
|
|
384
|
+
0.025,
|
|
385
|
+
0.05,
|
|
386
|
+
0.1,
|
|
387
|
+
0.25,
|
|
388
|
+
0.5,
|
|
389
|
+
1,
|
|
390
|
+
2.5,
|
|
391
|
+
5,
|
|
392
|
+
10
|
|
393
|
+
];
|
|
394
|
+
outcomes = ["acquired", "failed", "aborted"];
|
|
395
|
+
metricsBrand = Symbol("transaction acquisition metrics");
|
|
396
|
+
states = new WeakMap;
|
|
397
|
+
});
|
|
398
|
+
|
|
347
399
|
// ../../src/core/database/connection.ts
|
|
348
400
|
function createDatabaseConnection(source) {
|
|
349
401
|
return {
|
|
@@ -712,9 +764,13 @@ async function runInTransaction(operation, options = {}) {
|
|
|
712
764
|
throw new Error("Active database connection does not support transactions. Bind a client with begin() via bindDatabaseConnection.");
|
|
713
765
|
}
|
|
714
766
|
return await settleTransaction(() => runWithDeferredModelEvents(async () => {
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
767
|
+
let reserved;
|
|
768
|
+
if (signal || options.acquisitionMetrics) {
|
|
769
|
+
if (!pool.reserve)
|
|
770
|
+
throw new Error(signal ? "Active database connection does not support cancellable transaction acquisition." : "Active database connection does not support observable transaction acquisition.");
|
|
771
|
+
const reserve = pool.reserve.bind(pool);
|
|
772
|
+
reserved = options.acquisitionMetrics ? await observeTransactionAcquisition(options.acquisitionMetrics, () => reserve({ signal }), signal) : await reserve({ signal });
|
|
773
|
+
}
|
|
718
774
|
const connection = reserved ?? pool;
|
|
719
775
|
try {
|
|
720
776
|
signal?.throwIfAborted();
|
|
@@ -732,10 +788,12 @@ var transactionFrame, outerFrames;
|
|
|
732
788
|
var init_transaction = __esm(() => {
|
|
733
789
|
init_deferredModelEvents();
|
|
734
790
|
init_asyncContextStore();
|
|
791
|
+
init_acquisitionMetrics();
|
|
735
792
|
init_connection();
|
|
736
793
|
init_connectionContext();
|
|
737
794
|
init_repositoryConnection();
|
|
738
795
|
init_transactionControl();
|
|
796
|
+
init_acquisitionMetrics();
|
|
739
797
|
transactionFrame = createAsyncContextStore("@getstrata/transactionFrame");
|
|
740
798
|
outerFrames = new WeakMap;
|
|
741
799
|
});
|
|
@@ -52,6 +52,9 @@ function unwrapTransactionRollback(error, depth = 0) {
|
|
|
52
52
|
}
|
|
53
53
|
return unwrapTransactionRollback(error.cause, depth + 1);
|
|
54
54
|
}
|
|
55
|
+
function hasActiveTransaction() {
|
|
56
|
+
return hasActiveDatabaseConnection() && (transactionScopes.getStore()?.rollback.length ?? 0) > 0;
|
|
57
|
+
}
|
|
55
58
|
function requestTransactionRollback() {
|
|
56
59
|
const state = transactionScopes.getStore();
|
|
57
60
|
const index = state ? state.rollback.length - 1 : -1;
|
|
@@ -278,6 +281,55 @@ var init_deferredModelEvents = __esm(() => {
|
|
|
278
281
|
deferredModelEvents = createAsyncContextStore("@getstrata/deferredModelEvents");
|
|
279
282
|
});
|
|
280
283
|
|
|
284
|
+
// ../../src/core/database/acquisitionMetrics.ts
|
|
285
|
+
async function observeTransactionAcquisition(metrics, acquire, signal) {
|
|
286
|
+
const state = states.get(metrics);
|
|
287
|
+
if (!state)
|
|
288
|
+
throw new TypeError("Transaction acquisition metrics must be created by the framework factory.");
|
|
289
|
+
const started = performance.now();
|
|
290
|
+
state.inflight++;
|
|
291
|
+
let outcome = "acquired";
|
|
292
|
+
try {
|
|
293
|
+
return await acquire();
|
|
294
|
+
} catch (error) {
|
|
295
|
+
outcome = signal?.aborted ? "aborted" : "failed";
|
|
296
|
+
throw error;
|
|
297
|
+
} finally {
|
|
298
|
+
state.inflight--;
|
|
299
|
+
const elapsed = Math.max(0, performance.now() - started) / 1000;
|
|
300
|
+
const histogram = state.outcomes[outcomes.indexOf(outcome)];
|
|
301
|
+
if (histogram) {
|
|
302
|
+
histogram.count++;
|
|
303
|
+
histogram.sumSeconds += elapsed;
|
|
304
|
+
for (let index = 0;index < ACQUISITION_BUCKETS_SECONDS.length; index++) {
|
|
305
|
+
const bound = ACQUISITION_BUCKETS_SECONDS[index];
|
|
306
|
+
if (bound !== undefined && elapsed <= bound)
|
|
307
|
+
histogram.buckets[index] = (histogram.buckets[index] ?? 0) + 1;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
var ACQUISITION_BUCKETS_SECONDS, outcomes, metricsBrand, states;
|
|
313
|
+
var init_acquisitionMetrics = __esm(() => {
|
|
314
|
+
ACQUISITION_BUCKETS_SECONDS = [
|
|
315
|
+
0.001,
|
|
316
|
+
0.005,
|
|
317
|
+
0.01,
|
|
318
|
+
0.025,
|
|
319
|
+
0.05,
|
|
320
|
+
0.1,
|
|
321
|
+
0.25,
|
|
322
|
+
0.5,
|
|
323
|
+
1,
|
|
324
|
+
2.5,
|
|
325
|
+
5,
|
|
326
|
+
10
|
|
327
|
+
];
|
|
328
|
+
outcomes = ["acquired", "failed", "aborted"];
|
|
329
|
+
metricsBrand = Symbol("transaction acquisition metrics");
|
|
330
|
+
states = new WeakMap;
|
|
331
|
+
});
|
|
332
|
+
|
|
281
333
|
// ../../src/core/database/connection.ts
|
|
282
334
|
function createDatabaseConnection(source) {
|
|
283
335
|
return {
|
|
@@ -646,9 +698,13 @@ async function runInTransaction(operation, options = {}) {
|
|
|
646
698
|
throw new Error("Active database connection does not support transactions. Bind a client with begin() via bindDatabaseConnection.");
|
|
647
699
|
}
|
|
648
700
|
return await settleTransaction(() => runWithDeferredModelEvents(async () => {
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
701
|
+
let reserved;
|
|
702
|
+
if (signal || options.acquisitionMetrics) {
|
|
703
|
+
if (!pool.reserve)
|
|
704
|
+
throw new Error(signal ? "Active database connection does not support cancellable transaction acquisition." : "Active database connection does not support observable transaction acquisition.");
|
|
705
|
+
const reserve = pool.reserve.bind(pool);
|
|
706
|
+
reserved = options.acquisitionMetrics ? await observeTransactionAcquisition(options.acquisitionMetrics, () => reserve({ signal }), signal) : await reserve({ signal });
|
|
707
|
+
}
|
|
652
708
|
const connection = reserved ?? pool;
|
|
653
709
|
try {
|
|
654
710
|
signal?.throwIfAborted();
|
|
@@ -666,10 +722,12 @@ var transactionFrame, outerFrames;
|
|
|
666
722
|
var init_transaction = __esm(() => {
|
|
667
723
|
init_deferredModelEvents();
|
|
668
724
|
init_asyncContextStore();
|
|
725
|
+
init_acquisitionMetrics();
|
|
669
726
|
init_connection();
|
|
670
727
|
init_connectionContext();
|
|
671
728
|
init_repositoryConnection();
|
|
672
729
|
init_transactionControl();
|
|
730
|
+
init_acquisitionMetrics();
|
|
673
731
|
transactionFrame = createAsyncContextStore("@getstrata/transactionFrame");
|
|
674
732
|
outerFrames = new WeakMap;
|
|
675
733
|
});
|
|
@@ -48,10 +48,10 @@ import { AsyncLocalStorageContextManager } from "@opentelemetry/context-async-ho
|
|
|
48
48
|
import { W3CTraceContextPropagator } from "@opentelemetry/core";
|
|
49
49
|
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
|
|
50
50
|
import { resourceFromAttributes } from "@opentelemetry/resources";
|
|
51
|
+
import { BatchSpanProcessor } from "@opentelemetry/sdk-trace";
|
|
51
52
|
import {
|
|
52
53
|
AlwaysOffSampler,
|
|
53
54
|
AlwaysOnSampler,
|
|
54
|
-
BatchSpanProcessor,
|
|
55
55
|
ParentBasedSampler,
|
|
56
56
|
TraceIdRatioBasedSampler
|
|
57
57
|
} from "@opentelemetry/sdk-trace-base";
|
|
@@ -143,6 +143,172 @@ function sdkClientClassName() {
|
|
|
143
143
|
return fromName ? `${fromName}Client` : "AppClient";
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
+
// ../../src/core/tracing/health.ts
|
|
147
|
+
import {
|
|
148
|
+
createNoopMeter
|
|
149
|
+
} from "@opentelemetry/api";
|
|
150
|
+
import { ExportResultCode } from "@opentelemetry/core";
|
|
151
|
+
function observeExportDeadline(state, timeoutMillis) {
|
|
152
|
+
const deadline = setTimeout(() => {
|
|
153
|
+
state.exportDeadlineExceededBatches++;
|
|
154
|
+
}, timeoutMillis);
|
|
155
|
+
deadline.unref();
|
|
156
|
+
return deadline;
|
|
157
|
+
}
|
|
158
|
+
function createTracingHealth(enabled, exporterConfigured, timeoutMillis) {
|
|
159
|
+
const state = {
|
|
160
|
+
enabled,
|
|
161
|
+
exporterConfigured,
|
|
162
|
+
active: true,
|
|
163
|
+
queueSize: null,
|
|
164
|
+
queueCapacity: null,
|
|
165
|
+
droppedSpans: 0,
|
|
166
|
+
exportedBatches: 0,
|
|
167
|
+
failedBatches: 0,
|
|
168
|
+
exportedSpans: 0,
|
|
169
|
+
failedSpans: 0,
|
|
170
|
+
exportDeadlineExceededBatches: 0,
|
|
171
|
+
flushFailures: 0,
|
|
172
|
+
shutdownFailures: 0
|
|
173
|
+
};
|
|
174
|
+
let exportQueueFullSpans = 0;
|
|
175
|
+
let queueCallback;
|
|
176
|
+
const noop = createNoopMeter();
|
|
177
|
+
const meter = {
|
|
178
|
+
createGauge: noop.createGauge.bind(noop),
|
|
179
|
+
createHistogram: noop.createHistogram.bind(noop),
|
|
180
|
+
createObservableGauge: noop.createObservableGauge.bind(noop),
|
|
181
|
+
createObservableCounter: noop.createObservableCounter.bind(noop),
|
|
182
|
+
addBatchObservableCallback: noop.addBatchObservableCallback.bind(noop),
|
|
183
|
+
removeBatchObservableCallback: noop.removeBatchObservableCallback.bind(noop),
|
|
184
|
+
createCounter(name, options) {
|
|
185
|
+
if (name !== "otel.sdk.processor.span.processed")
|
|
186
|
+
return noop.createCounter(name, options);
|
|
187
|
+
return {
|
|
188
|
+
add(value, attributes) {
|
|
189
|
+
if (attributes?.["error.type"] === "queue_full")
|
|
190
|
+
state.droppedSpans += value;
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
},
|
|
194
|
+
createUpDownCounter(name, options) {
|
|
195
|
+
if (name !== "otel.sdk.processor.span.queue.capacity")
|
|
196
|
+
return noop.createUpDownCounter(name, options);
|
|
197
|
+
return {
|
|
198
|
+
add(value) {
|
|
199
|
+
state.queueCapacity = (state.queueCapacity ?? 0) + value;
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
},
|
|
203
|
+
createObservableUpDownCounter(name, options) {
|
|
204
|
+
if (name !== "otel.sdk.processor.span.queue.size")
|
|
205
|
+
return noop.createObservableUpDownCounter(name, options);
|
|
206
|
+
return {
|
|
207
|
+
addCallback(callback) {
|
|
208
|
+
queueCallback = callback;
|
|
209
|
+
},
|
|
210
|
+
removeCallback(callback) {
|
|
211
|
+
if (queueCallback === callback)
|
|
212
|
+
queueCallback = undefined;
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
const meterProvider = { getMeter: () => meter };
|
|
218
|
+
return {
|
|
219
|
+
state,
|
|
220
|
+
meterProvider,
|
|
221
|
+
snapshot() {
|
|
222
|
+
let queueSize = null;
|
|
223
|
+
queueCallback?.({
|
|
224
|
+
observe(value) {
|
|
225
|
+
queueSize = value;
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
return {
|
|
229
|
+
...state,
|
|
230
|
+
queueSize,
|
|
231
|
+
droppedSpans: Math.max(0, state.droppedSpans - exportQueueFullSpans)
|
|
232
|
+
};
|
|
233
|
+
},
|
|
234
|
+
wrap(exporter) {
|
|
235
|
+
return {
|
|
236
|
+
export(spans, callback) {
|
|
237
|
+
const count = spans.length;
|
|
238
|
+
let completed = false;
|
|
239
|
+
const deadline = observeExportDeadline(state, timeoutMillis);
|
|
240
|
+
const finish = (success) => {
|
|
241
|
+
completed = true;
|
|
242
|
+
clearTimeout(deadline);
|
|
243
|
+
if (success) {
|
|
244
|
+
state.exportedBatches++;
|
|
245
|
+
state.exportedSpans += count;
|
|
246
|
+
} else {
|
|
247
|
+
state.failedBatches++;
|
|
248
|
+
state.failedSpans += count;
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
try {
|
|
252
|
+
exporter.export(spans, (result) => {
|
|
253
|
+
if (completed)
|
|
254
|
+
return;
|
|
255
|
+
finish(result.code === ExportResultCode.SUCCESS);
|
|
256
|
+
if (result.error?.name === "queue_full")
|
|
257
|
+
exportQueueFullSpans += count;
|
|
258
|
+
callback(result);
|
|
259
|
+
});
|
|
260
|
+
} catch (error) {
|
|
261
|
+
if (!completed)
|
|
262
|
+
finish(false);
|
|
263
|
+
throw error;
|
|
264
|
+
}
|
|
265
|
+
},
|
|
266
|
+
shutdown: () => exporter.shutdown(),
|
|
267
|
+
...exporter.forceFlush ? { forceFlush: exporter.forceFlush.bind(exporter) } : {}
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
function renderTracingMetrics(snapshot) {
|
|
273
|
+
for (const key of ["enabled", "exporterConfigured", "active"])
|
|
274
|
+
if (typeof snapshot[key] !== "boolean")
|
|
275
|
+
throw new TypeError("Invalid tracing metrics.");
|
|
276
|
+
const values = {
|
|
277
|
+
strata_tracing_enabled: Number(snapshot.enabled),
|
|
278
|
+
strata_tracing_exporter_configured: Number(snapshot.exporterConfigured),
|
|
279
|
+
strata_tracing_active: Number(snapshot.active),
|
|
280
|
+
strata_tracing_queue_size: snapshot.queueSize,
|
|
281
|
+
strata_tracing_queue_capacity: snapshot.queueCapacity,
|
|
282
|
+
strata_tracing_dropped_spans_total: snapshot.droppedSpans,
|
|
283
|
+
strata_tracing_exported_batches_total: snapshot.exportedBatches,
|
|
284
|
+
strata_tracing_failed_batches_total: snapshot.failedBatches,
|
|
285
|
+
strata_tracing_exported_spans_total: snapshot.exportedSpans,
|
|
286
|
+
strata_tracing_failed_spans_total: snapshot.failedSpans,
|
|
287
|
+
strata_tracing_export_deadline_exceeded_batches_total: snapshot.exportDeadlineExceededBatches,
|
|
288
|
+
strata_tracing_flush_failures_total: snapshot.flushFailures,
|
|
289
|
+
strata_tracing_shutdown_failures_total: snapshot.shutdownFailures
|
|
290
|
+
};
|
|
291
|
+
let output = `# HELP strata_tracing_collector_success Whether tracing observation succeeded.
|
|
292
|
+
# TYPE strata_tracing_collector_success gauge
|
|
293
|
+
strata_tracing_collector_success 1
|
|
294
|
+
`;
|
|
295
|
+
for (const [name, value] of Object.entries(values)) {
|
|
296
|
+
if (value === null) {
|
|
297
|
+
if (name === "strata_tracing_queue_size" || name === "strata_tracing_queue_capacity")
|
|
298
|
+
continue;
|
|
299
|
+
throw new TypeError("Invalid tracing metrics.");
|
|
300
|
+
}
|
|
301
|
+
if (!Number.isSafeInteger(value) || value < 0)
|
|
302
|
+
throw new TypeError("Invalid tracing metrics.");
|
|
303
|
+
const type = name.endsWith("_total") ? "counter" : "gauge";
|
|
304
|
+
output += `# HELP ${name} Process-local tracing ${name.slice(15).replaceAll("_", " ")}.
|
|
305
|
+
# TYPE ${name} ${type}
|
|
306
|
+
${name} ${value}
|
|
307
|
+
`;
|
|
308
|
+
}
|
|
309
|
+
return output;
|
|
310
|
+
}
|
|
311
|
+
|
|
146
312
|
// ../../src/core/tracing/otel.ts
|
|
147
313
|
function numberOption(value, fallback, name, max = 1e6) {
|
|
148
314
|
const result = value ?? fallback;
|
|
@@ -193,11 +359,14 @@ function createTracingRuntime(options = {}) {
|
|
|
193
359
|
throw new TypeError("Invalid tracing collector endpoint.");
|
|
194
360
|
}
|
|
195
361
|
const exporter = disabled ? undefined : options.exporter ?? (endpoint ? new OTLPTraceExporter({ url: endpoint, timeoutMillis: timeout, concurrencyLimit: 1 }) : undefined);
|
|
362
|
+
const health = createTracingHealth(!disabled, exporter !== undefined, timeout);
|
|
196
363
|
const provider = new NodeTracerProvider({
|
|
197
364
|
resource: resourceFromAttributes({ "service.name": options.serviceName ?? otelServiceName() }),
|
|
198
365
|
sampler,
|
|
199
366
|
spanProcessors: exporter ? [
|
|
200
|
-
new BatchSpanProcessor(
|
|
367
|
+
new BatchSpanProcessor({
|
|
368
|
+
exporter: health.wrap(exporter),
|
|
369
|
+
selfObsMeterProvider: health.meterProvider,
|
|
201
370
|
maxQueueSize: queueSize,
|
|
202
371
|
maxExportBatchSize: batchSize,
|
|
203
372
|
scheduledDelayMillis: delay,
|
|
@@ -217,8 +386,21 @@ function createTracingRuntime(options = {}) {
|
|
|
217
386
|
tracer: provider.getTracer("@getstrata/http"),
|
|
218
387
|
propagator: new W3CTraceContextPropagator,
|
|
219
388
|
run: (parent, callback) => context.with(parent, callback),
|
|
220
|
-
|
|
221
|
-
|
|
389
|
+
metrics: () => health.snapshot(),
|
|
390
|
+
async forceFlush() {
|
|
391
|
+
try {
|
|
392
|
+
await provider.forceFlush();
|
|
393
|
+
} catch (error) {
|
|
394
|
+
health.state.flushFailures++;
|
|
395
|
+
throw error;
|
|
396
|
+
}
|
|
397
|
+
},
|
|
398
|
+
shutdown: () => shutdown ??= provider.shutdown().catch((error) => {
|
|
399
|
+
health.state.shutdownFailures++;
|
|
400
|
+
throw error;
|
|
401
|
+
}).finally(() => {
|
|
402
|
+
health.state.active = false;
|
|
403
|
+
})
|
|
222
404
|
};
|
|
223
405
|
}
|
|
224
406
|
var runtimeKey = Symbol.for("@getstrata/otel-runtime");
|
|
@@ -319,5 +501,6 @@ export {
|
|
|
319
501
|
acquireTracingRuntime,
|
|
320
502
|
createTracingMiddleware,
|
|
321
503
|
createTracingRuntime,
|
|
322
|
-
getTracingRuntime
|
|
504
|
+
getTracingRuntime,
|
|
505
|
+
renderTracingMetrics
|
|
323
506
|
};
|
|
@@ -32,6 +32,8 @@ export { CACHE_TAGS } from "../core/cache/tags.ts";
|
|
|
32
32
|
export { ConfigStore, createServiceToken, ServiceContainer, type ServiceToken, } from "../core/contracts/container.ts";
|
|
33
33
|
export type { ServiceProvider } from "../core/contracts/di.ts";
|
|
34
34
|
export { resolveService } from "../core/contracts/di.ts";
|
|
35
|
+
export type { TransactionAcquisitionMetrics, TransactionAcquisitionSnapshot, } from "../core/database/acquisitionMetrics.ts";
|
|
36
|
+
export { createTransactionAcquisitionMetrics, renderTransactionAcquisitionMetrics, } from "../core/database/acquisitionMetrics.ts";
|
|
35
37
|
export type { DatabaseConnection } from "../core/database/baseRepository.ts";
|
|
36
38
|
export { default as BaseRepository } from "../core/database/baseRepository.ts";
|
|
37
39
|
export { bindDatabaseConnection, getBoundDatabaseConnection, resetBoundDatabaseConnection, } from "../core/database/bindConnection.ts";
|
|
@@ -128,6 +130,8 @@ export { PrometheusRegistry, prometheusRegistry } from "../core/metrics/promethe
|
|
|
128
130
|
export type { DatabaseNotificationPayload, DatabaseNotificationStore, MailNotificationMessage, Notifiable, NotificationChannelName, } from "../core/notifications/index.ts";
|
|
129
131
|
export { createNotificationDispatcher, Notification, NotificationDispatcher, } from "../core/notifications/index.ts";
|
|
130
132
|
export type { CursorPaginatedResult, KeysetColumn, KeysetCursor, KeysetOptions, PaginatedResult, PaginationMeta, } from "../core/pagination/index.ts";
|
|
133
|
+
export type { FailedJobMetricsCollector, FailedJobMetricsOptions, FailedJobMetricsSnapshot, } from "../core/queue/failedJobMetrics.ts";
|
|
134
|
+
export { createFailedJobMetricsCollector, renderFailedJobMetrics, } from "../core/queue/failedJobMetrics.ts";
|
|
131
135
|
export type { Queue, QueuePriority } from "../core/queue/index.ts";
|
|
132
136
|
export { AsyncQueue, createQueue, Job, SyncQueue } from "../core/queue/index.ts";
|
|
133
137
|
export { JobRegistry } from "../core/queue/jobRegistry.ts";
|
|
@@ -155,6 +159,8 @@ export { currentTenant, currentTenantId, runWithTenant, tenantContext, } from ".
|
|
|
155
159
|
export { isInsideTenantDatabaseScope, runWithTenantDatabase, } from "../core/tenant/tenantDatabaseScope.ts";
|
|
156
160
|
export type { PublicTenancyOptions, TenantMiddlewareOptions, TenantResolver, } from "../core/tenant/tenantMiddleware.ts";
|
|
157
161
|
export { auditChecksum, createTenantMiddleware, DEFAULT_TENANT, normalizeTenantHostname, resolveUserTenantId, } from "../core/tenant/tenantMiddleware.ts";
|
|
162
|
+
export type { TracingMetricsSnapshot } from "../core/tracing/health.ts";
|
|
163
|
+
export { renderTracingMetrics } from "../core/tracing/health.ts";
|
|
158
164
|
export type { TraceContext } from "../core/tracing/traceContext.ts";
|
|
159
165
|
export { currentTraceId, runWithTraceContext, traceContextStorage, } from "../core/tracing/traceContext.ts";
|
|
160
166
|
export type { TracingOptions, TracingRuntime } from "../core/tracing/tracingMiddleware.ts";
|