logixia 2.0.0 → 2.0.6
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 +172 -2597
- package/dist/async-context-2mbUKhcl.mjs +132 -0
- package/dist/async-context-2mbUKhcl.mjs.map +1 -0
- package/dist/async-context-DUFMDYAr.js +148 -0
- package/dist/async-context-DUFMDYAr.js.map +1 -0
- package/dist/{azure-monitor.transport-CrvfHd9C.js → azure-monitor.transport-Bu4S2I2q.js} +32 -20
- package/dist/azure-monitor.transport-Bu4S2I2q.js.map +1 -0
- package/dist/{azure-monitor.transport-Cn_3Usvu.d.ts → azure-monitor.transport-Bvf7Xegt.d.ts} +3 -6
- package/dist/azure-monitor.transport-Bvf7Xegt.d.ts.map +1 -0
- package/dist/{azure-monitor.transport-CHnjVRF-.mjs → azure-monitor.transport-C1RWAumT.mjs} +27 -15
- package/dist/azure-monitor.transport-C1RWAumT.mjs.map +1 -0
- package/dist/{azure-monitor.transport-D7Da4RAb.d.mts → azure-monitor.transport-CbSHOnNX.d.mts} +3 -6
- package/dist/azure-monitor.transport-CbSHOnNX.d.mts.map +1 -0
- package/dist/azure.d.mts +1 -2
- package/dist/azure.d.ts +1 -2
- package/dist/azure.js +3 -6
- package/dist/azure.mjs +1 -6
- package/dist/{batch-buffer-PGvSgbmd.mjs → batch-buffer-BvXLDPlV.mjs} +21 -7
- package/dist/batch-buffer-BvXLDPlV.mjs.map +1 -0
- package/dist/{batch-buffer-BY-mRWIK.js → batch-buffer-C7Am4Mw-.js} +53 -40
- package/dist/batch-buffer-C7Am4Mw-.js.map +1 -0
- package/dist/browser.d.mts +47 -27
- package/dist/browser.d.mts.map +1 -1
- package/dist/browser.d.ts +47 -27
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +464 -62
- package/dist/browser.js.map +1 -1
- package/dist/browser.mjs +465 -65
- package/dist/browser.mjs.map +1 -1
- package/dist/{builder-0gEzRopq.mjs → builder-DhNhvOkt.mjs} +307 -246
- package/dist/builder-DhNhvOkt.mjs.map +1 -0
- package/dist/{builder-D44QktIo.js → builder-yFvJrz7o.js} +435 -399
- package/dist/builder-yFvJrz7o.js.map +1 -0
- package/dist/cli/index.js +216 -125
- package/dist/cloudwatch.d.mts +1 -2
- package/dist/cloudwatch.d.ts +1 -2
- package/dist/cloudwatch.js +3 -7
- package/dist/cloudwatch.mjs +1 -7
- package/dist/{cloudwatch.transport-DsEq633o.d.ts → cloudwatch.transport-CQyT6U91.d.ts} +2 -6
- package/dist/cloudwatch.transport-CQyT6U91.d.ts.map +1 -0
- package/dist/{cloudwatch.transport-BO1ahxw-.js → cloudwatch.transport-Ch1Uae-0.js} +61 -36
- package/dist/cloudwatch.transport-Ch1Uae-0.js.map +1 -0
- package/dist/{cloudwatch.transport-UlyZFWMn.d.mts → cloudwatch.transport-CjVrI6S4.d.mts} +2 -6
- package/dist/cloudwatch.transport-CjVrI6S4.d.mts.map +1 -0
- package/dist/{cloudwatch.transport-DZ6ies7g.mjs → cloudwatch.transport-DZqF2xZO.mjs} +54 -28
- package/dist/cloudwatch.transport-DZqF2xZO.mjs.map +1 -0
- package/dist/{coerce.utils-Cu6IUTgX.mjs → coerce.utils-B_rEudCn.mjs} +3 -4
- package/dist/{coerce.utils-Cu6IUTgX.mjs.map → coerce.utils-B_rEudCn.mjs.map} +1 -1
- package/dist/{coerce.utils-B-LilukN.js → coerce.utils-C1C5sIX0.js} +8 -10
- package/dist/{coerce.utils-B-LilukN.js.map → coerce.utils-C1C5sIX0.js.map} +1 -1
- package/dist/correlation.d.mts +15 -69
- package/dist/correlation.d.mts.map +1 -1
- package/dist/correlation.d.ts +15 -69
- package/dist/correlation.d.ts.map +1 -1
- package/dist/correlation.js +69 -20
- package/dist/correlation.js.map +1 -1
- package/dist/correlation.mjs +67 -17
- package/dist/correlation.mjs.map +1 -1
- package/dist/{entry-fields-BvOLFlJ4.js → entry-fields-BSLkzw18.js} +16 -13
- package/dist/entry-fields-BSLkzw18.js.map +1 -0
- package/dist/{entry-fields-BJkuPnIg.mjs → entry-fields-J1OBi24o.mjs} +11 -7
- package/dist/entry-fields-J1OBi24o.mjs.map +1 -0
- package/dist/gcp.d.mts +1 -2
- package/dist/gcp.d.ts +1 -2
- package/dist/gcp.js +3 -7
- package/dist/gcp.mjs +1 -7
- package/dist/{gcp.transport-B7oc97sG.d.ts → gcp.transport-BCIvdFV-.d.ts} +5 -8
- package/dist/gcp.transport-BCIvdFV-.d.ts.map +1 -0
- package/dist/{gcp.transport-GrJurKo8.d.mts → gcp.transport-D9SdLPwP.d.mts} +5 -8
- package/dist/gcp.transport-D9SdLPwP.d.mts.map +1 -0
- package/dist/{gcp.transport-DBX5TPIy.mjs → gcp.transport-DVCmnA3b.mjs} +59 -16
- package/dist/gcp.transport-DVCmnA3b.mjs.map +1 -0
- package/dist/{gcp.transport-CHV8MGgz.js → gcp.transport-Dy2Lf8FI.js} +64 -22
- package/dist/gcp.transport-Dy2Lf8FI.js.map +1 -0
- package/dist/http-shapes-BnBkJcid.d.mts +32 -0
- package/dist/http-shapes-BnBkJcid.d.mts.map +1 -0
- package/dist/http-shapes-BnBkJcid.d.ts +32 -0
- package/dist/http-shapes-BnBkJcid.d.ts.map +1 -0
- package/dist/{index-3mw5gaCw.d.mts → index-BSTtFcQ6.d.mts} +142 -13
- package/dist/index-BSTtFcQ6.d.mts.map +1 -0
- package/dist/{index-DhIoploR.d.ts → index-CFDGkI8n.d.ts} +142 -13
- package/dist/index-CFDGkI8n.d.ts.map +1 -0
- package/dist/index.d.mts +114 -217
- package/dist/index.d.mts.map +1 -1
- package/dist/index.d.ts +113 -216
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +182 -279
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +160 -256
- package/dist/index.mjs.map +1 -1
- package/dist/internal-log-Bg4V1cPg.mjs +170 -0
- package/dist/internal-log-Bg4V1cPg.mjs.map +1 -0
- package/dist/internal-log-By4Govmu.js +223 -0
- package/dist/internal-log-By4Govmu.js.map +1 -0
- package/dist/{logitron-logger-UVeN-mQm.d.ts → logitron-logger-D22Yb61K.d.mts} +121 -100
- package/dist/logitron-logger-D22Yb61K.d.mts.map +1 -0
- package/dist/{logitron-logger-BFDSO8Io.d.mts → logitron-logger-D_MYYrQt.d.ts} +121 -100
- package/dist/logitron-logger-D_MYYrQt.d.ts.map +1 -0
- package/dist/middleware.d.mts +13 -28
- package/dist/middleware.d.mts.map +1 -1
- package/dist/middleware.d.ts +13 -28
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +20 -81
- package/dist/middleware.js.map +1 -1
- package/dist/middleware.mjs +17 -79
- package/dist/middleware.mjs.map +1 -1
- package/dist/nest.d.mts +37 -48
- package/dist/nest.d.mts.map +1 -1
- package/dist/nest.d.ts +37 -48
- package/dist/nest.d.ts.map +1 -1
- package/dist/nest.js +124 -135
- package/dist/nest.js.map +1 -1
- package/dist/nest.mjs +69 -78
- package/dist/nest.mjs.map +1 -1
- package/dist/{transport.manager-BiuCAJd2.mjs → otel-Dt5riXuE.mjs} +275 -117
- package/dist/otel-Dt5riXuE.mjs.map +1 -0
- package/dist/{transport.manager-CXbKKdVE.js → otel-DyeH6DVR.js} +373 -178
- package/dist/otel-DyeH6DVR.js.map +1 -0
- package/dist/own-property-BWkibepN.js +40 -0
- package/dist/own-property-BWkibepN.js.map +1 -0
- package/dist/own-property-CjFw9qwZ.mjs +29 -0
- package/dist/own-property-CjFw9qwZ.mjs.map +1 -0
- package/dist/{trace.utils-CvXgaiQT.mjs → request-trace-BgNykH9M.mjs} +40 -9
- package/dist/request-trace-BgNykH9M.mjs.map +1 -0
- package/dist/{trace.utils-DpBOLDtq.js → request-trace-ByujsUZk.js} +117 -77
- package/dist/request-trace-ByujsUZk.js.map +1 -0
- package/dist/rolldown-runtime-D3PmRqjj.mjs +4 -0
- package/dist/{safe-stringify-DJ66tW5I.mjs → safe-stringify-B5p5ktFe.mjs} +39 -15
- package/dist/safe-stringify-B5p5ktFe.mjs.map +1 -0
- package/dist/{safe-stringify-DWo3aZp_.js → safe-stringify-J3sh-7YM.js} +59 -36
- package/dist/safe-stringify-J3sh-7YM.js.map +1 -0
- package/dist/{search-C4V0OMEn.js → search-CRjhHxe9.js} +319 -92
- package/dist/search-CRjhHxe9.js.map +1 -0
- package/dist/{search-CNh9uVwR.d.ts → search-DA3ft3X5.d.mts} +5 -22
- package/dist/search-DA3ft3X5.d.mts.map +1 -0
- package/dist/{search-BFbu_oVn.mjs → search-DAXKE-P9.mjs} +289 -62
- package/dist/search-DAXKE-P9.mjs.map +1 -0
- package/dist/{search-DXANsQ2n.d.mts → search-DEl3Pe47.d.ts} +5 -22
- package/dist/search-DEl3Pe47.d.ts.map +1 -0
- package/dist/search.d.mts +2 -4
- package/dist/search.d.ts +2 -4
- package/dist/search.js +3 -4
- package/dist/search.mjs +1 -4
- package/dist/secret-config-CmK2wVkr.js +272 -0
- package/dist/secret-config-CmK2wVkr.js.map +1 -0
- package/dist/secret-config-Dhb6pqTU.mjs +210 -0
- package/dist/secret-config-Dhb6pqTU.mjs.map +1 -0
- package/dist/{slack.transport-CXjQYOes.d.ts → slack.transport-BDyENuR0.d.mts} +56 -9
- package/dist/slack.transport-BDyENuR0.d.mts.map +1 -0
- package/dist/{slack.transport-Bzw7sucI.mjs → slack.transport-BTEwsREY.mjs} +263 -31
- package/dist/slack.transport-BTEwsREY.mjs.map +1 -0
- package/dist/{slack.transport-BZzoXDPn.d.mts → slack.transport-C6E0l4kw.d.ts} +56 -9
- package/dist/slack.transport-C6E0l4kw.d.ts.map +1 -0
- package/dist/{slack.transport-BfJRouB2.js → slack.transport-UbYvOdKx.js} +286 -42
- package/dist/slack.transport-UbYvOdKx.js.map +1 -0
- package/dist/testing.d.mts +13 -11
- package/dist/testing.d.mts.map +1 -1
- package/dist/testing.d.ts +13 -11
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +41 -7
- package/dist/testing.js.map +1 -1
- package/dist/testing.mjs +40 -6
- package/dist/testing.mjs.map +1 -1
- package/dist/{transport.types-CGoHpWQR.d.ts → transport.types-CzJq4IrF.d.mts} +14 -5
- package/dist/transport.types-CzJq4IrF.d.mts.map +1 -0
- package/dist/{transport.types-BMnurPcc.d.mts → transport.types-CzJq4IrF.d.ts} +14 -5
- package/dist/transport.types-CzJq4IrF.d.ts.map +1 -0
- package/dist/transports.d.mts +39 -41
- package/dist/transports.d.mts.map +1 -1
- package/dist/transports.d.ts +39 -41
- package/dist/transports.d.ts.map +1 -1
- package/dist/transports.js +19 -22
- package/dist/transports.mjs +7 -13
- package/dist/worker-entry.js +438 -107
- package/dist/worker.d.mts +1 -2
- package/dist/worker.d.ts +1 -2
- package/dist/worker.js +3 -4
- package/dist/worker.mjs +1 -4
- package/dist/{worker.transport-JvGPog3C.d.mts → worker.transport-B9mCQSM1.d.ts} +7 -6
- package/dist/worker.transport-B9mCQSM1.d.ts.map +1 -0
- package/dist/{worker.transport-CdzSZJmw.d.ts → worker.transport-Bl8lFRck.d.mts} +7 -6
- package/dist/worker.transport-Bl8lFRck.d.mts.map +1 -0
- package/dist/{worker.transport-lPxO2MVL.mjs → worker.transport-BmmOKb1-.mjs} +43 -10
- package/dist/worker.transport-BmmOKb1-.mjs.map +1 -0
- package/dist/{worker.transport-BdPxu3PN.js → worker.transport-DxxbqQCG.js} +48 -15
- package/dist/worker.transport-DxxbqQCG.js.map +1 -0
- package/package.json +51 -75
- package/dist/async-context-BzJrbfQs.mjs +0 -72
- package/dist/async-context-BzJrbfQs.mjs.map +0 -1
- package/dist/async-context-DyQQYq3I.js +0 -92
- package/dist/async-context-DyQQYq3I.js.map +0 -1
- package/dist/azure-monitor.transport-CHnjVRF-.mjs.map +0 -1
- package/dist/azure-monitor.transport-Cn_3Usvu.d.ts.map +0 -1
- package/dist/azure-monitor.transport-CrvfHd9C.js.map +0 -1
- package/dist/azure-monitor.transport-D7Da4RAb.d.mts.map +0 -1
- package/dist/batch-buffer-BY-mRWIK.js.map +0 -1
- package/dist/batch-buffer-PGvSgbmd.mjs.map +0 -1
- package/dist/builder-0gEzRopq.mjs.map +0 -1
- package/dist/builder-D44QktIo.js.map +0 -1
- package/dist/chunk-DLSkYcPk.mjs +0 -7
- package/dist/chunk-nOFOJqeH.js +0 -30
- package/dist/cloudwatch.transport-BO1ahxw-.js.map +0 -1
- package/dist/cloudwatch.transport-DZ6ies7g.mjs.map +0 -1
- package/dist/cloudwatch.transport-DsEq633o.d.ts.map +0 -1
- package/dist/cloudwatch.transport-UlyZFWMn.d.mts.map +0 -1
- package/dist/entry-fields-BJkuPnIg.mjs.map +0 -1
- package/dist/entry-fields-BvOLFlJ4.js.map +0 -1
- package/dist/gcp.transport-B7oc97sG.d.ts.map +0 -1
- package/dist/gcp.transport-CHV8MGgz.js.map +0 -1
- package/dist/gcp.transport-DBX5TPIy.mjs.map +0 -1
- package/dist/gcp.transport-GrJurKo8.d.mts.map +0 -1
- package/dist/index-3mw5gaCw.d.mts.map +0 -1
- package/dist/index-DhIoploR.d.ts.map +0 -1
- package/dist/internal-log-BUJYMZbE.js +0 -70
- package/dist/internal-log-BUJYMZbE.js.map +0 -1
- package/dist/internal-log-Cm8SOWSV.mjs +0 -52
- package/dist/internal-log-Cm8SOWSV.mjs.map +0 -1
- package/dist/logitron-logger-BFDSO8Io.d.mts.map +0 -1
- package/dist/logitron-logger-UVeN-mQm.d.ts.map +0 -1
- package/dist/safe-stringify-DJ66tW5I.mjs.map +0 -1
- package/dist/safe-stringify-DWo3aZp_.js.map +0 -1
- package/dist/search-BFbu_oVn.mjs.map +0 -1
- package/dist/search-C4V0OMEn.js.map +0 -1
- package/dist/search-CNh9uVwR.d.ts.map +0 -1
- package/dist/search-DXANsQ2n.d.mts.map +0 -1
- package/dist/slack.transport-BZzoXDPn.d.mts.map +0 -1
- package/dist/slack.transport-BfJRouB2.js.map +0 -1
- package/dist/slack.transport-Bzw7sucI.mjs.map +0 -1
- package/dist/slack.transport-CXjQYOes.d.ts.map +0 -1
- package/dist/trace.utils-CvXgaiQT.mjs.map +0 -1
- package/dist/trace.utils-DpBOLDtq.js.map +0 -1
- package/dist/transport.manager-BiuCAJd2.mjs.map +0 -1
- package/dist/transport.manager-CXbKKdVE.js.map +0 -1
- package/dist/transport.types-BMnurPcc.d.mts.map +0 -1
- package/dist/transport.types-CGoHpWQR.d.ts.map +0 -1
- package/dist/worker.transport-BdPxu3PN.js.map +0 -1
- package/dist/worker.transport-CdzSZJmw.d.ts.map +0 -1
- package/dist/worker.transport-JvGPog3C.d.mts.map +0 -1
- package/dist/worker.transport-lPxO2MVL.mjs.map +0 -1
package/dist/cli/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
// \0rolldown/runtime.js
|
|
3
4
|
var __create = Object.create;
|
|
4
5
|
var __defProp = Object.defineProperty;
|
|
5
6
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -16,22 +17,18 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
16
17
|
}
|
|
17
18
|
return to;
|
|
18
19
|
};
|
|
19
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
|
|
20
21
|
value: mod,
|
|
21
22
|
enumerable: true
|
|
22
23
|
}) : target, mod));
|
|
23
|
-
|
|
24
|
-
//#endregion
|
|
25
24
|
let node_fs = require("node:fs");
|
|
26
25
|
node_fs = __toESM(node_fs);
|
|
27
26
|
let node_path = require("node:path");
|
|
28
27
|
node_path = __toESM(node_path);
|
|
29
28
|
let commander = require("commander");
|
|
30
|
-
commander = __toESM(commander);
|
|
31
29
|
let picocolors = require("picocolors");
|
|
32
30
|
picocolors = __toESM(picocolors);
|
|
33
|
-
|
|
34
|
-
//#region src/utils/csv.utils.ts
|
|
31
|
+
// src/utils/csv.utils.ts
|
|
35
32
|
const CSV_FORMULA_PREFIX = /^[=+\-@\t\r]/;
|
|
36
33
|
/**
|
|
37
34
|
* Render one CSV field. String values that a spreadsheet would treat as a
|
|
@@ -48,9 +45,7 @@ function csvField(value, alwaysQuote = false) {
|
|
|
48
45
|
if (alwaysQuote || /[",\r\n]/.test(str)) return `"${str.replace(/"/g, "\"\"")}"`;
|
|
49
46
|
return str;
|
|
50
47
|
}
|
|
51
|
-
|
|
52
|
-
//#endregion
|
|
53
|
-
//#region src/cli/utils.ts
|
|
48
|
+
// src/cli/utils.ts
|
|
54
49
|
/**
|
|
55
50
|
* Render a single cell value. Uses a null/undefined check rather than `||` so
|
|
56
51
|
* falsy-but-real values (0, false, '') still render — a `count=0` or
|
|
@@ -88,6 +83,25 @@ function formatAsTable(rows, columns) {
|
|
|
88
83
|
rows.map((r) => columns.map((c, i) => cellText(r[c]).padEnd(colWidths[i] ?? 0)).join(" | ")).join("\n")
|
|
89
84
|
].join("\n");
|
|
90
85
|
}
|
|
86
|
+
/** Parse like {@link safeParseLogs} but keep each entry's original file line number. */
|
|
87
|
+
function parseLogLines(raw) {
|
|
88
|
+
const parsed = [];
|
|
89
|
+
for (const [i, text] of raw.split(/\r?\n/).entries()) {
|
|
90
|
+
if (!text) continue;
|
|
91
|
+
try {
|
|
92
|
+
parsed.push({
|
|
93
|
+
line: i + 1,
|
|
94
|
+
entry: JSON.parse(text)
|
|
95
|
+
});
|
|
96
|
+
} catch {
|
|
97
|
+
parsed.push({
|
|
98
|
+
line: i + 1,
|
|
99
|
+
entry: { message: text }
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return parsed;
|
|
104
|
+
}
|
|
91
105
|
function safeParseLogs(raw) {
|
|
92
106
|
const lines = raw.split(/\r?\n/).filter(Boolean);
|
|
93
107
|
const parsed = [];
|
|
@@ -101,9 +115,7 @@ function safeParseLogs(raw) {
|
|
|
101
115
|
}
|
|
102
116
|
return parsed;
|
|
103
117
|
}
|
|
104
|
-
|
|
105
|
-
//#endregion
|
|
106
|
-
//#region src/cli/commands/analyze.ts
|
|
118
|
+
// src/cli/commands/analyze.ts
|
|
107
119
|
function parseDurationToMs(input) {
|
|
108
120
|
if (!input) return;
|
|
109
121
|
const m = input.match(/^(\d+)([smhd])$/i);
|
|
@@ -139,6 +151,7 @@ async function analyzeFileContents(raw, opts = {}) {
|
|
|
139
151
|
total: filtered.length,
|
|
140
152
|
byLevel
|
|
141
153
|
};
|
|
154
|
+
if (opts.format === "csv") return sanitizeForTerminal(["level,count", ...Object.keys(byLevel).map((k) => `${csvField(k)},${byLevel[k]}`)].join("\n"));
|
|
142
155
|
return formatAsTable(Object.keys(byLevel).map((k) => ({
|
|
143
156
|
level: k,
|
|
144
157
|
count: byLevel[k]
|
|
@@ -157,16 +170,10 @@ const analyzeCommand = new commander.Command("analyze").description("Analyze log
|
|
|
157
170
|
}
|
|
158
171
|
console.log(result);
|
|
159
172
|
});
|
|
160
|
-
|
|
161
|
-
//#endregion
|
|
162
|
-
//#region src/cli/commands/explore.ts
|
|
173
|
+
// src/cli/commands/explore.ts
|
|
163
174
|
const CSI = "\x1B[";
|
|
164
|
-
const clearScreen =
|
|
165
|
-
const clearLine =
|
|
166
|
-
const hideCursor = CSI + "?25l";
|
|
167
|
-
const showCursor = CSI + "?25h";
|
|
168
|
-
const altScreen = CSI + "?1049h";
|
|
169
|
-
const mainScreen = CSI + "?1049l";
|
|
175
|
+
const clearScreen = "\x1B[2J";
|
|
176
|
+
const clearLine = "\x1B[K";
|
|
170
177
|
function moveTo(row, col) {
|
|
171
178
|
return `${CSI}${row};${col}H`;
|
|
172
179
|
}
|
|
@@ -243,7 +250,7 @@ function coloriseStackFrame(frame) {
|
|
|
243
250
|
function buildDetailLines(entry) {
|
|
244
251
|
if (!entry) return [picocolors.default.dim(" No entry selected")];
|
|
245
252
|
const lines = [];
|
|
246
|
-
const { stack
|
|
253
|
+
const { stack, ...rest } = entry;
|
|
247
254
|
const jsonText = sanitizeForTerminal(JSON.stringify(rest, null, 2));
|
|
248
255
|
for (const l of jsonText.split("\n")) lines.push(" " + syntaxColorJson(l));
|
|
249
256
|
if (stack) {
|
|
@@ -280,7 +287,7 @@ var TUIExplorer = class {
|
|
|
280
287
|
this.STATUS_ROWS = 1;
|
|
281
288
|
this.DETAIL_ROWS = 9;
|
|
282
289
|
this.filePath = node_path.default.resolve(process.cwd(), filePath);
|
|
283
|
-
this.levelFilters = new Set([
|
|
290
|
+
this.levelFilters = /* @__PURE__ */ new Set([
|
|
284
291
|
"error",
|
|
285
292
|
"warn",
|
|
286
293
|
"info",
|
|
@@ -301,7 +308,7 @@ var TUIExplorer = class {
|
|
|
301
308
|
this.filePos = node_fs.default.statSync(this.filePath).size;
|
|
302
309
|
this.allEntries = safeParseLogs(raw);
|
|
303
310
|
this.applyFilters();
|
|
304
|
-
write(
|
|
311
|
+
write("\x1B[?1049h\x1B[?25l");
|
|
305
312
|
this.getTerminalSize();
|
|
306
313
|
process.stdout.on("resize", () => {
|
|
307
314
|
this.getTerminalSize();
|
|
@@ -367,7 +374,7 @@ var TUIExplorer = class {
|
|
|
367
374
|
const leftLen = stripAnsi(left).length;
|
|
368
375
|
const rightLen = stripAnsi(right).length;
|
|
369
376
|
const gap = Math.max(1, w - leftLen - rightLen);
|
|
370
|
-
write(moveTo(1, 1) + picocolors.default.bgBlack(left + " ".repeat(gap) + right) +
|
|
377
|
+
write(moveTo(1, 1) + picocolors.default.bgBlack(left + " ".repeat(gap) + right) + "\x1B[K\n");
|
|
371
378
|
}
|
|
372
379
|
drawFilterBar() {
|
|
373
380
|
const badges = [
|
|
@@ -385,14 +392,12 @@ var TUIExplorer = class {
|
|
|
385
392
|
const left = " " + badges;
|
|
386
393
|
const right = searchPart + " ";
|
|
387
394
|
const gap = Math.max(1, w - stripAnsi(left).length - stripAnsi(right).length);
|
|
388
|
-
write(moveTo(2, 1) + picocolors.default.bgBlack(left + " ".repeat(gap) + right) +
|
|
395
|
+
write(moveTo(2, 1) + picocolors.default.bgBlack(left + " ".repeat(gap) + right) + "\x1B[K\n");
|
|
389
396
|
}
|
|
390
397
|
drawColHeader() {
|
|
391
398
|
const w = this.width;
|
|
392
|
-
const timeCol = " TIME ";
|
|
393
|
-
const levelCol = " LVL ";
|
|
394
399
|
const msgWidth = Math.max(20, w - 14 - 5 - 2);
|
|
395
|
-
write(moveTo(3, 1) + compose(picocolors.default.bold, picocolors.default.bgBlack, picocolors.default.dim)(
|
|
400
|
+
write(moveTo(3, 1) + compose(picocolors.default.bold, picocolors.default.bgBlack, picocolors.default.dim)(" TIME LVL " + this.pad("MESSAGE", msgWidth)) + "\x1B[K\n");
|
|
396
401
|
}
|
|
397
402
|
drawList() {
|
|
398
403
|
const lr = this.LIST_ROWS;
|
|
@@ -436,7 +441,7 @@ var TUIExplorer = class {
|
|
|
436
441
|
const label = selected ? ` ▼ DETAIL (${this.selectedIndex + 1}/${this.filteredEntries.length}) ` : " ▼ DETAIL ";
|
|
437
442
|
const labelLen = stripAnsi(label).length;
|
|
438
443
|
const sepLine = compose(picocolors.default.bgBlack, picocolors.default.cyan, picocolors.default.bold)(label) + picocolors.default.dim("─".repeat(Math.max(0, w - labelLen)));
|
|
439
|
-
write(moveTo(sepRow, 1) + sepLine +
|
|
444
|
+
write(moveTo(sepRow, 1) + sepLine + "\x1B[K\n");
|
|
440
445
|
const lines = buildDetailLines(selected);
|
|
441
446
|
for (let row = 0; row < 8; row++) {
|
|
442
447
|
write(moveTo(sepRow + 1 + row, 1));
|
|
@@ -548,7 +553,6 @@ var TUIExplorer = class {
|
|
|
548
553
|
case "q":
|
|
549
554
|
this.cleanup();
|
|
550
555
|
return;
|
|
551
|
-
default: break;
|
|
552
556
|
}
|
|
553
557
|
this.redraw();
|
|
554
558
|
}
|
|
@@ -666,7 +670,7 @@ var TUIExplorer = class {
|
|
|
666
670
|
}
|
|
667
671
|
cleanup() {
|
|
668
672
|
if (this.fileWatcher) node_fs.default.unwatchFile(this.filePath);
|
|
669
|
-
write(
|
|
673
|
+
write("\x1B[?25h\x1B[?1049l");
|
|
670
674
|
if (process.stdin.isTTY) process.stdin.setRawMode(false);
|
|
671
675
|
process.stdin.pause();
|
|
672
676
|
process.exit(0);
|
|
@@ -679,9 +683,7 @@ const exploreCommand = new commander.Command("explore").description("Interactive
|
|
|
679
683
|
search: String(opts.search ?? "")
|
|
680
684
|
}).run();
|
|
681
685
|
});
|
|
682
|
-
|
|
683
|
-
//#endregion
|
|
684
|
-
//#region src/cli/commands/export.ts
|
|
686
|
+
// src/cli/commands/export.ts
|
|
685
687
|
async function exportLogs(raw, opts = {}) {
|
|
686
688
|
const entries = safeParseLogs(raw);
|
|
687
689
|
const fields = opts.fields ? opts.fields.split(",").map((f) => f.trim()) : null;
|
|
@@ -722,9 +724,36 @@ const exportCommand = new commander.Command("export").description("Export log fi
|
|
|
722
724
|
console.log(`Exported to: ${outPath}`);
|
|
723
725
|
} else console.log(output);
|
|
724
726
|
});
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
727
|
+
// src/cli/commands/query.ts
|
|
728
|
+
/**
|
|
729
|
+
* logixia CLI — SQL-like log query engine
|
|
730
|
+
*
|
|
731
|
+
* Supports a subset of SQL syntax over NDJSON / JSON log files:
|
|
732
|
+
*
|
|
733
|
+
* SELECT * FROM logs WHERE level='error' AND duration > 500
|
|
734
|
+
* SELECT level, message FROM logs WHERE level='warn'
|
|
735
|
+
* COUNT BY level
|
|
736
|
+
* AVG(duration) BY endpoint
|
|
737
|
+
* GROUP BY statusCode
|
|
738
|
+
*
|
|
739
|
+
* Time-range shortcuts (--since / --until):
|
|
740
|
+
* --since "last 2 hours"
|
|
741
|
+
* --since "last 30 minutes"
|
|
742
|
+
* --since "today"
|
|
743
|
+
* --since "2024-01-15T08:00:00"
|
|
744
|
+
*
|
|
745
|
+
* @example Basic filter
|
|
746
|
+
* logixia query app.log --sql "SELECT * FROM logs WHERE level='error'"
|
|
747
|
+
*
|
|
748
|
+
* @example Aggregation
|
|
749
|
+
* logixia query app.log --sql "COUNT BY level"
|
|
750
|
+
*
|
|
751
|
+
* @example Time range + table output
|
|
752
|
+
* logixia query app.log --since "last 1 hour" --format table
|
|
753
|
+
*
|
|
754
|
+
* @example Live tail with SQL filter
|
|
755
|
+
* logixia query app.log --follow --sql "WHERE level='error'"
|
|
756
|
+
*/
|
|
728
757
|
/**
|
|
729
758
|
* Parse a human-friendly time range string into a `Date`.
|
|
730
759
|
* Returns `undefined` when the string is not recognised.
|
|
@@ -766,11 +795,12 @@ function parseTimeRange(value) {
|
|
|
766
795
|
function maskQuoted(sql) {
|
|
767
796
|
let out = "";
|
|
768
797
|
let quote = null;
|
|
769
|
-
for (const ch of sql) if (quote !== null)
|
|
770
|
-
quote
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
798
|
+
for (const ch of sql) if (quote !== null) {
|
|
799
|
+
if (ch === quote) {
|
|
800
|
+
quote = null;
|
|
801
|
+
out += ch;
|
|
802
|
+
} else out += "_";
|
|
803
|
+
} else {
|
|
774
804
|
if (ch === "'" || ch === "\"") quote = ch;
|
|
775
805
|
out += ch;
|
|
776
806
|
}
|
|
@@ -1019,7 +1049,7 @@ function matchesNode(row, node) {
|
|
|
1019
1049
|
}
|
|
1020
1050
|
function runAggregation(entries, agg) {
|
|
1021
1051
|
const { fn, field, groupBy } = agg;
|
|
1022
|
-
if (!groupBy) return
|
|
1052
|
+
if (!groupBy) return { warning: "Aggregation requires a GROUP BY field" };
|
|
1023
1053
|
const groups = /* @__PURE__ */ new Map();
|
|
1024
1054
|
for (const entry of entries) {
|
|
1025
1055
|
const key = String(entry[groupBy] ?? "(empty)");
|
|
@@ -1027,42 +1057,48 @@ function runAggregation(entries, agg) {
|
|
|
1027
1057
|
if (bucket) bucket.push(entry);
|
|
1028
1058
|
else groups.set(key, [entry]);
|
|
1029
1059
|
}
|
|
1030
|
-
if (fn === "COUNT" || fn === "GROUP") return
|
|
1031
|
-
[
|
|
1032
|
-
count: v.length
|
|
1033
|
-
})).sort((a, b) => b.count - a.count), [groupBy, "count"]);
|
|
1034
|
-
if (!field) return picocolors.default.yellow("Numeric aggregation requires a field: AVG(field) BY group");
|
|
1035
|
-
return formatAsTable([...groups.entries()].map(([k, v]) => {
|
|
1036
|
-
const nums = v.map((e) => Number(e[field])).filter((n) => !Number.isNaN(n));
|
|
1037
|
-
let result;
|
|
1038
|
-
switch (fn) {
|
|
1039
|
-
case "AVG":
|
|
1040
|
-
result = nums.length ? nums.reduce((a, b) => a + b, 0) / nums.length : 0;
|
|
1041
|
-
break;
|
|
1042
|
-
case "SUM":
|
|
1043
|
-
result = nums.reduce((a, b) => a + b, 0);
|
|
1044
|
-
break;
|
|
1045
|
-
case "MIN":
|
|
1046
|
-
result = nums.length ? Math.min(...nums) : 0;
|
|
1047
|
-
break;
|
|
1048
|
-
case "MAX":
|
|
1049
|
-
result = nums.length ? Math.max(...nums) : 0;
|
|
1050
|
-
break;
|
|
1051
|
-
default: result = 0;
|
|
1052
|
-
}
|
|
1053
|
-
return {
|
|
1060
|
+
if (fn === "COUNT" || fn === "GROUP") return {
|
|
1061
|
+
rows: [...groups.entries()].map(([k, v]) => ({
|
|
1054
1062
|
[groupBy]: k,
|
|
1055
|
-
[`${fn}(${field})`]: Math.round(result * 100) / 100,
|
|
1056
1063
|
count: v.length
|
|
1057
|
-
}
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1064
|
+
})).sort((a, b) => b.count - a.count),
|
|
1065
|
+
columns: [groupBy, "count"]
|
|
1066
|
+
};
|
|
1067
|
+
if (!field) return { warning: "Numeric aggregation requires a field: AVG(field) BY group" };
|
|
1068
|
+
return {
|
|
1069
|
+
rows: [...groups.entries()].map(([k, v]) => {
|
|
1070
|
+
const nums = v.map((e) => Number(e[field])).filter((n) => !Number.isNaN(n));
|
|
1071
|
+
let result;
|
|
1072
|
+
switch (fn) {
|
|
1073
|
+
case "AVG":
|
|
1074
|
+
result = nums.length ? nums.reduce((a, b) => a + b, 0) / nums.length : 0;
|
|
1075
|
+
break;
|
|
1076
|
+
case "SUM":
|
|
1077
|
+
result = nums.reduce((a, b) => a + b, 0);
|
|
1078
|
+
break;
|
|
1079
|
+
case "MIN":
|
|
1080
|
+
result = nums.length ? Math.min(...nums) : 0;
|
|
1081
|
+
break;
|
|
1082
|
+
case "MAX":
|
|
1083
|
+
result = nums.length ? Math.max(...nums) : 0;
|
|
1084
|
+
break;
|
|
1085
|
+
default: result = 0;
|
|
1086
|
+
}
|
|
1087
|
+
return {
|
|
1088
|
+
[groupBy]: k,
|
|
1089
|
+
[`${fn}(${field})`]: Math.round(result * 100) / 100,
|
|
1090
|
+
count: v.length
|
|
1091
|
+
};
|
|
1092
|
+
}).sort((a, b) => {
|
|
1093
|
+
const key = `${fn}(${field})`;
|
|
1094
|
+
return b[key] - a[key];
|
|
1095
|
+
}),
|
|
1096
|
+
columns: [
|
|
1097
|
+
groupBy,
|
|
1098
|
+
`${fn}(${field})`,
|
|
1099
|
+
"count"
|
|
1100
|
+
]
|
|
1101
|
+
};
|
|
1066
1102
|
}
|
|
1067
1103
|
function projectRow(row, select) {
|
|
1068
1104
|
if (select === "*") return row;
|
|
@@ -1070,6 +1106,11 @@ function projectRow(row, select) {
|
|
|
1070
1106
|
for (const field of select) projected[field] = row[field];
|
|
1071
1107
|
return projected;
|
|
1072
1108
|
}
|
|
1109
|
+
/** json prints an array (`[]` when empty); ndjson prints one row per line (nothing when empty). */
|
|
1110
|
+
function printMachineRows(rows, format) {
|
|
1111
|
+
if (format === "json") console.log(sanitizeForTerminal(JSON.stringify(rows, null, 2)));
|
|
1112
|
+
else if (rows.length > 0) console.log(rows.map((r) => sanitizeForTerminal(JSON.stringify(r))).join("\n"));
|
|
1113
|
+
}
|
|
1073
1114
|
function formatResults(results, format) {
|
|
1074
1115
|
if (results.length === 0) return picocolors.default.yellow("No results found");
|
|
1075
1116
|
if (format === "json") return sanitizeForTerminal(JSON.stringify(results, null, 2));
|
|
@@ -1104,10 +1145,19 @@ function executeQuery(entries, opts) {
|
|
|
1104
1145
|
limit: null
|
|
1105
1146
|
};
|
|
1106
1147
|
if (query.where) rows = rows.filter((row) => matchesWhere(row, query.where));
|
|
1107
|
-
if (query.aggregation)
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1148
|
+
if (query.aggregation) {
|
|
1149
|
+
const agg = runAggregation(rows, query.aggregation);
|
|
1150
|
+
if ("warning" in agg) return {
|
|
1151
|
+
results: [],
|
|
1152
|
+
aggregationOutput: picocolors.default.yellow(agg.warning),
|
|
1153
|
+
aggregationRows: []
|
|
1154
|
+
};
|
|
1155
|
+
return {
|
|
1156
|
+
results: [],
|
|
1157
|
+
aggregationOutput: formatAsTable(agg.rows, agg.columns),
|
|
1158
|
+
aggregationRows: agg.rows
|
|
1159
|
+
};
|
|
1160
|
+
}
|
|
1111
1161
|
const orderField = ((_query$orderBy = query.orderBy) === null || _query$orderBy === void 0 ? void 0 : _query$orderBy.field) ?? opts.orderBy;
|
|
1112
1162
|
if (orderField) {
|
|
1113
1163
|
var _query$orderBy2;
|
|
@@ -1129,7 +1179,8 @@ function executeQuery(entries, opts) {
|
|
|
1129
1179
|
rows = rows.map((row) => projectRow(row, query.select));
|
|
1130
1180
|
return {
|
|
1131
1181
|
results: rows,
|
|
1132
|
-
aggregationOutput: null
|
|
1182
|
+
aggregationOutput: null,
|
|
1183
|
+
aggregationRows: null
|
|
1133
1184
|
};
|
|
1134
1185
|
}
|
|
1135
1186
|
const queryCommand = new commander.Command("query").description("Query log files with SQL-like syntax\n\n Examples:\n logixia query app.log --sql \"SELECT * FROM logs WHERE level='error'\"\n logixia query app.log --sql \"COUNT BY level\"\n logixia query app.log --sql \"AVG(duration) BY endpoint\"\n logixia query app.log --since \"last 2 hours\" --format table\n logixia query app.log --follow --sql \"WHERE level='error'\"\n").argument("<file>", "Path to NDJSON or JSON log file").option("--sql <query>", "SQL-like query string").option("--since <time>", "Only include entries after this time (e.g. \"last 2 hours\", \"today\")").option("--until <time>", "Only include entries before this time").option("--limit <n>", "Maximum number of results to return").option("--order-by <field>", "Sort results by this field").option("--format <fmt>", "Output format: line, table, json, ndjson", "line").option("--follow", "Follow file for new entries matching the query (tail mode)", false).action(async (file, opts) => {
|
|
@@ -1141,22 +1192,26 @@ const queryCommand = new commander.Command("query").description("Query log files
|
|
|
1141
1192
|
const entries = safeParseLogs(node_fs.default.readFileSync(full, "utf8"));
|
|
1142
1193
|
const parsedLimit = opts.limit === void 0 ? NaN : Number.parseInt(opts.limit, 10);
|
|
1143
1194
|
const limitN = Number.isNaN(parsedLimit) ? void 0 : parsedLimit;
|
|
1144
|
-
const { results, aggregationOutput } = executeQuery(entries, {
|
|
1195
|
+
const { results, aggregationOutput, aggregationRows } = executeQuery(entries, {
|
|
1145
1196
|
sql: opts.sql,
|
|
1146
1197
|
since: opts.since,
|
|
1147
1198
|
until: opts.until,
|
|
1148
1199
|
limit: limitN,
|
|
1149
1200
|
orderBy: opts.orderBy
|
|
1150
1201
|
});
|
|
1202
|
+
const machineFormat = opts.format === "json" || opts.format === "ndjson";
|
|
1203
|
+
const status = machineFormat ? console.error : console.log;
|
|
1151
1204
|
if (aggregationOutput !== null) {
|
|
1152
|
-
|
|
1153
|
-
|
|
1205
|
+
status(picocolors.default.bold("\nAggregation result:"));
|
|
1206
|
+
if (machineFormat) printMachineRows(aggregationRows ?? [], opts.format);
|
|
1207
|
+
else console.log(aggregationOutput);
|
|
1154
1208
|
} else {
|
|
1155
|
-
|
|
1156
|
-
if (
|
|
1209
|
+
status(picocolors.default.bold(`\nFound ${picocolors.default.cyan(String(results.length))} match${results.length === 1 ? "" : "es"}`));
|
|
1210
|
+
if (machineFormat) printMachineRows(results, opts.format);
|
|
1211
|
+
else if (results.length > 0) console.log(formatResults(results, opts.format || "line"));
|
|
1157
1212
|
}
|
|
1158
1213
|
if (opts.follow) {
|
|
1159
|
-
|
|
1214
|
+
status(picocolors.default.dim("\n--- following (ctrl-c to exit) ---"));
|
|
1160
1215
|
let pos = node_fs.default.statSync(full).size;
|
|
1161
1216
|
let buffer = "";
|
|
1162
1217
|
node_fs.default.watchFile(full, { interval: 300 }, (curr) => {
|
|
@@ -1187,9 +1242,7 @@ const queryCommand = new commander.Command("query").description("Query log files
|
|
|
1187
1242
|
});
|
|
1188
1243
|
}
|
|
1189
1244
|
});
|
|
1190
|
-
|
|
1191
|
-
//#endregion
|
|
1192
|
-
//#region src/cli/commands/search.ts
|
|
1245
|
+
// src/cli/commands/search.ts
|
|
1193
1246
|
function parseQuery(query) {
|
|
1194
1247
|
const match = query.match(/^(\w+):(.+)$/);
|
|
1195
1248
|
if (match) return {
|
|
@@ -1198,31 +1251,76 @@ function parseQuery(query) {
|
|
|
1198
1251
|
};
|
|
1199
1252
|
return { value: query };
|
|
1200
1253
|
}
|
|
1201
|
-
|
|
1202
|
-
const
|
|
1203
|
-
const
|
|
1204
|
-
return
|
|
1254
|
+
function entryMatcher(query) {
|
|
1255
|
+
const criteria = parseQuery(query);
|
|
1256
|
+
const needle = criteria.value.toLowerCase();
|
|
1257
|
+
return (entry) => {
|
|
1205
1258
|
const row = entry;
|
|
1206
1259
|
if (criteria.field) {
|
|
1207
1260
|
const fieldValue = row[criteria.field];
|
|
1208
1261
|
if (fieldValue === void 0) return false;
|
|
1209
|
-
return String(fieldValue).toLowerCase().includes(
|
|
1210
|
-
}
|
|
1211
|
-
|
|
1262
|
+
return String(fieldValue).toLowerCase().includes(needle);
|
|
1263
|
+
}
|
|
1264
|
+
return JSON.stringify(row).toLowerCase().includes(needle);
|
|
1265
|
+
};
|
|
1212
1266
|
}
|
|
1213
|
-
|
|
1214
|
-
|
|
1267
|
+
/**
|
|
1268
|
+
* Like grep -C: matches plus `context` parsed entries (blank lines are skipped) before and
|
|
1269
|
+
* after each, in file order, tagged with their original file line numbers. Single pass.
|
|
1270
|
+
*/
|
|
1271
|
+
async function searchLogsWithContext(raw, opts = {}) {
|
|
1272
|
+
const parsed = parseLogLines(raw);
|
|
1273
|
+
const isMatch = entryMatcher(opts.query || "");
|
|
1274
|
+
const context = Math.max(0, Number.parseInt(String(opts.context ?? 0), 10) || 0);
|
|
1275
|
+
const matched = parsed.map((p) => isMatch(p.entry));
|
|
1276
|
+
const nextMatch = Array.from({ length: parsed.length }, () => Number.POSITIVE_INFINITY);
|
|
1277
|
+
let next = Number.POSITIVE_INFINITY;
|
|
1278
|
+
for (let i = parsed.length - 1; i >= 0; i--) {
|
|
1279
|
+
if (matched[i]) next = i;
|
|
1280
|
+
nextMatch[i] = next;
|
|
1281
|
+
}
|
|
1282
|
+
const hits = [];
|
|
1283
|
+
let lastMatch = Number.NEGATIVE_INFINITY;
|
|
1284
|
+
for (const [i, p] of parsed.entries()) {
|
|
1285
|
+
if (matched[i]) lastMatch = i;
|
|
1286
|
+
if (i - lastMatch <= context || nextMatch[i] - i <= context) hits.push({
|
|
1287
|
+
index: i,
|
|
1288
|
+
line: p.line,
|
|
1289
|
+
entry: p.entry,
|
|
1290
|
+
match: Boolean(matched[i])
|
|
1291
|
+
});
|
|
1292
|
+
}
|
|
1293
|
+
return hits;
|
|
1294
|
+
}
|
|
1295
|
+
function matchedColumns(hits) {
|
|
1296
|
+
const cols = /* @__PURE__ */ new Set();
|
|
1297
|
+
for (const h of hits) if (h.match) for (const k of Object.keys(h.entry || {})) cols.add(k);
|
|
1298
|
+
if (cols.size === 0) for (const h of hits) for (const k of Object.keys(h.entry || {})) cols.add(k);
|
|
1299
|
+
return [...cols].slice(0, 4);
|
|
1300
|
+
}
|
|
1301
|
+
function formatSearchResults(hits, format) {
|
|
1302
|
+
if (format === "json") return sanitizeForTerminal(JSON.stringify(hits.filter((h) => h.match).map((h) => h.entry), null, 2));
|
|
1303
|
+
if (hits.length === 0) return picocolors.default.yellow("No results found");
|
|
1215
1304
|
if (format === "table") {
|
|
1216
|
-
|
|
1217
|
-
|
|
1305
|
+
const withContext = hits.some((h) => !h.match);
|
|
1306
|
+
const rows = hits.map((h) => withContext ? {
|
|
1307
|
+
match: h.match ? "*" : "",
|
|
1308
|
+
...h.entry
|
|
1309
|
+
} : h.entry);
|
|
1310
|
+
const columns = matchedColumns(hits);
|
|
1311
|
+
return formatAsTable(rows, withContext ? ["match", ...columns] : columns);
|
|
1218
1312
|
}
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1313
|
+
const lines = [];
|
|
1314
|
+
let prev = -1;
|
|
1315
|
+
for (const h of hits) {
|
|
1316
|
+
if (prev >= 0 && h.index > prev + 1) lines.push(picocolors.default.gray("--"));
|
|
1317
|
+
prev = h.index;
|
|
1318
|
+
const sep = h.match ? ":" : "-";
|
|
1319
|
+
lines.push(`${picocolors.default.gray(String(h.line) + sep)} ${sanitizeForTerminal(JSON.stringify(h.entry))}`);
|
|
1320
|
+
}
|
|
1321
|
+
return lines.join("\n");
|
|
1224
1322
|
}
|
|
1225
|
-
const searchCommand = new commander.Command("search").description("Search log files with query patterns").argument("<file>", "Path to log file").option("--query <query>", "Search query (e.g., \"user_id:123\" or \"error\")", "").option("--format <fmt>", "Output format (table, json, line)", "line").option("--context <lines>", "
|
|
1323
|
+
const searchCommand = new commander.Command("search").description("Search log files with query patterns").argument("<file>", "Path to log file").option("--query <query>", "Search query (e.g., \"user_id:123\" or \"error\")", "").option("--format <fmt>", "Output format (table, json, line)", "line").option("--context <lines>", "Entries of context around each match (line/table formats)", "0").action(async (file, opts) => {
|
|
1226
1324
|
const full = node_path.default.resolve(process.cwd(), file);
|
|
1227
1325
|
if (!node_fs.default.existsSync(full)) {
|
|
1228
1326
|
console.error(`File not found: ${full}`);
|
|
@@ -1232,13 +1330,12 @@ const searchCommand = new commander.Command("search").description("Search log fi
|
|
|
1232
1330
|
console.error("--query is required");
|
|
1233
1331
|
process.exit(2);
|
|
1234
1332
|
}
|
|
1235
|
-
const
|
|
1236
|
-
|
|
1237
|
-
|
|
1333
|
+
const hits = await searchLogsWithContext(node_fs.default.readFileSync(full, "utf8"), opts);
|
|
1334
|
+
const count = hits.filter((h) => h.match).length;
|
|
1335
|
+
(opts.format === "json" ? console.error : console.log)(picocolors.default.bold(`\nFound ${count} matches`));
|
|
1336
|
+
console.log(formatSearchResults(hits, opts.format));
|
|
1238
1337
|
});
|
|
1239
|
-
|
|
1240
|
-
//#endregion
|
|
1241
|
-
//#region src/cli/commands/stats.ts
|
|
1338
|
+
// src/cli/commands/stats.ts
|
|
1242
1339
|
async function generateStats(raw, opts = {}) {
|
|
1243
1340
|
const entries = safeParseLogs(raw);
|
|
1244
1341
|
const group = opts.groupBy || "level";
|
|
@@ -1298,9 +1395,7 @@ const statsCommand = new commander.Command("stats").description("Show statistics
|
|
|
1298
1395
|
if (opts.format === "json") console.log(sanitizeForTerminal(JSON.stringify(stats, null, 2)));
|
|
1299
1396
|
else console.log(formatStatsOutput(stats, file));
|
|
1300
1397
|
});
|
|
1301
|
-
|
|
1302
|
-
//#endregion
|
|
1303
|
-
//#region src/cli/commands/tail.ts
|
|
1398
|
+
// src/cli/commands/tail.ts
|
|
1304
1399
|
function parseFilter(filter) {
|
|
1305
1400
|
if (!filter) return null;
|
|
1306
1401
|
const match = filter.match(/^(\w+):(.+)$/);
|
|
@@ -1368,9 +1463,7 @@ const tailCommand = new commander.Command("tail").description("Follow log files
|
|
|
1368
1463
|
});
|
|
1369
1464
|
}
|
|
1370
1465
|
});
|
|
1371
|
-
|
|
1372
|
-
//#endregion
|
|
1373
|
-
//#region src/cli/index.ts
|
|
1466
|
+
// src/cli/index.ts
|
|
1374
1467
|
const pkgPath = node_path.default.resolve(__dirname, "../..", "package.json");
|
|
1375
1468
|
let pkg;
|
|
1376
1469
|
try {
|
|
@@ -1400,7 +1493,5 @@ function isDirectRun(argv1, file) {
|
|
|
1400
1493
|
}
|
|
1401
1494
|
}
|
|
1402
1495
|
if (isDirectRun(process.argv[1], __filename)) program.parse(process.argv);
|
|
1403
|
-
|
|
1404
|
-
//#endregion
|
|
1405
1496
|
exports.isDirectRun = isDirectRun;
|
|
1406
|
-
exports.program = program;
|
|
1497
|
+
exports.program = program;
|
package/dist/cloudwatch.d.mts
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import "./transport
|
|
2
|
-
import { n as CloudWatchTransportConfig, t as CloudWatchTransport } from "./cloudwatch.transport-UlyZFWMn.mjs";
|
|
1
|
+
import { n as CloudWatchTransportConfig, t as CloudWatchTransport } from "./cloudwatch.transport-CjVrI6S4.mjs";
|
|
3
2
|
export { CloudWatchTransport, CloudWatchTransportConfig };
|
package/dist/cloudwatch.d.ts
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import "./transport
|
|
2
|
-
import { n as CloudWatchTransportConfig, t as CloudWatchTransport } from "./cloudwatch.transport-DsEq633o.js";
|
|
1
|
+
import { n as CloudWatchTransportConfig, t as CloudWatchTransport } from "./cloudwatch.transport-CQyT6U91.js";
|
|
3
2
|
export { CloudWatchTransport, CloudWatchTransportConfig };
|
package/dist/cloudwatch.js
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
require(
|
|
3
|
-
|
|
4
|
-
const require_cloudwatch_transport = require('./cloudwatch.transport-BO1ahxw-.js');
|
|
5
|
-
require('./entry-fields-BvOLFlJ4.js');
|
|
6
|
-
|
|
7
|
-
exports.CloudWatchTransport = require_cloudwatch_transport.CloudWatchTransport;
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_cloudwatch_transport = require("./cloudwatch.transport-Ch1Uae-0.js");
|
|
3
|
+
exports.CloudWatchTransport = require_cloudwatch_transport.CloudWatchTransport;
|
package/dist/cloudwatch.mjs
CHANGED
|
@@ -1,7 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import "./safe-stringify-DJ66tW5I.mjs";
|
|
3
|
-
import "./batch-buffer-PGvSgbmd.mjs";
|
|
4
|
-
import { t as CloudWatchTransport } from "./cloudwatch.transport-DZ6ies7g.mjs";
|
|
5
|
-
import "./entry-fields-BJkuPnIg.mjs";
|
|
6
|
-
|
|
7
|
-
export { CloudWatchTransport };
|
|
1
|
+
export { t as CloudWatchTransport } from "./cloudwatch.transport-DZqF2xZO.mjs";
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
//#region src/transports/cloudwatch.transport.d.ts
|
|
4
|
-
|
|
1
|
+
import { _ as TransportLogEntry, l as IAsyncTransport } from "./transport.types-CzJq4IrF.js";
|
|
5
2
|
interface CloudWatchTransportConfig {
|
|
6
3
|
/** AWS region, e.g. `'us-east-1'`. Falls back to `AWS_REGION` env var. */
|
|
7
4
|
region?: string;
|
|
@@ -83,6 +80,5 @@ declare class CloudWatchTransport implements IAsyncTransport {
|
|
|
83
80
|
private ensureStream;
|
|
84
81
|
private call;
|
|
85
82
|
}
|
|
86
|
-
//#endregion
|
|
87
83
|
export { CloudWatchTransportConfig as n, CloudWatchTransport as t };
|
|
88
|
-
//# sourceMappingURL=cloudwatch.transport-
|
|
84
|
+
//# sourceMappingURL=cloudwatch.transport-CQyT6U91.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloudwatch.transport-CQyT6U91.d.ts","names":[],"sources":["../src/transports/cloudwatch.transport.ts"],"mappings":";UAmDiB;;EAEf;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA;;;;;;EAMA;;;;;EAKA;;;;;;EAMA;;EAEA;;;;;;EAMA;;EAEA;;EAEA;;EAEA;;;;;cAkCW,+BAA+B;WAC1B;WACA;WACA;WACA;mBAEC;mBACA;UACT;mBACS;mBACA;UACT;mBAES;mBACA;mBACA;mBACA;mBACA;mBACA;EAEL,YAAA,QAAQ;EAmCpB,MAAM,OAAO;EAOb,SAAS;;;;;;EASH,SAAS;UAQP;UAyBM;UAkBA;UAsBA"}
|