@spinajs/log 2.0.481 → 2.0.484
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/README.md +744 -0
- package/lib/cjs/archive/LogArchiveService.d.ts +75 -0
- package/lib/cjs/archive/LogArchiveService.d.ts.map +1 -0
- package/lib/cjs/archive/LogArchiveService.js +189 -0
- package/lib/cjs/archive/LogArchiveService.js.map +1 -0
- package/lib/cjs/archive/archive-strategy.d.ts +32 -0
- package/lib/cjs/archive/archive-strategy.d.ts.map +1 -0
- package/lib/cjs/archive/archive-strategy.js +43 -0
- package/lib/cjs/archive/archive-strategy.js.map +1 -0
- package/lib/cjs/archive/context.d.ts +50 -0
- package/lib/cjs/archive/context.d.ts.map +1 -0
- package/lib/cjs/archive/context.js +3 -0
- package/lib/cjs/archive/context.js.map +1 -0
- package/lib/cjs/archive/index.d.ts +10 -0
- package/lib/cjs/archive/index.d.ts.map +1 -0
- package/lib/cjs/archive/index.js +26 -0
- package/lib/cjs/archive/index.js.map +1 -0
- package/lib/cjs/archive/retention-strategy.d.ts +26 -0
- package/lib/cjs/archive/retention-strategy.d.ts.map +1 -0
- package/lib/cjs/archive/retention-strategy.js +42 -0
- package/lib/cjs/archive/retention-strategy.js.map +1 -0
- package/lib/cjs/archive/strategies/AgeLogRetentionStrategy.d.ts +10 -0
- package/lib/cjs/archive/strategies/AgeLogRetentionStrategy.d.ts.map +1 -0
- package/lib/cjs/archive/strategies/AgeLogRetentionStrategy.js +46 -0
- package/lib/cjs/archive/strategies/AgeLogRetentionStrategy.js.map +1 -0
- package/lib/cjs/archive/strategies/CountLogRetentionStrategy.d.ts +10 -0
- package/lib/cjs/archive/strategies/CountLogRetentionStrategy.d.ts.map +1 -0
- package/lib/cjs/archive/strategies/CountLogRetentionStrategy.js +42 -0
- package/lib/cjs/archive/strategies/CountLogRetentionStrategy.js.map +1 -0
- package/lib/cjs/archive/strategies/CronLogArchiveStrategy.d.ts +15 -0
- package/lib/cjs/archive/strategies/CronLogArchiveStrategy.d.ts.map +1 -0
- package/lib/cjs/archive/strategies/CronLogArchiveStrategy.js +52 -0
- package/lib/cjs/archive/strategies/CronLogArchiveStrategy.js.map +1 -0
- package/lib/cjs/archive/strategies/SizeLogArchiveStrategy.d.ts +18 -0
- package/lib/cjs/archive/strategies/SizeLogArchiveStrategy.d.ts.map +1 -0
- package/lib/cjs/archive/strategies/SizeLogArchiveStrategy.js +63 -0
- package/lib/cjs/archive/strategies/SizeLogArchiveStrategy.js.map +1 -0
- package/lib/cjs/archive/strategies/util.d.ts +28 -0
- package/lib/cjs/archive/strategies/util.d.ts.map +1 -0
- package/lib/cjs/archive/strategies/util.js +59 -0
- package/lib/cjs/archive/strategies/util.js.map +1 -0
- package/lib/cjs/bootstrap.d.ts.map +1 -1
- package/lib/cjs/bootstrap.js +24 -1
- package/lib/cjs/bootstrap.js.map +1 -1
- package/lib/cjs/callsite.d.ts +26 -0
- package/lib/cjs/callsite.d.ts.map +1 -0
- package/lib/cjs/callsite.js +60 -0
- package/lib/cjs/callsite.js.map +1 -0
- package/lib/cjs/config/log.d.ts +96 -0
- package/lib/cjs/config/log.d.ts.map +1 -0
- package/lib/cjs/config/log.js +75 -0
- package/lib/cjs/config/log.js.map +1 -0
- package/lib/cjs/context.browser.d.ts +46 -0
- package/lib/cjs/context.browser.d.ts.map +1 -0
- package/lib/cjs/context.browser.js +85 -0
- package/lib/cjs/context.browser.js.map +1 -0
- package/lib/cjs/context.d.ts +61 -0
- package/lib/cjs/context.d.ts.map +1 -0
- package/lib/cjs/context.js +92 -0
- package/lib/cjs/context.js.map +1 -0
- package/lib/cjs/filters/LevelFilter.d.ts +24 -0
- package/lib/cjs/filters/LevelFilter.d.ts.map +1 -0
- package/lib/cjs/filters/LevelFilter.js +39 -0
- package/lib/cjs/filters/LevelFilter.js.map +1 -0
- package/lib/cjs/filters/MatchFilter.d.ts +30 -0
- package/lib/cjs/filters/MatchFilter.d.ts.map +1 -0
- package/lib/cjs/filters/MatchFilter.js +65 -0
- package/lib/cjs/filters/MatchFilter.js.map +1 -0
- package/lib/cjs/filters/RateLimitFilter.d.ts +37 -0
- package/lib/cjs/filters/RateLimitFilter.d.ts.map +1 -0
- package/lib/cjs/filters/RateLimitFilter.js +70 -0
- package/lib/cjs/filters/RateLimitFilter.js.map +1 -0
- package/lib/cjs/filters/index.d.ts +4 -0
- package/lib/cjs/filters/index.d.ts.map +1 -0
- package/lib/cjs/filters/index.js +20 -0
- package/lib/cjs/filters/index.js.map +1 -0
- package/lib/cjs/index.browser.d.ts +14 -0
- package/lib/cjs/index.browser.d.ts.map +1 -0
- package/lib/cjs/index.browser.js +46 -0
- package/lib/cjs/index.browser.js.map +1 -0
- package/lib/cjs/index.d.ts +8 -0
- package/lib/cjs/index.d.ts.map +1 -1
- package/lib/cjs/index.js +8 -0
- package/lib/cjs/index.js.map +1 -1
- package/lib/cjs/log.d.ts +60 -1
- package/lib/cjs/log.d.ts.map +1 -1
- package/lib/cjs/log.js +294 -32
- package/lib/cjs/log.js.map +1 -1
- package/lib/cjs/perf/LogMetricSink.d.ts +55 -0
- package/lib/cjs/perf/LogMetricSink.d.ts.map +1 -0
- package/lib/cjs/perf/LogMetricSink.js +154 -0
- package/lib/cjs/perf/LogMetricSink.js.map +1 -0
- package/lib/cjs/perf/measure.d.ts +9 -0
- package/lib/cjs/perf/measure.d.ts.map +1 -0
- package/lib/cjs/perf/measure.js +21 -0
- package/lib/cjs/perf/measure.js.map +1 -0
- package/lib/cjs/perf.d.ts +9 -0
- package/lib/cjs/perf.d.ts.map +1 -0
- package/lib/cjs/perf.js +18 -0
- package/lib/cjs/perf.js.map +1 -0
- package/lib/cjs/schemas/log.configuration.d.ts +151 -18
- package/lib/cjs/schemas/log.configuration.d.ts.map +1 -1
- package/lib/cjs/schemas/log.configuration.js +154 -21
- package/lib/cjs/schemas/log.configuration.js.map +1 -1
- package/lib/cjs/targets/BrowserConsoleTarget.d.ts +48 -0
- package/lib/cjs/targets/BrowserConsoleTarget.d.ts.map +1 -0
- package/lib/cjs/targets/BrowserConsoleTarget.js +48 -0
- package/lib/cjs/targets/BrowserConsoleTarget.js.map +1 -0
- package/lib/cjs/targets/ColoredConsoleTarget.d.ts.map +1 -1
- package/lib/cjs/targets/ColoredConsoleTarget.js +21 -12
- package/lib/cjs/targets/ColoredConsoleTarget.js.map +1 -1
- package/lib/cjs/targets/FileTarget.d.ts +96 -20
- package/lib/cjs/targets/FileTarget.d.ts.map +1 -1
- package/lib/cjs/targets/FileTarget.js +188 -225
- package/lib/cjs/targets/FileTarget.js.map +1 -1
- package/lib/cjs/targets/JsonFileTarget.d.ts +19 -0
- package/lib/cjs/targets/JsonFileTarget.d.ts.map +1 -0
- package/lib/cjs/targets/JsonFileTarget.js +44 -0
- package/lib/cjs/targets/JsonFileTarget.js.map +1 -0
- package/lib/cjs/targets/JsonTarget.d.ts +27 -0
- package/lib/cjs/targets/JsonTarget.d.ts.map +1 -0
- package/lib/cjs/targets/JsonTarget.js +46 -0
- package/lib/cjs/targets/JsonTarget.js.map +1 -0
- package/lib/cjs/targets/MemoryTarget.d.ts +33 -0
- package/lib/cjs/targets/MemoryTarget.d.ts.map +1 -0
- package/lib/cjs/targets/MemoryTarget.js +63 -0
- package/lib/cjs/targets/MemoryTarget.js.map +1 -0
- package/lib/cjs/targets/index.d.ts +7 -0
- package/lib/cjs/targets/index.d.ts.map +1 -1
- package/lib/cjs/targets/index.js +7 -0
- package/lib/cjs/targets/index.js.map +1 -1
- package/lib/cjs/targets/wrappers/AutoFlushTarget.d.ts +37 -0
- package/lib/cjs/targets/wrappers/AutoFlushTarget.d.ts.map +1 -0
- package/lib/cjs/targets/wrappers/AutoFlushTarget.js +48 -0
- package/lib/cjs/targets/wrappers/AutoFlushTarget.js.map +1 -0
- package/lib/cjs/targets/wrappers/FallbackGroupTarget.d.ts +45 -0
- package/lib/cjs/targets/wrappers/FallbackGroupTarget.d.ts.map +1 -0
- package/lib/cjs/targets/wrappers/FallbackGroupTarget.js +94 -0
- package/lib/cjs/targets/wrappers/FallbackGroupTarget.js.map +1 -0
- package/lib/cjs/targets/wrappers/RetryingTarget.d.ts +44 -0
- package/lib/cjs/targets/wrappers/RetryingTarget.d.ts.map +1 -0
- package/lib/cjs/targets/wrappers/RetryingTarget.js +61 -0
- package/lib/cjs/targets/wrappers/RetryingTarget.js.map +1 -0
- package/lib/cjs/targets/wrappers/SplitGroupTarget.d.ts +30 -0
- package/lib/cjs/targets/wrappers/SplitGroupTarget.d.ts.map +1 -0
- package/lib/cjs/targets/wrappers/SplitGroupTarget.js +52 -0
- package/lib/cjs/targets/wrappers/SplitGroupTarget.js.map +1 -0
- package/lib/cjs/traceparent.d.ts +63 -0
- package/lib/cjs/traceparent.d.ts.map +1 -0
- package/lib/cjs/traceparent.js +107 -0
- package/lib/cjs/traceparent.js.map +1 -0
- package/lib/mjs/archive/LogArchiveService.d.ts +75 -0
- package/lib/mjs/archive/LogArchiveService.d.ts.map +1 -0
- package/lib/mjs/archive/LogArchiveService.js +186 -0
- package/lib/mjs/archive/LogArchiveService.js.map +1 -0
- package/lib/mjs/archive/archive-strategy.d.ts +32 -0
- package/lib/mjs/archive/archive-strategy.d.ts.map +1 -0
- package/lib/mjs/archive/archive-strategy.js +39 -0
- package/lib/mjs/archive/archive-strategy.js.map +1 -0
- package/lib/mjs/archive/context.d.ts +50 -0
- package/lib/mjs/archive/context.d.ts.map +1 -0
- package/lib/mjs/archive/context.js +2 -0
- package/lib/mjs/archive/context.js.map +1 -0
- package/lib/mjs/archive/index.d.ts +10 -0
- package/lib/mjs/archive/index.d.ts.map +1 -0
- package/lib/mjs/archive/index.js +10 -0
- package/lib/mjs/archive/index.js.map +1 -0
- package/lib/mjs/archive/retention-strategy.d.ts +26 -0
- package/lib/mjs/archive/retention-strategy.d.ts.map +1 -0
- package/lib/mjs/archive/retention-strategy.js +38 -0
- package/lib/mjs/archive/retention-strategy.js.map +1 -0
- package/lib/mjs/archive/strategies/AgeLogRetentionStrategy.d.ts +10 -0
- package/lib/mjs/archive/strategies/AgeLogRetentionStrategy.d.ts.map +1 -0
- package/lib/mjs/archive/strategies/AgeLogRetentionStrategy.js +43 -0
- package/lib/mjs/archive/strategies/AgeLogRetentionStrategy.js.map +1 -0
- package/lib/mjs/archive/strategies/CountLogRetentionStrategy.d.ts +10 -0
- package/lib/mjs/archive/strategies/CountLogRetentionStrategy.d.ts.map +1 -0
- package/lib/mjs/archive/strategies/CountLogRetentionStrategy.js +39 -0
- package/lib/mjs/archive/strategies/CountLogRetentionStrategy.js.map +1 -0
- package/lib/mjs/archive/strategies/CronLogArchiveStrategy.d.ts +15 -0
- package/lib/mjs/archive/strategies/CronLogArchiveStrategy.d.ts.map +1 -0
- package/lib/mjs/archive/strategies/CronLogArchiveStrategy.js +49 -0
- package/lib/mjs/archive/strategies/CronLogArchiveStrategy.js.map +1 -0
- package/lib/mjs/archive/strategies/SizeLogArchiveStrategy.d.ts +18 -0
- package/lib/mjs/archive/strategies/SizeLogArchiveStrategy.d.ts.map +1 -0
- package/lib/mjs/archive/strategies/SizeLogArchiveStrategy.js +60 -0
- package/lib/mjs/archive/strategies/SizeLogArchiveStrategy.js.map +1 -0
- package/lib/mjs/archive/strategies/util.d.ts +28 -0
- package/lib/mjs/archive/strategies/util.d.ts.map +1 -0
- package/lib/mjs/archive/strategies/util.js +54 -0
- package/lib/mjs/archive/strategies/util.js.map +1 -0
- package/lib/mjs/bootstrap.d.ts.map +1 -1
- package/lib/mjs/bootstrap.js +25 -2
- package/lib/mjs/bootstrap.js.map +1 -1
- package/lib/mjs/callsite.d.ts +26 -0
- package/lib/mjs/callsite.d.ts.map +1 -0
- package/lib/mjs/callsite.js +57 -0
- package/lib/mjs/callsite.js.map +1 -0
- package/lib/mjs/config/log.d.ts +96 -0
- package/lib/mjs/config/log.d.ts.map +1 -0
- package/lib/mjs/config/log.js +72 -0
- package/lib/mjs/config/log.js.map +1 -0
- package/lib/mjs/context.browser.d.ts +46 -0
- package/lib/mjs/context.browser.d.ts.map +1 -0
- package/lib/mjs/context.browser.js +81 -0
- package/lib/mjs/context.browser.js.map +1 -0
- package/lib/mjs/context.d.ts +61 -0
- package/lib/mjs/context.d.ts.map +1 -0
- package/lib/mjs/context.js +88 -0
- package/lib/mjs/context.js.map +1 -0
- package/lib/mjs/filters/LevelFilter.d.ts +24 -0
- package/lib/mjs/filters/LevelFilter.d.ts.map +1 -0
- package/lib/mjs/filters/LevelFilter.js +36 -0
- package/lib/mjs/filters/LevelFilter.js.map +1 -0
- package/lib/mjs/filters/MatchFilter.d.ts +30 -0
- package/lib/mjs/filters/MatchFilter.d.ts.map +1 -0
- package/lib/mjs/filters/MatchFilter.js +62 -0
- package/lib/mjs/filters/MatchFilter.js.map +1 -0
- package/lib/mjs/filters/RateLimitFilter.d.ts +37 -0
- package/lib/mjs/filters/RateLimitFilter.d.ts.map +1 -0
- package/lib/mjs/filters/RateLimitFilter.js +67 -0
- package/lib/mjs/filters/RateLimitFilter.js.map +1 -0
- package/lib/mjs/filters/index.d.ts +4 -0
- package/lib/mjs/filters/index.d.ts.map +1 -0
- package/lib/mjs/filters/index.js +4 -0
- package/lib/mjs/filters/index.js.map +1 -0
- package/lib/mjs/index.browser.d.ts +14 -0
- package/lib/mjs/index.browser.d.ts.map +1 -0
- package/lib/mjs/index.browser.js +30 -0
- package/lib/mjs/index.browser.js.map +1 -0
- package/lib/mjs/index.d.ts +8 -0
- package/lib/mjs/index.d.ts.map +1 -1
- package/lib/mjs/index.js +8 -0
- package/lib/mjs/index.js.map +1 -1
- package/lib/mjs/log.d.ts +60 -1
- package/lib/mjs/log.d.ts.map +1 -1
- package/lib/mjs/log.js +295 -33
- package/lib/mjs/log.js.map +1 -1
- package/lib/mjs/perf/LogMetricSink.d.ts +55 -0
- package/lib/mjs/perf/LogMetricSink.d.ts.map +1 -0
- package/lib/mjs/perf/LogMetricSink.js +151 -0
- package/lib/mjs/perf/LogMetricSink.js.map +1 -0
- package/lib/mjs/perf/measure.d.ts +9 -0
- package/lib/mjs/perf/measure.d.ts.map +1 -0
- package/lib/mjs/perf/measure.js +18 -0
- package/lib/mjs/perf/measure.js.map +1 -0
- package/lib/mjs/perf.d.ts +9 -0
- package/lib/mjs/perf.d.ts.map +1 -0
- package/lib/mjs/perf.js +15 -0
- package/lib/mjs/perf.js.map +1 -0
- package/lib/mjs/schemas/log.configuration.d.ts +151 -18
- package/lib/mjs/schemas/log.configuration.d.ts.map +1 -1
- package/lib/mjs/schemas/log.configuration.js +154 -21
- package/lib/mjs/schemas/log.configuration.js.map +1 -1
- package/lib/mjs/targets/BrowserConsoleTarget.d.ts +48 -0
- package/lib/mjs/targets/BrowserConsoleTarget.d.ts.map +1 -0
- package/lib/mjs/targets/BrowserConsoleTarget.js +45 -0
- package/lib/mjs/targets/BrowserConsoleTarget.js.map +1 -0
- package/lib/mjs/targets/ColoredConsoleTarget.d.ts.map +1 -1
- package/lib/mjs/targets/ColoredConsoleTarget.js +21 -9
- package/lib/mjs/targets/ColoredConsoleTarget.js.map +1 -1
- package/lib/mjs/targets/FileTarget.d.ts +96 -20
- package/lib/mjs/targets/FileTarget.d.ts.map +1 -1
- package/lib/mjs/targets/FileTarget.js +191 -192
- package/lib/mjs/targets/FileTarget.js.map +1 -1
- package/lib/mjs/targets/JsonFileTarget.d.ts +19 -0
- package/lib/mjs/targets/JsonFileTarget.d.ts.map +1 -0
- package/lib/mjs/targets/JsonFileTarget.js +41 -0
- package/lib/mjs/targets/JsonFileTarget.js.map +1 -0
- package/lib/mjs/targets/JsonTarget.d.ts +27 -0
- package/lib/mjs/targets/JsonTarget.d.ts.map +1 -0
- package/lib/mjs/targets/JsonTarget.js +43 -0
- package/lib/mjs/targets/JsonTarget.js.map +1 -0
- package/lib/mjs/targets/MemoryTarget.d.ts +33 -0
- package/lib/mjs/targets/MemoryTarget.d.ts.map +1 -0
- package/lib/mjs/targets/MemoryTarget.js +60 -0
- package/lib/mjs/targets/MemoryTarget.js.map +1 -0
- package/lib/mjs/targets/index.d.ts +7 -0
- package/lib/mjs/targets/index.d.ts.map +1 -1
- package/lib/mjs/targets/index.js +7 -0
- package/lib/mjs/targets/index.js.map +1 -1
- package/lib/mjs/targets/wrappers/AutoFlushTarget.d.ts +37 -0
- package/lib/mjs/targets/wrappers/AutoFlushTarget.d.ts.map +1 -0
- package/lib/mjs/targets/wrappers/AutoFlushTarget.js +45 -0
- package/lib/mjs/targets/wrappers/AutoFlushTarget.js.map +1 -0
- package/lib/mjs/targets/wrappers/FallbackGroupTarget.d.ts +45 -0
- package/lib/mjs/targets/wrappers/FallbackGroupTarget.d.ts.map +1 -0
- package/lib/mjs/targets/wrappers/FallbackGroupTarget.js +91 -0
- package/lib/mjs/targets/wrappers/FallbackGroupTarget.js.map +1 -0
- package/lib/mjs/targets/wrappers/RetryingTarget.d.ts +44 -0
- package/lib/mjs/targets/wrappers/RetryingTarget.d.ts.map +1 -0
- package/lib/mjs/targets/wrappers/RetryingTarget.js +58 -0
- package/lib/mjs/targets/wrappers/RetryingTarget.js.map +1 -0
- package/lib/mjs/targets/wrappers/SplitGroupTarget.d.ts +30 -0
- package/lib/mjs/targets/wrappers/SplitGroupTarget.d.ts.map +1 -0
- package/lib/mjs/targets/wrappers/SplitGroupTarget.js +49 -0
- package/lib/mjs/targets/wrappers/SplitGroupTarget.js.map +1 -0
- package/lib/mjs/traceparent.d.ts +63 -0
- package/lib/mjs/traceparent.d.ts.map +1 -0
- package/lib/mjs/traceparent.js +100 -0
- package/lib/mjs/traceparent.js.map +1 -0
- package/lib/tsconfig.cjs.tsbuildinfo +1 -1
- package/lib/tsconfig.mjs.tsbuildinfo +1 -1
- package/package.json +26 -15
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.SplitGroupTarget = void 0;
|
|
10
|
+
const log_common_1 = require("@spinajs/log-common");
|
|
11
|
+
const di_1 = require("@spinajs/di");
|
|
12
|
+
/**
|
|
13
|
+
* Fan-out wrapper: one configured target name that writes every entry to MANY
|
|
14
|
+
* inner targets. The inner targets are declared inline under `options.targets`
|
|
15
|
+
* and are owned by this wrapper ( they are NOT part of the logger's Targets
|
|
16
|
+
* list ), so the wrapper resolves, flushes and disposes them.
|
|
17
|
+
*
|
|
18
|
+
* Pure / browser-safe - just delegates to its children.
|
|
19
|
+
*/
|
|
20
|
+
let SplitGroupTarget = class SplitGroupTarget extends log_common_1.LogTarget {
|
|
21
|
+
constructor() {
|
|
22
|
+
super(...arguments);
|
|
23
|
+
this.Inner = [];
|
|
24
|
+
}
|
|
25
|
+
resolve() {
|
|
26
|
+
// resolve each child via DI exactly like FrameworkLogger.resolveLogTargets
|
|
27
|
+
// does - the child's ITargetsOption is passed as the single ctor arg.
|
|
28
|
+
this.Inner = this.Options.options.targets.map((t) => di_1.DI.resolve(t.type, [t]));
|
|
29
|
+
super.resolve();
|
|
30
|
+
}
|
|
31
|
+
write(entry) {
|
|
32
|
+
if (!this.Options.enabled) {
|
|
33
|
+
return Promise.resolve();
|
|
34
|
+
}
|
|
35
|
+
// wrap in Promise.resolve because some targets' write is sync / void.
|
|
36
|
+
return Promise.allSettled(this.Inner.map((t) => Promise.resolve(t.write(entry)))).then(() => undefined);
|
|
37
|
+
}
|
|
38
|
+
forceFlush() {
|
|
39
|
+
return Promise.allSettled(this.Inner.map((t) => t.forceFlush())).then(() => undefined);
|
|
40
|
+
}
|
|
41
|
+
async dispose() {
|
|
42
|
+
// the wrapper owns its children ( they are not in the logger's Targets list )
|
|
43
|
+
// so it drives their teardown.
|
|
44
|
+
await Promise.allSettled(this.Inner.map((t) => t.dispose?.()));
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
exports.SplitGroupTarget = SplitGroupTarget;
|
|
48
|
+
exports.SplitGroupTarget = SplitGroupTarget = __decorate([
|
|
49
|
+
(0, di_1.Singleton)(),
|
|
50
|
+
(0, di_1.Injectable)("SplitGroupTarget")
|
|
51
|
+
], SplitGroupTarget);
|
|
52
|
+
//# sourceMappingURL=SplitGroupTarget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SplitGroupTarget.js","sourceRoot":"","sources":["../../../../src/targets/wrappers/SplitGroupTarget.ts"],"names":[],"mappings":";;;;;;;;;AAAA,oDAAiG;AACjG,oCAAwD;AAgBxD;;;;;;;GAOG;AAGI,IAAM,gBAAgB,GAAtB,MAAM,gBAAiB,SAAQ,sBAAmC;IAAlE;;QACK,UAAK,GAAsC,EAAE,CAAC;IA4B1D,CAAC;IA1BQ,OAAO;QACZ,2EAA2E;QAC3E,sEAAsE;QACtE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAE,CAAC,OAAO,CAAkC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAE/G,KAAK,CAAC,OAAO,EAAE,CAAC;IAClB,CAAC;IAEM,KAAK,CAAC,KAAgB;QAC3B,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YAC1B,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;QAC3B,CAAC;QAED,sEAAsE;QACtE,OAAO,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAC1G,CAAC;IAEM,UAAU;QACf,OAAO,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IACzF,CAAC;IAEM,KAAK,CAAC,OAAO;QAClB,8EAA8E;QAC9E,+BAA+B;QAC/B,MAAM,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAE,CAAS,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;IAC1E,CAAC;CACF,CAAA;AA7BY,4CAAgB;2BAAhB,gBAAgB;IAF5B,IAAA,cAAS,GAAE;IACX,IAAA,eAAU,EAAC,kBAAkB,CAAC;GAClB,gBAAgB,CA6B5B"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* W3C Trace Context ( traceparent ) utilities.
|
|
3
|
+
*
|
|
4
|
+
* Pure, dependency-free and cross-platform ( Node 20+ and browsers ) — randomness
|
|
5
|
+
* is sourced from the WHATWG `crypto.getRandomValues`, available on `globalThis`
|
|
6
|
+
* in both environments, so this module deliberately does NOT import
|
|
7
|
+
* `node:crypto` and stays safe to bundle for the browser.
|
|
8
|
+
*
|
|
9
|
+
* A W3C `traceparent` header has the shape:
|
|
10
|
+
*
|
|
11
|
+
* version "-" trace-id "-" parent-id "-" trace-flags
|
|
12
|
+
* 00 - 32 hex - 16 hex - 2 hex
|
|
13
|
+
*
|
|
14
|
+
* See https://www.w3.org/TR/trace-context/#traceparent-header.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Minimal trace context this service carries on the ambient store and emits on
|
|
18
|
+
* the outbound `traceparent` header.
|
|
19
|
+
*/
|
|
20
|
+
export interface ITraceContext {
|
|
21
|
+
/** 32-hex-char trace id, shared by every span across services in one trace. */
|
|
22
|
+
traceId: string;
|
|
23
|
+
/** 16-hex-char span id identifying this service's span within the trace. */
|
|
24
|
+
spanId: string;
|
|
25
|
+
/** Whether the trace is sampled ( low bit of the trace-flags ). */
|
|
26
|
+
sampled: boolean;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Parse & validate an inbound `traceparent` header value.
|
|
30
|
+
*
|
|
31
|
+
* @returns the decomposed parts ( plus the derived `sampled` flag ), or `null`
|
|
32
|
+
* when the value is missing / malformed / forbidden by the spec
|
|
33
|
+
* ( all-zero trace-id, all-zero parent-id, or version `ff` ).
|
|
34
|
+
*/
|
|
35
|
+
export declare function parseTraceparent(value: string | undefined | null): {
|
|
36
|
+
version: string;
|
|
37
|
+
traceId: string;
|
|
38
|
+
parentId: string;
|
|
39
|
+
flags: string;
|
|
40
|
+
sampled: boolean;
|
|
41
|
+
} | null;
|
|
42
|
+
/**
|
|
43
|
+
* A fresh random trace id ( 16 bytes -> 32 lowercase hex chars ).
|
|
44
|
+
*/
|
|
45
|
+
export declare function randomTraceId(): string;
|
|
46
|
+
/**
|
|
47
|
+
* A fresh random span id ( 8 bytes -> 16 lowercase hex chars ).
|
|
48
|
+
*/
|
|
49
|
+
export declare function randomSpanId(): string;
|
|
50
|
+
/**
|
|
51
|
+
* Render a {@link ITraceContext} as a W3C `traceparent` header value.
|
|
52
|
+
*/
|
|
53
|
+
export declare function formatTraceparent(ctx: ITraceContext): string;
|
|
54
|
+
/**
|
|
55
|
+
* Derive this service's trace context for a request.
|
|
56
|
+
*
|
|
57
|
+
* When `inboundTraceparent` is a valid header we CONTINUE the trace: the trace
|
|
58
|
+
* id and sampled decision are inherited, and a fresh span id is minted for this
|
|
59
|
+
* service's own span ( its parent being the inbound `parent-id` ). Otherwise a
|
|
60
|
+
* brand-new, sampled trace is STARTED.
|
|
61
|
+
*/
|
|
62
|
+
export declare function newTraceContext(inboundTraceparent?: string | null): ITraceContext;
|
|
63
|
+
//# sourceMappingURL=traceparent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"traceparent.d.ts","sourceRoot":"","sources":["../../src/traceparent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,+EAA+E;IAC/E,OAAO,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,OAAO,EAAE,OAAO,CAAC;CAClB;AAMD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAwBjK;AAgBD;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAE5D;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,aAAa,CAejF"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* W3C Trace Context ( traceparent ) utilities.
|
|
4
|
+
*
|
|
5
|
+
* Pure, dependency-free and cross-platform ( Node 20+ and browsers ) — randomness
|
|
6
|
+
* is sourced from the WHATWG `crypto.getRandomValues`, available on `globalThis`
|
|
7
|
+
* in both environments, so this module deliberately does NOT import
|
|
8
|
+
* `node:crypto` and stays safe to bundle for the browser.
|
|
9
|
+
*
|
|
10
|
+
* A W3C `traceparent` header has the shape:
|
|
11
|
+
*
|
|
12
|
+
* version "-" trace-id "-" parent-id "-" trace-flags
|
|
13
|
+
* 00 - 32 hex - 16 hex - 2 hex
|
|
14
|
+
*
|
|
15
|
+
* See https://www.w3.org/TR/trace-context/#traceparent-header.
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.parseTraceparent = parseTraceparent;
|
|
19
|
+
exports.randomTraceId = randomTraceId;
|
|
20
|
+
exports.randomSpanId = randomSpanId;
|
|
21
|
+
exports.formatTraceparent = formatTraceparent;
|
|
22
|
+
exports.newTraceContext = newTraceContext;
|
|
23
|
+
const TRACEPARENT_RE = /^([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/;
|
|
24
|
+
const ZERO_TRACE_ID = "00000000000000000000000000000000";
|
|
25
|
+
const ZERO_SPAN_ID = "0000000000000000";
|
|
26
|
+
/**
|
|
27
|
+
* Parse & validate an inbound `traceparent` header value.
|
|
28
|
+
*
|
|
29
|
+
* @returns the decomposed parts ( plus the derived `sampled` flag ), or `null`
|
|
30
|
+
* when the value is missing / malformed / forbidden by the spec
|
|
31
|
+
* ( all-zero trace-id, all-zero parent-id, or version `ff` ).
|
|
32
|
+
*/
|
|
33
|
+
function parseTraceparent(value) {
|
|
34
|
+
if (!value) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
const match = TRACEPARENT_RE.exec(value.toLowerCase());
|
|
38
|
+
if (!match) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
const [, version, traceId, parentId, flags] = match;
|
|
42
|
+
// Spec-forbidden values: version ff is reserved, and all-zero ids are invalid.
|
|
43
|
+
if (version === "ff" || traceId === ZERO_TRACE_ID || parentId === ZERO_SPAN_ID) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
version,
|
|
48
|
+
traceId,
|
|
49
|
+
parentId,
|
|
50
|
+
flags,
|
|
51
|
+
sampled: (parseInt(flags, 16) & 0x01) === 1,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Cross-platform `n` random bytes rendered as lowercase hex.
|
|
56
|
+
*/
|
|
57
|
+
function randomHex(bytes) {
|
|
58
|
+
const buffer = new Uint8Array(bytes);
|
|
59
|
+
globalThis.crypto.getRandomValues(buffer);
|
|
60
|
+
let out = "";
|
|
61
|
+
for (const b of buffer) {
|
|
62
|
+
out += b.toString(16).padStart(2, "0");
|
|
63
|
+
}
|
|
64
|
+
return out;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* A fresh random trace id ( 16 bytes -> 32 lowercase hex chars ).
|
|
68
|
+
*/
|
|
69
|
+
function randomTraceId() {
|
|
70
|
+
return randomHex(16);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* A fresh random span id ( 8 bytes -> 16 lowercase hex chars ).
|
|
74
|
+
*/
|
|
75
|
+
function randomSpanId() {
|
|
76
|
+
return randomHex(8);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Render a {@link ITraceContext} as a W3C `traceparent` header value.
|
|
80
|
+
*/
|
|
81
|
+
function formatTraceparent(ctx) {
|
|
82
|
+
return `00-${ctx.traceId}-${ctx.spanId}-${ctx.sampled ? "01" : "00"}`;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Derive this service's trace context for a request.
|
|
86
|
+
*
|
|
87
|
+
* When `inboundTraceparent` is a valid header we CONTINUE the trace: the trace
|
|
88
|
+
* id and sampled decision are inherited, and a fresh span id is minted for this
|
|
89
|
+
* service's own span ( its parent being the inbound `parent-id` ). Otherwise a
|
|
90
|
+
* brand-new, sampled trace is STARTED.
|
|
91
|
+
*/
|
|
92
|
+
function newTraceContext(inboundTraceparent) {
|
|
93
|
+
const parsed = parseTraceparent(inboundTraceparent);
|
|
94
|
+
if (parsed) {
|
|
95
|
+
return {
|
|
96
|
+
traceId: parsed.traceId,
|
|
97
|
+
spanId: randomSpanId(),
|
|
98
|
+
sampled: parsed.sampled,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
traceId: randomTraceId(),
|
|
103
|
+
spanId: randomSpanId(),
|
|
104
|
+
sampled: true,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=traceparent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"traceparent.js","sourceRoot":"","sources":["../../src/traceparent.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;AA0BH,4CAwBC;AAmBD,sCAEC;AAKD,oCAEC;AAKD,8CAEC;AAUD,0CAeC;AA/FD,MAAM,cAAc,GAAG,6DAA6D,CAAC;AACrF,MAAM,aAAa,GAAG,kCAAkC,CAAC;AACzD,MAAM,YAAY,GAAG,kBAAkB,CAAC;AAExC;;;;;;GAMG;AACH,SAAgB,gBAAgB,CAAC,KAAgC;IAC/D,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;IACvD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC;IAEpD,+EAA+E;IAC/E,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,aAAa,IAAI,QAAQ,KAAK,YAAY,EAAE,CAAC;QAC/E,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO;QACL,OAAO;QACP,OAAO;QACP,QAAQ;QACR,KAAK;QACL,OAAO,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;KAC5C,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,SAAS,CAAC,KAAa;IAC9B,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;IACrC,UAAU,CAAC,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;IAE1C,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,GAAG,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;GAEG;AACH,SAAgB,aAAa;IAC3B,OAAO,SAAS,CAAC,EAAE,CAAC,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,SAAgB,YAAY;IAC1B,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,SAAgB,iBAAiB,CAAC,GAAkB;IAClD,OAAO,MAAM,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;AACxE,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,eAAe,CAAC,kBAAkC;IAChE,MAAM,MAAM,GAAG,gBAAgB,CAAC,kBAAkB,CAAC,CAAC;IACpD,IAAI,MAAM,EAAE,CAAC;QACX,OAAO;YACL,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,MAAM,EAAE,YAAY,EAAE;YACtB,OAAO,EAAE,MAAM,CAAC,OAAO;SACxB,CAAC;IACJ,CAAC;IAED,OAAO;QACL,OAAO,EAAE,aAAa,EAAE;QACxB,MAAM,EAAE,YAAY,EAAE;QACtB,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { AsyncService, Class } from "@spinajs/di";
|
|
2
|
+
import { Log } from "@spinajs/log-common";
|
|
3
|
+
import { LogArchiveStrategy } from "./archive-strategy.js";
|
|
4
|
+
import { LogRetentionStrategy } from "./retention-strategy.js";
|
|
5
|
+
import { ILogArchiveContext } from "./context.js";
|
|
6
|
+
/**
|
|
7
|
+
* Orchestrates rotation + retention for a single file log target.
|
|
8
|
+
*
|
|
9
|
+
* It owns nothing schedule-wise itself: it resolves ONE rotation strategy
|
|
10
|
+
* ( `archiveStrategy` ) and a LIST of retention strategies
|
|
11
|
+
* ( `retentionStrategies` ) by class name from DI, delegates start / stop to the
|
|
12
|
+
* rotation strategy, and provides the shared `rotate()` routine every rotation
|
|
13
|
+
* ( interval, cron or manual ) funnels through.
|
|
14
|
+
*
|
|
15
|
+
* `@NewInstance()` - each file target gets its own service ( per-target
|
|
16
|
+
* scheduling and strategy state ).
|
|
17
|
+
*/
|
|
18
|
+
export declare class LogArchiveService extends AsyncService {
|
|
19
|
+
protected Logger: Log;
|
|
20
|
+
protected ArchiveStrategy: LogArchiveStrategy;
|
|
21
|
+
protected RetentionStrategies: LogRetentionStrategy[];
|
|
22
|
+
/**
|
|
23
|
+
* Resolves the configured rotation + retention strategies by class name.
|
|
24
|
+
* Follows the fs temp-provider mechanism: look the class up in the DI
|
|
25
|
+
* registry by name, then resolve an instance.
|
|
26
|
+
*/
|
|
27
|
+
resolve(): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Wires strategies for the given context and starts the rotation schedule.
|
|
30
|
+
*/
|
|
31
|
+
start(ctx: ILogArchiveContext): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Stops the rotation schedule. Safe to call multiple times.
|
|
34
|
+
*/
|
|
35
|
+
stop(): void;
|
|
36
|
+
/**
|
|
37
|
+
* Single rotation routine, shared by every scheduling strategy:
|
|
38
|
+
*
|
|
39
|
+
* 1. acquire the target write-lock so no append runs while we rename,
|
|
40
|
+
* 2. rename the active file to a sequenced archive name in the archive dir,
|
|
41
|
+
* 3. compress ( zip into archiveFs, drop the raw file ) OR move cross-fs,
|
|
42
|
+
* 4. run every retention strategy in order,
|
|
43
|
+
* 5. release the lock ( always, even on failure ).
|
|
44
|
+
*
|
|
45
|
+
* The whole routine is guarded so a failed rotation neither crashes the
|
|
46
|
+
* scheduler nor leaves the lock held.
|
|
47
|
+
*/
|
|
48
|
+
rotate(ctx: ILogArchiveContext): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Renames the active log file into the archive dir under a unique
|
|
51
|
+
* `archived_<name>_<seq><ext>` name. When `archiveFs` differs from `fs` the
|
|
52
|
+
* file is first renamed within `fs` then moved across.
|
|
53
|
+
*
|
|
54
|
+
* Returns the archive path relative to `archiveFs`.
|
|
55
|
+
*/
|
|
56
|
+
protected moveToArchive(ctx: ILogArchiveContext): Promise<string>;
|
|
57
|
+
/**
|
|
58
|
+
* Zips `archived` into `archiveFs` and removes the raw archived file, so the
|
|
59
|
+
* archive dir only ever holds the compressed copy.
|
|
60
|
+
*/
|
|
61
|
+
protected compress(ctx: ILogArchiveContext, archived: string): Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* Next archive sequence number for a given base name. Uses existing archive
|
|
64
|
+
* file names first, falling back to a timestamp so two rotations in the same
|
|
65
|
+
* tick never collide.
|
|
66
|
+
*/
|
|
67
|
+
protected nextSequence(ctx: ILogArchiveContext, name: string, ext: string): Promise<number>;
|
|
68
|
+
/**
|
|
69
|
+
* Resolves a strategy instance by class name, mirroring the fs temp-provider
|
|
70
|
+
* mechanism: look the class up in the DI registry by name, then resolve an
|
|
71
|
+
* instance ( `@NewInstance()` gives a fresh per-target instance ).
|
|
72
|
+
*/
|
|
73
|
+
protected resolveStrategy<T>(base: Class<T>, className: string): T;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=LogArchiveService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LogArchiveService.d.ts","sourceRoot":"","sources":["../../../src/archive/LogArchiveService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,EAAiD,MAAM,aAAa,CAAC;AACjG,OAAO,EAAU,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAGlD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAGlD;;;;;;;;;;;GAWG;AACH,qBAEa,iBAAkB,SAAQ,YAAY;IAEjD,SAAS,CAAC,MAAM,EAAE,GAAG,CAAC;IAEtB,SAAS,CAAC,eAAe,EAAE,kBAAkB,CAAC;IAC9C,SAAS,CAAC,mBAAmB,EAAE,oBAAoB,EAAE,CAAM;IAE3D;;;;OAIG;IACU,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrC;;OAEG;IACU,KAAK,CAAC,GAAG,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAY1D;;OAEG;IACI,IAAI,IAAI,IAAI;IAInB;;;;;;;;;;;OAWG;IACU,MAAM,CAAC,GAAG,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAqB3D;;;;;;OAMG;cACa,aAAa,CAAC,GAAG,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC;IAkBvE;;;OAGG;cACa,QAAQ,CAAC,GAAG,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUlF;;;;OAIG;cACa,YAAY,CAAC,GAAG,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAoCjG;;;;OAIG;IACH,SAAS,CAAC,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,GAAG,CAAC;CAcnE"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { AsyncService, DI, Injectable, NewInstance, ResolveException } from "@spinajs/di";
|
|
11
|
+
import { Logger, Log } from "@spinajs/log-common";
|
|
12
|
+
import { DateTime } from "luxon";
|
|
13
|
+
import { parse, posix } from "path";
|
|
14
|
+
import { LogArchiveStrategy } from "./archive-strategy.js";
|
|
15
|
+
import { LogRetentionStrategy } from "./retention-strategy.js";
|
|
16
|
+
import { ARCHIVE_PREFIX, archivePath } from "./strategies/util.js";
|
|
17
|
+
/**
|
|
18
|
+
* Orchestrates rotation + retention for a single file log target.
|
|
19
|
+
*
|
|
20
|
+
* It owns nothing schedule-wise itself: it resolves ONE rotation strategy
|
|
21
|
+
* ( `archiveStrategy` ) and a LIST of retention strategies
|
|
22
|
+
* ( `retentionStrategies` ) by class name from DI, delegates start / stop to the
|
|
23
|
+
* rotation strategy, and provides the shared `rotate()` routine every rotation
|
|
24
|
+
* ( interval, cron or manual ) funnels through.
|
|
25
|
+
*
|
|
26
|
+
* `@NewInstance()` - each file target gets its own service ( per-target
|
|
27
|
+
* scheduling and strategy state ).
|
|
28
|
+
*/
|
|
29
|
+
let LogArchiveService = class LogArchiveService extends AsyncService {
|
|
30
|
+
constructor() {
|
|
31
|
+
super(...arguments);
|
|
32
|
+
this.RetentionStrategies = [];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Resolves the configured rotation + retention strategies by class name.
|
|
36
|
+
* Follows the fs temp-provider mechanism: look the class up in the DI
|
|
37
|
+
* registry by name, then resolve an instance.
|
|
38
|
+
*/
|
|
39
|
+
async resolve() {
|
|
40
|
+
await super.resolve();
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Wires strategies for the given context and starts the rotation schedule.
|
|
44
|
+
*/
|
|
45
|
+
async start(ctx) {
|
|
46
|
+
// archiveStrategy / retentionStrategies are populated from the logger.file
|
|
47
|
+
// config defaults ( see FileTarget.resolve ), so no inline fallback here -
|
|
48
|
+
// the config is the single source of truth for what runs.
|
|
49
|
+
this.ArchiveStrategy = this.resolveStrategy(LogArchiveStrategy, ctx.options.archiveStrategy);
|
|
50
|
+
const retentionNames = ctx.options.retentionStrategies ?? [];
|
|
51
|
+
this.RetentionStrategies = retentionNames.map((n) => this.resolveStrategy(LogRetentionStrategy, n));
|
|
52
|
+
this.ArchiveStrategy.start(ctx);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Stops the rotation schedule. Safe to call multiple times.
|
|
56
|
+
*/
|
|
57
|
+
stop() {
|
|
58
|
+
this.ArchiveStrategy?.stop();
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Single rotation routine, shared by every scheduling strategy:
|
|
62
|
+
*
|
|
63
|
+
* 1. acquire the target write-lock so no append runs while we rename,
|
|
64
|
+
* 2. rename the active file to a sequenced archive name in the archive dir,
|
|
65
|
+
* 3. compress ( zip into archiveFs, drop the raw file ) OR move cross-fs,
|
|
66
|
+
* 4. run every retention strategy in order,
|
|
67
|
+
* 5. release the lock ( always, even on failure ).
|
|
68
|
+
*
|
|
69
|
+
* The whole routine is guarded so a failed rotation neither crashes the
|
|
70
|
+
* scheduler nor leaves the lock held.
|
|
71
|
+
*/
|
|
72
|
+
async rotate(ctx) {
|
|
73
|
+
await ctx.withWriteLock(async () => {
|
|
74
|
+
// nothing written yet - nothing to rotate
|
|
75
|
+
if (!(await ctx.fs.exists(ctx.activePath))) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const archived = await this.moveToArchive(ctx);
|
|
79
|
+
if (ctx.options.compress) {
|
|
80
|
+
await this.compress(ctx, archived);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
// retention runs OUTSIDE the write-lock - it only touches archive files,
|
|
84
|
+
// never the active log, so it must not block appends.
|
|
85
|
+
for (const strategy of this.RetentionStrategies) {
|
|
86
|
+
await strategy.safePrune(ctx);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Renames the active log file into the archive dir under a unique
|
|
91
|
+
* `archived_<name>_<seq><ext>` name. When `archiveFs` differs from `fs` the
|
|
92
|
+
* file is first renamed within `fs` then moved across.
|
|
93
|
+
*
|
|
94
|
+
* Returns the archive path relative to `archiveFs`.
|
|
95
|
+
*/
|
|
96
|
+
async moveToArchive(ctx) {
|
|
97
|
+
const { name, ext } = parse(posix.basename(ctx.activePath.replace(/\\/g, "/")));
|
|
98
|
+
const seq = await this.nextSequence(ctx, name, ext);
|
|
99
|
+
const archiveName = `${ARCHIVE_PREFIX}${name}_${seq}${ext}`;
|
|
100
|
+
const archiveRel = archivePath(ctx, archiveName);
|
|
101
|
+
if (ctx.archiveFs === ctx.fs) {
|
|
102
|
+
await ctx.fs.rename(ctx.activePath, archiveRel);
|
|
103
|
+
return archiveRel;
|
|
104
|
+
}
|
|
105
|
+
// cross-fs: rename to a temp name inside `fs`, then move into archiveFs
|
|
106
|
+
const stagingRel = `${ARCHIVE_PREFIX}${name}_${seq}${ext}`;
|
|
107
|
+
await ctx.fs.rename(ctx.activePath, stagingRel);
|
|
108
|
+
await ctx.fs.move(stagingRel, archiveRel, ctx.archiveFs);
|
|
109
|
+
return archiveRel;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Zips `archived` into `archiveFs` and removes the raw archived file, so the
|
|
113
|
+
* archive dir only ever holds the compressed copy.
|
|
114
|
+
*/
|
|
115
|
+
async compress(ctx, archived) {
|
|
116
|
+
const zipRel = `${archived}.zip`;
|
|
117
|
+
// zip() honors a non-temp dstFs / dstFile - output lands directly in archiveFs
|
|
118
|
+
await ctx.archiveFs.zip(archived, ctx.archiveFs, zipRel);
|
|
119
|
+
await ctx.archiveFs.rm(archived);
|
|
120
|
+
this.Logger.trace(`Compressed archive ${archived} -> ${zipRel}`);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Next archive sequence number for a given base name. Uses existing archive
|
|
124
|
+
* file names first, falling back to a timestamp so two rotations in the same
|
|
125
|
+
* tick never collide.
|
|
126
|
+
*/
|
|
127
|
+
async nextSequence(ctx, name, ext) {
|
|
128
|
+
let existing = [];
|
|
129
|
+
try {
|
|
130
|
+
existing = await ctx.archiveFs.list(ctx.archiveDir || "/");
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
existing = [];
|
|
134
|
+
}
|
|
135
|
+
const prefix = `${ARCHIVE_PREFIX}${name}_`;
|
|
136
|
+
// prefix is escaped via escapeRegExp before interpolation
|
|
137
|
+
// eslint-disable-next-line security/detect-non-literal-regexp
|
|
138
|
+
const seqReg = new RegExp(`^${escapeRegExp(prefix)}(\\d+)`);
|
|
139
|
+
let max = 0;
|
|
140
|
+
for (const f of existing) {
|
|
141
|
+
const m = seqReg.exec(f);
|
|
142
|
+
if (m) {
|
|
143
|
+
const n = parseInt(m[1], 10);
|
|
144
|
+
if (n > max) {
|
|
145
|
+
max = n;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
const next = max + 1;
|
|
150
|
+
// guard against a name clash ( eg. same-second cron + size rotation ) by
|
|
151
|
+
// appending a millisecond timestamp only when the computed name already exists
|
|
152
|
+
const candidate = archivePath(ctx, `${ARCHIVE_PREFIX}${name}_${next}${ext}`);
|
|
153
|
+
if (await ctx.archiveFs.exists(candidate)) {
|
|
154
|
+
return DateTime.now().toMillis();
|
|
155
|
+
}
|
|
156
|
+
return next;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Resolves a strategy instance by class name, mirroring the fs temp-provider
|
|
160
|
+
* mechanism: look the class up in the DI registry by name, then resolve an
|
|
161
|
+
* instance ( `@NewInstance()` gives a fresh per-target instance ).
|
|
162
|
+
*/
|
|
163
|
+
resolveStrategy(base, className) {
|
|
164
|
+
const types = DI.RootContainer.Registry.getTypes(base);
|
|
165
|
+
const type = types.find((x) => x.name === className);
|
|
166
|
+
if (!type) {
|
|
167
|
+
const baseName = base.name;
|
|
168
|
+
throw new ResolveException(`Log archive strategy ${className} ( ${baseName} ) not registered, make sure it is imported and registered in DI container`);
|
|
169
|
+
}
|
|
170
|
+
// strategies are plain ( non-async ) services, so resolve is synchronous
|
|
171
|
+
return DI.resolve(type);
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
__decorate([
|
|
175
|
+
Logger("LogFileTarget"),
|
|
176
|
+
__metadata("design:type", Log)
|
|
177
|
+
], LogArchiveService.prototype, "Logger", void 0);
|
|
178
|
+
LogArchiveService = __decorate([
|
|
179
|
+
Injectable(),
|
|
180
|
+
NewInstance()
|
|
181
|
+
], LogArchiveService);
|
|
182
|
+
export { LogArchiveService };
|
|
183
|
+
function escapeRegExp(s) {
|
|
184
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=LogArchiveService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LogArchiveService.js","sourceRoot":"","sources":["../../../src/archive/LogArchiveService.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,YAAY,EAAS,EAAE,EAAE,UAAU,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACjG,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAE/D,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnE;;;;;;;;;;;GAWG;AAGI,IAAM,iBAAiB,GAAvB,MAAM,iBAAkB,SAAQ,YAAY;IAA5C;;QAKK,wBAAmB,GAA2B,EAAE,CAAC;IAqK7D,CAAC;IAnKC;;;;OAIG;IACI,KAAK,CAAC,OAAO;QAClB,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;IACxB,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,KAAK,CAAC,GAAuB;QACxC,2EAA2E;QAC3E,2EAA2E;QAC3E,0DAA0D;QAC1D,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC,kBAAkB,EAAE,GAAG,CAAC,OAAO,CAAC,eAAyB,CAAC,CAAC;QAEvG,MAAM,cAAc,GAAG,GAAG,CAAC,OAAO,CAAC,mBAAmB,IAAI,EAAE,CAAC;QAC7D,IAAI,CAAC,mBAAmB,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,oBAAoB,EAAE,CAAC,CAAC,CAAC,CAAC;QAEpG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC;IAED;;OAEG;IACI,IAAI;QACT,IAAI,CAAC,eAAe,EAAE,IAAI,EAAE,CAAC;IAC/B,CAAC;IAED;;;;;;;;;;;OAWG;IACI,KAAK,CAAC,MAAM,CAAC,GAAuB;QACzC,MAAM,GAAG,CAAC,aAAa,CAAC,KAAK,IAAI,EAAE;YACjC,0CAA0C;YAC1C,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;gBAC3C,OAAO;YACT,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;YAE/C,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;gBACzB,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;YACrC,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,yEAAyE;QACzE,sDAAsD;QACtD,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAChD,MAAM,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACO,KAAK,CAAC,aAAa,CAAC,GAAuB;QACnD,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QAChF,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;QACpD,MAAM,WAAW,GAAG,GAAG,cAAc,GAAG,IAAI,IAAI,GAAG,GAAG,GAAG,EAAE,CAAC;QAC5D,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QAEjD,IAAI,GAAG,CAAC,SAAS,KAAK,GAAG,CAAC,EAAE,EAAE,CAAC;YAC7B,MAAM,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;YAChD,OAAO,UAAU,CAAC;QACpB,CAAC;QAED,wEAAwE;QACxE,MAAM,UAAU,GAAG,GAAG,cAAc,GAAG,IAAI,IAAI,GAAG,GAAG,GAAG,EAAE,CAAC;QAC3D,MAAM,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;QAChD,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC;QACzD,OAAO,UAAU,CAAC;IACpB,CAAC;IAED;;;OAGG;IACO,KAAK,CAAC,QAAQ,CAAC,GAAuB,EAAE,QAAgB;QAChE,MAAM,MAAM,GAAG,GAAG,QAAQ,MAAM,CAAC;QAEjC,+EAA+E;QAC/E,MAAM,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACzD,MAAM,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;QAEjC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,sBAAsB,QAAQ,OAAO,MAAM,EAAE,CAAC,CAAC;IACnE,CAAC;IAED;;;;OAIG;IACO,KAAK,CAAC,YAAY,CAAC,GAAuB,EAAE,IAAY,EAAE,GAAW;QAC7E,IAAI,QAAQ,GAAa,EAAE,CAAC;QAC5B,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,CAAC;QAC7D,CAAC;QAAC,MAAM,CAAC;YACP,QAAQ,GAAG,EAAE,CAAC;QAChB,CAAC;QAED,MAAM,MAAM,GAAG,GAAG,cAAc,GAAG,IAAI,GAAG,CAAC;QAC3C,0DAA0D;QAC1D,8DAA8D;QAC9D,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAE5D,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACzB,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACzB,IAAI,CAAC,EAAE,CAAC;gBACN,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC7B,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC;oBACZ,GAAG,GAAG,CAAC,CAAC;gBACV,CAAC;YACH,CAAC;QACH,CAAC;QAED,MAAM,IAAI,GAAG,GAAG,GAAG,CAAC,CAAC;QAErB,yEAAyE;QACzE,+EAA+E;QAC/E,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,cAAc,GAAG,IAAI,IAAI,IAAI,GAAG,GAAG,EAAE,CAAC,CAAC;QAC7E,IAAI,MAAM,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;YAC1C,OAAO,QAAQ,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;QACnC,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;OAIG;IACO,eAAe,CAAI,IAAc,EAAE,SAAiB;QAC5D,MAAM,KAAK,GAAG,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACvD,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAE,CAAsB,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;QAE3E,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,QAAQ,GAAI,IAAyB,CAAC,IAAI,CAAC;YACjD,MAAM,IAAI,gBAAgB,CACxB,wBAAwB,SAAS,MAAM,QAAQ,4EAA4E,CAC5H,CAAC;QACJ,CAAC;QAED,yEAAyE;QACzE,OAAO,EAAE,CAAC,OAAO,CAAC,IAAgB,CAAM,CAAC;IAC3C,CAAC;CACF,CAAA;AAxKW;IADT,MAAM,CAAC,eAAe,CAAC;8BACN,GAAG;iDAAC;AAFX,iBAAiB;IAF7B,UAAU,EAAE;IACZ,WAAW,EAAE;GACD,iBAAiB,CA0K7B;;AAED,SAAS,YAAY,CAAC,CAAS;IAC7B,OAAO,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAClD,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Log } from "@spinajs/log-common";
|
|
2
|
+
import { ILogArchiveContext } from "./context.js";
|
|
3
|
+
/**
|
|
4
|
+
* Rotation policy for a file log target. Decides WHEN the active log file is
|
|
5
|
+
* rotated ( moved to the archive ) and owns its own schedule - the scheduling
|
|
6
|
+
* mechanism ( interval, cron, ... ) is strategy specific and implemented in
|
|
7
|
+
* `start` / `stop`.
|
|
8
|
+
*
|
|
9
|
+
* Mirrors the shape of fs `TempCleanupStrategy`: strategies hold per-target
|
|
10
|
+
* scheduling state, so implementations MUST be registered with `@NewInstance()`
|
|
11
|
+
* - otherwise a single instance would be shared between all file targets.
|
|
12
|
+
*/
|
|
13
|
+
export declare abstract class LogArchiveStrategy {
|
|
14
|
+
protected Logger: Log;
|
|
15
|
+
/**
|
|
16
|
+
* Starts scheduled rotation. How rotations are scheduled is up to the
|
|
17
|
+
* strategy.
|
|
18
|
+
*
|
|
19
|
+
* @param ctx archive context of the file target
|
|
20
|
+
*/
|
|
21
|
+
abstract start(ctx: ILogArchiveContext): void;
|
|
22
|
+
/**
|
|
23
|
+
* Stops scheduled rotation. Safe to call multiple times.
|
|
24
|
+
*/
|
|
25
|
+
abstract stop(): void;
|
|
26
|
+
/**
|
|
27
|
+
* Single rotation trigger guarded against errors - a failed rotation ( disk
|
|
28
|
+
* full, remote backend down, ... ) must never crash the scheduler tick.
|
|
29
|
+
*/
|
|
30
|
+
protected triggerRotation(ctx: ILogArchiveContext): Promise<void>;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=archive-strategy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archive-strategy.d.ts","sourceRoot":"","sources":["../../../src/archive/archive-strategy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAElD;;;;;;;;;GASG;AACH,8BAAsB,kBAAkB;IAEtC,SAAS,CAAC,MAAM,EAAE,GAAG,CAAC;IAEtB;;;;;OAKG;aACa,KAAK,CAAC,GAAG,EAAE,kBAAkB,GAAG,IAAI;IAEpD;;OAEG;aACa,IAAI,IAAI,IAAI;IAE5B;;;OAGG;cACa,eAAe,CAAC,GAAG,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;CAOxE"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { Logger, Log } from "@spinajs/log-common";
|
|
11
|
+
/**
|
|
12
|
+
* Rotation policy for a file log target. Decides WHEN the active log file is
|
|
13
|
+
* rotated ( moved to the archive ) and owns its own schedule - the scheduling
|
|
14
|
+
* mechanism ( interval, cron, ... ) is strategy specific and implemented in
|
|
15
|
+
* `start` / `stop`.
|
|
16
|
+
*
|
|
17
|
+
* Mirrors the shape of fs `TempCleanupStrategy`: strategies hold per-target
|
|
18
|
+
* scheduling state, so implementations MUST be registered with `@NewInstance()`
|
|
19
|
+
* - otherwise a single instance would be shared between all file targets.
|
|
20
|
+
*/
|
|
21
|
+
export class LogArchiveStrategy {
|
|
22
|
+
/**
|
|
23
|
+
* Single rotation trigger guarded against errors - a failed rotation ( disk
|
|
24
|
+
* full, remote backend down, ... ) must never crash the scheduler tick.
|
|
25
|
+
*/
|
|
26
|
+
async triggerRotation(ctx) {
|
|
27
|
+
try {
|
|
28
|
+
await ctx.rotate();
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
this.Logger.warn(`Log rotation for target ${ctx.options.path} failed: ${err.message}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
__decorate([
|
|
36
|
+
Logger("LogFileTarget"),
|
|
37
|
+
__metadata("design:type", Log)
|
|
38
|
+
], LogArchiveStrategy.prototype, "Logger", void 0);
|
|
39
|
+
//# sourceMappingURL=archive-strategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archive-strategy.js","sourceRoot":"","sources":["../../../src/archive/archive-strategy.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAGlD;;;;;;;;;GASG;AACH,MAAM,OAAgB,kBAAkB;IAiBtC;;;OAGG;IACO,KAAK,CAAC,eAAe,CAAC,GAAuB;QACrD,IAAI,CAAC;YACH,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC;QACrB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,2BAA2B,GAAG,CAAC,OAAO,CAAC,IAAI,YAAa,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QACpG,CAAC;IACH,CAAC;CACF;AA1BW;IADT,MAAM,CAAC,eAAe,CAAC;8BACN,GAAG;kDAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { fs } from "@spinajs/fs";
|
|
2
|
+
import { Log, IFileTargetOptions } from "@spinajs/log-common";
|
|
3
|
+
/**
|
|
4
|
+
* Shared context handed to every archive / retention strategy.
|
|
5
|
+
*
|
|
6
|
+
* It exposes the filesystems and paths a strategy needs, plus the two
|
|
7
|
+
* cross-cutting hooks it must go through:
|
|
8
|
+
*
|
|
9
|
+
* - `rotate()` - perform a single rotation ( owned by LogArchiveService ),
|
|
10
|
+
* - `withWriteLock()` - run a critical section under the target write-lock so
|
|
11
|
+
* a rename never races an in-flight append.
|
|
12
|
+
*/
|
|
13
|
+
export interface ILogArchiveContext {
|
|
14
|
+
/**
|
|
15
|
+
* Filesystem holding the ACTIVE log file.
|
|
16
|
+
*/
|
|
17
|
+
fs: fs;
|
|
18
|
+
/**
|
|
19
|
+
* Filesystem archives ( rotated / zipped files ) are moved to. Defaults to
|
|
20
|
+
* the same provider as `fs`.
|
|
21
|
+
*/
|
|
22
|
+
archiveFs: fs;
|
|
23
|
+
/**
|
|
24
|
+
* Path ( relative to `fs` base path ) of the active log file.
|
|
25
|
+
*/
|
|
26
|
+
activePath: string;
|
|
27
|
+
/**
|
|
28
|
+
* Directory ( relative to `archiveFs` base path ) archives are stored in.
|
|
29
|
+
*/
|
|
30
|
+
archiveDir: string;
|
|
31
|
+
/**
|
|
32
|
+
* Resolved file target options ( maxSize, maxAge, compress, ... ).
|
|
33
|
+
*/
|
|
34
|
+
options: IFileTargetOptions["options"];
|
|
35
|
+
/**
|
|
36
|
+
* Target logger, used for diagnostics.
|
|
37
|
+
*/
|
|
38
|
+
logger: Log;
|
|
39
|
+
/**
|
|
40
|
+
* Perform a single rotation of the active log file. Implemented by
|
|
41
|
+
* LogArchiveService - strategies call this from their schedule.
|
|
42
|
+
*/
|
|
43
|
+
rotate(): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Run `fn` under the target write-lock so it cannot overlap with an
|
|
46
|
+
* in-flight append / flush.
|
|
47
|
+
*/
|
|
48
|
+
withWriteLock<T>(fn: () => Promise<T>): Promise<T>;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/archive/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,GAAG,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE9D;;;;;;;;;GASG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,EAAE,EAAE,EAAE,CAAC;IAEP;;;OAGG;IACH,SAAS,EAAE,EAAE,CAAC;IAEd;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,OAAO,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAEvC;;OAEG;IACH,MAAM,EAAE,GAAG,CAAC;IAEZ;;;OAGG;IACH,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAExB;;;OAGG;IACH,aAAa,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACpD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/archive/context.ts"],"names":[],"mappings":""}
|