@ketvietlab/ketjs 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +8 -2
- package/dist/agent/capabilities.d.ts +1 -3
- package/dist/agent/capabilities.d.ts.map +1 -1
- package/dist/agent/capabilities.js +10 -1
- package/dist/agent/capabilities.js.map +1 -1
- package/dist/agent/permissions.d.ts +43 -1
- package/dist/agent/permissions.d.ts.map +1 -1
- package/dist/agent/permissions.js +50 -2
- package/dist/agent/permissions.js.map +1 -1
- package/dist/cli.js +246 -97
- package/dist/cli.js.map +1 -1
- package/dist/codegen/dts.d.ts.map +1 -1
- package/dist/codegen/dts.js +1 -0
- package/dist/codegen/dts.js.map +1 -1
- package/dist/data/changeset.d.ts +12 -0
- package/dist/data/changeset.d.ts.map +1 -1
- package/dist/data/changeset.js +73 -17
- package/dist/data/changeset.js.map +1 -1
- package/dist/data/expr.d.ts +16 -0
- package/dist/data/expr.d.ts.map +1 -1
- package/dist/data/expr.js +33 -5
- package/dist/data/expr.js.map +1 -1
- package/dist/data/fleet.d.ts +41 -1
- package/dist/data/fleet.d.ts.map +1 -1
- package/dist/data/fleet.js +100 -11
- package/dist/data/fleet.js.map +1 -1
- package/dist/data/migrate.d.ts +20 -0
- package/dist/data/migrate.d.ts.map +1 -1
- package/dist/data/migrate.js +86 -3
- package/dist/data/migrate.js.map +1 -1
- package/dist/data/physical.d.ts +5 -0
- package/dist/data/physical.d.ts.map +1 -0
- package/dist/data/physical.js +196 -0
- package/dist/data/physical.js.map +1 -0
- package/dist/data/pool.d.ts +2 -1
- package/dist/data/pool.d.ts.map +1 -1
- package/dist/data/pool.js +159 -31
- package/dist/data/pool.js.map +1 -1
- package/dist/data/query.d.ts +10 -1
- package/dist/data/query.d.ts.map +1 -1
- package/dist/data/query.js +136 -27
- package/dist/data/query.js.map +1 -1
- package/dist/data/sqlite.d.ts.map +1 -1
- package/dist/data/sqlite.js +350 -52
- package/dist/data/sqlite.js.map +1 -1
- package/dist/data/time.d.ts +13 -0
- package/dist/data/time.d.ts.map +1 -1
- package/dist/data/time.js +61 -17
- package/dist/data/time.js.map +1 -1
- package/dist/index.d.ts +43 -22
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +32 -16
- package/dist/index.js.map +1 -1
- package/dist/kernel/audit.d.ts +27 -0
- package/dist/kernel/audit.d.ts.map +1 -0
- package/dist/kernel/audit.js +67 -0
- package/dist/kernel/audit.js.map +1 -0
- package/dist/kernel/classification.d.ts +26 -0
- package/dist/kernel/classification.d.ts.map +1 -0
- package/dist/kernel/classification.js +73 -0
- package/dist/kernel/classification.js.map +1 -0
- package/dist/kernel/compose.d.ts +6 -2
- package/dist/kernel/compose.d.ts.map +1 -1
- package/dist/kernel/compose.js +269 -15
- package/dist/kernel/compose.js.map +1 -1
- package/dist/kernel/define.d.ts +2 -3
- package/dist/kernel/define.d.ts.map +1 -1
- package/dist/kernel/define.js +22 -12
- package/dist/kernel/define.js.map +1 -1
- package/dist/kernel/diff.d.ts.map +1 -1
- package/dist/kernel/diff.js +28 -4
- package/dist/kernel/diff.js.map +1 -1
- package/dist/kernel/graph.js +1 -1
- package/dist/kernel/graph.js.map +1 -1
- package/dist/kernel/i18n.d.ts +10 -1
- package/dist/kernel/i18n.d.ts.map +1 -1
- package/dist/kernel/i18n.js +34 -1
- package/dist/kernel/i18n.js.map +1 -1
- package/dist/kernel/layout.d.ts +97 -0
- package/dist/kernel/layout.d.ts.map +1 -1
- package/dist/kernel/layout.js +294 -12
- package/dist/kernel/layout.js.map +1 -1
- package/dist/kernel/menu.d.ts +33 -2
- package/dist/kernel/menu.d.ts.map +1 -1
- package/dist/kernel/menu.js +99 -7
- package/dist/kernel/menu.js.map +1 -1
- package/dist/kernel/modules.d.ts +3 -3
- package/dist/kernel/modules.d.ts.map +1 -1
- package/dist/kernel/modules.js +21 -21
- package/dist/kernel/modules.js.map +1 -1
- package/dist/kernel/permissions.d.ts +10 -0
- package/dist/kernel/permissions.d.ts.map +1 -0
- package/dist/kernel/permissions.js +365 -0
- package/dist/kernel/permissions.js.map +1 -0
- package/dist/kernel/schedule.d.ts +23 -0
- package/dist/kernel/schedule.d.ts.map +1 -0
- package/dist/kernel/schedule.js +83 -0
- package/dist/kernel/schedule.js.map +1 -0
- package/dist/kernel/types.d.ts.map +1 -1
- package/dist/kernel/types.js +5 -4
- package/dist/kernel/types.js.map +1 -1
- package/dist/kernel/workspace.d.ts +92 -14
- package/dist/kernel/workspace.d.ts.map +1 -1
- package/dist/kernel/workspace.js +128 -49
- package/dist/kernel/workspace.js.map +1 -1
- package/dist/pdf/assets/Inter-Bold.ttf +0 -0
- package/dist/pdf/assets/Inter-Regular.ttf +0 -0
- package/dist/pdf/assets/Inter-SemiBold.ttf +0 -0
- package/dist/pdf/assets/LICENSE.txt +92 -0
- package/dist/pdf/font.d.ts +10 -0
- package/dist/pdf/font.d.ts.map +1 -0
- package/dist/pdf/font.js +83 -0
- package/dist/pdf/font.js.map +1 -0
- package/dist/pdf/image.d.ts +8 -0
- package/dist/pdf/image.d.ts.map +1 -0
- package/dist/pdf/image.js +94 -0
- package/dist/pdf/image.js.map +1 -0
- package/dist/pdf/index.d.ts +15 -0
- package/dist/pdf/index.d.ts.map +1 -0
- package/dist/pdf/index.js +17 -0
- package/dist/pdf/index.js.map +1 -0
- package/dist/pdf/markup.d.ts +19 -0
- package/dist/pdf/markup.d.ts.map +1 -0
- package/dist/pdf/markup.js +146 -0
- package/dist/pdf/markup.js.map +1 -0
- package/dist/pdf/render.d.ts +14 -0
- package/dist/pdf/render.d.ts.map +1 -0
- package/dist/pdf/render.js +387 -0
- package/dist/pdf/render.js.map +1 -0
- package/dist/scaffold/index.js +6 -6
- package/dist/scaffold/index.js.map +1 -1
- package/dist/scaffold/templates/{app.test.ts.tmpl → deployment.test.ts.tmpl} +3 -3
- package/dist/scaffold/templates/ket.workspace.ts.tmpl +4 -6
- package/dist/scaffold/templates/module.ts.tmpl +1 -4
- package/dist/server/assets.d.ts +23 -0
- package/dist/server/assets.d.ts.map +1 -0
- package/dist/server/assets.js +97 -0
- package/dist/server/assets.js.map +1 -0
- package/dist/server/boot.d.ts +157 -38
- package/dist/server/boot.d.ts.map +1 -1
- package/dist/server/boot.js +360 -138
- package/dist/server/boot.js.map +1 -1
- package/dist/server/config.d.ts +30 -10
- package/dist/server/config.d.ts.map +1 -1
- package/dist/server/config.js +73 -17
- package/dist/server/config.js.map +1 -1
- package/dist/server/ctx.d.ts +10 -0
- package/dist/server/ctx.d.ts.map +1 -1
- package/dist/server/ctx.js +266 -48
- package/dist/server/ctx.js.map +1 -1
- package/dist/server/development.d.ts +10 -0
- package/dist/server/development.d.ts.map +1 -0
- package/dist/server/development.js +15 -0
- package/dist/server/development.js.map +1 -0
- package/dist/server/fn.d.ts +22 -3
- package/dist/server/fn.d.ts.map +1 -1
- package/dist/server/fn.js +116 -32
- package/dist/server/fn.js.map +1 -1
- package/dist/server/form.d.ts +33 -0
- package/dist/server/form.d.ts.map +1 -0
- package/dist/server/form.js +47 -0
- package/dist/server/form.js.map +1 -0
- package/dist/server/http.d.ts +55 -3
- package/dist/server/http.d.ts.map +1 -1
- package/dist/server/http.js +306 -22
- package/dist/server/http.js.map +1 -1
- package/dist/server/idem.d.ts +3 -2
- package/dist/server/idem.d.ts.map +1 -1
- package/dist/server/idem.js +12 -4
- package/dist/server/idem.js.map +1 -1
- package/dist/server/jobs.js +1 -1
- package/dist/server/jobs.js.map +1 -1
- package/dist/server/log/combinators.d.ts +42 -0
- package/dist/server/log/combinators.d.ts.map +1 -0
- package/dist/server/log/combinators.js +270 -0
- package/dist/server/log/combinators.js.map +1 -0
- package/dist/server/log/console.d.ts +12 -0
- package/dist/server/log/console.d.ts.map +1 -0
- package/dist/server/log/console.js +96 -0
- package/dist/server/log/console.js.map +1 -0
- package/dist/server/log/file.d.ts +11 -0
- package/dist/server/log/file.d.ts.map +1 -0
- package/dist/server/log/file.js +61 -0
- package/dist/server/log/file.js.map +1 -0
- package/dist/server/log/index.d.ts +23 -0
- package/dist/server/log/index.d.ts.map +1 -0
- package/dist/server/log/index.js +45 -0
- package/dist/server/log/index.js.map +1 -0
- package/dist/server/log/logger.d.ts +53 -0
- package/dist/server/log/logger.d.ts.map +1 -0
- package/dist/server/log/logger.js +94 -0
- package/dist/server/log/logger.js.map +1 -0
- package/dist/server/log/memory.d.ts +11 -0
- package/dist/server/log/memory.d.ts.map +1 -0
- package/dist/server/log/memory.js +25 -0
- package/dist/server/log/memory.js.map +1 -0
- package/dist/server/log/types.d.ts +112 -0
- package/dist/server/log/types.d.ts.map +1 -0
- package/dist/server/log/types.js +58 -0
- package/dist/server/log/types.js.map +1 -0
- package/dist/server/policy.d.ts +29 -0
- package/dist/server/policy.d.ts.map +1 -0
- package/dist/server/policy.js +29 -0
- package/dist/server/policy.js.map +1 -0
- package/dist/server/queue.d.ts +1 -1
- package/dist/server/queue.d.ts.map +1 -1
- package/dist/server/queue.js.map +1 -1
- package/dist/server/ratelimit.d.ts +48 -0
- package/dist/server/ratelimit.d.ts.map +1 -0
- package/dist/server/ratelimit.js +102 -0
- package/dist/server/ratelimit.js.map +1 -0
- package/dist/server/respond.d.ts.map +1 -1
- package/dist/server/respond.js +16 -1
- package/dist/server/respond.js.map +1 -1
- package/dist/server/runtime.d.ts +18 -3
- package/dist/server/runtime.d.ts.map +1 -1
- package/dist/server/runtime.js +32 -2
- package/dist/server/runtime.js.map +1 -1
- package/dist/server/schedule.d.ts +18 -0
- package/dist/server/schedule.d.ts.map +1 -0
- package/dist/server/schedule.js +70 -0
- package/dist/server/schedule.js.map +1 -0
- package/dist/server/sequence.d.ts +42 -0
- package/dist/server/sequence.d.ts.map +1 -0
- package/dist/server/sequence.js +97 -0
- package/dist/server/sequence.js.map +1 -0
- package/dist/server/session.d.ts +21 -0
- package/dist/server/session.d.ts.map +1 -1
- package/dist/server/session.js +84 -10
- package/dist/server/session.js.map +1 -1
- package/dist/server/sessionstore.d.ts +3 -1
- package/dist/server/sessionstore.d.ts.map +1 -1
- package/dist/server/sessionstore.js +7 -3
- package/dist/server/sessionstore.js.map +1 -1
- package/dist/server/storage/index.d.ts +1 -1
- package/dist/server/storage/index.d.ts.map +1 -1
- package/dist/server/storage/index.js +61 -1
- package/dist/server/storage/index.js.map +1 -1
- package/dist/server/storage/types.d.ts +8 -0
- package/dist/server/storage/types.d.ts.map +1 -1
- package/dist/server/storage/types.js +58 -0
- package/dist/server/storage/types.js.map +1 -1
- package/dist/server/tenants.d.ts +20 -18
- package/dist/server/tenants.d.ts.map +1 -1
- package/dist/server/tenants.js +133 -84
- package/dist/server/tenants.js.map +1 -1
- package/dist/server/transport/types.js +2 -2
- package/dist/server/transport/types.js.map +1 -1
- package/dist/server/worker.d.ts +19 -3
- package/dist/server/worker.d.ts.map +1 -1
- package/dist/server/worker.js +168 -21
- package/dist/server/worker.js.map +1 -1
- package/dist/testing.d.ts +26 -10
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +41 -14
- package/dist/testing.js.map +1 -1
- package/dist/theme/contracts.d.ts +14 -1
- package/dist/theme/contracts.d.ts.map +1 -1
- package/dist/theme/contracts.js +35 -6
- package/dist/theme/contracts.js.map +1 -1
- package/dist/theme/index.d.ts +1 -1
- package/dist/theme/index.d.ts.map +1 -1
- package/dist/theme/index.js +1 -1
- package/dist/theme/index.js.map +1 -1
- package/dist/theme/joint-runtime.d.ts +33 -0
- package/dist/theme/joint-runtime.d.ts.map +1 -0
- package/dist/theme/joint-runtime.js +121 -0
- package/dist/theme/joint-runtime.js.map +1 -0
- package/dist/theme/joints.d.ts.map +1 -1
- package/dist/theme/joints.js +15 -97
- package/dist/theme/joints.js.map +1 -1
- package/dist/theme/ktl/compile.d.ts +4 -0
- package/dist/theme/ktl/compile.d.ts.map +1 -1
- package/dist/theme/ktl/compile.js +54 -1
- package/dist/theme/ktl/compile.js.map +1 -1
- package/dist/theme/ktl/parser.d.ts +4 -0
- package/dist/theme/ktl/parser.d.ts.map +1 -1
- package/dist/theme/ktl/parser.js +8 -0
- package/dist/theme/ktl/parser.js.map +1 -1
- package/dist/theme/render.d.ts +8 -0
- package/dist/theme/render.d.ts.map +1 -1
- package/dist/theme/render.js +88 -118
- package/dist/theme/render.js.map +1 -1
- package/dist/theme/tokens.d.ts +6 -0
- package/dist/theme/tokens.d.ts.map +1 -1
- package/dist/theme/tokens.js +6 -0
- package/dist/theme/tokens.js.map +1 -1
- package/dist/theme/viewmodel.d.ts +24 -0
- package/dist/theme/viewmodel.d.ts.map +1 -1
- package/dist/theme/viewmodel.js +75 -6
- package/dist/theme/viewmodel.js.map +1 -1
- package/dist/types.d.ts +304 -56
- package/dist/types.d.ts.map +1 -1
- package/package.json +6 -2
- package/dist/kernel/apps.d.ts +0 -43
- package/dist/kernel/apps.d.ts.map +0 -1
- package/dist/kernel/apps.js +0 -234
- package/dist/kernel/apps.js.map +0 -1
package/dist/server/jobs.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Job declarations are data in the manifest and executable handlers in this
|
|
2
2
|
// process. Keeping the two joined by one qualified key mirrors server functions
|
|
3
|
-
// while allowing `ket worker` to load the same
|
|
3
|
+
// while allowing `ket worker` to load the same DeploymentSpec without booting HTTP.
|
|
4
4
|
import { KetError } from '../kernel/errors.js';
|
|
5
5
|
const registry = new Map();
|
|
6
6
|
export function defineJob(spec) {
|
package/dist/server/jobs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jobs.js","sourceRoot":"","sources":["../../../../../../packages/ketjs/src/server/jobs.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,gFAAgF;AAChF,
|
|
1
|
+
{"version":3,"file":"jobs.js","sourceRoot":"","sources":["../../../../../../packages/ketjs/src/server/jobs.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,gFAAgF;AAChF,oFAAoF;AAEpF,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAG9C,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAmB,CAAA;AAE3C,MAAM,UAAU,SAAS,CAAC,IAAa;IACrC,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI;QAC1B,MAAM,IAAI,QAAQ,CAAC;YACjB,IAAI,EAAE,sBAAsB;YAC5B,OAAO,EAAE,yEAAyE;SACnF,CAAC,CAAA;IACJ,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,UAAU;QACpC,MAAM,IAAI,QAAQ,CAAC,EAAE,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,gCAAgC,EAAE,CAAC,CAAA;IAC7F,OAAO,IAAI,CAAA;AACb,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAAoB;IAC/C,QAAQ,CAAC,KAAK,EAAE,CAAA;IAChB,KAAK,MAAM,MAAM,IAAI,OAAO;QAC1B,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC;YAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,IAAI,IAAI,IAAI,EAAE,EAAE,IAAI,CAAC,CAAA;IACtG,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,GAAW,EAAkB,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAA"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { LogDriver, LogLevel } from './types.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Fan out to several sinks.
|
|
4
|
+
*
|
|
5
|
+
* A driver that throws must not stop the drivers after it, so this catches as a
|
|
6
|
+
* last resort. It reports nothing: wrap the risky driver in `isolatedLog` when a
|
|
7
|
+
* failure should be visible rather than merely survivable.
|
|
8
|
+
*/
|
|
9
|
+
export declare function multiLog(drivers: readonly LogDriver[]): LogDriver;
|
|
10
|
+
/** Drop anything below `min`. Cheapest when it is the outermost wrapper. */
|
|
11
|
+
export declare function leveledLog(driver: LogDriver, min: LogLevel): LogDriver;
|
|
12
|
+
/**
|
|
13
|
+
* Batch, with a bound on memory and a visible gap when that bound is reached.
|
|
14
|
+
*
|
|
15
|
+
* Newest is dropped rather than oldest: in a cascade the first failure is the
|
|
16
|
+
* cause and the tail is repetition. A slice of the bound is reserved for
|
|
17
|
+
* error-level records, so a flood of `info` can never bury the errors explaining
|
|
18
|
+
* it. Whatever is dropped is announced — a silent gap in a log is worse than a
|
|
19
|
+
* gap, because it cannot be distinguished from nothing having happened.
|
|
20
|
+
*/
|
|
21
|
+
export declare function bufferedLog(driver: LogDriver, options?: {
|
|
22
|
+
max?: number;
|
|
23
|
+
everyMs?: number;
|
|
24
|
+
errorReserve?: number;
|
|
25
|
+
batch?: number;
|
|
26
|
+
}): LogDriver;
|
|
27
|
+
/**
|
|
28
|
+
* Swallow a driver's failures, and say so exactly once.
|
|
29
|
+
*
|
|
30
|
+
* Once, because a sink that fails usually fails for every record, and a fallback
|
|
31
|
+
* flooded with reports of the first sink's failure is a second outage.
|
|
32
|
+
*/
|
|
33
|
+
export declare function isolatedLog(driver: LogDriver, fallback?: LogDriver): LogDriver;
|
|
34
|
+
/**
|
|
35
|
+
* The mandatory outermost wrapper, applied by the runtime and not optional.
|
|
36
|
+
*
|
|
37
|
+
* The type system already refuses a non-scalar field, which stops the common way a
|
|
38
|
+
* customer payload reaches an aggregator. This handles what the type system cannot
|
|
39
|
+
* see: values arriving from JavaScript callers, and from `catch (e)`.
|
|
40
|
+
*/
|
|
41
|
+
export declare function redactLog(driver: LogDriver): LogDriver;
|
|
42
|
+
//# sourceMappingURL=combinators.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"combinators.d.ts","sourceRoot":"","sources":["../../../../../../packages/ketjs/src/server/log/combinators.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAa,QAAQ,EAAa,MAAM,YAAY,CAAA;AA0B3E;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,CA2BjE;AAED,4EAA4E;AAC5E,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,QAAQ,GAAG,SAAS,CAUtE;AAaD;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,SAAS,EACjB,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GACtF,SAAS,CAgEX;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,SAAS,GAAG,SAAS,CAgD9E;AA0BD;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,CAqBtD"}
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
// Drivers stay primitive; behaviour is composed. This is where "several drivers"
|
|
2
|
+
// actually lives, so that a fan-out, a level filter, a bound on memory and an
|
|
3
|
+
// isolation boundary are four small things that can be reasoned about separately
|
|
4
|
+
// rather than four flags on every driver.
|
|
5
|
+
import { atLeast } from './types.js';
|
|
6
|
+
/** Keys whose value is never worth the risk, matched as a lower-case substring. */
|
|
7
|
+
const DENY = [
|
|
8
|
+
'password',
|
|
9
|
+
'passwd',
|
|
10
|
+
'secret',
|
|
11
|
+
'token',
|
|
12
|
+
'authorization',
|
|
13
|
+
'cookie',
|
|
14
|
+
'apikey',
|
|
15
|
+
'api_key',
|
|
16
|
+
'privatekey',
|
|
17
|
+
'private_key',
|
|
18
|
+
'credential',
|
|
19
|
+
'card',
|
|
20
|
+
'cvv',
|
|
21
|
+
'ssn',
|
|
22
|
+
'otp',
|
|
23
|
+
'pin',
|
|
24
|
+
];
|
|
25
|
+
const VALUE_MAX = 512;
|
|
26
|
+
const MESSAGE_MAX = 1_000;
|
|
27
|
+
/**
|
|
28
|
+
* Fan out to several sinks.
|
|
29
|
+
*
|
|
30
|
+
* A driver that throws must not stop the drivers after it, so this catches as a
|
|
31
|
+
* last resort. It reports nothing: wrap the risky driver in `isolatedLog` when a
|
|
32
|
+
* failure should be visible rather than merely survivable.
|
|
33
|
+
*/
|
|
34
|
+
export function multiLog(drivers) {
|
|
35
|
+
return {
|
|
36
|
+
name: `multi(${drivers.map((d) => d.name).join(',')})`,
|
|
37
|
+
write(records) {
|
|
38
|
+
for (const driver of drivers) {
|
|
39
|
+
try {
|
|
40
|
+
driver.write(records);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
/* a sink is never allowed to break the work it is describing */
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
async flush() {
|
|
48
|
+
for (const driver of drivers) {
|
|
49
|
+
try {
|
|
50
|
+
await driver.flush?.();
|
|
51
|
+
}
|
|
52
|
+
catch { }
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
async close() {
|
|
56
|
+
for (const driver of drivers) {
|
|
57
|
+
try {
|
|
58
|
+
await driver.close?.();
|
|
59
|
+
}
|
|
60
|
+
catch { }
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/** Drop anything below `min`. Cheapest when it is the outermost wrapper. */
|
|
66
|
+
export function leveledLog(driver, min) {
|
|
67
|
+
return {
|
|
68
|
+
name: `leveled(${driver.name},${min})`,
|
|
69
|
+
write(records) {
|
|
70
|
+
const kept = records.filter((r) => atLeast(r.level, min));
|
|
71
|
+
if (kept.length)
|
|
72
|
+
driver.write(kept);
|
|
73
|
+
},
|
|
74
|
+
flush: driver.flush ? () => driver.flush() : undefined,
|
|
75
|
+
close: driver.close ? () => driver.close() : undefined,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
const dropNotice = (like, count, sinceMs, reason) => ({
|
|
79
|
+
at: new Date().toISOString(),
|
|
80
|
+
level: 'warn',
|
|
81
|
+
event: 'log_dropped',
|
|
82
|
+
deployment: like.deployment,
|
|
83
|
+
process: like.process,
|
|
84
|
+
tenant: null,
|
|
85
|
+
trace: null,
|
|
86
|
+
fields: { count, sinceMs, reason },
|
|
87
|
+
});
|
|
88
|
+
/**
|
|
89
|
+
* Batch, with a bound on memory and a visible gap when that bound is reached.
|
|
90
|
+
*
|
|
91
|
+
* Newest is dropped rather than oldest: in a cascade the first failure is the
|
|
92
|
+
* cause and the tail is repetition. A slice of the bound is reserved for
|
|
93
|
+
* error-level records, so a flood of `info` can never bury the errors explaining
|
|
94
|
+
* it. Whatever is dropped is announced — a silent gap in a log is worse than a
|
|
95
|
+
* gap, because it cannot be distinguished from nothing having happened.
|
|
96
|
+
*/
|
|
97
|
+
export function bufferedLog(driver, options = {}) {
|
|
98
|
+
const max = Math.max(1, options.max ?? 10_000);
|
|
99
|
+
const everyMs = Math.max(1, options.everyMs ?? 1_000);
|
|
100
|
+
const reserve = Math.min(0.9, Math.max(0, options.errorReserve ?? 0.25));
|
|
101
|
+
const softMax = Math.max(1, Math.floor(max * (1 - reserve)));
|
|
102
|
+
// Batching exists to amortise I/O, not to hold records back, and a few hundred
|
|
103
|
+
// already amortises it. Waiting for the bound instead would mean a burst inside
|
|
104
|
+
// one interval gets dropped by a buffer the sink could have drained twice over.
|
|
105
|
+
const batch = Math.max(1, Math.min(options.batch ?? 512, max));
|
|
106
|
+
let queue = [];
|
|
107
|
+
let dropped = 0;
|
|
108
|
+
let droppedSince = Date.now();
|
|
109
|
+
let last = null;
|
|
110
|
+
const drain = () => {
|
|
111
|
+
if (!queue.length && !dropped)
|
|
112
|
+
return;
|
|
113
|
+
const pending = queue;
|
|
114
|
+
queue = [];
|
|
115
|
+
if (dropped && last) {
|
|
116
|
+
pending.unshift(dropNotice(last, dropped, Date.now() - droppedSince, 'buffer_full'));
|
|
117
|
+
dropped = 0;
|
|
118
|
+
droppedSince = Date.now();
|
|
119
|
+
}
|
|
120
|
+
if (!pending.length)
|
|
121
|
+
return;
|
|
122
|
+
try {
|
|
123
|
+
driver.write(pending);
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
// drain() runs from a timer, where a throw is an uncaught exception and the
|
|
127
|
+
// end of the process. Note that a sink wrapped from the outside cannot help
|
|
128
|
+
// here: this call is beneath that wrapper, not through it.
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
// Unreferenced: a log timer must never be the reason a process stays alive.
|
|
132
|
+
const timer = setInterval(drain, everyMs);
|
|
133
|
+
timer.unref?.();
|
|
134
|
+
return {
|
|
135
|
+
name: `buffered(${driver.name})`,
|
|
136
|
+
write(records) {
|
|
137
|
+
for (const record of records) {
|
|
138
|
+
last = record;
|
|
139
|
+
const limit = record.level === 'error' ? max : softMax;
|
|
140
|
+
if (queue.length >= limit) {
|
|
141
|
+
if (!dropped)
|
|
142
|
+
droppedSince = Date.now();
|
|
143
|
+
dropped++;
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
queue.push(record);
|
|
147
|
+
}
|
|
148
|
+
if (queue.length >= batch)
|
|
149
|
+
drain();
|
|
150
|
+
},
|
|
151
|
+
async flush() {
|
|
152
|
+
drain();
|
|
153
|
+
await driver.flush?.();
|
|
154
|
+
},
|
|
155
|
+
async close() {
|
|
156
|
+
clearInterval(timer);
|
|
157
|
+
drain();
|
|
158
|
+
await driver.flush?.();
|
|
159
|
+
await driver.close?.();
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Swallow a driver's failures, and say so exactly once.
|
|
165
|
+
*
|
|
166
|
+
* Once, because a sink that fails usually fails for every record, and a fallback
|
|
167
|
+
* flooded with reports of the first sink's failure is a second outage.
|
|
168
|
+
*/
|
|
169
|
+
export function isolatedLog(driver, fallback) {
|
|
170
|
+
let reported = false;
|
|
171
|
+
const report = (like, cause) => {
|
|
172
|
+
if (reported || !fallback || !like)
|
|
173
|
+
return;
|
|
174
|
+
reported = true;
|
|
175
|
+
try {
|
|
176
|
+
fallback.write([
|
|
177
|
+
{
|
|
178
|
+
at: new Date().toISOString(),
|
|
179
|
+
level: 'error',
|
|
180
|
+
event: 'log_driver_failed',
|
|
181
|
+
deployment: like.deployment,
|
|
182
|
+
process: like.process,
|
|
183
|
+
tenant: null,
|
|
184
|
+
trace: null,
|
|
185
|
+
error: {
|
|
186
|
+
code: 'E_LOG_DRIVER',
|
|
187
|
+
message: cause instanceof Error ? cause.message : String(cause),
|
|
188
|
+
module: null,
|
|
189
|
+
},
|
|
190
|
+
fields: { driver: driver.name },
|
|
191
|
+
},
|
|
192
|
+
]);
|
|
193
|
+
}
|
|
194
|
+
catch { }
|
|
195
|
+
};
|
|
196
|
+
return {
|
|
197
|
+
name: `isolated(${driver.name})`,
|
|
198
|
+
write(records) {
|
|
199
|
+
try {
|
|
200
|
+
driver.write(records);
|
|
201
|
+
}
|
|
202
|
+
catch (cause) {
|
|
203
|
+
report(records[0], cause);
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
async flush() {
|
|
207
|
+
try {
|
|
208
|
+
await driver.flush?.();
|
|
209
|
+
}
|
|
210
|
+
catch (cause) {
|
|
211
|
+
report(undefined, cause);
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
async close() {
|
|
215
|
+
try {
|
|
216
|
+
await driver.close?.();
|
|
217
|
+
}
|
|
218
|
+
catch { }
|
|
219
|
+
},
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
const scalar = (value) => value === null || typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean';
|
|
223
|
+
const clip = (value, max) => (value.length <= max ? value : `${value.slice(0, max)}…`);
|
|
224
|
+
function redactFields(fields) {
|
|
225
|
+
if (!fields)
|
|
226
|
+
return undefined;
|
|
227
|
+
const out = {};
|
|
228
|
+
for (const [key, value] of Object.entries(fields)) {
|
|
229
|
+
const lower = key.toLowerCase();
|
|
230
|
+
if (DENY.some((needle) => lower.includes(needle))) {
|
|
231
|
+
out[key] = '[redacted]';
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
if (!scalar(value)) {
|
|
235
|
+
// The type forbids this; JavaScript callers do not have the type.
|
|
236
|
+
out[key] = '[dropped: non-scalar]';
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
out[key] = typeof value === 'string' ? clip(value, VALUE_MAX) : value;
|
|
240
|
+
}
|
|
241
|
+
return out;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* The mandatory outermost wrapper, applied by the runtime and not optional.
|
|
245
|
+
*
|
|
246
|
+
* The type system already refuses a non-scalar field, which stops the common way a
|
|
247
|
+
* customer payload reaches an aggregator. This handles what the type system cannot
|
|
248
|
+
* see: values arriving from JavaScript callers, and from `catch (e)`.
|
|
249
|
+
*/
|
|
250
|
+
export function redactLog(driver) {
|
|
251
|
+
return {
|
|
252
|
+
name: `redacted(${driver.name})`,
|
|
253
|
+
write(records) {
|
|
254
|
+
driver.write(records.map((record) => {
|
|
255
|
+
const fields = redactFields(record.fields);
|
|
256
|
+
return {
|
|
257
|
+
...record,
|
|
258
|
+
...(record.message === undefined ? {} : { message: clip(record.message, MESSAGE_MAX) }),
|
|
259
|
+
...(record.error === undefined
|
|
260
|
+
? {}
|
|
261
|
+
: { error: { ...record.error, message: clip(record.error.message, MESSAGE_MAX) } }),
|
|
262
|
+
...(fields === undefined ? {} : { fields }),
|
|
263
|
+
};
|
|
264
|
+
}));
|
|
265
|
+
},
|
|
266
|
+
flush: driver.flush ? () => driver.flush() : undefined,
|
|
267
|
+
close: driver.close ? () => driver.close() : undefined,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
//# sourceMappingURL=combinators.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"combinators.js","sourceRoot":"","sources":["../../../../../../../packages/ketjs/src/server/log/combinators.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { LogDriver } from './types.ts';
|
|
2
|
+
export type ConsoleLogOptions = {
|
|
3
|
+
stream?: 'stdout' | 'stderr';
|
|
4
|
+
/** Human-readable columns instead of NDJSON. For `ket dev`, never for production. */
|
|
5
|
+
pretty?: boolean;
|
|
6
|
+
color?: boolean;
|
|
7
|
+
bufferMax?: number;
|
|
8
|
+
};
|
|
9
|
+
export declare function consoleLog(options?: ConsoleLogOptions): LogDriver;
|
|
10
|
+
/** `consoleLog` with columns a person can read. The development default. */
|
|
11
|
+
export declare const prettyLog: (options?: Omit<ConsoleLogOptions, 'pretty'>) => LogDriver;
|
|
12
|
+
//# sourceMappingURL=console.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../../../../../../packages/ketjs/src/server/log/console.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,SAAS,EAAa,MAAM,YAAY,CAAA;AAmBtD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAA;IAC5B,qFAAqF;IACrF,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAyBD,wBAAgB,UAAU,CAAC,OAAO,GAAE,iBAAsB,GAAG,SAAS,CA6CrE;AAED,4EAA4E;AAC5E,eAAO,MAAM,SAAS,aAAa,IAAI,CAAC,iBAAiB,EAAE,QAAQ,CAAC,KAAQ,SAClC,CAAA"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// The default sink: NDJSON, one record per line, on stderr.
|
|
2
|
+
//
|
|
3
|
+
// stderr rather than stdout, and that is not a stylistic choice. `ket manifest`,
|
|
4
|
+
// `ket agent`, `ket permissions --json` and a dozen other commands write their
|
|
5
|
+
// answer to stdout, and a log line interleaved into that answer breaks
|
|
6
|
+
// `ket manifest | jq` for everyone downstream. stdout belongs to the program's
|
|
7
|
+
// output; a log is a side channel. Both are collected in a container runtime, so
|
|
8
|
+
// nothing is lost by being correct here.
|
|
9
|
+
/**
|
|
10
|
+
* How much may sit unwritten in the stream before records are dropped.
|
|
11
|
+
*
|
|
12
|
+
* Node's stdout and stderr are asynchronous when they point at a pipe, and their
|
|
13
|
+
* internal buffer has no bound: a log collector that stops reading turns into
|
|
14
|
+
* unbounded memory growth in the application. This is the bound.
|
|
15
|
+
*/
|
|
16
|
+
const BUFFER_MAX = 4 * 1024 * 1024;
|
|
17
|
+
const LEVEL_COLOR = {
|
|
18
|
+
debug: '\u001b[90m',
|
|
19
|
+
info: '\u001b[36m',
|
|
20
|
+
warn: '\u001b[33m',
|
|
21
|
+
error: '\u001b[31m',
|
|
22
|
+
};
|
|
23
|
+
const COLOR_OFF = '\u001b[0m';
|
|
24
|
+
function target(name) {
|
|
25
|
+
return name === 'stdout' ? process.stdout : process.stderr;
|
|
26
|
+
}
|
|
27
|
+
const pad = (value, width) => value.padEnd(width);
|
|
28
|
+
function prettyLine(record, color) {
|
|
29
|
+
const time = record.at.slice(11, 23);
|
|
30
|
+
const tint = color ? (LEVEL_COLOR[record.level] ?? '') : '';
|
|
31
|
+
const off = tint ? COLOR_OFF : '';
|
|
32
|
+
const parts = [];
|
|
33
|
+
if (record.fn)
|
|
34
|
+
parts.push(`fn=${record.fn}`);
|
|
35
|
+
if (record.tenant)
|
|
36
|
+
parts.push(`tenant=${record.tenant}`);
|
|
37
|
+
if (record.durationMs !== undefined)
|
|
38
|
+
parts.push(`${record.durationMs}ms`);
|
|
39
|
+
if (record.dryRun)
|
|
40
|
+
parts.push('dry-run');
|
|
41
|
+
if (record.replayed)
|
|
42
|
+
parts.push('replayed');
|
|
43
|
+
for (const [key, value] of Object.entries(record.fields ?? {}))
|
|
44
|
+
parts.push(`${key}=${value}`);
|
|
45
|
+
if (record.error)
|
|
46
|
+
parts.push(`${record.error.code}: ${record.error.message}`);
|
|
47
|
+
const message = record.message ? ` ${record.message}` : '';
|
|
48
|
+
const tail = parts.length ? ` ${parts.join(' ')}` : '';
|
|
49
|
+
return `${time} ${tint}${pad(record.level, 5)}${off} ${pad(record.event, 18)}${message}${tail}\n`;
|
|
50
|
+
}
|
|
51
|
+
export function consoleLog(options = {}) {
|
|
52
|
+
const out = target(options.stream ?? 'stderr');
|
|
53
|
+
const pretty = options.pretty ?? false;
|
|
54
|
+
const color = options.color ?? Boolean(out.isTTY);
|
|
55
|
+
const bufferMax = options.bufferMax ?? BUFFER_MAX;
|
|
56
|
+
let dropped = 0;
|
|
57
|
+
let droppedSince = Date.now();
|
|
58
|
+
const line = (record) => pretty ? prettyLine(record, color) : `${JSON.stringify(record)}\n`;
|
|
59
|
+
return {
|
|
60
|
+
name: pretty ? 'pretty' : 'console',
|
|
61
|
+
write(records) {
|
|
62
|
+
for (const record of records) {
|
|
63
|
+
if (out.writableLength > bufferMax) {
|
|
64
|
+
if (!dropped)
|
|
65
|
+
droppedSince = Date.now();
|
|
66
|
+
dropped++;
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
if (dropped) {
|
|
71
|
+
const count = dropped;
|
|
72
|
+
const sinceMs = Date.now() - droppedSince;
|
|
73
|
+
dropped = 0;
|
|
74
|
+
out.write(line({
|
|
75
|
+
at: new Date().toISOString(),
|
|
76
|
+
level: 'warn',
|
|
77
|
+
event: 'log_dropped',
|
|
78
|
+
deployment: record.deployment,
|
|
79
|
+
process: record.process,
|
|
80
|
+
tenant: null,
|
|
81
|
+
trace: null,
|
|
82
|
+
fields: { count, sinceMs, reason: 'stream_backpressure' },
|
|
83
|
+
}));
|
|
84
|
+
}
|
|
85
|
+
out.write(line(record));
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
/* a closed stdio stream must not take the application with it */
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/** `consoleLog` with columns a person can read. The development default. */
|
|
95
|
+
export const prettyLog = (options = {}) => consoleLog({ ...options, pretty: true });
|
|
96
|
+
//# sourceMappingURL=console.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"console.js","sourceRoot":"","sources":["../../../../../../../packages/ketjs/src/server/log/console.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { LogDriver } from './types.ts';
|
|
2
|
+
export type FileLogOptions = {
|
|
3
|
+
dir: string;
|
|
4
|
+
file?: string;
|
|
5
|
+
/** Rotate once the active file passes this size. */
|
|
6
|
+
maxBytes?: number;
|
|
7
|
+
/** How many rotated generations to keep beside the active file. */
|
|
8
|
+
keep?: number;
|
|
9
|
+
};
|
|
10
|
+
export declare function fileLog(options: FileLogOptions): LogDriver;
|
|
11
|
+
//# sourceMappingURL=file.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../../../../../packages/ketjs/src/server/log/file.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,SAAS,EAAa,MAAM,YAAY,CAAA;AAEtD,MAAM,MAAM,cAAc,GAAG;IAC3B,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,oDAAoD;IACpD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,mEAAmE;IACnE,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,CAAA;AAUD,wBAAgB,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,SAAS,CAoC1D"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// A rotating file, for a deployment with nowhere to send stderr.
|
|
2
|
+
//
|
|
3
|
+
// In a container runtime this driver is the wrong answer: the runtime already
|
|
4
|
+
// captures stderr, and a file inside a pod is deleted with the pod. It is here for
|
|
5
|
+
// the deployment that runs under a service manager on a host it owns.
|
|
6
|
+
//
|
|
7
|
+
// One `appendFileSync` per batch rather than a managed stream. A synchronous
|
|
8
|
+
// append is durable the moment it returns, which removes rotation races, partial
|
|
9
|
+
// lines on crash, and the question of what `flush` means — and `bufferedLog` in
|
|
10
|
+
// front of it amortises the open/close across a whole second of records.
|
|
11
|
+
import { appendFileSync, mkdirSync, renameSync, statSync } from 'node:fs';
|
|
12
|
+
import { join } from 'node:path';
|
|
13
|
+
const sizeOf = (path) => {
|
|
14
|
+
try {
|
|
15
|
+
return statSync(path).size;
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return 0;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
export function fileLog(options) {
|
|
22
|
+
const maxBytes = Math.max(1, options.maxBytes ?? 32 * 1024 * 1024);
|
|
23
|
+
const keep = Math.max(1, options.keep ?? 5);
|
|
24
|
+
const path = join(options.dir, options.file ?? 'ket.log');
|
|
25
|
+
mkdirSync(options.dir, { recursive: true });
|
|
26
|
+
const rotate = () => {
|
|
27
|
+
// Downwards, so a generation is never overwritten before it has moved. rename
|
|
28
|
+
// replaces its destination, which is what retires the oldest generation.
|
|
29
|
+
for (let index = keep - 1; index >= 1; index--) {
|
|
30
|
+
try {
|
|
31
|
+
renameSync(`${path}.${index}`, `${path}.${index + 1}`);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
/* that generation does not exist yet */
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
renameSync(path, `${path}.1`);
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
/* nothing written yet */
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
return {
|
|
45
|
+
name: 'file',
|
|
46
|
+
write(records) {
|
|
47
|
+
if (!records.length)
|
|
48
|
+
return;
|
|
49
|
+
const payload = `${records.map((record) => JSON.stringify(record)).join('\n')}\n`;
|
|
50
|
+
try {
|
|
51
|
+
appendFileSync(path, payload);
|
|
52
|
+
if (sizeOf(path) >= maxBytes)
|
|
53
|
+
rotate();
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
/* a full or read-only disk must not take the application with it */
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file.js","sourceRoot":"","sources":["../../../../../../../packages/ketjs/src/server/log/file.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,EAAE;AACF,8EAA8E;AAC9E,mFAAmF;AACnF,sEAAsE;AACtE,EAAE;AACF,6EAA6E;AAC7E,iFAAiF;AACjF,gFAAgF;AAChF,yEAAyE;AAEzE,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AACzE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAYhC,MAAM,MAAM,GAAG,CAAC,IAAY,EAAU,EAAE;IACtC,IAAI,CAAC;QACH,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAA;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,CAAA;IACV,CAAC;AACH,CAAC,CAAA;AAED,MAAM,UAAU,OAAO,CAAC,OAAuB;IAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,QAAQ,IAAI,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC,CAAA;IAClE,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,CAAA;IAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,IAAI,SAAS,CAAC,CAAA;IACzD,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAE3C,MAAM,MAAM,GAAG,GAAS,EAAE;QACxB,8EAA8E;QAC9E,yEAAyE;QACzE,KAAK,IAAI,KAAK,GAAG,IAAI,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;YAC/C,IAAI,CAAC;gBACH,UAAU,CAAC,GAAG,IAAI,IAAI,KAAK,EAAE,EAAE,GAAG,IAAI,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC,CAAA;YACxD,CAAC;YAAC,MAAM,CAAC;gBACP,wCAAwC;YAC1C,CAAC;QACH,CAAC;QACD,IAAI,CAAC;YACH,UAAU,CAAC,IAAI,EAAE,GAAG,IAAI,IAAI,CAAC,CAAA;QAC/B,CAAC;QAAC,MAAM,CAAC;YACP,yBAAyB;QAC3B,CAAC;IACH,CAAC,CAAA;IAED,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,KAAK,CAAC,OAA6B;YACjC,IAAI,CAAC,OAAO,CAAC,MAAM;gBAAE,OAAM;YAC3B,MAAM,OAAO,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAA;YACjF,IAAI,CAAC;gBACH,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;gBAC7B,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,QAAQ;oBAAE,MAAM,EAAE,CAAA;YACxC,CAAC;YAAC,MAAM,CAAC;gBACP,oEAAoE;YACtE,CAAC;QACH,CAAC;KACF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { RuntimeConfig } from '../config.ts';
|
|
2
|
+
import type { LogDriver } from './types.ts';
|
|
3
|
+
export { atLeast, isLogDriverName, isLogLevel, nullLog, CORE_EVENTS, MODULE_EVENT } from './types.ts';
|
|
4
|
+
export type { CoreEvent, LogDriver, LogDriverName, LogError, LogFields, LogLevel, LogProcess, LogRecord, OpenLog, } from './types.ts';
|
|
5
|
+
export { bufferedLog, isolatedLog, leveledLog, multiLog, redactLog } from './combinators.ts';
|
|
6
|
+
export { consoleLog, prettyLog } from './console.ts';
|
|
7
|
+
export type { ConsoleLogOptions } from './console.ts';
|
|
8
|
+
export { fileLog } from './file.ts';
|
|
9
|
+
export type { FileLogOptions } from './file.ts';
|
|
10
|
+
export { memoryLog } from './memory.ts';
|
|
11
|
+
export type { MemoryLog } from './memory.ts';
|
|
12
|
+
export { createLogger, describeError, traceOf } from './logger.ts';
|
|
13
|
+
export type { LogContext, LogEntry, Logger } from './logger.ts';
|
|
14
|
+
/**
|
|
15
|
+
* The sink the framework opens when the deployment does not hand one in.
|
|
16
|
+
*
|
|
17
|
+
* Which driver, not which behaviour: level filtering and redaction are applied by
|
|
18
|
+
* the runtime around whatever comes back from here, so a deployment's own
|
|
19
|
+
* `serve.openLog` gets the same treatment as the built-ins rather than having to
|
|
20
|
+
* remember to ask for it.
|
|
21
|
+
*/
|
|
22
|
+
export declare function logFromConfig(config: RuntimeConfig): LogDriver;
|
|
23
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../packages/ketjs/src/server/log/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAIjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAG3C,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACrG,YAAY,EACV,SAAS,EACT,SAAS,EACT,aAAa,EACb,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,UAAU,EACV,SAAS,EACT,OAAO,GACR,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC5F,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AACpD,YAAY,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAClE,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAE/D;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,CAwB9D"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { KetError } from '../../kernel/errors.js';
|
|
2
|
+
import { bufferedLog } from './combinators.js';
|
|
3
|
+
import { consoleLog, prettyLog } from './console.js';
|
|
4
|
+
import { fileLog } from './file.js';
|
|
5
|
+
import { nullLog } from './types.js';
|
|
6
|
+
export { atLeast, isLogDriverName, isLogLevel, nullLog, CORE_EVENTS, MODULE_EVENT } from './types.js';
|
|
7
|
+
export { bufferedLog, isolatedLog, leveledLog, multiLog, redactLog } from './combinators.js';
|
|
8
|
+
export { consoleLog, prettyLog } from './console.js';
|
|
9
|
+
export { fileLog } from './file.js';
|
|
10
|
+
export { memoryLog } from './memory.js';
|
|
11
|
+
export { createLogger, describeError, traceOf } from './logger.js';
|
|
12
|
+
/**
|
|
13
|
+
* The sink the framework opens when the deployment does not hand one in.
|
|
14
|
+
*
|
|
15
|
+
* Which driver, not which behaviour: level filtering and redaction are applied by
|
|
16
|
+
* the runtime around whatever comes back from here, so a deployment's own
|
|
17
|
+
* `serve.openLog` gets the same treatment as the built-ins rather than having to
|
|
18
|
+
* remember to ask for it.
|
|
19
|
+
*/
|
|
20
|
+
export function logFromConfig(config) {
|
|
21
|
+
switch (config.logDriver) {
|
|
22
|
+
case 'null':
|
|
23
|
+
return nullLog();
|
|
24
|
+
case 'console':
|
|
25
|
+
return consoleLog({ stream: config.logStream });
|
|
26
|
+
case 'pretty':
|
|
27
|
+
return prettyLog({ stream: config.logStream });
|
|
28
|
+
case 'file': {
|
|
29
|
+
if (!config.logDir)
|
|
30
|
+
throw new KetError({
|
|
31
|
+
code: 'E_LOG_CONFIG',
|
|
32
|
+
message: 'file logging is missing KET_LOG_DIR',
|
|
33
|
+
hint: 'set KET_LOG_DIR, or choose another KET_LOG driver',
|
|
34
|
+
});
|
|
35
|
+
// Batched, because an append per record would be an open per record.
|
|
36
|
+
return bufferedLog(fileLog({ dir: config.logDir }), { max: config.logBuffer });
|
|
37
|
+
}
|
|
38
|
+
default:
|
|
39
|
+
// A terminal gets columns; a pipe gets NDJSON. Nobody configures the obvious.
|
|
40
|
+
return process.stderr.isTTY
|
|
41
|
+
? prettyLog({ stream: config.logStream })
|
|
42
|
+
: consoleLog({ stream: config.logStream });
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../packages/ketjs/src/server/log/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AAEjD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAEnC,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAEpC,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAYrG,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC5F,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAEpD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAEnC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAEvC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAGlE;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,MAAqB;IACjD,QAAQ,MAAM,CAAC,SAAS,EAAE,CAAC;QACzB,KAAK,MAAM;YACT,OAAO,OAAO,EAAE,CAAA;QAClB,KAAK,SAAS;YACZ,OAAO,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAA;QACjD,KAAK,QAAQ;YACX,OAAO,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAA;QAChD,KAAK,MAAM,EAAE,CAAC;YACZ,IAAI,CAAC,MAAM,CAAC,MAAM;gBAChB,MAAM,IAAI,QAAQ,CAAC;oBACjB,IAAI,EAAE,cAAc;oBACpB,OAAO,EAAE,qCAAqC;oBAC9C,IAAI,EAAE,mDAAmD;iBAC1D,CAAC,CAAA;YACJ,qEAAqE;YACrE,OAAO,WAAW,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAA;QAChF,CAAC;QACD;YACE,8EAA8E;YAC9E,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK;gBACzB,CAAC,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC;gBACzC,CAAC,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAA;IAChD,CAAC;AACH,CAAC"}
|