asaihost-nodejs 0.0.1
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 +518 -0
- package/dist/InterventionLog-25EHE4QR.cjs +30 -0
- package/dist/InterventionLog-25EHE4QR.cjs.map +1 -0
- package/dist/InterventionLog-R6CCPU2B.es.js +30 -0
- package/dist/InterventionLog-R6CCPU2B.es.js.map +1 -0
- package/dist/LogStore-ECXX34WC.es.js +54 -0
- package/dist/LogStore-ECXX34WC.es.js.map +1 -0
- package/dist/LogStore-M2AUBNGO.cjs +54 -0
- package/dist/LogStore-M2AUBNGO.cjs.map +1 -0
- package/dist/asaihost-nodejs.cjs +6761 -0
- package/dist/asaihost-nodejs.cjs.map +1 -0
- package/dist/asaihost-nodejs.d.cts +406 -0
- package/dist/asaihost-nodejs.d.ts +406 -0
- package/dist/asaihost-nodejs.es.js +6761 -0
- package/dist/asaihost-nodejs.es.js.map +1 -0
- package/dist/chunk-4WJDC4M4.es.js +311 -0
- package/dist/chunk-4WJDC4M4.es.js.map +1 -0
- package/dist/chunk-6U2I5EON.es.js +12 -0
- package/dist/chunk-6U2I5EON.es.js.map +1 -0
- package/dist/chunk-DROOHKB3.es.js +87 -0
- package/dist/chunk-DROOHKB3.es.js.map +1 -0
- package/dist/chunk-E7V3EBDB.es.js +435 -0
- package/dist/chunk-E7V3EBDB.es.js.map +1 -0
- package/dist/chunk-EOGZPRML.es.js +740 -0
- package/dist/chunk-EOGZPRML.es.js.map +1 -0
- package/dist/chunk-G4WVDUBH.cjs +463 -0
- package/dist/chunk-G4WVDUBH.cjs.map +1 -0
- package/dist/chunk-HHPGUJ75.cjs +162 -0
- package/dist/chunk-HHPGUJ75.cjs.map +1 -0
- package/dist/chunk-KOFCBB3N.cjs +87 -0
- package/dist/chunk-KOFCBB3N.cjs.map +1 -0
- package/dist/chunk-KUZQ36IJ.es.js +162 -0
- package/dist/chunk-KUZQ36IJ.es.js.map +1 -0
- package/dist/chunk-LOMSUPPU.es.js +1202 -0
- package/dist/chunk-LOMSUPPU.es.js.map +1 -0
- package/dist/chunk-MCMADJQR.es.js +463 -0
- package/dist/chunk-MCMADJQR.es.js.map +1 -0
- package/dist/chunk-NLBFIRDB.cjs +105 -0
- package/dist/chunk-NLBFIRDB.cjs.map +1 -0
- package/dist/chunk-O6LVLSNB.cjs +40 -0
- package/dist/chunk-O6LVLSNB.cjs.map +1 -0
- package/dist/chunk-QWVR2HNT.cjs +435 -0
- package/dist/chunk-QWVR2HNT.cjs.map +1 -0
- package/dist/chunk-SMVZ3ZDJ.cjs +12 -0
- package/dist/chunk-SMVZ3ZDJ.cjs.map +1 -0
- package/dist/chunk-UTKVJE7N.es.js +40 -0
- package/dist/chunk-UTKVJE7N.es.js.map +1 -0
- package/dist/chunk-VLMM735Q.cjs +1202 -0
- package/dist/chunk-VLMM735Q.cjs.map +1 -0
- package/dist/chunk-W7DVKGX5.cjs +311 -0
- package/dist/chunk-W7DVKGX5.cjs.map +1 -0
- package/dist/chunk-X7VHW2TD.cjs +740 -0
- package/dist/chunk-X7VHW2TD.cjs.map +1 -0
- package/dist/chunk-XBIN4C2V.es.js +105 -0
- package/dist/chunk-XBIN4C2V.es.js.map +1 -0
- package/dist/intervention-hooks-FI4EHOL5.es.js +21 -0
- package/dist/intervention-hooks-FI4EHOL5.es.js.map +1 -0
- package/dist/intervention-hooks-LE6X4C6N.cjs +21 -0
- package/dist/intervention-hooks-LE6X4C6N.cjs.map +1 -0
- package/dist/log-alert-GLCULMQP.es.js +51 -0
- package/dist/log-alert-GLCULMQP.es.js.map +1 -0
- package/dist/log-alert-LAJ6VSAG.cjs +51 -0
- package/dist/log-alert-LAJ6VSAG.cjs.map +1 -0
- package/dist/log-formats-FKFMQKNO.cjs +31 -0
- package/dist/log-formats-FKFMQKNO.cjs.map +1 -0
- package/dist/log-formats-I5E32H5F.es.js +31 -0
- package/dist/log-formats-I5E32H5F.es.js.map +1 -0
- package/dist/password-63OY27RX.es.js +20 -0
- package/dist/password-63OY27RX.es.js.map +1 -0
- package/dist/password-NZ5EGDWG.cjs +20 -0
- package/dist/password-NZ5EGDWG.cjs.map +1 -0
- package/dist/user-store-J7LWEXSW.es.js +12 -0
- package/dist/user-store-J7LWEXSW.es.js.map +1 -0
- package/dist/user-store-SX4N6PQ4.cjs +12 -0
- package/dist/user-store-SX4N6PQ4.cjs.map +1 -0
- package/package.json +79 -0
|
@@ -0,0 +1,1202 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
|
+
|
|
3
|
+
var _chunkO6LVLSNBcjs = require('./chunk-O6LVLSNB.cjs');
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
var _chunkHHPGUJ75cjs = require('./chunk-HHPGUJ75.cjs');
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
var _chunkSMVZ3ZDJcjs = require('./chunk-SMVZ3ZDJ.cjs');
|
|
16
|
+
|
|
17
|
+
// src/sysserver/lib/common/LogStore.ts
|
|
18
|
+
var LogStore_exports = {};
|
|
19
|
+
_chunkSMVZ3ZDJcjs.__export.call(void 0, LogStore_exports, {
|
|
20
|
+
archiveInterventionYear: () => archiveInterventionYear,
|
|
21
|
+
exportLogContent: () => exportLogContent,
|
|
22
|
+
getComplianceReport: () => getComplianceReport,
|
|
23
|
+
getEffectiveStoreType: () => getEffectiveStoreType,
|
|
24
|
+
getLogStoreConfig: () => getLogStoreConfig,
|
|
25
|
+
getLogStoreMeta: () => getLogStoreMeta,
|
|
26
|
+
getUnifiedEntry: () => getUnifiedEntry,
|
|
27
|
+
getUnifiedStats: () => getUnifiedStats,
|
|
28
|
+
groupsToInterventionFiles: () => groupsToInterventionFiles,
|
|
29
|
+
groupsToManageChildren: () => groupsToManageChildren,
|
|
30
|
+
isLogStoreEnabled: () => isLogStoreEnabled,
|
|
31
|
+
isLogStoreFileBackend: () => isLogStoreFileBackend,
|
|
32
|
+
isLogStoreSqlite: () => isLogStoreSqlite,
|
|
33
|
+
listUnifiedGroups: () => listUnifiedGroups,
|
|
34
|
+
mirrorAccessLog: () => mirrorAccessLog,
|
|
35
|
+
mirrorInterventionLog: () => mirrorInterventionLog,
|
|
36
|
+
mirrorWebLog: () => mirrorWebLog,
|
|
37
|
+
prefersDiskLogAccess: () => prefersDiskLogAccess,
|
|
38
|
+
purgeSqliteEntriesForFile: () => purgeSqliteEntriesForFile,
|
|
39
|
+
purgeStoreEntriesForFile: () => purgeStoreEntriesForFile,
|
|
40
|
+
queryUnifiedLogs: () => queryUnifiedLogs,
|
|
41
|
+
readWebLogFromStore: () => readWebLogFromStore,
|
|
42
|
+
searchUnifiedLogs: () => searchUnifiedLogs
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// src/sysserver/lib/common/log-file-store.ts
|
|
46
|
+
var _promises = require('fs/promises'); var _promises2 = _interopRequireDefault(_promises);
|
|
47
|
+
var _path = require('path'); var _path2 = _interopRequireDefault(_path);
|
|
48
|
+
function storeBaseAbs($asai) {
|
|
49
|
+
const resolved = _chunkHHPGUJ75cjs.resolveStoreConfig.call(void 0, $asai, "log");
|
|
50
|
+
const opt = _chunkHHPGUJ75cjs.normalizeStoreOpt.call(void 0, "log", resolved.type, resolved.opt);
|
|
51
|
+
const dir = String(opt.dir || "webdata/webdb/log/store/");
|
|
52
|
+
return _path2.default.resolve(process.cwd(), dir);
|
|
53
|
+
}
|
|
54
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, storeBaseAbs, "storeBaseAbs");
|
|
55
|
+
var INDEX_ROOT = "index";
|
|
56
|
+
var META_ROOT = "_meta";
|
|
57
|
+
var ID_COUNTER = "id-counter.json";
|
|
58
|
+
var LEGACY_BLOB = "log_entries.json";
|
|
59
|
+
function indexRootAbs($asai) {
|
|
60
|
+
return _path2.default.join(storeBaseAbs($asai), INDEX_ROOT);
|
|
61
|
+
}
|
|
62
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, indexRootAbs, "indexRootAbs");
|
|
63
|
+
function safeSeg(v) {
|
|
64
|
+
return (v || "_").replace(/[\\/:*?"<>|]/g, "_").slice(0, 64) || "_";
|
|
65
|
+
}
|
|
66
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, safeSeg, "safeSeg");
|
|
67
|
+
function entryRelPath(row) {
|
|
68
|
+
const kind = safeSeg(String(row.kind || "web"));
|
|
69
|
+
const ns = safeSeg(String(row.ns || "_"));
|
|
70
|
+
const source = safeSeg(String(row.source || "_"));
|
|
71
|
+
const logDate = safeSeg(String(row.log_date || "unknown"));
|
|
72
|
+
const id = String(_nullishCoalesce(row.id, () => ( "0")));
|
|
73
|
+
return _path2.default.join(INDEX_ROOT, kind, ns, source, logDate, `${id}.json`);
|
|
74
|
+
}
|
|
75
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, entryRelPath, "entryRelPath");
|
|
76
|
+
function rowToRecord(row) {
|
|
77
|
+
const out = { ...row };
|
|
78
|
+
for (const k of ["severity", "retention_protected", "created_at", "id"]) {
|
|
79
|
+
if (out[k] != null && out[k] !== "") out[k] = Number(out[k]);
|
|
80
|
+
}
|
|
81
|
+
return out;
|
|
82
|
+
}
|
|
83
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, rowToRecord, "rowToRecord");
|
|
84
|
+
async function ensureDir(dir) {
|
|
85
|
+
await _promises2.default.mkdir(dir, { recursive: true });
|
|
86
|
+
}
|
|
87
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, ensureDir, "ensureDir");
|
|
88
|
+
async function readCounter($asai) {
|
|
89
|
+
const file = _path2.default.join(storeBaseAbs($asai), META_ROOT, ID_COUNTER);
|
|
90
|
+
try {
|
|
91
|
+
const raw = await _promises2.default.readFile(file, "utf8");
|
|
92
|
+
const parsed = JSON.parse(raw);
|
|
93
|
+
return Math.max(0, Number(parsed.next || parsed.last || 0));
|
|
94
|
+
} catch (e2) {
|
|
95
|
+
return 0;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, readCounter, "readCounter");
|
|
99
|
+
async function writeCounter($asai, next) {
|
|
100
|
+
const dir = _path2.default.join(storeBaseAbs($asai), META_ROOT);
|
|
101
|
+
await ensureDir(dir);
|
|
102
|
+
await _promises2.default.writeFile(_path2.default.join(dir, ID_COUNTER), JSON.stringify({ next, updatedAt: Date.now() }, null, 2), "utf8");
|
|
103
|
+
}
|
|
104
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, writeCounter, "writeCounter");
|
|
105
|
+
async function nextId($asai) {
|
|
106
|
+
const cur = await readCounter($asai);
|
|
107
|
+
const id = cur + 1;
|
|
108
|
+
await writeCounter($asai, id);
|
|
109
|
+
return id;
|
|
110
|
+
}
|
|
111
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, nextId, "nextId");
|
|
112
|
+
async function migrateLegacyBlobIfNeeded($asai) {
|
|
113
|
+
const base = storeBaseAbs($asai);
|
|
114
|
+
const legacyPath = _path2.default.join(base, LEGACY_BLOB);
|
|
115
|
+
let legacy = [];
|
|
116
|
+
try {
|
|
117
|
+
const raw = await _promises2.default.readFile(legacyPath, "utf8");
|
|
118
|
+
const parsed = JSON.parse(raw);
|
|
119
|
+
if (Array.isArray(parsed) && parsed.length) legacy = parsed;
|
|
120
|
+
} catch (e3) {
|
|
121
|
+
return 0;
|
|
122
|
+
}
|
|
123
|
+
let maxId = await readCounter($asai);
|
|
124
|
+
for (const row of legacy) {
|
|
125
|
+
const id = Number(row.id || ++maxId);
|
|
126
|
+
if (id > maxId) maxId = id;
|
|
127
|
+
const record = rowToRecord({ ...row, id });
|
|
128
|
+
const abs = _path2.default.join(base, entryRelPath(record));
|
|
129
|
+
await ensureDir(_path2.default.dirname(abs));
|
|
130
|
+
await _promises2.default.writeFile(abs, JSON.stringify(record, null, 2), "utf8");
|
|
131
|
+
}
|
|
132
|
+
await writeCounter($asai, maxId);
|
|
133
|
+
await _promises2.default.rename(legacyPath, `${legacyPath}.migrated.${Date.now()}`).catch(() => void 0);
|
|
134
|
+
return legacy.length;
|
|
135
|
+
}
|
|
136
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, migrateLegacyBlobIfNeeded, "migrateLegacyBlobIfNeeded");
|
|
137
|
+
async function walkIndexFiles($asai) {
|
|
138
|
+
const root = indexRootAbs($asai);
|
|
139
|
+
const rows = [];
|
|
140
|
+
async function walk(dir) {
|
|
141
|
+
let entries;
|
|
142
|
+
try {
|
|
143
|
+
entries = await _promises2.default.readdir(dir, { withFileTypes: true });
|
|
144
|
+
} catch (e4) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
for (const ent of entries) {
|
|
148
|
+
const full = _path2.default.join(dir, ent.name);
|
|
149
|
+
if (ent.isDirectory()) {
|
|
150
|
+
await walk(full);
|
|
151
|
+
} else if (ent.isFile() && ent.name.endsWith(".json")) {
|
|
152
|
+
try {
|
|
153
|
+
const raw = await _promises2.default.readFile(full, "utf8");
|
|
154
|
+
const parsed = JSON.parse(raw);
|
|
155
|
+
if (parsed && typeof parsed === "object") rows.push(rowToRecord(parsed));
|
|
156
|
+
} catch (e5) {
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, walk, "walk");
|
|
162
|
+
await walk(root);
|
|
163
|
+
return rows;
|
|
164
|
+
}
|
|
165
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, walkIndexFiles, "walkIndexFiles");
|
|
166
|
+
function applyQueryFilter(rows, filter) {
|
|
167
|
+
let out = rows;
|
|
168
|
+
if (filter.kind) out = out.filter((r) => r.kind === filter.kind);
|
|
169
|
+
if (filter.ns) out = out.filter((r) => r.ns === filter.ns);
|
|
170
|
+
if (filter.source) out = out.filter((r) => r.source === filter.source);
|
|
171
|
+
if (filter.log_date) out = out.filter((r) => r.log_date === filter.log_date);
|
|
172
|
+
if (filter.file_name) out = out.filter((r) => r.file_name === filter.file_name);
|
|
173
|
+
out.sort((a, b) => Number(b.created_at || 0) - Number(a.created_at || 0));
|
|
174
|
+
if (filter.limit != null) out = out.slice(0, filter.limit);
|
|
175
|
+
return out;
|
|
176
|
+
}
|
|
177
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, applyQueryFilter, "applyQueryFilter");
|
|
178
|
+
function applySearchFilters(rows, filter) {
|
|
179
|
+
let out = rows;
|
|
180
|
+
if (filter.keyword) {
|
|
181
|
+
const kw = filter.keyword.toLowerCase();
|
|
182
|
+
out = out.filter((r) => {
|
|
183
|
+
const hay = [r.message, r.raw_line, r.event_type, r.us, r.identification, r.category].map((v) => String(v || "").toLowerCase()).join(" ");
|
|
184
|
+
return hay.includes(kw);
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
if (filter.event_type) {
|
|
188
|
+
const et = filter.event_type.toUpperCase();
|
|
189
|
+
out = out.filter((r) => String(r.event_type || "").toUpperCase() === et);
|
|
190
|
+
}
|
|
191
|
+
if (filter.severity_min != null && !Number.isNaN(Number(filter.severity_min))) {
|
|
192
|
+
const min = Number(filter.severity_min);
|
|
193
|
+
out = out.filter((r) => Number(r.severity || 0) >= min);
|
|
194
|
+
}
|
|
195
|
+
if (filter.date_from) out = out.filter((r) => String(r.log_date || "") >= filter.date_from);
|
|
196
|
+
if (filter.date_to) out = out.filter((r) => String(r.log_date || "") <= filter.date_to);
|
|
197
|
+
if (filter.outcome) {
|
|
198
|
+
const oc = filter.outcome.toLowerCase();
|
|
199
|
+
out = out.filter((r) => String(r.outcome || "").toLowerCase() === oc);
|
|
200
|
+
}
|
|
201
|
+
return out;
|
|
202
|
+
}
|
|
203
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, applySearchFilters, "applySearchFilters");
|
|
204
|
+
var migrateOnce = null;
|
|
205
|
+
async function ensureMigrated($asai) {
|
|
206
|
+
if (!migrateOnce) {
|
|
207
|
+
migrateOnce = migrateLegacyBlobIfNeeded($asai).then(() => void 0);
|
|
208
|
+
}
|
|
209
|
+
await migrateOnce;
|
|
210
|
+
}
|
|
211
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, ensureMigrated, "ensureMigrated");
|
|
212
|
+
async function fileStoreInsert($asai, row) {
|
|
213
|
+
await ensureMigrated($asai);
|
|
214
|
+
const id = await nextId($asai);
|
|
215
|
+
const record = rowToRecord({ id, ...row });
|
|
216
|
+
const abs = _path2.default.join(storeBaseAbs($asai), entryRelPath(record));
|
|
217
|
+
await ensureDir(_path2.default.dirname(abs));
|
|
218
|
+
await _promises2.default.writeFile(abs, JSON.stringify(record, null, 2), "utf8");
|
|
219
|
+
}
|
|
220
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, fileStoreInsert, "fileStoreInsert");
|
|
221
|
+
async function fileStoreQuery($asai, filter = {}) {
|
|
222
|
+
await ensureMigrated($asai);
|
|
223
|
+
const rows = await walkIndexFiles($asai);
|
|
224
|
+
return applyQueryFilter(rows, { ...filter, limit: _nullishCoalesce(filter.limit, () => ( 500)) });
|
|
225
|
+
}
|
|
226
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, fileStoreQuery, "fileStoreQuery");
|
|
227
|
+
async function fileStoreGet($asai, id) {
|
|
228
|
+
await ensureMigrated($asai);
|
|
229
|
+
const rows = await walkIndexFiles($asai);
|
|
230
|
+
const found = rows.find((r) => String(r.id) === String(id));
|
|
231
|
+
return found ? rowToRecord(found) : null;
|
|
232
|
+
}
|
|
233
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, fileStoreGet, "fileStoreGet");
|
|
234
|
+
async function fileStoreSearch($asai, filter = {}) {
|
|
235
|
+
await ensureMigrated($asai);
|
|
236
|
+
const baseLimit = 2e4;
|
|
237
|
+
const rows = await fileStoreQuery($asai, {
|
|
238
|
+
kind: filter.kind,
|
|
239
|
+
ns: filter.ns,
|
|
240
|
+
source: filter.source,
|
|
241
|
+
log_date: filter.log_date,
|
|
242
|
+
file_name: filter.file_name,
|
|
243
|
+
limit: baseLimit
|
|
244
|
+
});
|
|
245
|
+
const filtered = applySearchFilters(rows, filter);
|
|
246
|
+
const offset = Math.max(0, Number(filter.offset) || 0);
|
|
247
|
+
const limit = Math.min(2e3, Math.max(1, Number(filter.limit) || 200));
|
|
248
|
+
return {
|
|
249
|
+
entries: filtered.slice(offset, offset + limit),
|
|
250
|
+
total: filtered.length,
|
|
251
|
+
truncated: rows.length >= baseLimit
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, fileStoreSearch, "fileStoreSearch");
|
|
255
|
+
async function fileStoreStats($asai) {
|
|
256
|
+
await ensureMigrated($asai);
|
|
257
|
+
const rows = await walkIndexFiles($asai);
|
|
258
|
+
const stats = { total: rows.length, web: 0, intervention: 0, sec: 0, access: 0, prod: 0, test: 0 };
|
|
259
|
+
for (const r of rows) {
|
|
260
|
+
const k = String(r.kind || "");
|
|
261
|
+
if (k === "web") stats.web += 1;
|
|
262
|
+
else if (k === "intervention") stats.intervention += 1;
|
|
263
|
+
else if (k === "sec") stats.sec += 1;
|
|
264
|
+
else if (k === "access") stats.access += 1;
|
|
265
|
+
const ns = String(r.ns || "");
|
|
266
|
+
if (ns === "prod") stats.prod += 1;
|
|
267
|
+
if (ns === "test") stats.test += 1;
|
|
268
|
+
}
|
|
269
|
+
return stats;
|
|
270
|
+
}
|
|
271
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, fileStoreStats, "fileStoreStats");
|
|
272
|
+
async function fileStoreDeleteByFile($asai, fileName, ns = "") {
|
|
273
|
+
await ensureMigrated($asai);
|
|
274
|
+
const base = storeBaseAbs($asai);
|
|
275
|
+
const root = indexRootAbs($asai);
|
|
276
|
+
let removed = 0;
|
|
277
|
+
async function walk(dir) {
|
|
278
|
+
let entries;
|
|
279
|
+
try {
|
|
280
|
+
entries = await _promises2.default.readdir(dir, { withFileTypes: true });
|
|
281
|
+
} catch (e6) {
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
for (const ent of entries) {
|
|
285
|
+
const full = _path2.default.join(dir, ent.name);
|
|
286
|
+
if (ent.isDirectory()) {
|
|
287
|
+
await walk(full);
|
|
288
|
+
} else if (ent.isFile() && ent.name.endsWith(".json")) {
|
|
289
|
+
try {
|
|
290
|
+
const raw = await _promises2.default.readFile(full, "utf8");
|
|
291
|
+
const parsed = JSON.parse(raw);
|
|
292
|
+
if (String(parsed.file_name) !== fileName) continue;
|
|
293
|
+
if (ns && String(parsed.ns) !== ns) continue;
|
|
294
|
+
await _promises2.default.unlink(full);
|
|
295
|
+
removed += 1;
|
|
296
|
+
} catch (e7) {
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, walk, "walk");
|
|
302
|
+
await walk(root);
|
|
303
|
+
return removed;
|
|
304
|
+
}
|
|
305
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, fileStoreDeleteByFile, "fileStoreDeleteByFile");
|
|
306
|
+
async function fileStoreDiskStats($asai) {
|
|
307
|
+
const logger = _optionalChain([$asai, 'optionalAccess', _ => _.hostconfig, 'optionalAccess', _2 => _2.logger]) || {};
|
|
308
|
+
const scanDirs = [
|
|
309
|
+
{ kind: "web", dir: _optionalChain([logger, 'access', _3 => _3.path, 'optionalAccess', _4 => _4.server]) },
|
|
310
|
+
{ kind: "web", dir: _optionalChain([logger, 'access', _5 => _5.path, 'optionalAccess', _6 => _6.client]) },
|
|
311
|
+
{ kind: "access", dir: _optionalChain([logger, 'access', _7 => _7.path, 'optionalAccess', _8 => _8.access]) },
|
|
312
|
+
{ kind: "intervention", dir: _optionalChain([logger, 'access', _9 => _9.intervention, 'optionalAccess', _10 => _10.path]), ns: "prod" },
|
|
313
|
+
{ kind: "intervention", dir: _optionalChain([logger, 'access', _11 => _11.intervention, 'optionalAccess', _12 => _12.testPath]), ns: "test" }
|
|
314
|
+
].filter((d) => d.dir);
|
|
315
|
+
const stats = { total: 0, web: 0, intervention: 0, sec: 0, access: 0, prod: 0, test: 0 };
|
|
316
|
+
for (const { kind, dir, ns } of scanDirs) {
|
|
317
|
+
let count = 0;
|
|
318
|
+
try {
|
|
319
|
+
const entries = await _promises2.default.readdir(String(dir), { withFileTypes: true });
|
|
320
|
+
for (const ent of entries) {
|
|
321
|
+
if (!ent.isFile()) continue;
|
|
322
|
+
if (ent.name.endsWith(".delete") || ent.name.startsWith(".")) continue;
|
|
323
|
+
count += 1;
|
|
324
|
+
}
|
|
325
|
+
} catch (e8) {
|
|
326
|
+
continue;
|
|
327
|
+
}
|
|
328
|
+
if (kind === "web") stats.web += count;
|
|
329
|
+
else if (kind === "intervention") stats.intervention += count;
|
|
330
|
+
else if (kind === "access") stats.access += count;
|
|
331
|
+
if (ns === "prod") stats.prod += count;
|
|
332
|
+
if (ns === "test") stats.test += count;
|
|
333
|
+
stats.total += count;
|
|
334
|
+
}
|
|
335
|
+
const indexStats = await fileStoreStats($asai).catch(() => ({ sec: 0 }));
|
|
336
|
+
stats.sec = indexStats.sec || 0;
|
|
337
|
+
return stats;
|
|
338
|
+
}
|
|
339
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, fileStoreDiskStats, "fileStoreDiskStats");
|
|
340
|
+
function getFileStorePaths($asai) {
|
|
341
|
+
const base = storeBaseAbs($asai);
|
|
342
|
+
return { base, index: _path2.default.join(base, INDEX_ROOT) };
|
|
343
|
+
}
|
|
344
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, getFileStorePaths, "getFileStorePaths");
|
|
345
|
+
|
|
346
|
+
// src/sysserver/lib/common/log-db.ts
|
|
347
|
+
var LOG_ENTRY_FIELDS = [
|
|
348
|
+
"kind",
|
|
349
|
+
"ns",
|
|
350
|
+
"source",
|
|
351
|
+
"log_date",
|
|
352
|
+
"file_name",
|
|
353
|
+
"event_type",
|
|
354
|
+
"category",
|
|
355
|
+
"severity",
|
|
356
|
+
"us",
|
|
357
|
+
"message",
|
|
358
|
+
"raw_line",
|
|
359
|
+
"chain_hash",
|
|
360
|
+
"prev_hash",
|
|
361
|
+
"outcome",
|
|
362
|
+
"identification",
|
|
363
|
+
"retention_protected",
|
|
364
|
+
"created_at"
|
|
365
|
+
];
|
|
366
|
+
var TABLE_LOG_ENTRIES = "asai_log_entries";
|
|
367
|
+
var SQLITE_FALLBACK_KEY = "_logStoreUseFileFallback";
|
|
368
|
+
function getLogStoreConfig($asai) {
|
|
369
|
+
const resolved = _chunkHHPGUJ75cjs.resolveStoreConfig.call(void 0, $asai, "log");
|
|
370
|
+
return {
|
|
371
|
+
type: resolved.type,
|
|
372
|
+
opt: _chunkHHPGUJ75cjs.normalizeStoreOpt.call(void 0, "log", resolved.type, resolved.opt)
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, getLogStoreConfig, "getLogStoreConfig");
|
|
376
|
+
var STORE_TYPE_LABELS = {
|
|
377
|
+
file: "File",
|
|
378
|
+
sqlite: "SQLite",
|
|
379
|
+
mysql: "MySQL"
|
|
380
|
+
};
|
|
381
|
+
function getLogStoreMeta($asai) {
|
|
382
|
+
const cfg = getLogStoreConfig($asai);
|
|
383
|
+
const effective = getEffectiveStoreType($asai);
|
|
384
|
+
const { type: configuredType, opt } = cfg;
|
|
385
|
+
const type = effective === "none" ? configuredType : effective;
|
|
386
|
+
const enabled = isLogStoreEnabled($asai);
|
|
387
|
+
const logger = _optionalChain([$asai, 'optionalAccess', _13 => _13.hostconfig, 'optionalAccess', _14 => _14.logger]) || {};
|
|
388
|
+
const fallback = _optionalChain([$asai, 'optionalAccess', _15 => _15[SQLITE_FALLBACK_KEY]]);
|
|
389
|
+
const meta = {
|
|
390
|
+
type,
|
|
391
|
+
configuredType,
|
|
392
|
+
enabled,
|
|
393
|
+
label: STORE_TYPE_LABELS[type] || type,
|
|
394
|
+
mode: type === "file" ? "file-folder" : type,
|
|
395
|
+
dualWrite: true,
|
|
396
|
+
folderManaged: type === "file",
|
|
397
|
+
create: _nullishCoalesce(opt.create, () => ( 1)),
|
|
398
|
+
fallbackFrom: fallback ? configuredType : void 0,
|
|
399
|
+
fallbackReason: _optionalChain([fallback, 'optionalAccess', _16 => _16.reason]),
|
|
400
|
+
compliancePaths: {
|
|
401
|
+
server: _optionalChain([logger, 'access', _17 => _17.path, 'optionalAccess', _18 => _18.server]),
|
|
402
|
+
client: _optionalChain([logger, 'access', _19 => _19.path, 'optionalAccess', _20 => _20.client]),
|
|
403
|
+
access: _optionalChain([logger, 'access', _21 => _21.path, 'optionalAccess', _22 => _22.access]),
|
|
404
|
+
intervention: _optionalChain([logger, 'access', _23 => _23.intervention, 'optionalAccess', _24 => _24.path]),
|
|
405
|
+
interventionTest: _optionalChain([logger, 'access', _25 => _25.intervention, 'optionalAccess', _26 => _26.testPath]),
|
|
406
|
+
interventionArchive: _optionalChain([logger, 'access', _27 => _27.intervention, 'optionalAccess', _28 => _28.archivePath])
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
if (type === "file") {
|
|
410
|
+
const paths = getFileStorePaths($asai);
|
|
411
|
+
meta.dir = opt.dir;
|
|
412
|
+
meta.ext = opt.ext || ".json";
|
|
413
|
+
meta.indexDir = paths.index;
|
|
414
|
+
meta.layout = "index/{kind}/{ns}/{source}/{log_date}/{id}.json";
|
|
415
|
+
meta.location = String(opt.dir || "");
|
|
416
|
+
} else if (type === "sqlite") {
|
|
417
|
+
meta.database = opt.database;
|
|
418
|
+
meta.location = String(opt.database || "");
|
|
419
|
+
} else if (type === "mysql") {
|
|
420
|
+
meta.host = opt.host;
|
|
421
|
+
meta.database = opt.database;
|
|
422
|
+
meta.location = `${opt.host || "127.0.0.1"}/${opt.database || "asai_logs"}`;
|
|
423
|
+
}
|
|
424
|
+
return meta;
|
|
425
|
+
}
|
|
426
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, getLogStoreMeta, "getLogStoreMeta");
|
|
427
|
+
function isLogStoreEnabled($asai) {
|
|
428
|
+
return getEffectiveStoreType($asai) !== "none";
|
|
429
|
+
}
|
|
430
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, isLogStoreEnabled, "isLogStoreEnabled");
|
|
431
|
+
function isLogStoreFileBackend($asai) {
|
|
432
|
+
return getEffectiveStoreType($asai) === "file";
|
|
433
|
+
}
|
|
434
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, isLogStoreFileBackend, "isLogStoreFileBackend");
|
|
435
|
+
function prefersDiskLogAccess($asai) {
|
|
436
|
+
return isLogStoreFileBackend($asai);
|
|
437
|
+
}
|
|
438
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, prefersDiskLogAccess, "prefersDiskLogAccess");
|
|
439
|
+
function markSqliteFallback($asai, reason) {
|
|
440
|
+
if (!$asai[SQLITE_FALLBACK_KEY]) {
|
|
441
|
+
$asai[SQLITE_FALLBACK_KEY] = { at: Date.now(), reason: String(_optionalChain([reason, 'optionalAccess', _29 => _29.message]) || reason || "sqlite unavailable") };
|
|
442
|
+
try {
|
|
443
|
+
(_optionalChain([$asai, 'optionalAccess', _30 => _30.$log]) || console.warn)("LOG", "[store] SQLite unavailable, fallback to file folder storage:", $asai[SQLITE_FALLBACK_KEY].reason);
|
|
444
|
+
} catch (e9) {
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, markSqliteFallback, "markSqliteFallback");
|
|
449
|
+
function getEffectiveStoreType($asai) {
|
|
450
|
+
const cfg = getLogStoreConfig($asai).type;
|
|
451
|
+
if (_optionalChain([$asai, 'optionalAccess', _31 => _31[SQLITE_FALLBACK_KEY]]) && (cfg === "sqlite" || cfg === "mysql")) return "file";
|
|
452
|
+
if (cfg === "file" || cfg === "sqlite" || cfg === "mysql") return cfg;
|
|
453
|
+
return "none";
|
|
454
|
+
}
|
|
455
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, getEffectiveStoreType, "getEffectiveStoreType");
|
|
456
|
+
function dbType($asai) {
|
|
457
|
+
return getEffectiveStoreType($asai);
|
|
458
|
+
}
|
|
459
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, dbType, "dbType");
|
|
460
|
+
function rowToRecord2(row) {
|
|
461
|
+
const out = { ...row };
|
|
462
|
+
for (const k of ["severity", "retention_protected", "created_at", "id"]) {
|
|
463
|
+
if (out[k] != null && out[k] !== "") out[k] = Number(out[k]);
|
|
464
|
+
}
|
|
465
|
+
return out;
|
|
466
|
+
}
|
|
467
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, rowToRecord2, "rowToRecord");
|
|
468
|
+
function isTableMissing(err) {
|
|
469
|
+
const msg = String(_optionalChain([err, 'optionalAccess', _32 => _32.message]) || err || "");
|
|
470
|
+
return msg.includes("no such table") || msg.includes("doesn't exist");
|
|
471
|
+
}
|
|
472
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, isTableMissing, "isTableMissing");
|
|
473
|
+
function isSqliteUnavailable(err) {
|
|
474
|
+
const msg = String(_optionalChain([err, 'optionalAccess', _33 => _33.message]) || err || "").toLowerCase();
|
|
475
|
+
return isTableMissing(err) || msg.includes("sqlite") || msg.includes("cannot open") || msg.includes("unable to open") || msg.includes("enoent") || msg.includes("not a directory");
|
|
476
|
+
}
|
|
477
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, isSqliteUnavailable, "isSqliteUnavailable");
|
|
478
|
+
var LOG_TABLE_ENSURED = "_logTableEnsured";
|
|
479
|
+
var ensureLogTablePromise = null;
|
|
480
|
+
async function ensureLogTable($asai) {
|
|
481
|
+
if ($asai[LOG_TABLE_ENSURED]) return;
|
|
482
|
+
if (getLogStoreConfig($asai).type !== "sqlite") return;
|
|
483
|
+
if (!ensureLogTablePromise) {
|
|
484
|
+
ensureLogTablePromise = (async () => {
|
|
485
|
+
const db = getDb($asai);
|
|
486
|
+
try {
|
|
487
|
+
await db.sqlDb({ type: "select", table: TABLE_LOG_ENTRIES, field: ["id"], limit: 1 });
|
|
488
|
+
} catch (err) {
|
|
489
|
+
if (!isTableMissing(err)) throw err;
|
|
490
|
+
await db.sqlDb({
|
|
491
|
+
type: "insert",
|
|
492
|
+
table: TABLE_LOG_ENTRIES,
|
|
493
|
+
field: [...LOG_ENTRY_FIELDS],
|
|
494
|
+
value: [
|
|
495
|
+
LOG_ENTRY_FIELDS.map((f) => {
|
|
496
|
+
if (f === "severity" || f === "retention_protected" || f === "created_at") return _chunkHHPGUJ75cjs.qNum.call(void 0, 0);
|
|
497
|
+
return _chunkHHPGUJ75cjs.qStr.call(void 0, "", "sqlite");
|
|
498
|
+
})
|
|
499
|
+
]
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
$asai[LOG_TABLE_ENSURED] = true;
|
|
503
|
+
})();
|
|
504
|
+
}
|
|
505
|
+
try {
|
|
506
|
+
await ensureLogTablePromise;
|
|
507
|
+
} catch (err) {
|
|
508
|
+
ensureLogTablePromise = null;
|
|
509
|
+
throw err;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, ensureLogTable, "ensureLogTable");
|
|
513
|
+
async function beforeSqliteLogOp($asai) {
|
|
514
|
+
if (getLogStoreConfig($asai).type === "sqlite" && !$asai[SQLITE_FALLBACK_KEY]) {
|
|
515
|
+
await ensureLogTable($asai);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, beforeSqliteLogOp, "beforeSqliteLogOp");
|
|
519
|
+
function isLogStoreSqlite($asai) {
|
|
520
|
+
return getEffectiveStoreType($asai) === "sqlite" || getEffectiveStoreType($asai) === "mysql";
|
|
521
|
+
}
|
|
522
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, isLogStoreSqlite, "isLogStoreSqlite");
|
|
523
|
+
function getDb($asai) {
|
|
524
|
+
return _chunkHHPGUJ75cjs.getDataServer.call(void 0, $asai, "log");
|
|
525
|
+
}
|
|
526
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, getDb, "getDb");
|
|
527
|
+
async function dbInsertLogEntry($asai, row) {
|
|
528
|
+
if (!isLogStoreEnabled($asai)) return;
|
|
529
|
+
const type = dbType($asai);
|
|
530
|
+
if (type === "file") {
|
|
531
|
+
await fileStoreInsert($asai, row);
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
const db = getDb($asai);
|
|
535
|
+
try {
|
|
536
|
+
await beforeSqliteLogOp($asai);
|
|
537
|
+
await db.sqlDb({
|
|
538
|
+
type: "insert",
|
|
539
|
+
table: TABLE_LOG_ENTRIES,
|
|
540
|
+
field: [...LOG_ENTRY_FIELDS],
|
|
541
|
+
value: [
|
|
542
|
+
LOG_ENTRY_FIELDS.map((f) => {
|
|
543
|
+
const v = row[f];
|
|
544
|
+
if (f === "severity" || f === "retention_protected" || f === "created_at") return _chunkHHPGUJ75cjs.qNum.call(void 0, v);
|
|
545
|
+
return _chunkHHPGUJ75cjs.qStr.call(void 0, v == null ? "" : String(v), type);
|
|
546
|
+
})
|
|
547
|
+
]
|
|
548
|
+
});
|
|
549
|
+
} catch (err) {
|
|
550
|
+
if (getLogStoreConfig($asai).type === "sqlite" && isSqliteUnavailable(err)) {
|
|
551
|
+
markSqliteFallback($asai, err);
|
|
552
|
+
await fileStoreInsert($asai, row);
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
555
|
+
throw err;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, dbInsertLogEntry, "dbInsertLogEntry");
|
|
559
|
+
async function dbQueryLogEntries($asai, filter = {}) {
|
|
560
|
+
if (!isLogStoreEnabled($asai)) return [];
|
|
561
|
+
const type = dbType($asai);
|
|
562
|
+
if (type === "file") {
|
|
563
|
+
return fileStoreQuery($asai, filter);
|
|
564
|
+
}
|
|
565
|
+
const db = getDb($asai);
|
|
566
|
+
const where = [];
|
|
567
|
+
if (filter.kind) where.push(["kind", "=", _chunkHHPGUJ75cjs.qStr.call(void 0, filter.kind, type)]);
|
|
568
|
+
if (filter.ns) where.push(["ns", "=", _chunkHHPGUJ75cjs.qStr.call(void 0, filter.ns, type)]);
|
|
569
|
+
if (filter.source) where.push(["source", "=", _chunkHHPGUJ75cjs.qStr.call(void 0, filter.source, type)]);
|
|
570
|
+
if (filter.log_date) where.push(["log_date", "=", _chunkHHPGUJ75cjs.qStr.call(void 0, filter.log_date, type)]);
|
|
571
|
+
if (filter.file_name) where.push(["file_name", "=", _chunkHHPGUJ75cjs.qStr.call(void 0, filter.file_name, type)]);
|
|
572
|
+
try {
|
|
573
|
+
await beforeSqliteLogOp($asai);
|
|
574
|
+
const res = await db.sqlDb({
|
|
575
|
+
type: "select",
|
|
576
|
+
table: TABLE_LOG_ENTRIES,
|
|
577
|
+
field: ["id", ...LOG_ENTRY_FIELDS],
|
|
578
|
+
where: where.length ? where : void 0,
|
|
579
|
+
order: [["created_at", "desc"], ["id", "desc"]],
|
|
580
|
+
limit: _nullishCoalesce(filter.limit, () => ( 500))
|
|
581
|
+
});
|
|
582
|
+
return _chunkHHPGUJ75cjs.asRows.call(void 0, res).map(rowToRecord2);
|
|
583
|
+
} catch (err) {
|
|
584
|
+
if (isTableMissing(err) || isSqliteUnavailable(err)) {
|
|
585
|
+
if (getLogStoreConfig($asai).type === "sqlite") markSqliteFallback($asai, err);
|
|
586
|
+
return fileStoreQuery($asai, filter);
|
|
587
|
+
}
|
|
588
|
+
throw err;
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, dbQueryLogEntries, "dbQueryLogEntries");
|
|
592
|
+
async function dbGetLogEntry($asai, id) {
|
|
593
|
+
if (!isLogStoreEnabled($asai)) return null;
|
|
594
|
+
const type = dbType($asai);
|
|
595
|
+
if (type === "file") {
|
|
596
|
+
return fileStoreGet($asai, id);
|
|
597
|
+
}
|
|
598
|
+
const db = getDb($asai);
|
|
599
|
+
try {
|
|
600
|
+
await beforeSqliteLogOp($asai);
|
|
601
|
+
const res = await db.sqlDb({
|
|
602
|
+
type: "select",
|
|
603
|
+
table: TABLE_LOG_ENTRIES,
|
|
604
|
+
field: ["id", ...LOG_ENTRY_FIELDS],
|
|
605
|
+
where: [["id", "=", _chunkHHPGUJ75cjs.qNum.call(void 0, Number(id))]],
|
|
606
|
+
limit: 1
|
|
607
|
+
});
|
|
608
|
+
const rows = _chunkHHPGUJ75cjs.asRows.call(void 0, res);
|
|
609
|
+
return rows.length ? rowToRecord2(rows[0]) : null;
|
|
610
|
+
} catch (err) {
|
|
611
|
+
if (isTableMissing(err) || isSqliteUnavailable(err)) {
|
|
612
|
+
if (getLogStoreConfig($asai).type === "sqlite") markSqliteFallback($asai, err);
|
|
613
|
+
return fileStoreGet($asai, id);
|
|
614
|
+
}
|
|
615
|
+
throw err;
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, dbGetLogEntry, "dbGetLogEntry");
|
|
619
|
+
async function dbListLogGroups($asai, filter = {}) {
|
|
620
|
+
const entries = await dbQueryLogEntries($asai, {
|
|
621
|
+
kind: filter.kind,
|
|
622
|
+
ns: filter.ns,
|
|
623
|
+
source: filter.source,
|
|
624
|
+
limit: 5e3
|
|
625
|
+
});
|
|
626
|
+
const groups = /* @__PURE__ */ new Map();
|
|
627
|
+
for (const e of entries) {
|
|
628
|
+
const kind = String(e.kind || "");
|
|
629
|
+
const ns = String(e.ns || "");
|
|
630
|
+
const source = String(e.source || "");
|
|
631
|
+
const logDate = String(e.log_date || "");
|
|
632
|
+
const fileName = String(e.file_name || (kind === "web" ? `log-${logDate}.txt` : ""));
|
|
633
|
+
const key = `${kind}|${ns}|${source}|${fileName}`;
|
|
634
|
+
const created = Number(e.created_at || 0);
|
|
635
|
+
const g = groups.get(key);
|
|
636
|
+
if (!g) {
|
|
637
|
+
groups.set(key, { key, kind, ns, source, log_date: logDate, file_name: fileName, entryCount: 1, lastAt: created });
|
|
638
|
+
} else {
|
|
639
|
+
g.entryCount += 1;
|
|
640
|
+
if (created > g.lastAt) g.lastAt = created;
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
return [...groups.values()].sort((a, b) => b.lastAt - a.lastAt);
|
|
644
|
+
}
|
|
645
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, dbListLogGroups, "dbListLogGroups");
|
|
646
|
+
function countStatsFromRows(rows) {
|
|
647
|
+
const stats = { total: rows.length, web: 0, intervention: 0, sec: 0, access: 0, prod: 0, test: 0 };
|
|
648
|
+
for (const r of rows) {
|
|
649
|
+
const k = String(r.kind || "");
|
|
650
|
+
if (k === "web") stats.web += 1;
|
|
651
|
+
else if (k === "intervention") stats.intervention += 1;
|
|
652
|
+
else if (k === "sec") stats.sec += 1;
|
|
653
|
+
else if (k === "access") stats.access += 1;
|
|
654
|
+
const ns = String(r.ns || "");
|
|
655
|
+
if (ns === "prod") stats.prod += 1;
|
|
656
|
+
if (ns === "test") stats.test += 1;
|
|
657
|
+
}
|
|
658
|
+
return stats;
|
|
659
|
+
}
|
|
660
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, countStatsFromRows, "countStatsFromRows");
|
|
661
|
+
function applySearchFilters2(rows, filter) {
|
|
662
|
+
let out = rows;
|
|
663
|
+
if (filter.keyword) {
|
|
664
|
+
const kw = filter.keyword.toLowerCase();
|
|
665
|
+
out = out.filter((r) => {
|
|
666
|
+
const hay = [r.message, r.raw_line, r.event_type, r.us, r.identification, r.category].map((v) => String(v || "").toLowerCase()).join(" ");
|
|
667
|
+
return hay.includes(kw);
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
if (filter.event_type) {
|
|
671
|
+
const et = filter.event_type.toUpperCase();
|
|
672
|
+
out = out.filter((r) => String(r.event_type || "").toUpperCase() === et);
|
|
673
|
+
}
|
|
674
|
+
if (filter.severity_min != null && !Number.isNaN(Number(filter.severity_min))) {
|
|
675
|
+
const min = Number(filter.severity_min);
|
|
676
|
+
out = out.filter((r) => Number(r.severity || 0) >= min);
|
|
677
|
+
}
|
|
678
|
+
if (filter.date_from) {
|
|
679
|
+
out = out.filter((r) => String(r.log_date || "") >= filter.date_from);
|
|
680
|
+
}
|
|
681
|
+
if (filter.date_to) {
|
|
682
|
+
out = out.filter((r) => String(r.log_date || "") <= filter.date_to);
|
|
683
|
+
}
|
|
684
|
+
if (filter.outcome) {
|
|
685
|
+
const oc = filter.outcome.toLowerCase();
|
|
686
|
+
out = out.filter((r) => String(r.outcome || "").toLowerCase() === oc);
|
|
687
|
+
}
|
|
688
|
+
return out;
|
|
689
|
+
}
|
|
690
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, applySearchFilters2, "applySearchFilters");
|
|
691
|
+
async function dbSearchLogEntries($asai, filter = {}) {
|
|
692
|
+
if (!isLogStoreEnabled($asai)) return { entries: [], total: 0, truncated: false };
|
|
693
|
+
if (dbType($asai) === "file") return fileStoreSearch($asai, filter);
|
|
694
|
+
const baseLimit = 2e4;
|
|
695
|
+
const rows = await dbQueryLogEntries($asai, {
|
|
696
|
+
kind: filter.kind,
|
|
697
|
+
ns: filter.ns,
|
|
698
|
+
source: filter.source,
|
|
699
|
+
log_date: filter.log_date,
|
|
700
|
+
file_name: filter.file_name,
|
|
701
|
+
limit: baseLimit
|
|
702
|
+
});
|
|
703
|
+
const filtered = applySearchFilters2(rows, filter);
|
|
704
|
+
const offset = Math.max(0, Number(filter.offset) || 0);
|
|
705
|
+
const limit = Math.min(2e3, Math.max(1, Number(filter.limit) || 200));
|
|
706
|
+
const entries = filtered.slice(offset, offset + limit);
|
|
707
|
+
return {
|
|
708
|
+
entries,
|
|
709
|
+
total: filtered.length,
|
|
710
|
+
truncated: rows.length >= baseLimit
|
|
711
|
+
};
|
|
712
|
+
}
|
|
713
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, dbSearchLogEntries, "dbSearchLogEntries");
|
|
714
|
+
async function dbLogStats($asai) {
|
|
715
|
+
if (!isLogStoreEnabled($asai)) {
|
|
716
|
+
return { total: 0, web: 0, intervention: 0, sec: 0, access: 0, prod: 0, test: 0 };
|
|
717
|
+
}
|
|
718
|
+
const type = dbType($asai);
|
|
719
|
+
if (type === "file") {
|
|
720
|
+
const disk = await fileStoreDiskStats($asai);
|
|
721
|
+
const index = await fileStoreStats($asai).catch(() => null);
|
|
722
|
+
if (index && index.total > 0) {
|
|
723
|
+
return { ...disk, sec: index.sec, total: Math.max(disk.total, index.total) };
|
|
724
|
+
}
|
|
725
|
+
return disk;
|
|
726
|
+
}
|
|
727
|
+
const db = getDb($asai);
|
|
728
|
+
try {
|
|
729
|
+
await beforeSqliteLogOp($asai);
|
|
730
|
+
const res = await db.sqlDb({
|
|
731
|
+
type: "select",
|
|
732
|
+
table: TABLE_LOG_ENTRIES,
|
|
733
|
+
field: ["kind", "ns"],
|
|
734
|
+
limit: 1e5
|
|
735
|
+
});
|
|
736
|
+
return countStatsFromRows(_chunkHHPGUJ75cjs.asRows.call(void 0, res));
|
|
737
|
+
} catch (err) {
|
|
738
|
+
if (isTableMissing(err) || isSqliteUnavailable(err)) {
|
|
739
|
+
if (getLogStoreConfig($asai).type === "sqlite") markSqliteFallback($asai, err);
|
|
740
|
+
return fileStoreDiskStats($asai);
|
|
741
|
+
}
|
|
742
|
+
throw err;
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, dbLogStats, "dbLogStats");
|
|
746
|
+
async function dbDeleteLogEntriesByFile($asai, fileName, ns = "") {
|
|
747
|
+
if (!isLogStoreEnabled($asai)) return 0;
|
|
748
|
+
const type = dbType($asai);
|
|
749
|
+
if (type === "file") {
|
|
750
|
+
return fileStoreDeleteByFile($asai, fileName, ns);
|
|
751
|
+
}
|
|
752
|
+
const db = getDb($asai);
|
|
753
|
+
const where = [["file_name", "=", _chunkHHPGUJ75cjs.qStr.call(void 0, fileName, type)]];
|
|
754
|
+
if (ns) where.push(["ns", "=", _chunkHHPGUJ75cjs.qStr.call(void 0, ns, type)]);
|
|
755
|
+
try {
|
|
756
|
+
await beforeSqliteLogOp($asai);
|
|
757
|
+
const res = await db.sqlDb({
|
|
758
|
+
type: "delete",
|
|
759
|
+
table: TABLE_LOG_ENTRIES,
|
|
760
|
+
where
|
|
761
|
+
});
|
|
762
|
+
if (res && typeof res === "object" && "changes" in res) return Number(res.changes || 0);
|
|
763
|
+
return 0;
|
|
764
|
+
} catch (err) {
|
|
765
|
+
if (isTableMissing(err) || isSqliteUnavailable(err)) {
|
|
766
|
+
if (getLogStoreConfig($asai).type === "sqlite") markSqliteFallback($asai, err);
|
|
767
|
+
return fileStoreDeleteByFile($asai, fileName, ns);
|
|
768
|
+
}
|
|
769
|
+
throw err;
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, dbDeleteLogEntriesByFile, "dbDeleteLogEntriesByFile");
|
|
773
|
+
|
|
774
|
+
// src/sysserver/lib/common/LogStore.ts
|
|
775
|
+
async function mirrorWebLog($asai, opts) {
|
|
776
|
+
if (!isLogStoreEnabled($asai)) return;
|
|
777
|
+
const now = /* @__PURE__ */ new Date();
|
|
778
|
+
const logDate = _chunkO6LVLSNBcjs.getNowTime.call(void 0, 2, now);
|
|
779
|
+
const kind = opts.source === "sec" ? "sec" : "web";
|
|
780
|
+
await dbInsertLogEntry($asai, {
|
|
781
|
+
kind,
|
|
782
|
+
ns: "",
|
|
783
|
+
source: opts.source,
|
|
784
|
+
log_date: logDate,
|
|
785
|
+
file_name: `log-${logDate}.txt`,
|
|
786
|
+
event_type: "",
|
|
787
|
+
category: kind === "sec" ? "AuditLogEvents" : "",
|
|
788
|
+
severity: kind === "sec" ? 7 : 2,
|
|
789
|
+
us: "",
|
|
790
|
+
message: opts.message || opts.rawLine.slice(0, 2e3),
|
|
791
|
+
raw_line: opts.rawLine,
|
|
792
|
+
chain_hash: "",
|
|
793
|
+
prev_hash: "",
|
|
794
|
+
outcome: "",
|
|
795
|
+
identification: "",
|
|
796
|
+
retention_protected: 0,
|
|
797
|
+
created_at: now.getTime()
|
|
798
|
+
});
|
|
799
|
+
}
|
|
800
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, mirrorWebLog, "mirrorWebLog");
|
|
801
|
+
async function mirrorInterventionLog($asai, opts) {
|
|
802
|
+
if (!isLogStoreEnabled($asai)) return;
|
|
803
|
+
const logDate = _chunkO6LVLSNBcjs.getNowTime.call(void 0, 2);
|
|
804
|
+
const isAudit = opts.fileName.includes("deletion-audit");
|
|
805
|
+
await dbInsertLogEntry($asai, {
|
|
806
|
+
kind: "intervention",
|
|
807
|
+
ns: opts.ns,
|
|
808
|
+
source: "",
|
|
809
|
+
log_date: logDate,
|
|
810
|
+
file_name: opts.fileName,
|
|
811
|
+
event_type: opts.event.type,
|
|
812
|
+
category: opts.category,
|
|
813
|
+
severity: opts.severity,
|
|
814
|
+
us: opts.event.us || "",
|
|
815
|
+
message: opts.event.detail || opts.event.name,
|
|
816
|
+
raw_line: opts.rawLine,
|
|
817
|
+
chain_hash: opts.chainHash,
|
|
818
|
+
prev_hash: opts.prevHash,
|
|
819
|
+
outcome: opts.event.outcome || "Success",
|
|
820
|
+
identification: opts.event.identification || "",
|
|
821
|
+
retention_protected: isAudit ? 1 : 0,
|
|
822
|
+
created_at: Date.now()
|
|
823
|
+
});
|
|
824
|
+
}
|
|
825
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, mirrorInterventionLog, "mirrorInterventionLog");
|
|
826
|
+
async function mirrorAccessLog($asai, opts) {
|
|
827
|
+
if (!isLogStoreEnabled($asai)) return;
|
|
828
|
+
const now = /* @__PURE__ */ new Date();
|
|
829
|
+
const logDate = _chunkO6LVLSNBcjs.getNowTime.call(void 0, 2, now);
|
|
830
|
+
const fileName = opts.format === "clf" ? `access-clf-${logDate}.log` : `access-w3c-${logDate}.log`;
|
|
831
|
+
await dbInsertLogEntry($asai, {
|
|
832
|
+
kind: "access",
|
|
833
|
+
ns: "",
|
|
834
|
+
source: opts.format,
|
|
835
|
+
log_date: logDate,
|
|
836
|
+
file_name: fileName,
|
|
837
|
+
event_type: opts.logType || "HTTP",
|
|
838
|
+
category: "RequestErrors",
|
|
839
|
+
severity: opts.status && opts.status >= 500 ? 4 : 2,
|
|
840
|
+
us: "",
|
|
841
|
+
message: `${opts.method || "-"} ${opts.url || "-"} ${_nullishCoalesce(opts.status, () => ( "-"))}`,
|
|
842
|
+
raw_line: opts.rawLine.trim(),
|
|
843
|
+
chain_hash: "",
|
|
844
|
+
prev_hash: "",
|
|
845
|
+
outcome: opts.status && opts.status < 400 ? "Success" : "Failure",
|
|
846
|
+
identification: opts.host || "",
|
|
847
|
+
retention_protected: 0,
|
|
848
|
+
created_at: now.getTime()
|
|
849
|
+
});
|
|
850
|
+
}
|
|
851
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, mirrorAccessLog, "mirrorAccessLog");
|
|
852
|
+
async function queryUnifiedLogs($asai, filter) {
|
|
853
|
+
return dbQueryLogEntries($asai, filter);
|
|
854
|
+
}
|
|
855
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, queryUnifiedLogs, "queryUnifiedLogs");
|
|
856
|
+
async function searchUnifiedLogs($asai, filter) {
|
|
857
|
+
return dbSearchLogEntries($asai, filter);
|
|
858
|
+
}
|
|
859
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, searchUnifiedLogs, "searchUnifiedLogs");
|
|
860
|
+
async function exportLogContent($asai, opts) {
|
|
861
|
+
const format = opts.format || "raw";
|
|
862
|
+
const { readInterventionFile } = await Promise.resolve().then(() => _interopRequireWildcard(require("./InterventionLog-25EHE4QR.cjs")));
|
|
863
|
+
const ns = opts.ns === "test" ? "test" : "prod";
|
|
864
|
+
if (opts.kind === "intervention" && opts.fileName) {
|
|
865
|
+
const data = await readInterventionFile($asai, opts.fileName, ns);
|
|
866
|
+
if (format === "json") {
|
|
867
|
+
return {
|
|
868
|
+
fileName: opts.fileName,
|
|
869
|
+
format,
|
|
870
|
+
content: JSON.stringify({ fileName: opts.fileName, ns, parsed: data.parsed, chain: data.chain, meta: data.meta }, null, 2),
|
|
871
|
+
mime: "application/json",
|
|
872
|
+
lineCount: data.parsed.length
|
|
873
|
+
};
|
|
874
|
+
}
|
|
875
|
+
return {
|
|
876
|
+
fileName: opts.fileName,
|
|
877
|
+
format: format === "cef" ? "cef" : "raw",
|
|
878
|
+
content: data.raw,
|
|
879
|
+
mime: "text/plain",
|
|
880
|
+
lineCount: data.parsed.length
|
|
881
|
+
};
|
|
882
|
+
}
|
|
883
|
+
const fileName = opts.fileName || "";
|
|
884
|
+
const source = opts.source || "server";
|
|
885
|
+
let content = "";
|
|
886
|
+
if (fileName.startsWith("log-")) {
|
|
887
|
+
content = await readWebLogFromStore($asai, source, fileName);
|
|
888
|
+
} else if (isLogStoreEnabled($asai)) {
|
|
889
|
+
const rows = await dbQueryLogEntries($asai, {
|
|
890
|
+
kind: opts.kind === "intervention" ? "intervention" : opts.kind,
|
|
891
|
+
ns: opts.ns,
|
|
892
|
+
source,
|
|
893
|
+
file_name: fileName || void 0,
|
|
894
|
+
limit: 5e3
|
|
895
|
+
});
|
|
896
|
+
content = rows.reverse().map((r) => String(r.raw_line || "")).join("");
|
|
897
|
+
}
|
|
898
|
+
if (format === "json") {
|
|
899
|
+
const rows = await dbQueryLogEntries($asai, {
|
|
900
|
+
kind: opts.kind === "intervention" ? "intervention" : opts.kind,
|
|
901
|
+
ns: opts.ns,
|
|
902
|
+
source,
|
|
903
|
+
file_name: fileName || void 0,
|
|
904
|
+
limit: 5e3
|
|
905
|
+
});
|
|
906
|
+
return {
|
|
907
|
+
fileName: fileName || "export.json",
|
|
908
|
+
format,
|
|
909
|
+
content: JSON.stringify({ fileName, source, entries: rows }, null, 2),
|
|
910
|
+
mime: "application/json",
|
|
911
|
+
lineCount: rows.length
|
|
912
|
+
};
|
|
913
|
+
}
|
|
914
|
+
const lineCount = content ? content.split("\n").filter((l) => l.trim()).length : 0;
|
|
915
|
+
return {
|
|
916
|
+
fileName: fileName || "export.log",
|
|
917
|
+
format: "raw",
|
|
918
|
+
content,
|
|
919
|
+
mime: "text/plain",
|
|
920
|
+
lineCount
|
|
921
|
+
};
|
|
922
|
+
}
|
|
923
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, exportLogContent, "exportLogContent");
|
|
924
|
+
async function getComplianceReport($asai, ns = "prod") {
|
|
925
|
+
const { listInterventionFiles, readInterventionFile } = await Promise.resolve().then(() => _interopRequireWildcard(require("./InterventionLog-25EHE4QR.cjs")));
|
|
926
|
+
const retentionYears = _nullishCoalesce(_optionalChain([$asai, 'optionalAccess', _34 => _34.hostconfig, 'optionalAccess', _35 => _35.logger, 'optionalAccess', _36 => _36.intervention, 'optionalAccess', _37 => _37.retentionYears]), () => ( 5));
|
|
927
|
+
const stats = await dbLogStats($asai);
|
|
928
|
+
const storeMeta = getLogStoreMeta($asai);
|
|
929
|
+
const effectiveType = getEffectiveStoreType($asai);
|
|
930
|
+
let files = [];
|
|
931
|
+
try {
|
|
932
|
+
files = await listInterventionFiles($asai, ns);
|
|
933
|
+
} catch (e10) {
|
|
934
|
+
files = [];
|
|
935
|
+
}
|
|
936
|
+
const chainChecks = [];
|
|
937
|
+
for (const f of files.slice(0, 30)) {
|
|
938
|
+
if (!_optionalChain([f, 'access', _38 => _38.name, 'optionalAccess', _39 => _39.includes, 'call', _40 => _40(".cef.")])) continue;
|
|
939
|
+
try {
|
|
940
|
+
const data = await readInterventionFile($asai, f.name, ns);
|
|
941
|
+
chainChecks.push({
|
|
942
|
+
fileName: f.name,
|
|
943
|
+
entryCount: data.parsed.length,
|
|
944
|
+
chainOk: data.chain.ok,
|
|
945
|
+
brokenLines: data.chain.results.filter((r) => !r.ok).length,
|
|
946
|
+
protectedAudit: !!f.protectedAudit,
|
|
947
|
+
expired: !!f.expired
|
|
948
|
+
});
|
|
949
|
+
} catch (e11) {
|
|
950
|
+
chainChecks.push({
|
|
951
|
+
fileName: f.name,
|
|
952
|
+
entryCount: 0,
|
|
953
|
+
chainOk: false,
|
|
954
|
+
brokenLines: -1,
|
|
955
|
+
protectedAudit: !!f.protectedAudit,
|
|
956
|
+
expired: !!f.expired
|
|
957
|
+
});
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
const allChainsOk = chainChecks.length > 0 && chainChecks.every((c) => c.chainOk);
|
|
961
|
+
const disk = await measureLogDiskUsage($asai);
|
|
962
|
+
const diskThreshold = Number(_optionalChain([$asai, 'optionalAccess', _41 => _41.hostconfig, 'optionalAccess', _42 => _42.logger, 'optionalAccess', _43 => _43.diskAlertMb]) || 512) * 1048576;
|
|
963
|
+
if (disk.totalBytes >= diskThreshold) {
|
|
964
|
+
const { alertDiskUsage } = await Promise.resolve().then(() => _interopRequireWildcard(require("./log-alert-LAJ6VSAG.cjs")));
|
|
965
|
+
alertDiskUsage($asai, "log", disk.totalBytes, diskThreshold);
|
|
966
|
+
}
|
|
967
|
+
return {
|
|
968
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
969
|
+
ns,
|
|
970
|
+
retentionYears,
|
|
971
|
+
store: {
|
|
972
|
+
enabled: !!storeMeta.enabled,
|
|
973
|
+
type: effectiveType,
|
|
974
|
+
label: storeMeta.label,
|
|
975
|
+
mode: storeMeta.mode,
|
|
976
|
+
location: storeMeta.location,
|
|
977
|
+
dir: storeMeta.dir,
|
|
978
|
+
database: storeMeta.database,
|
|
979
|
+
indexDir: storeMeta.indexDir,
|
|
980
|
+
layout: storeMeta.layout,
|
|
981
|
+
dualWrite: storeMeta.dualWrite,
|
|
982
|
+
folderManaged: storeMeta.folderManaged,
|
|
983
|
+
fallbackFrom: storeMeta.fallbackFrom,
|
|
984
|
+
fallbackReason: storeMeta.fallbackReason
|
|
985
|
+
},
|
|
986
|
+
stats,
|
|
987
|
+
fileCount: files.length,
|
|
988
|
+
disk,
|
|
989
|
+
chainSummary: {
|
|
990
|
+
checked: chainChecks.length,
|
|
991
|
+
allOk: allChainsOk,
|
|
992
|
+
brokenFiles: chainChecks.filter((c) => !c.chainOk).map((c) => c.fileName)
|
|
993
|
+
},
|
|
994
|
+
chainChecks,
|
|
995
|
+
formats: ["CLF", "W3C Extended", "CEF"]
|
|
996
|
+
};
|
|
997
|
+
}
|
|
998
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, getComplianceReport, "getComplianceReport");
|
|
999
|
+
async function measureLogDiskUsage($asai) {
|
|
1000
|
+
const fsp = await Promise.resolve().then(() => _interopRequireWildcard(require("fs/promises")));
|
|
1001
|
+
const pathMod = await Promise.resolve().then(() => _interopRequireWildcard(require("path")));
|
|
1002
|
+
const storeMeta = getLogStoreMeta($asai);
|
|
1003
|
+
const dirs = {};
|
|
1004
|
+
const paths = [
|
|
1005
|
+
_optionalChain([$asai, 'optionalAccess', _44 => _44.hostconfig, 'optionalAccess', _45 => _45.logger, 'optionalAccess', _46 => _46.path, 'optionalAccess', _47 => _47.access]),
|
|
1006
|
+
_optionalChain([$asai, 'optionalAccess', _48 => _48.hostconfig, 'optionalAccess', _49 => _49.logger, 'optionalAccess', _50 => _50.path, 'optionalAccess', _51 => _51.server]),
|
|
1007
|
+
_optionalChain([$asai, 'optionalAccess', _52 => _52.hostconfig, 'optionalAccess', _53 => _53.logger, 'optionalAccess', _54 => _54.path, 'optionalAccess', _55 => _55.client]),
|
|
1008
|
+
_optionalChain([$asai, 'optionalAccess', _56 => _56.hostconfig, 'optionalAccess', _57 => _57.logger, 'optionalAccess', _58 => _58.intervention, 'optionalAccess', _59 => _59.path]),
|
|
1009
|
+
_optionalChain([$asai, 'optionalAccess', _60 => _60.hostconfig, 'optionalAccess', _61 => _61.logger, 'optionalAccess', _62 => _62.intervention, 'optionalAccess', _63 => _63.testPath]),
|
|
1010
|
+
_optionalChain([$asai, 'optionalAccess', _64 => _64.hostconfig, 'optionalAccess', _65 => _65.logger, 'optionalAccess', _66 => _66.intervention, 'optionalAccess', _67 => _67.archivePath])
|
|
1011
|
+
].filter(Boolean);
|
|
1012
|
+
if (storeMeta.type === "file" && storeMeta.dir) {
|
|
1013
|
+
paths.push(String(storeMeta.dir));
|
|
1014
|
+
}
|
|
1015
|
+
async function dirSize(dir) {
|
|
1016
|
+
let total = 0;
|
|
1017
|
+
try {
|
|
1018
|
+
const entries = await fsp.readdir(dir, { withFileTypes: true });
|
|
1019
|
+
for (const ent of entries) {
|
|
1020
|
+
const full = pathMod.join(dir, ent.name);
|
|
1021
|
+
if (ent.isDirectory()) total += await dirSize(full);
|
|
1022
|
+
else {
|
|
1023
|
+
const st = await fsp.stat(full);
|
|
1024
|
+
total += st.size;
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
} catch (e12) {
|
|
1028
|
+
}
|
|
1029
|
+
return total;
|
|
1030
|
+
}
|
|
1031
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, dirSize, "dirSize");
|
|
1032
|
+
async function fileSize(filePath) {
|
|
1033
|
+
try {
|
|
1034
|
+
const st = await fsp.stat(filePath);
|
|
1035
|
+
return st.isFile() ? st.size : 0;
|
|
1036
|
+
} catch (e13) {
|
|
1037
|
+
return 0;
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, fileSize, "fileSize");
|
|
1041
|
+
let totalBytes = 0;
|
|
1042
|
+
for (const d of paths) {
|
|
1043
|
+
const bytes = await dirSize(d);
|
|
1044
|
+
dirs[d] = bytes;
|
|
1045
|
+
totalBytes += bytes;
|
|
1046
|
+
}
|
|
1047
|
+
if (storeMeta.type === "sqlite" && storeMeta.database) {
|
|
1048
|
+
const dbPath = String(storeMeta.database);
|
|
1049
|
+
const bytes = await fileSize(dbPath);
|
|
1050
|
+
dirs[dbPath] = bytes;
|
|
1051
|
+
totalBytes += bytes;
|
|
1052
|
+
}
|
|
1053
|
+
return { totalBytes, dirs };
|
|
1054
|
+
}
|
|
1055
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, measureLogDiskUsage, "measureLogDiskUsage");
|
|
1056
|
+
async function archiveInterventionYear($asai, opts) {
|
|
1057
|
+
const fsp = await Promise.resolve().then(() => _interopRequireWildcard(require("fs/promises")));
|
|
1058
|
+
const path2 = await Promise.resolve().then(() => _interopRequireWildcard(require("path")));
|
|
1059
|
+
const zlib = await Promise.resolve().then(() => _interopRequireWildcard(require("zlib")));
|
|
1060
|
+
const { pipeline } = await Promise.resolve().then(() => _interopRequireWildcard(require("stream/promises")));
|
|
1061
|
+
const { createReadStream, createWriteStream } = await Promise.resolve().then(() => _interopRequireWildcard(require("fs")));
|
|
1062
|
+
const ns = opts.ns || "prod";
|
|
1063
|
+
const { listInterventionFiles, readInterventionFile } = await Promise.resolve().then(() => _interopRequireWildcard(require("./InterventionLog-25EHE4QR.cjs")));
|
|
1064
|
+
const yearStr = String(opts.year);
|
|
1065
|
+
const archiveBase = _optionalChain([$asai, 'optionalAccess', _68 => _68.hostconfig, 'optionalAccess', _69 => _69.logger, 'optionalAccess', _70 => _70.intervention, 'optionalAccess', _71 => _71.archivePath]) || path2.join(_optionalChain([$asai, 'optionalAccess', _72 => _72.hostconfig, 'optionalAccess', _73 => _73.logger, 'optionalAccess', _74 => _74.intervention, 'optionalAccess', _75 => _75.path]) || "./webdata/webdb/log/intervention/", "archive/");
|
|
1066
|
+
const archiveDir = path2.join(archiveBase, yearStr);
|
|
1067
|
+
const files = await listInterventionFiles($asai, ns);
|
|
1068
|
+
const targets = files.filter((f) => f.name.includes(`intervention-${yearStr}-`) && f.name.endsWith(".cef.log"));
|
|
1069
|
+
const archived = [];
|
|
1070
|
+
const skipped = [];
|
|
1071
|
+
const errors = [];
|
|
1072
|
+
for (const f of targets) {
|
|
1073
|
+
const gzName = `${f.name}.gz`;
|
|
1074
|
+
const gzPath = path2.join(archiveDir, gzName);
|
|
1075
|
+
try {
|
|
1076
|
+
const content = await readInterventionFile($asai, f.name, ns);
|
|
1077
|
+
if (!content.chain.ok) {
|
|
1078
|
+
errors.push(`${f.name}: chain verification failed`);
|
|
1079
|
+
continue;
|
|
1080
|
+
}
|
|
1081
|
+
if (opts.dryRun) {
|
|
1082
|
+
skipped.push(`${f.name} (dry-run)`);
|
|
1083
|
+
continue;
|
|
1084
|
+
}
|
|
1085
|
+
await fsp.mkdir(archiveDir, { recursive: true });
|
|
1086
|
+
if (await fsp.stat(gzPath).then(() => true).catch(() => false)) {
|
|
1087
|
+
skipped.push(`${f.name}: archive exists`);
|
|
1088
|
+
continue;
|
|
1089
|
+
}
|
|
1090
|
+
const srcPath = path2.join(
|
|
1091
|
+
ns === "test" ? _optionalChain([$asai, 'optionalAccess', _76 => _76.hostconfig, 'optionalAccess', _77 => _77.logger, 'optionalAccess', _78 => _78.intervention, 'optionalAccess', _79 => _79.testPath]) || "./webdata/webdb/log/intervention-test/" : _optionalChain([$asai, 'optionalAccess', _80 => _80.hostconfig, 'optionalAccess', _81 => _81.logger, 'optionalAccess', _82 => _82.intervention, 'optionalAccess', _83 => _83.path]) || "./webdata/webdb/log/intervention/",
|
|
1092
|
+
f.name
|
|
1093
|
+
);
|
|
1094
|
+
await pipeline(
|
|
1095
|
+
createReadStream(srcPath),
|
|
1096
|
+
zlib.createGzip(),
|
|
1097
|
+
createWriteStream(gzPath)
|
|
1098
|
+
);
|
|
1099
|
+
await fsp.unlink(srcPath);
|
|
1100
|
+
await purgeStoreEntriesForFile($asai, f.name, ns);
|
|
1101
|
+
const { logProcessGuardEvent } = await Promise.resolve().then(() => _interopRequireWildcard(require("./intervention-hooks-LE6X4C6N.cjs")));
|
|
1102
|
+
await logProcessGuardEvent($asai, {
|
|
1103
|
+
action: "archive_intervention",
|
|
1104
|
+
detail: `${f.name} -> ${gzPath}`,
|
|
1105
|
+
outcome: "Success",
|
|
1106
|
+
severity: 6
|
|
1107
|
+
});
|
|
1108
|
+
archived.push(f.name);
|
|
1109
|
+
} catch (err) {
|
|
1110
|
+
errors.push(`${f.name}: ${_optionalChain([err, 'optionalAccess', _84 => _84.message]) || err}`);
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
return { archived, skipped, errors };
|
|
1114
|
+
}
|
|
1115
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, archiveInterventionYear, "archiveInterventionYear");
|
|
1116
|
+
async function listUnifiedGroups($asai, filter = {}) {
|
|
1117
|
+
return dbListLogGroups($asai, filter);
|
|
1118
|
+
}
|
|
1119
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, listUnifiedGroups, "listUnifiedGroups");
|
|
1120
|
+
async function getUnifiedStats($asai) {
|
|
1121
|
+
return dbLogStats($asai);
|
|
1122
|
+
}
|
|
1123
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, getUnifiedStats, "getUnifiedStats");
|
|
1124
|
+
async function getUnifiedEntry($asai, id) {
|
|
1125
|
+
return dbGetLogEntry($asai, id);
|
|
1126
|
+
}
|
|
1127
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, getUnifiedEntry, "getUnifiedEntry");
|
|
1128
|
+
async function purgeStoreEntriesForFile($asai, fileName, ns = "") {
|
|
1129
|
+
return dbDeleteLogEntriesByFile($asai, fileName, ns);
|
|
1130
|
+
}
|
|
1131
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, purgeStoreEntriesForFile, "purgeStoreEntriesForFile");
|
|
1132
|
+
async function purgeSqliteEntriesForFile($asai, fileName, ns = "") {
|
|
1133
|
+
return purgeStoreEntriesForFile($asai, fileName, ns);
|
|
1134
|
+
}
|
|
1135
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, purgeSqliteEntriesForFile, "purgeSqliteEntriesForFile");
|
|
1136
|
+
function groupsToManageChildren(groups) {
|
|
1137
|
+
return groups.filter((g) => g.kind === "web" || g.kind === "sec").map((g) => ({
|
|
1138
|
+
name: g.file_name,
|
|
1139
|
+
path: g.file_name,
|
|
1140
|
+
size: g.entryCount,
|
|
1141
|
+
entryCount: g.entryCount,
|
|
1142
|
+
source: g.source,
|
|
1143
|
+
fromStore: true
|
|
1144
|
+
}));
|
|
1145
|
+
}
|
|
1146
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, groupsToManageChildren, "groupsToManageChildren");
|
|
1147
|
+
function groupsToInterventionFiles(groups, ns) {
|
|
1148
|
+
return groups.filter((g) => g.kind === "intervention" && (!ns || g.ns === ns)).map((g) => ({
|
|
1149
|
+
name: g.file_name,
|
|
1150
|
+
ns: g.ns || ns,
|
|
1151
|
+
size: g.entryCount,
|
|
1152
|
+
mtime: new Date(g.lastAt).toISOString(),
|
|
1153
|
+
entryCount: g.entryCount,
|
|
1154
|
+
ageDays: 0,
|
|
1155
|
+
retentionDays: 0,
|
|
1156
|
+
retentionYears: 5,
|
|
1157
|
+
expired: false,
|
|
1158
|
+
protectedAudit: g.file_name.includes("deletion-audit"),
|
|
1159
|
+
fromStore: true
|
|
1160
|
+
}));
|
|
1161
|
+
}
|
|
1162
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, groupsToInterventionFiles, "groupsToInterventionFiles");
|
|
1163
|
+
async function readWebLogFromStore($asai, source, fileName) {
|
|
1164
|
+
const m = fileName.match(/log-(\d{4}-\d{2}-\d{2})/);
|
|
1165
|
+
const logDate = _optionalChain([m, 'optionalAccess', _85 => _85[1]]) || "";
|
|
1166
|
+
const rows = await dbQueryLogEntries($asai, {
|
|
1167
|
+
kind: source === "sec" ? "sec" : "web",
|
|
1168
|
+
source,
|
|
1169
|
+
log_date: logDate,
|
|
1170
|
+
limit: 5e3
|
|
1171
|
+
});
|
|
1172
|
+
return rows.reverse().map((r) => String(r.raw_line || "")).join("");
|
|
1173
|
+
}
|
|
1174
|
+
_chunkSMVZ3ZDJcjs.__name.call(void 0, readWebLogFromStore, "readWebLogFromStore");
|
|
1175
|
+
|
|
1176
|
+
|
|
1177
|
+
|
|
1178
|
+
|
|
1179
|
+
|
|
1180
|
+
|
|
1181
|
+
|
|
1182
|
+
|
|
1183
|
+
|
|
1184
|
+
|
|
1185
|
+
|
|
1186
|
+
|
|
1187
|
+
|
|
1188
|
+
|
|
1189
|
+
|
|
1190
|
+
|
|
1191
|
+
|
|
1192
|
+
|
|
1193
|
+
|
|
1194
|
+
|
|
1195
|
+
|
|
1196
|
+
|
|
1197
|
+
|
|
1198
|
+
|
|
1199
|
+
|
|
1200
|
+
|
|
1201
|
+
exports.getLogStoreConfig = getLogStoreConfig; exports.getLogStoreMeta = getLogStoreMeta; exports.isLogStoreEnabled = isLogStoreEnabled; exports.isLogStoreFileBackend = isLogStoreFileBackend; exports.prefersDiskLogAccess = prefersDiskLogAccess; exports.getEffectiveStoreType = getEffectiveStoreType; exports.isLogStoreSqlite = isLogStoreSqlite; exports.mirrorWebLog = mirrorWebLog; exports.mirrorInterventionLog = mirrorInterventionLog; exports.mirrorAccessLog = mirrorAccessLog; exports.queryUnifiedLogs = queryUnifiedLogs; exports.searchUnifiedLogs = searchUnifiedLogs; exports.exportLogContent = exportLogContent; exports.getComplianceReport = getComplianceReport; exports.archiveInterventionYear = archiveInterventionYear; exports.listUnifiedGroups = listUnifiedGroups; exports.getUnifiedStats = getUnifiedStats; exports.getUnifiedEntry = getUnifiedEntry; exports.purgeStoreEntriesForFile = purgeStoreEntriesForFile; exports.purgeSqliteEntriesForFile = purgeSqliteEntriesForFile; exports.groupsToManageChildren = groupsToManageChildren; exports.groupsToInterventionFiles = groupsToInterventionFiles; exports.readWebLogFromStore = readWebLogFromStore; exports.LogStore_exports = LogStore_exports;
|
|
1202
|
+
//# sourceMappingURL=chunk-VLMM735Q.cjs.map
|