@salesforce/b2c-tooling-sdk 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/auth/api-key.d.ts +2 -2
- package/dist/cjs/auth/api-key.js +1 -0
- package/dist/cjs/auth/api-key.js.map +1 -1
- package/dist/cjs/auth/basic.d.ts +2 -2
- package/dist/cjs/auth/basic.js +2 -0
- package/dist/cjs/auth/basic.js.map +1 -1
- package/dist/cjs/auth/index.d.ts +1 -1
- package/dist/cjs/auth/index.js.map +1 -1
- package/dist/cjs/auth/oauth-implicit.d.ts +2 -2
- package/dist/cjs/auth/oauth-implicit.js +1 -0
- package/dist/cjs/auth/oauth-implicit.js.map +1 -1
- package/dist/cjs/auth/oauth.d.ts +2 -2
- package/dist/cjs/auth/oauth.js +2 -0
- package/dist/cjs/auth/oauth.js.map +1 -1
- package/dist/cjs/auth/types.d.ts +10 -1
- package/dist/cjs/auth/types.js +5 -0
- package/dist/cjs/auth/types.js.map +1 -1
- package/dist/cjs/cli/base-command.d.ts +23 -0
- package/dist/cjs/cli/base-command.js +29 -4
- package/dist/cjs/cli/base-command.js.map +1 -1
- package/dist/cjs/cli/config.d.ts +71 -0
- package/dist/cjs/cli/config.js +105 -2
- package/dist/cjs/cli/config.js.map +1 -1
- package/dist/cjs/cli/index.d.ts +2 -2
- package/dist/cjs/cli/index.js +3 -1
- package/dist/cjs/cli/index.js.map +1 -1
- package/dist/cjs/cli/instance-command.d.ts +4 -0
- package/dist/cjs/cli/instance-command.js +24 -23
- package/dist/cjs/cli/instance-command.js.map +1 -1
- package/dist/cjs/cli/mrt-command.d.ts +0 -6
- package/dist/cjs/cli/mrt-command.js +5 -29
- package/dist/cjs/cli/mrt-command.js.map +1 -1
- package/dist/cjs/cli/oauth-command.d.ts +5 -6
- package/dist/cjs/cli/oauth-command.js +13 -35
- package/dist/cjs/cli/oauth-command.js.map +1 -1
- package/dist/cjs/cli/ods-command.d.ts +18 -0
- package/dist/cjs/cli/ods-command.js +51 -0
- package/dist/cjs/cli/ods-command.js.map +1 -1
- package/dist/cjs/cli/webdav-command.d.ts +4 -0
- package/dist/cjs/clients/cdn-zones.d.ts +33 -1
- package/dist/cjs/clients/cdn-zones.js.map +1 -1
- package/dist/cjs/clients/custom-apis.d.ts +30 -1
- package/dist/cjs/clients/custom-apis.js.map +1 -1
- package/dist/cjs/clients/index.d.ts +2 -0
- package/dist/cjs/clients/index.js +1 -0
- package/dist/cjs/clients/index.js.map +1 -1
- package/dist/cjs/clients/mrt-b2c.d.ts +25 -1
- package/dist/cjs/clients/mrt-b2c.js.map +1 -1
- package/dist/cjs/clients/mrt.d.ts +24 -1
- package/dist/cjs/clients/mrt.js.map +1 -1
- package/dist/cjs/clients/ocapi.d.ts +22 -2
- package/dist/cjs/clients/ocapi.js +0 -2
- package/dist/cjs/clients/ocapi.js.map +1 -1
- package/dist/cjs/clients/ods.d.ts +28 -1
- package/dist/cjs/clients/ods.js.map +1 -1
- package/dist/cjs/clients/scapi-schemas.d.ts +30 -1
- package/dist/cjs/clients/scapi-schemas.js.map +1 -1
- package/dist/cjs/clients/slas-admin.d.ts +28 -0
- package/dist/cjs/clients/slas-admin.js.map +1 -1
- package/dist/cjs/clients/tls-dispatcher.d.ts +42 -0
- package/dist/cjs/clients/tls-dispatcher.js +107 -0
- package/dist/cjs/clients/tls-dispatcher.js.map +1 -0
- package/dist/cjs/clients/webdav.d.ts +8 -1
- package/dist/cjs/clients/webdav.js +5 -1
- package/dist/cjs/clients/webdav.js.map +1 -1
- package/dist/cjs/config/dw-json.d.ts +14 -0
- package/dist/cjs/config/dw-json.js +3 -2
- package/dist/cjs/config/dw-json.js.map +1 -1
- package/dist/cjs/config/index.d.ts +2 -2
- package/dist/cjs/config/index.js +1 -1
- package/dist/cjs/config/index.js.map +1 -1
- package/dist/cjs/config/mapping.d.ts +1 -1
- package/dist/cjs/config/mapping.js +20 -4
- package/dist/cjs/config/mapping.js.map +1 -1
- package/dist/cjs/config/resolved-config.d.ts +1 -3
- package/dist/cjs/config/resolved-config.js +0 -8
- package/dist/cjs/config/resolved-config.js.map +1 -1
- package/dist/cjs/config/resolver.d.ts +1 -1
- package/dist/cjs/config/resolver.js +20 -4
- package/dist/cjs/config/resolver.js.map +1 -1
- package/dist/cjs/config/sources/mobify-source.js +3 -2
- package/dist/cjs/config/sources/mobify-source.js.map +1 -1
- package/dist/cjs/config/sources/package-json-source.js +3 -1
- package/dist/cjs/config/sources/package-json-source.js.map +1 -1
- package/dist/cjs/config/types.d.ts +6 -18
- package/dist/{esm/operations → cjs}/docs/download.d.ts +1 -1
- package/dist/cjs/{operations/docs → docs}/download.js +2 -2
- package/dist/cjs/docs/download.js.map +1 -0
- package/dist/{esm/operations → cjs}/docs/index.d.ts +4 -4
- package/dist/cjs/docs/index.js.map +1 -0
- package/dist/cjs/docs/schema.js.map +1 -0
- package/dist/cjs/docs/search.js.map +1 -0
- package/dist/cjs/docs/types.js.map +1 -0
- package/dist/cjs/index.d.ts +5 -10
- package/dist/cjs/index.js +4 -8
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/instance/index.d.ts +4 -0
- package/dist/cjs/instance/index.js +6 -1
- package/dist/cjs/instance/index.js.map +1 -1
- package/dist/cjs/logging/index.d.ts +1 -1
- package/dist/cjs/logging/logger.js +15 -0
- package/dist/cjs/logging/logger.js.map +1 -1
- package/dist/cjs/logging/types.d.ts +9 -0
- package/dist/cjs/operations/logs/index.d.ts +65 -0
- package/dist/cjs/operations/logs/index.js +73 -0
- package/dist/cjs/operations/logs/index.js.map +1 -0
- package/dist/cjs/operations/logs/list.d.ts +35 -0
- package/dist/cjs/operations/logs/list.js +144 -0
- package/dist/cjs/operations/logs/list.js.map +1 -0
- package/dist/cjs/operations/logs/path-normalizer.d.ts +82 -0
- package/dist/cjs/operations/logs/path-normalizer.js +190 -0
- package/dist/cjs/operations/logs/path-normalizer.js.map +1 -0
- package/dist/cjs/operations/logs/tail.d.ts +92 -0
- package/dist/cjs/operations/logs/tail.js +525 -0
- package/dist/cjs/operations/logs/tail.js.map +1 -0
- package/dist/cjs/operations/logs/types.d.ts +132 -0
- package/dist/cjs/operations/logs/types.js +7 -0
- package/dist/cjs/operations/logs/types.js.map +1 -0
- package/dist/cjs/operations/mrt/push.js +3 -0
- package/dist/cjs/operations/mrt/push.js.map +1 -1
- package/dist/cjs/operations/ods/index.d.ts +6 -0
- package/dist/cjs/operations/ods/index.js +12 -0
- package/dist/cjs/operations/ods/index.js.map +1 -0
- package/dist/cjs/operations/ods/sandbox-lookup.d.ts +63 -0
- package/dist/cjs/operations/ods/sandbox-lookup.js +130 -0
- package/dist/cjs/operations/ods/sandbox-lookup.js.map +1 -0
- package/dist/{esm/operations/scapi-schemas → cjs/schemas}/collapse.d.ts +1 -1
- package/dist/cjs/schemas/collapse.js.map +1 -0
- package/dist/cjs/{operations/scapi-schemas → schemas}/index.d.ts +5 -5
- package/dist/cjs/{operations/scapi-schemas → schemas}/index.js +5 -5
- package/dist/cjs/schemas/index.js.map +1 -0
- package/dist/cjs/test-utils/config-isolation.js +7 -0
- package/dist/cjs/test-utils/config-isolation.js.map +1 -1
- package/dist/esm/auth/api-key.d.ts +2 -2
- package/dist/esm/auth/api-key.js +1 -0
- package/dist/esm/auth/api-key.js.map +1 -1
- package/dist/esm/auth/basic.d.ts +2 -2
- package/dist/esm/auth/basic.js +2 -0
- package/dist/esm/auth/basic.js.map +1 -1
- package/dist/esm/auth/index.d.ts +1 -1
- package/dist/esm/auth/index.js.map +1 -1
- package/dist/esm/auth/oauth-implicit.d.ts +2 -2
- package/dist/esm/auth/oauth-implicit.js +1 -0
- package/dist/esm/auth/oauth-implicit.js.map +1 -1
- package/dist/esm/auth/oauth.d.ts +2 -2
- package/dist/esm/auth/oauth.js +2 -0
- package/dist/esm/auth/oauth.js.map +1 -1
- package/dist/esm/auth/types.d.ts +10 -1
- package/dist/esm/auth/types.js +5 -0
- package/dist/esm/auth/types.js.map +1 -1
- package/dist/esm/cli/base-command.d.ts +23 -0
- package/dist/esm/cli/base-command.js +29 -4
- package/dist/esm/cli/base-command.js.map +1 -1
- package/dist/esm/cli/config.d.ts +71 -0
- package/dist/esm/cli/config.js +105 -2
- package/dist/esm/cli/config.js.map +1 -1
- package/dist/esm/cli/index.d.ts +2 -2
- package/dist/esm/cli/index.js +3 -1
- package/dist/esm/cli/index.js.map +1 -1
- package/dist/esm/cli/instance-command.d.ts +4 -0
- package/dist/esm/cli/instance-command.js +24 -23
- package/dist/esm/cli/instance-command.js.map +1 -1
- package/dist/esm/cli/mrt-command.d.ts +0 -6
- package/dist/esm/cli/mrt-command.js +5 -29
- package/dist/esm/cli/mrt-command.js.map +1 -1
- package/dist/esm/cli/oauth-command.d.ts +5 -6
- package/dist/esm/cli/oauth-command.js +13 -35
- package/dist/esm/cli/oauth-command.js.map +1 -1
- package/dist/esm/cli/ods-command.d.ts +18 -0
- package/dist/esm/cli/ods-command.js +51 -0
- package/dist/esm/cli/ods-command.js.map +1 -1
- package/dist/esm/cli/webdav-command.d.ts +4 -0
- package/dist/esm/clients/cdn-zones.d.ts +33 -1
- package/dist/esm/clients/cdn-zones.js.map +1 -1
- package/dist/esm/clients/custom-apis.d.ts +30 -1
- package/dist/esm/clients/custom-apis.js.map +1 -1
- package/dist/esm/clients/index.d.ts +2 -0
- package/dist/esm/clients/index.js +1 -0
- package/dist/esm/clients/index.js.map +1 -1
- package/dist/esm/clients/mrt-b2c.d.ts +25 -1
- package/dist/esm/clients/mrt-b2c.js.map +1 -1
- package/dist/esm/clients/mrt.d.ts +24 -1
- package/dist/esm/clients/mrt.js.map +1 -1
- package/dist/esm/clients/ocapi.d.ts +22 -2
- package/dist/esm/clients/ocapi.js +0 -2
- package/dist/esm/clients/ocapi.js.map +1 -1
- package/dist/esm/clients/ods.d.ts +28 -1
- package/dist/esm/clients/ods.js.map +1 -1
- package/dist/esm/clients/scapi-schemas.d.ts +30 -1
- package/dist/esm/clients/scapi-schemas.js.map +1 -1
- package/dist/esm/clients/slas-admin.d.ts +28 -0
- package/dist/esm/clients/slas-admin.js.map +1 -1
- package/dist/esm/clients/tls-dispatcher.d.ts +42 -0
- package/dist/esm/clients/tls-dispatcher.js +107 -0
- package/dist/esm/clients/tls-dispatcher.js.map +1 -0
- package/dist/esm/clients/webdav.d.ts +8 -1
- package/dist/esm/clients/webdav.js +5 -1
- package/dist/esm/clients/webdav.js.map +1 -1
- package/dist/esm/config/dw-json.d.ts +14 -0
- package/dist/esm/config/dw-json.js +3 -2
- package/dist/esm/config/dw-json.js.map +1 -1
- package/dist/esm/config/index.d.ts +2 -2
- package/dist/esm/config/index.js +1 -1
- package/dist/esm/config/index.js.map +1 -1
- package/dist/esm/config/mapping.d.ts +1 -1
- package/dist/esm/config/mapping.js +20 -4
- package/dist/esm/config/mapping.js.map +1 -1
- package/dist/esm/config/resolved-config.d.ts +1 -3
- package/dist/esm/config/resolved-config.js +0 -8
- package/dist/esm/config/resolved-config.js.map +1 -1
- package/dist/esm/config/resolver.d.ts +1 -1
- package/dist/esm/config/resolver.js +20 -4
- package/dist/esm/config/resolver.js.map +1 -1
- package/dist/esm/config/sources/mobify-source.js +3 -2
- package/dist/esm/config/sources/mobify-source.js.map +1 -1
- package/dist/esm/config/sources/package-json-source.js +3 -1
- package/dist/esm/config/sources/package-json-source.js.map +1 -1
- package/dist/esm/config/types.d.ts +6 -18
- package/dist/{cjs/operations → esm}/docs/download.d.ts +1 -1
- package/dist/esm/{operations/docs → docs}/download.js +2 -2
- package/dist/esm/docs/download.js.map +1 -0
- package/dist/{cjs/operations → esm}/docs/index.d.ts +4 -4
- package/dist/esm/docs/index.js.map +1 -0
- package/dist/esm/docs/schema.js.map +1 -0
- package/dist/esm/docs/search.js.map +1 -0
- package/dist/esm/docs/types.js.map +1 -0
- package/dist/esm/index.d.ts +5 -10
- package/dist/esm/index.js +4 -8
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/instance/index.d.ts +4 -0
- package/dist/esm/instance/index.js +6 -1
- package/dist/esm/instance/index.js.map +1 -1
- package/dist/esm/logging/index.d.ts +1 -1
- package/dist/esm/logging/logger.js +15 -0
- package/dist/esm/logging/logger.js.map +1 -1
- package/dist/esm/logging/types.d.ts +9 -0
- package/dist/esm/operations/logs/index.d.ts +65 -0
- package/dist/esm/operations/logs/index.js +73 -0
- package/dist/esm/operations/logs/index.js.map +1 -0
- package/dist/esm/operations/logs/list.d.ts +35 -0
- package/dist/esm/operations/logs/list.js +144 -0
- package/dist/esm/operations/logs/list.js.map +1 -0
- package/dist/esm/operations/logs/path-normalizer.d.ts +82 -0
- package/dist/esm/operations/logs/path-normalizer.js +190 -0
- package/dist/esm/operations/logs/path-normalizer.js.map +1 -0
- package/dist/esm/operations/logs/tail.d.ts +92 -0
- package/dist/esm/operations/logs/tail.js +525 -0
- package/dist/esm/operations/logs/tail.js.map +1 -0
- package/dist/esm/operations/logs/types.d.ts +132 -0
- package/dist/esm/operations/logs/types.js +7 -0
- package/dist/esm/operations/logs/types.js.map +1 -0
- package/dist/esm/operations/mrt/push.js +3 -0
- package/dist/esm/operations/mrt/push.js.map +1 -1
- package/dist/esm/operations/ods/index.d.ts +6 -0
- package/dist/esm/operations/ods/index.js +12 -0
- package/dist/esm/operations/ods/index.js.map +1 -0
- package/dist/esm/operations/ods/sandbox-lookup.d.ts +63 -0
- package/dist/esm/operations/ods/sandbox-lookup.js +130 -0
- package/dist/esm/operations/ods/sandbox-lookup.js.map +1 -0
- package/dist/{cjs/operations/scapi-schemas → esm/schemas}/collapse.d.ts +1 -1
- package/dist/esm/schemas/collapse.js.map +1 -0
- package/dist/esm/{operations/scapi-schemas → schemas}/index.d.ts +5 -5
- package/dist/esm/{operations/scapi-schemas → schemas}/index.js +5 -5
- package/dist/esm/schemas/index.js.map +1 -0
- package/dist/esm/test-utils/config-isolation.js +7 -0
- package/dist/esm/test-utils/config-isolation.js.map +1 -1
- package/package.json +28 -35
- package/dist/cjs/logger.d.ts +0 -66
- package/dist/cjs/logger.js +0 -80
- package/dist/cjs/logger.js.map +0 -1
- package/dist/cjs/operations/docs/download.js.map +0 -1
- package/dist/cjs/operations/docs/index.js.map +0 -1
- package/dist/cjs/operations/docs/schema.js.map +0 -1
- package/dist/cjs/operations/docs/search.js.map +0 -1
- package/dist/cjs/operations/docs/types.js.map +0 -1
- package/dist/cjs/operations/scapi-schemas/collapse.js.map +0 -1
- package/dist/cjs/operations/scapi-schemas/index.js.map +0 -1
- package/dist/cjs/operations/sites/index.d.ts +0 -56
- package/dist/cjs/operations/sites/index.js +0 -19
- package/dist/cjs/operations/sites/index.js.map +0 -1
- package/dist/cjs/platform/index.d.ts +0 -38
- package/dist/cjs/platform/index.js +0 -42
- package/dist/cjs/platform/index.js.map +0 -1
- package/dist/cjs/platform/mrt.d.ts +0 -19
- package/dist/cjs/platform/mrt.js +0 -22
- package/dist/cjs/platform/mrt.js.map +0 -1
- package/dist/cjs/platform/ods.d.ts +0 -17
- package/dist/cjs/platform/ods.js +0 -22
- package/dist/cjs/platform/ods.js.map +0 -1
- package/dist/esm/logger.d.ts +0 -66
- package/dist/esm/logger.js +0 -80
- package/dist/esm/logger.js.map +0 -1
- package/dist/esm/operations/docs/download.js.map +0 -1
- package/dist/esm/operations/docs/index.js.map +0 -1
- package/dist/esm/operations/docs/schema.js.map +0 -1
- package/dist/esm/operations/docs/search.js.map +0 -1
- package/dist/esm/operations/docs/types.js.map +0 -1
- package/dist/esm/operations/scapi-schemas/collapse.js.map +0 -1
- package/dist/esm/operations/scapi-schemas/index.js.map +0 -1
- package/dist/esm/operations/sites/index.d.ts +0 -56
- package/dist/esm/operations/sites/index.js +0 -67
- package/dist/esm/operations/sites/index.js.map +0 -1
- package/dist/esm/platform/index.d.ts +0 -38
- package/dist/esm/platform/index.js +0 -42
- package/dist/esm/platform/index.js.map +0 -1
- package/dist/esm/platform/mrt.d.ts +0 -19
- package/dist/esm/platform/mrt.js +0 -22
- package/dist/esm/platform/mrt.js.map +0 -1
- package/dist/esm/platform/ods.d.ts +0 -17
- package/dist/esm/platform/ods.js +0 -22
- package/dist/esm/platform/ods.js.map +0 -1
- /package/dist/cjs/{operations/docs → docs}/index.js +0 -0
- /package/dist/cjs/{operations/docs → docs}/schema.d.ts +0 -0
- /package/dist/cjs/{operations/docs → docs}/schema.js +0 -0
- /package/dist/cjs/{operations/docs → docs}/search.d.ts +0 -0
- /package/dist/cjs/{operations/docs → docs}/search.js +0 -0
- /package/dist/cjs/{operations/docs → docs}/types.d.ts +0 -0
- /package/dist/cjs/{operations/docs → docs}/types.js +0 -0
- /package/dist/cjs/{operations/scapi-schemas → schemas}/collapse.js +0 -0
- /package/dist/esm/{operations/docs → docs}/index.js +0 -0
- /package/dist/esm/{operations/docs → docs}/schema.d.ts +0 -0
- /package/dist/esm/{operations/docs → docs}/schema.js +0 -0
- /package/dist/esm/{operations/docs → docs}/search.d.ts +0 -0
- /package/dist/esm/{operations/docs → docs}/search.js +0 -0
- /package/dist/esm/{operations/docs → docs}/types.d.ts +0 -0
- /package/dist/esm/{operations/docs → docs}/types.js +0 -0
- /package/dist/esm/{operations/scapi-schemas → schemas}/collapse.js +0 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Log tailing operations for B2C Commerce.
|
|
3
|
+
*/
|
|
4
|
+
import type { B2CInstance } from '../../instance/index.js';
|
|
5
|
+
import type { GetRecentLogsOptions, LogEntry, TailLogsOptions, TailLogsResult } from './types.js';
|
|
6
|
+
/**
|
|
7
|
+
* Parses the first line of a log entry to extract timestamp, level, and message.
|
|
8
|
+
*
|
|
9
|
+
* Expected format: [timestamp GMT] LEVEL context - message
|
|
10
|
+
* Example: [2025-01-25 10:30:45.123 GMT] ERROR PipelineCallServlet|... - Error message
|
|
11
|
+
*
|
|
12
|
+
* The message field will contain:
|
|
13
|
+
* - The content portion from the first line (after LEVEL)
|
|
14
|
+
* - Plus any continuation lines (stack traces, etc.)
|
|
15
|
+
*
|
|
16
|
+
* @param firstLine - First line of the log entry
|
|
17
|
+
* @param file - File name the entry came from
|
|
18
|
+
* @param fullMessage - Complete raw message including all lines
|
|
19
|
+
* @param pathNormalizer - Optional function to normalize paths in the message
|
|
20
|
+
* @returns Parsed log entry
|
|
21
|
+
*/
|
|
22
|
+
export declare function parseLogEntry(firstLine: string, file: string, fullMessage: string, pathNormalizer?: (msg: string) => string): LogEntry;
|
|
23
|
+
/**
|
|
24
|
+
* Splits content into lines, handling incomplete lines at boundaries.
|
|
25
|
+
* Uses TextDecoder with stream mode for proper UTF-8 multi-byte character handling.
|
|
26
|
+
*
|
|
27
|
+
* @param content - ArrayBuffer content
|
|
28
|
+
* @param decoder - TextDecoder instance (should be reused for streaming)
|
|
29
|
+
* @param isComplete - Whether this is the final chunk (flush decoder)
|
|
30
|
+
* @returns Array of complete lines (without trailing incomplete line)
|
|
31
|
+
*/
|
|
32
|
+
export declare function splitLines(content: ArrayBuffer, decoder: InstanceType<typeof TextDecoder>, isComplete?: boolean): string[];
|
|
33
|
+
/**
|
|
34
|
+
* Aggregates lines into multi-line log entries.
|
|
35
|
+
*
|
|
36
|
+
* B2C log entries can span multiple lines. A new entry starts when a line
|
|
37
|
+
* begins with a timestamp pattern: [YYYY-MM-DD HH:MM:SS.mmm GMT]
|
|
38
|
+
*
|
|
39
|
+
* @param lines - Array of individual lines
|
|
40
|
+
* @param pendingLines - Lines carried over from previous chunk (incomplete entry)
|
|
41
|
+
* @returns Object with complete entries and any pending lines for next chunk
|
|
42
|
+
*/
|
|
43
|
+
export declare function aggregateLogEntries(lines: string[], pendingLines?: string[]): {
|
|
44
|
+
entries: string[][];
|
|
45
|
+
pending: string[];
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Tails log files on a B2C Commerce instance.
|
|
49
|
+
*
|
|
50
|
+
* Continuously polls for new log content using HTTP Range requests for efficiency.
|
|
51
|
+
* Calls the onEntry callback for each new log line.
|
|
52
|
+
*
|
|
53
|
+
* @param instance - B2C instance to tail logs from
|
|
54
|
+
* @param options - Tailing options (filters, callbacks, polling interval)
|
|
55
|
+
* @returns Tail result with stop() control and done promise
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* const result = await tailLogs(instance, {
|
|
60
|
+
* prefixes: ['error', 'customerror'],
|
|
61
|
+
* onEntry: (entry) => console.log(`[${entry.file}] ${entry.message}`),
|
|
62
|
+
* onError: (err) => console.error('Tail error:', err),
|
|
63
|
+
* });
|
|
64
|
+
*
|
|
65
|
+
* // Stop after 10 seconds
|
|
66
|
+
* setTimeout(() => result.stop(), 10000);
|
|
67
|
+
*
|
|
68
|
+
* // Wait for tailing to complete
|
|
69
|
+
* await result.done;
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export declare function tailLogs(instance: B2CInstance, options?: TailLogsOptions): Promise<TailLogsResult>;
|
|
73
|
+
/**
|
|
74
|
+
* Gets recent log entries (one-shot retrieval).
|
|
75
|
+
*
|
|
76
|
+
* Useful for MCP server integration or programmatic access without continuous tailing.
|
|
77
|
+
* Reads the tail end of log files and returns parsed entries.
|
|
78
|
+
*
|
|
79
|
+
* @param instance - B2C instance to get logs from
|
|
80
|
+
* @param options - Retrieval options
|
|
81
|
+
* @returns Array of recent log entries
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```typescript
|
|
85
|
+
* // Get the last 50 error entries
|
|
86
|
+
* const entries = await getRecentLogs(instance, {
|
|
87
|
+
* prefixes: ['error'],
|
|
88
|
+
* maxEntries: 50
|
|
89
|
+
* });
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
export declare function getRecentLogs(instance: B2CInstance, options?: GetRecentLogsOptions): Promise<LogEntry[]>;
|
|
@@ -0,0 +1,525 @@
|
|
|
1
|
+
import { getLogger } from '../../logging/logger.js';
|
|
2
|
+
import { listLogFiles } from './list.js';
|
|
3
|
+
/**
|
|
4
|
+
* Default log prefixes to tail.
|
|
5
|
+
*/
|
|
6
|
+
const DEFAULT_PREFIXES = ['error', 'customerror'];
|
|
7
|
+
/**
|
|
8
|
+
* Default polling interval in milliseconds.
|
|
9
|
+
*/
|
|
10
|
+
const DEFAULT_POLL_INTERVAL = 3000;
|
|
11
|
+
/**
|
|
12
|
+
* Default max entries for getRecentLogs.
|
|
13
|
+
*/
|
|
14
|
+
const DEFAULT_MAX_ENTRIES = 100;
|
|
15
|
+
/**
|
|
16
|
+
* Default bytes to read from end of file for getRecentLogs.
|
|
17
|
+
*/
|
|
18
|
+
const DEFAULT_TAIL_BYTES = 65536; // 64KB
|
|
19
|
+
/**
|
|
20
|
+
* Regex to detect the start of a new log entry.
|
|
21
|
+
* Matches: [YYYY-MM-DD HH:MM:SS.mmm GMT]
|
|
22
|
+
*/
|
|
23
|
+
const LOG_ENTRY_START = /^\[\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}\.\d+\s+\w+\]/;
|
|
24
|
+
/**
|
|
25
|
+
* Parses the first line of a log entry to extract timestamp, level, and message.
|
|
26
|
+
*
|
|
27
|
+
* Expected format: [timestamp GMT] LEVEL context - message
|
|
28
|
+
* Example: [2025-01-25 10:30:45.123 GMT] ERROR PipelineCallServlet|... - Error message
|
|
29
|
+
*
|
|
30
|
+
* The message field will contain:
|
|
31
|
+
* - The content portion from the first line (after LEVEL)
|
|
32
|
+
* - Plus any continuation lines (stack traces, etc.)
|
|
33
|
+
*
|
|
34
|
+
* @param firstLine - First line of the log entry
|
|
35
|
+
* @param file - File name the entry came from
|
|
36
|
+
* @param fullMessage - Complete raw message including all lines
|
|
37
|
+
* @param pathNormalizer - Optional function to normalize paths in the message
|
|
38
|
+
* @returns Parsed log entry
|
|
39
|
+
*/
|
|
40
|
+
export function parseLogEntry(firstLine, file, fullMessage, pathNormalizer) {
|
|
41
|
+
// Try to parse the standard B2C log format: [timestamp GMT] LEVEL message
|
|
42
|
+
const match = firstLine.match(/^\[([^\]]+)\]\s+(INFO|WARN|ERROR|DEBUG|FATAL|TRACE)\s+(.*)$/s);
|
|
43
|
+
if (match) {
|
|
44
|
+
const [, timestamp, level, firstLineContent] = match;
|
|
45
|
+
// Build the message: first line content + continuation lines
|
|
46
|
+
const lines = fullMessage.split('\n');
|
|
47
|
+
const continuationLines = lines.slice(1);
|
|
48
|
+
let message = continuationLines.length > 0 ? [firstLineContent, ...continuationLines].join('\n') : firstLineContent;
|
|
49
|
+
if (pathNormalizer) {
|
|
50
|
+
message = pathNormalizer(message);
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
file,
|
|
54
|
+
timestamp,
|
|
55
|
+
level,
|
|
56
|
+
message,
|
|
57
|
+
raw: fullMessage,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
// Fallback: return as unparsed entry
|
|
61
|
+
let message = fullMessage;
|
|
62
|
+
if (pathNormalizer) {
|
|
63
|
+
message = pathNormalizer(message);
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
file,
|
|
67
|
+
message,
|
|
68
|
+
raw: fullMessage,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Splits content into lines, handling incomplete lines at boundaries.
|
|
73
|
+
* Uses TextDecoder with stream mode for proper UTF-8 multi-byte character handling.
|
|
74
|
+
*
|
|
75
|
+
* @param content - ArrayBuffer content
|
|
76
|
+
* @param decoder - TextDecoder instance (should be reused for streaming)
|
|
77
|
+
* @param isComplete - Whether this is the final chunk (flush decoder)
|
|
78
|
+
* @returns Array of complete lines (without trailing incomplete line)
|
|
79
|
+
*/
|
|
80
|
+
export function splitLines(content, decoder, isComplete = true) {
|
|
81
|
+
const text = decoder.decode(content, { stream: !isComplete });
|
|
82
|
+
// Split by newlines, keeping track of whether last line is complete
|
|
83
|
+
const lines = text.split(/\r?\n/);
|
|
84
|
+
// If the text doesn't end with a newline, the last line is incomplete
|
|
85
|
+
// We should not include it in the results (it will be completed in next read)
|
|
86
|
+
if (!isComplete && lines.length > 0 && !text.endsWith('\n')) {
|
|
87
|
+
lines.pop();
|
|
88
|
+
}
|
|
89
|
+
// Filter out empty lines
|
|
90
|
+
return lines.filter((line) => line.trim().length > 0);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Aggregates lines into multi-line log entries.
|
|
94
|
+
*
|
|
95
|
+
* B2C log entries can span multiple lines. A new entry starts when a line
|
|
96
|
+
* begins with a timestamp pattern: [YYYY-MM-DD HH:MM:SS.mmm GMT]
|
|
97
|
+
*
|
|
98
|
+
* @param lines - Array of individual lines
|
|
99
|
+
* @param pendingLines - Lines carried over from previous chunk (incomplete entry)
|
|
100
|
+
* @returns Object with complete entries and any pending lines for next chunk
|
|
101
|
+
*/
|
|
102
|
+
export function aggregateLogEntries(lines, pendingLines = []) {
|
|
103
|
+
const entries = [];
|
|
104
|
+
let currentEntry = [...pendingLines];
|
|
105
|
+
for (const line of lines) {
|
|
106
|
+
if (LOG_ENTRY_START.test(line)) {
|
|
107
|
+
// This line starts a new entry
|
|
108
|
+
if (currentEntry.length > 0) {
|
|
109
|
+
// Save the previous entry
|
|
110
|
+
entries.push(currentEntry);
|
|
111
|
+
}
|
|
112
|
+
currentEntry = [line];
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
// Continuation line - add to current entry
|
|
116
|
+
currentEntry.push(line);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// Return complete entries and any pending lines
|
|
120
|
+
return {
|
|
121
|
+
entries,
|
|
122
|
+
pending: currentEntry,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Tails log files on a B2C Commerce instance.
|
|
127
|
+
*
|
|
128
|
+
* Continuously polls for new log content using HTTP Range requests for efficiency.
|
|
129
|
+
* Calls the onEntry callback for each new log line.
|
|
130
|
+
*
|
|
131
|
+
* @param instance - B2C instance to tail logs from
|
|
132
|
+
* @param options - Tailing options (filters, callbacks, polling interval)
|
|
133
|
+
* @returns Tail result with stop() control and done promise
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* ```typescript
|
|
137
|
+
* const result = await tailLogs(instance, {
|
|
138
|
+
* prefixes: ['error', 'customerror'],
|
|
139
|
+
* onEntry: (entry) => console.log(`[${entry.file}] ${entry.message}`),
|
|
140
|
+
* onError: (err) => console.error('Tail error:', err),
|
|
141
|
+
* });
|
|
142
|
+
*
|
|
143
|
+
* // Stop after 10 seconds
|
|
144
|
+
* setTimeout(() => result.stop(), 10000);
|
|
145
|
+
*
|
|
146
|
+
* // Wait for tailing to complete
|
|
147
|
+
* await result.done;
|
|
148
|
+
* ```
|
|
149
|
+
*/
|
|
150
|
+
export async function tailLogs(instance, options = {}) {
|
|
151
|
+
const logger = getLogger();
|
|
152
|
+
const { prefixes = DEFAULT_PREFIXES, pollInterval = DEFAULT_POLL_INTERVAL, lastEntries = 1, maxEntries, pathNormalizer, onEntry, onError, onFileDiscovered, onFileRotated, } = options;
|
|
153
|
+
// Track file positions and collected entries
|
|
154
|
+
const filePositions = new Map();
|
|
155
|
+
const fileSizes = new Map();
|
|
156
|
+
const trackedFiles = [];
|
|
157
|
+
const collectedEntries = [];
|
|
158
|
+
// Control state
|
|
159
|
+
let running = true;
|
|
160
|
+
let resolveComplete;
|
|
161
|
+
const donePromise = new Promise((resolve) => {
|
|
162
|
+
resolveComplete = resolve;
|
|
163
|
+
});
|
|
164
|
+
// TextDecoder for proper UTF-8 handling (one per file for streaming)
|
|
165
|
+
const decoders = new Map();
|
|
166
|
+
// Pending lines for multi-line entry aggregation (per file)
|
|
167
|
+
const pendingLines = new Map();
|
|
168
|
+
/**
|
|
169
|
+
* Stop the tailing operation.
|
|
170
|
+
*/
|
|
171
|
+
const stop = async () => {
|
|
172
|
+
running = false;
|
|
173
|
+
// Give a small delay to allow any in-flight requests to complete
|
|
174
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
175
|
+
};
|
|
176
|
+
/**
|
|
177
|
+
* Get or create a decoder for a file.
|
|
178
|
+
*/
|
|
179
|
+
const getDecoder = (filename) => {
|
|
180
|
+
let decoder = decoders.get(filename);
|
|
181
|
+
if (!decoder) {
|
|
182
|
+
decoder = new TextDecoder('utf-8', { fatal: false });
|
|
183
|
+
decoders.set(filename, decoder);
|
|
184
|
+
}
|
|
185
|
+
return decoder;
|
|
186
|
+
};
|
|
187
|
+
/**
|
|
188
|
+
* Fetch the last N entries from a file's tail.
|
|
189
|
+
*/
|
|
190
|
+
const fetchLastEntries = async (file, count) => {
|
|
191
|
+
if (count <= 0 || file.size === 0) {
|
|
192
|
+
return [];
|
|
193
|
+
}
|
|
194
|
+
try {
|
|
195
|
+
// Read last ~64KB of the file to find recent entries
|
|
196
|
+
const tailBytes = Math.min(file.size, DEFAULT_TAIL_BYTES);
|
|
197
|
+
const startByte = Math.max(0, file.size - tailBytes);
|
|
198
|
+
let content;
|
|
199
|
+
if (startByte === 0) {
|
|
200
|
+
// Read entire file
|
|
201
|
+
content = await instance.webdav.get(file.path);
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
// Use Range request for tail
|
|
205
|
+
const response = await instance.webdav.request(file.path, {
|
|
206
|
+
method: 'GET',
|
|
207
|
+
headers: {
|
|
208
|
+
Range: `bytes=${startByte}-`,
|
|
209
|
+
},
|
|
210
|
+
});
|
|
211
|
+
if (response.status === 416) {
|
|
212
|
+
// File might be smaller than expected, read entire file
|
|
213
|
+
content = await instance.webdav.get(file.path);
|
|
214
|
+
}
|
|
215
|
+
else if (!response.ok && response.status !== 206) {
|
|
216
|
+
throw new Error(`Failed to read ${file.name}: ${response.status}`);
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
content = await response.arrayBuffer();
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
// Parse lines and aggregate into multi-line entries
|
|
223
|
+
const decoder = new TextDecoder('utf-8', { fatal: false });
|
|
224
|
+
const lines = splitLines(content, decoder, true);
|
|
225
|
+
// If we started mid-file, skip lines until we find an entry start
|
|
226
|
+
let startIndex = 0;
|
|
227
|
+
if (startByte > 0) {
|
|
228
|
+
for (let i = 0; i < lines.length; i++) {
|
|
229
|
+
if (LOG_ENTRY_START.test(lines[i])) {
|
|
230
|
+
startIndex = i;
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
// Aggregate lines into entries
|
|
236
|
+
const { entries: rawEntries, pending } = aggregateLogEntries(lines.slice(startIndex), []);
|
|
237
|
+
// Include pending as the last entry if it has content
|
|
238
|
+
const allRawEntries = pending.length > 0 ? [...rawEntries, pending] : rawEntries;
|
|
239
|
+
const entries = [];
|
|
240
|
+
for (const entryLines of allRawEntries) {
|
|
241
|
+
const firstLine = entryLines[0];
|
|
242
|
+
const fullMessage = entryLines.join('\n');
|
|
243
|
+
const entry = parseLogEntry(firstLine, file.name, fullMessage, pathNormalizer);
|
|
244
|
+
entries.push(entry);
|
|
245
|
+
}
|
|
246
|
+
// Return only the last N entries (most recent)
|
|
247
|
+
return entries.slice(-count);
|
|
248
|
+
}
|
|
249
|
+
catch (error) {
|
|
250
|
+
logger.error({ error, file: file.name }, `Error fetching last entries from ${file.name}`);
|
|
251
|
+
if (onError) {
|
|
252
|
+
onError(error instanceof Error ? error : new Error(String(error)));
|
|
253
|
+
}
|
|
254
|
+
return [];
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
/**
|
|
258
|
+
* Discover and track log files matching the prefix filters.
|
|
259
|
+
*/
|
|
260
|
+
const discoverFiles = async () => {
|
|
261
|
+
try {
|
|
262
|
+
const files = await listLogFiles(instance, { prefixes, sortBy: 'date', sortOrder: 'desc' });
|
|
263
|
+
for (const file of files) {
|
|
264
|
+
if (!filePositions.has(file.name)) {
|
|
265
|
+
// New file discovered
|
|
266
|
+
logger.debug({ file: file.name }, `Discovered log file: ${file.name}`);
|
|
267
|
+
trackedFiles.push(file);
|
|
268
|
+
fileSizes.set(file.name, file.size);
|
|
269
|
+
// Notify about discovery first
|
|
270
|
+
if (onFileDiscovered) {
|
|
271
|
+
onFileDiscovered(file);
|
|
272
|
+
}
|
|
273
|
+
// Fetch and emit last N entries if requested
|
|
274
|
+
if (lastEntries > 0) {
|
|
275
|
+
const recentEntries = await fetchLastEntries(file, lastEntries);
|
|
276
|
+
for (const entry of recentEntries) {
|
|
277
|
+
if (onEntry) {
|
|
278
|
+
onEntry(entry);
|
|
279
|
+
}
|
|
280
|
+
if (maxEntries !== undefined) {
|
|
281
|
+
collectedEntries.push(entry);
|
|
282
|
+
if (collectedEntries.length >= maxEntries) {
|
|
283
|
+
running = false;
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
// Set position to end of file to only tail new content
|
|
290
|
+
filePositions.set(file.name, file.size);
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
// Check for file rotation (size decreased)
|
|
294
|
+
const previousSize = fileSizes.get(file.name) || 0;
|
|
295
|
+
if (file.size < previousSize) {
|
|
296
|
+
logger.debug({ file: file.name, previousSize, newSize: file.size }, `File rotated: ${file.name}`);
|
|
297
|
+
// Reset position to start of new file
|
|
298
|
+
filePositions.set(file.name, 0);
|
|
299
|
+
fileSizes.set(file.name, file.size);
|
|
300
|
+
// Create fresh decoder and clear pending lines
|
|
301
|
+
decoders.set(file.name, new TextDecoder('utf-8', { fatal: false }));
|
|
302
|
+
pendingLines.delete(file.name);
|
|
303
|
+
if (onFileRotated) {
|
|
304
|
+
onFileRotated(file);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
fileSizes.set(file.name, file.size);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
catch (error) {
|
|
314
|
+
logger.error({ error }, 'Error discovering log files');
|
|
315
|
+
if (onError) {
|
|
316
|
+
onError(error instanceof Error ? error : new Error(String(error)));
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
/**
|
|
321
|
+
* Read new content from a file using Range request.
|
|
322
|
+
*/
|
|
323
|
+
const readNewContent = async (file) => {
|
|
324
|
+
const position = filePositions.get(file.name) || 0;
|
|
325
|
+
const currentSize = fileSizes.get(file.name) || 0;
|
|
326
|
+
// No new content
|
|
327
|
+
if (position >= currentSize) {
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
try {
|
|
331
|
+
// Use Range header to get only new content
|
|
332
|
+
const response = await instance.webdav.request(file.path, {
|
|
333
|
+
method: 'GET',
|
|
334
|
+
headers: {
|
|
335
|
+
Range: `bytes=${position}-`,
|
|
336
|
+
},
|
|
337
|
+
});
|
|
338
|
+
// Handle different response statuses
|
|
339
|
+
if (response.status === 416) {
|
|
340
|
+
// Range Not Satisfiable - position is at or past end of file
|
|
341
|
+
// This can happen due to race conditions, just skip
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
if (!response.ok && response.status !== 206) {
|
|
345
|
+
throw new Error(`Failed to read ${file.name}: ${response.status} ${response.statusText}`);
|
|
346
|
+
}
|
|
347
|
+
const content = await response.arrayBuffer();
|
|
348
|
+
const decoder = getDecoder(file.name);
|
|
349
|
+
// Update position based on content received
|
|
350
|
+
const contentLength = content.byteLength;
|
|
351
|
+
filePositions.set(file.name, position + contentLength);
|
|
352
|
+
// Parse lines and aggregate into multi-line entries
|
|
353
|
+
const lines = splitLines(content, decoder, true);
|
|
354
|
+
const { entries: rawEntries, pending } = aggregateLogEntries(lines, pendingLines.get(file.name) || []);
|
|
355
|
+
// Check if we've caught up to the end of the file
|
|
356
|
+
const newPosition = position + contentLength;
|
|
357
|
+
const atEndOfFile = newPosition >= currentSize;
|
|
358
|
+
// If we're at the end of the file, flush pending as a complete entry
|
|
359
|
+
// (the entry is complete for now, more content may arrive later)
|
|
360
|
+
let allEntries = rawEntries;
|
|
361
|
+
if (atEndOfFile && pending.length > 0) {
|
|
362
|
+
allEntries = [...rawEntries, pending];
|
|
363
|
+
pendingLines.set(file.name, []);
|
|
364
|
+
}
|
|
365
|
+
else {
|
|
366
|
+
pendingLines.set(file.name, pending);
|
|
367
|
+
}
|
|
368
|
+
// Process complete entries
|
|
369
|
+
for (const entryLines of allEntries) {
|
|
370
|
+
const firstLine = entryLines[0];
|
|
371
|
+
const fullMessage = entryLines.join('\n');
|
|
372
|
+
const entry = parseLogEntry(firstLine, file.name, fullMessage, pathNormalizer);
|
|
373
|
+
if (onEntry) {
|
|
374
|
+
onEntry(entry);
|
|
375
|
+
}
|
|
376
|
+
if (maxEntries !== undefined) {
|
|
377
|
+
collectedEntries.push(entry);
|
|
378
|
+
if (collectedEntries.length >= maxEntries) {
|
|
379
|
+
running = false;
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
catch (error) {
|
|
386
|
+
logger.error({ error, file: file.name }, `Error reading ${file.name}`);
|
|
387
|
+
if (onError) {
|
|
388
|
+
onError(error instanceof Error ? error : new Error(String(error)));
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
};
|
|
392
|
+
/**
|
|
393
|
+
* Main polling loop.
|
|
394
|
+
*/
|
|
395
|
+
const poll = async () => {
|
|
396
|
+
// Initial file discovery
|
|
397
|
+
await discoverFiles();
|
|
398
|
+
while (running) {
|
|
399
|
+
// Read new content from all tracked files
|
|
400
|
+
for (const file of trackedFiles) {
|
|
401
|
+
if (!running)
|
|
402
|
+
break;
|
|
403
|
+
await readNewContent(file);
|
|
404
|
+
}
|
|
405
|
+
if (!running)
|
|
406
|
+
break;
|
|
407
|
+
// Wait for next poll
|
|
408
|
+
await new Promise((resolve) => setTimeout(resolve, pollInterval));
|
|
409
|
+
// Check for new files
|
|
410
|
+
await discoverFiles();
|
|
411
|
+
}
|
|
412
|
+
resolveComplete();
|
|
413
|
+
};
|
|
414
|
+
// Start polling (don't await - runs in background)
|
|
415
|
+
poll().catch((error) => {
|
|
416
|
+
logger.error({ error }, 'Polling error');
|
|
417
|
+
if (onError) {
|
|
418
|
+
onError(error instanceof Error ? error : new Error(String(error)));
|
|
419
|
+
}
|
|
420
|
+
resolveComplete();
|
|
421
|
+
});
|
|
422
|
+
return {
|
|
423
|
+
stop,
|
|
424
|
+
files: trackedFiles,
|
|
425
|
+
entries: collectedEntries,
|
|
426
|
+
done: donePromise,
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Gets recent log entries (one-shot retrieval).
|
|
431
|
+
*
|
|
432
|
+
* Useful for MCP server integration or programmatic access without continuous tailing.
|
|
433
|
+
* Reads the tail end of log files and returns parsed entries.
|
|
434
|
+
*
|
|
435
|
+
* @param instance - B2C instance to get logs from
|
|
436
|
+
* @param options - Retrieval options
|
|
437
|
+
* @returns Array of recent log entries
|
|
438
|
+
*
|
|
439
|
+
* @example
|
|
440
|
+
* ```typescript
|
|
441
|
+
* // Get the last 50 error entries
|
|
442
|
+
* const entries = await getRecentLogs(instance, {
|
|
443
|
+
* prefixes: ['error'],
|
|
444
|
+
* maxEntries: 50
|
|
445
|
+
* });
|
|
446
|
+
* ```
|
|
447
|
+
*/
|
|
448
|
+
export async function getRecentLogs(instance, options = {}) {
|
|
449
|
+
const logger = getLogger();
|
|
450
|
+
const { prefixes = DEFAULT_PREFIXES, maxEntries = DEFAULT_MAX_ENTRIES, tailBytes = DEFAULT_TAIL_BYTES, pathNormalizer, } = options;
|
|
451
|
+
logger.debug({ prefixes, maxEntries, tailBytes }, 'Getting recent logs');
|
|
452
|
+
// Get log files
|
|
453
|
+
const files = await listLogFiles(instance, {
|
|
454
|
+
prefixes,
|
|
455
|
+
sortBy: 'date',
|
|
456
|
+
sortOrder: 'desc',
|
|
457
|
+
});
|
|
458
|
+
const allEntries = [];
|
|
459
|
+
// Read from files until we have enough entries
|
|
460
|
+
for (const file of files) {
|
|
461
|
+
if (allEntries.length >= maxEntries)
|
|
462
|
+
break;
|
|
463
|
+
try {
|
|
464
|
+
// Calculate range to read (tail end of file)
|
|
465
|
+
const startByte = Math.max(0, file.size - tailBytes);
|
|
466
|
+
let content;
|
|
467
|
+
if (startByte === 0) {
|
|
468
|
+
// Read entire file
|
|
469
|
+
content = await instance.webdav.get(file.path);
|
|
470
|
+
}
|
|
471
|
+
else {
|
|
472
|
+
// Use Range request for tail
|
|
473
|
+
const response = await instance.webdav.request(file.path, {
|
|
474
|
+
method: 'GET',
|
|
475
|
+
headers: {
|
|
476
|
+
Range: `bytes=${startByte}-`,
|
|
477
|
+
},
|
|
478
|
+
});
|
|
479
|
+
if (response.status === 416) {
|
|
480
|
+
// File might be smaller than expected, read entire file
|
|
481
|
+
content = await instance.webdav.get(file.path);
|
|
482
|
+
}
|
|
483
|
+
else if (!response.ok && response.status !== 206) {
|
|
484
|
+
throw new Error(`Failed to read ${file.name}: ${response.status}`);
|
|
485
|
+
}
|
|
486
|
+
else {
|
|
487
|
+
content = await response.arrayBuffer();
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
// Parse lines and aggregate into multi-line entries
|
|
491
|
+
const decoder = new TextDecoder('utf-8', { fatal: false });
|
|
492
|
+
const lines = splitLines(content, decoder, true);
|
|
493
|
+
// If we started mid-file, skip lines until we find an entry start
|
|
494
|
+
let startIndex = 0;
|
|
495
|
+
if (startByte > 0) {
|
|
496
|
+
for (let i = 0; i < lines.length; i++) {
|
|
497
|
+
if (LOG_ENTRY_START.test(lines[i])) {
|
|
498
|
+
startIndex = i;
|
|
499
|
+
break;
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
// Aggregate lines into entries
|
|
504
|
+
const { entries: rawEntries, pending } = aggregateLogEntries(lines.slice(startIndex), []);
|
|
505
|
+
// Process complete entries (ignore pending - we're reading a snapshot)
|
|
506
|
+
// Also include pending as the last entry if it has content
|
|
507
|
+
const allRawEntries = pending.length > 0 ? [...rawEntries, pending] : rawEntries;
|
|
508
|
+
for (const entryLines of allRawEntries) {
|
|
509
|
+
const firstLine = entryLines[0];
|
|
510
|
+
const fullMessage = entryLines.join('\n');
|
|
511
|
+
const entry = parseLogEntry(firstLine, file.name, fullMessage, pathNormalizer);
|
|
512
|
+
allEntries.push(entry);
|
|
513
|
+
if (allEntries.length >= maxEntries)
|
|
514
|
+
break;
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
catch (error) {
|
|
518
|
+
logger.error({ error, file: file.name }, `Error reading ${file.name}`);
|
|
519
|
+
// Continue to next file instead of failing completely
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
// Return entries in reverse order (most recent first)
|
|
523
|
+
return allEntries.reverse().slice(0, maxEntries);
|
|
524
|
+
}
|
|
525
|
+
//# sourceMappingURL=tail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tail.js","sourceRoot":"","sources":["../../../../src/operations/logs/tail.ts"],"names":[],"mappings":"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"}
|