logixia 1.12.5 → 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/README.md +75 -18
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/async-context-CSHWoHMB.js +88 -0
  4. package/dist/async-context-CSHWoHMB.js.map +1 -0
  5. package/dist/async-context-CwBNMm2E.mjs +68 -0
  6. package/dist/async-context-CwBNMm2E.mjs.map +1 -0
  7. package/dist/azure-monitor.transport-CG7ClkYj.d.ts +62 -0
  8. package/dist/azure-monitor.transport-CG7ClkYj.d.ts.map +1 -0
  9. package/dist/azure-monitor.transport-CHnjVRF-.mjs +152 -0
  10. package/dist/azure-monitor.transport-CHnjVRF-.mjs.map +1 -0
  11. package/dist/azure-monitor.transport-Cm74kXZS.d.mts +62 -0
  12. package/dist/azure-monitor.transport-Cm74kXZS.d.mts.map +1 -0
  13. package/dist/azure-monitor.transport-CrvfHd9C.js +157 -0
  14. package/dist/azure-monitor.transport-CrvfHd9C.js.map +1 -0
  15. package/dist/azure.d.mts +3 -0
  16. package/dist/azure.d.ts +3 -0
  17. package/dist/azure.js +6 -0
  18. package/dist/azure.mjs +6 -0
  19. package/dist/batch-buffer-BY-mRWIK.js +170 -0
  20. package/dist/batch-buffer-BY-mRWIK.js.map +1 -0
  21. package/dist/batch-buffer-PGvSgbmd.mjs +132 -0
  22. package/dist/batch-buffer-PGvSgbmd.mjs.map +1 -0
  23. package/dist/browser.d.mts +427 -0
  24. package/dist/browser.d.mts.map +1 -0
  25. package/dist/browser.d.ts +427 -0
  26. package/dist/browser.d.ts.map +1 -0
  27. package/dist/browser.js +590 -0
  28. package/dist/browser.js.map +1 -0
  29. package/dist/browser.mjs +586 -0
  30. package/dist/browser.mjs.map +1 -0
  31. package/dist/chunk-DLSkYcPk.mjs +7 -0
  32. package/dist/chunk-nOFOJqeH.js +30 -0
  33. package/dist/cloudwatch.d.mts +3 -0
  34. package/dist/cloudwatch.d.ts +3 -0
  35. package/dist/cloudwatch.js +6 -0
  36. package/dist/cloudwatch.mjs +6 -0
  37. package/dist/cloudwatch.transport-CGHY4buE.d.mts +81 -0
  38. package/dist/cloudwatch.transport-CGHY4buE.d.mts.map +1 -0
  39. package/dist/cloudwatch.transport-DK_8cKd3.d.ts +81 -0
  40. package/dist/cloudwatch.transport-DK_8cKd3.d.ts.map +1 -0
  41. package/dist/cloudwatch.transport-pNBNWJLt.js +370 -0
  42. package/dist/cloudwatch.transport-pNBNWJLt.js.map +1 -0
  43. package/dist/cloudwatch.transport-yBwm4OeO.mjs +360 -0
  44. package/dist/cloudwatch.transport-yBwm4OeO.mjs.map +1 -0
  45. package/dist/coerce.utils-BN980Y9V.js +44 -0
  46. package/dist/coerce.utils-BN980Y9V.js.map +1 -0
  47. package/dist/coerce.utils-Dxv4_ikC.mjs +38 -0
  48. package/dist/coerce.utils-Dxv4_ikC.mjs.map +1 -0
  49. package/dist/correlation.d.mts +245 -0
  50. package/dist/correlation.d.mts.map +1 -0
  51. package/dist/correlation.d.ts +245 -0
  52. package/dist/correlation.d.ts.map +1 -0
  53. package/dist/correlation.js +272 -0
  54. package/dist/correlation.js.map +1 -0
  55. package/dist/correlation.mjs +261 -0
  56. package/dist/correlation.mjs.map +1 -0
  57. package/dist/gcp.d.mts +3 -0
  58. package/dist/gcp.d.ts +3 -0
  59. package/dist/gcp.js +6 -0
  60. package/dist/gcp.mjs +6 -0
  61. package/dist/gcp.transport-BJuNRFe_.mjs +192 -0
  62. package/dist/gcp.transport-BJuNRFe_.mjs.map +1 -0
  63. package/dist/gcp.transport-BOhkVKlI.d.ts +71 -0
  64. package/dist/gcp.transport-BOhkVKlI.d.ts.map +1 -0
  65. package/dist/gcp.transport-Bi6CUqZR.d.mts +71 -0
  66. package/dist/gcp.transport-Bi6CUqZR.d.mts.map +1 -0
  67. package/dist/gcp.transport-SHdtc1n0.js +198 -0
  68. package/dist/gcp.transport-SHdtc1n0.js.map +1 -0
  69. package/dist/{index-CwFww7VC.d.ts → index-BPKwwERo.d.mts} +18 -174
  70. package/dist/index-BPKwwERo.d.mts.map +1 -0
  71. package/dist/{index-DnyeaoZU.d.mts → index-C1X-TE5I.d.ts} +18 -174
  72. package/dist/index-C1X-TE5I.d.ts.map +1 -0
  73. package/dist/index.d.mts +41 -11
  74. package/dist/index.d.mts.map +1 -1
  75. package/dist/index.d.ts +40 -10
  76. package/dist/index.d.ts.map +1 -1
  77. package/dist/index.js +87 -147
  78. package/dist/index.js.map +1 -1
  79. package/dist/index.mjs +62 -132
  80. package/dist/index.mjs.map +1 -1
  81. package/dist/internal-log-BUJYMZbE.js +70 -0
  82. package/dist/internal-log-BUJYMZbE.js.map +1 -0
  83. package/dist/internal-log-Cm8SOWSV.mjs +52 -0
  84. package/dist/internal-log-Cm8SOWSV.mjs.map +1 -0
  85. package/dist/{logitron-logger.module-CpffEHec.d.mts → logitron-logger.module-BdG1Jnpk.d.mts} +23 -10
  86. package/dist/logitron-logger.module-BdG1Jnpk.d.mts.map +1 -0
  87. package/dist/{logitron-logger.module-BIGTm2V6.mjs → logitron-logger.module-Bs3XYZgF.mjs} +266 -166
  88. package/dist/logitron-logger.module-Bs3XYZgF.mjs.map +1 -0
  89. package/dist/{logitron-logger.module-BTxDpK6u.js → logitron-logger.module-BsDZR5BH.js} +297 -203
  90. package/dist/logitron-logger.module-BsDZR5BH.js.map +1 -0
  91. package/dist/{logitron-logger.module-DvqtI43C.d.ts → logitron-logger.module-CbXy2gfW.d.ts} +23 -10
  92. package/dist/logitron-logger.module-CbXy2gfW.d.ts.map +1 -0
  93. package/dist/middleware.d.mts +5 -2
  94. package/dist/middleware.d.mts.map +1 -1
  95. package/dist/middleware.d.ts +5 -2
  96. package/dist/middleware.d.ts.map +1 -1
  97. package/dist/middleware.js +13 -4
  98. package/dist/middleware.js.map +1 -1
  99. package/dist/middleware.mjs +14 -4
  100. package/dist/middleware.mjs.map +1 -1
  101. package/dist/nest.d.mts +3 -2
  102. package/dist/nest.d.mts.map +1 -1
  103. package/dist/nest.d.ts +3 -2
  104. package/dist/nest.d.ts.map +1 -1
  105. package/dist/nest.js +6 -2
  106. package/dist/nest.mjs +6 -2
  107. package/dist/safe-stringify-DJ66tW5I.mjs +118 -0
  108. package/dist/safe-stringify-DJ66tW5I.mjs.map +1 -0
  109. package/dist/safe-stringify-DWo3aZp_.js +142 -0
  110. package/dist/safe-stringify-DWo3aZp_.js.map +1 -0
  111. package/dist/search-CFQRISUv.mjs +1596 -0
  112. package/dist/search-CFQRISUv.mjs.map +1 -0
  113. package/dist/search-CQOo-Iq6.d.mts +816 -0
  114. package/dist/search-CQOo-Iq6.d.mts.map +1 -0
  115. package/dist/search-DujhR94O.d.ts +816 -0
  116. package/dist/search-DujhR94O.d.ts.map +1 -0
  117. package/dist/search-njTI2hdo.js +1631 -0
  118. package/dist/search-njTI2hdo.js.map +1 -0
  119. package/dist/search.d.mts +4 -1
  120. package/dist/search.d.ts +4 -1
  121. package/dist/search.js +9 -1
  122. package/dist/search.mjs +3 -2
  123. package/dist/testing.d.mts +2 -1
  124. package/dist/testing.d.mts.map +1 -1
  125. package/dist/testing.d.ts +2 -1
  126. package/dist/testing.d.ts.map +1 -1
  127. package/dist/{transport.manager-ciG4r5uz.js → transport.manager-BivyUTtU.js} +497 -437
  128. package/dist/transport.manager-BivyUTtU.js.map +1 -0
  129. package/dist/{transport.manager-DETpXuaY.mjs → transport.manager-D6KL3t9V.mjs} +473 -364
  130. package/dist/transport.manager-D6KL3t9V.mjs.map +1 -0
  131. package/dist/transport.types-B5vcyv2k.d.mts +187 -0
  132. package/dist/transport.types-B5vcyv2k.d.mts.map +1 -0
  133. package/dist/transport.types-BuY84TwO.d.ts +187 -0
  134. package/dist/transport.types-BuY84TwO.d.ts.map +1 -0
  135. package/dist/transports.d.mts +90 -29
  136. package/dist/transports.d.mts.map +1 -1
  137. package/dist/transports.d.ts +90 -29
  138. package/dist/transports.d.ts.map +1 -1
  139. package/dist/transports.js +14 -2
  140. package/dist/transports.mjs +10 -2
  141. package/dist/worker-entry.js +1241 -0
  142. package/dist/worker.d.mts +3 -0
  143. package/dist/worker.d.ts +3 -0
  144. package/dist/worker.js +4 -0
  145. package/dist/worker.mjs +4 -0
  146. package/dist/worker.transport-BP8Q28Z2.d.mts +76 -0
  147. package/dist/worker.transport-BP8Q28Z2.d.mts.map +1 -0
  148. package/dist/worker.transport-BhMyvqQ2.mjs +167 -0
  149. package/dist/worker.transport-BhMyvqQ2.mjs.map +1 -0
  150. package/dist/worker.transport-CfH6z37Z.js +168 -0
  151. package/dist/worker.transport-CfH6z37Z.js.map +1 -0
  152. package/dist/worker.transport-mKXgNK0L.d.ts +76 -0
  153. package/dist/worker.transport-mKXgNK0L.d.ts.map +1 -0
  154. package/package.json +23 -18
  155. package/dist/index-CwFww7VC.d.ts.map +0 -1
  156. package/dist/index-DnyeaoZU.d.mts.map +0 -1
  157. package/dist/logitron-logger.module-BIGTm2V6.mjs.map +0 -1
  158. package/dist/logitron-logger.module-BTxDpK6u.js.map +0 -1
  159. package/dist/logitron-logger.module-CpffEHec.d.mts.map +0 -1
  160. package/dist/logitron-logger.module-DvqtI43C.d.ts.map +0 -1
  161. package/dist/search-Cg_OasF-.d.ts +0 -1
  162. package/dist/search-DN676Dnz.d.mts +0 -1
  163. package/dist/search-DOvSI-mb.mjs +0 -1
  164. package/dist/search-DoZF3RZj.js +0 -0
  165. package/dist/transport.manager-DETpXuaY.mjs.map +0 -1
  166. package/dist/transport.manager-ciG4r5uz.js.map +0 -1
@@ -0,0 +1,1631 @@
1
+ const require_coerce_utils = require('./coerce.utils-BN980Y9V.js');
2
+
3
+ //#region src/search/core/basic-log-indexer.ts
4
+ /**
5
+ * Basic log indexer implementation
6
+ */
7
+ var BasicLogIndexer = class {
8
+ constructor(options) {
9
+ this.options = options;
10
+ this.index = /* @__PURE__ */ new Map();
11
+ this.fieldIndices = /* @__PURE__ */ new Map();
12
+ this.indexSizeBytes = 0;
13
+ this.logSizeById = /* @__PURE__ */ new Map();
14
+ this.options = {
15
+ maxIndexSize: 1e6,
16
+ autoOptimize: true,
17
+ optimizeThreshold: 1e4,
18
+ ...options
19
+ };
20
+ this.initializeFieldIndices();
21
+ }
22
+ /**
23
+ * Index a single log entry
24
+ */
25
+ async indexLog(log) {
26
+ var _this$options, _this$options2;
27
+ const logId = this.generateLogId(log);
28
+ this.trackInsert(logId, log);
29
+ this.updateFieldIndices(logId, log);
30
+ if (((_this$options = this.options) === null || _this$options === void 0 ? void 0 : _this$options.autoOptimize) && this.index.size % (this.options.optimizeThreshold || 1e4) === 0) await this.optimizeIndex();
31
+ if (this.index.size > (((_this$options2 = this.options) === null || _this$options2 === void 0 ? void 0 : _this$options2.maxIndexSize) || 1e6)) {
32
+ var _this$options3;
33
+ await this.removeOldestLogs(Math.floor((((_this$options3 = this.options) === null || _this$options3 === void 0 ? void 0 : _this$options3.maxIndexSize) || 1e6) * .1));
34
+ }
35
+ }
36
+ /**
37
+ * Index multiple log entries in batch
38
+ */
39
+ async indexBatch(logs) {
40
+ var _this$options4;
41
+ for (const log of logs) {
42
+ const logId = this.generateLogId(log);
43
+ this.trackInsert(logId, log);
44
+ this.updateFieldIndices(logId, log);
45
+ }
46
+ if ((_this$options4 = this.options) === null || _this$options4 === void 0 ? void 0 : _this$options4.autoOptimize) await this.optimizeIndex();
47
+ }
48
+ /**
49
+ * Build semantic index for intelligent search
50
+ */
51
+ async buildSemanticIndex(logs) {
52
+ const clusters = await this.clusterLogs(logs);
53
+ this.semanticIndex = {
54
+ version: "1.0.0",
55
+ indexedCount: logs.length,
56
+ lastUpdated: /* @__PURE__ */ new Date(),
57
+ clusters
58
+ };
59
+ return this.semanticIndex;
60
+ }
61
+ /**
62
+ * Update search suggestions based on search history
63
+ */
64
+ async updateSearchSuggestions(searchHistory) {
65
+ const patterns = /* @__PURE__ */ new Map();
66
+ for (const query of searchHistory) {
67
+ const normalizedQuery = query.query.toLowerCase().trim();
68
+ patterns.set(normalizedQuery, (patterns.get(normalizedQuery) || 0) + 1);
69
+ }
70
+ }
71
+ /**
72
+ * Optimize the index for better performance
73
+ */
74
+ async optimizeIndex() {
75
+ this.fieldIndices.clear();
76
+ this.initializeFieldIndices();
77
+ for (const [logId, log] of this.index.entries()) this.updateFieldIndices(logId, log);
78
+ this.lastOptimized = /* @__PURE__ */ new Date();
79
+ }
80
+ /**
81
+ * Clear the index
82
+ */
83
+ async clearIndex() {
84
+ this.index.clear();
85
+ this.fieldIndices.clear();
86
+ this.semanticIndex = void 0;
87
+ this.indexSizeBytes = 0;
88
+ this.logSizeById.clear();
89
+ this.initializeFieldIndices();
90
+ }
91
+ /**
92
+ * Get index statistics
93
+ */
94
+ async getIndexStats() {
95
+ return {
96
+ totalDocuments: this.index.size,
97
+ indexSize: this.calculateIndexSize(),
98
+ ...this.lastOptimized !== void 0 ? { lastOptimized: this.lastOptimized } : {}
99
+ };
100
+ }
101
+ /**
102
+ * Remove logs older than specified time
103
+ */
104
+ async removeOldLogs(olderThan) {
105
+ const cutoffTime = olderThan.getTime();
106
+ let removedCount = 0;
107
+ for (const [logId, log] of this.index.entries()) if (new Date(log.timestamp).getTime() < cutoffTime) {
108
+ this.trackDelete(logId);
109
+ this.removeFromFieldIndices(logId);
110
+ removedCount++;
111
+ }
112
+ return removedCount;
113
+ }
114
+ /**
115
+ * Search logs by field
116
+ */
117
+ searchByField(field, value) {
118
+ const fieldIndex = this.fieldIndices.get(field);
119
+ if (!fieldIndex) return [];
120
+ const logIds = fieldIndex.get(value.toLowerCase());
121
+ if (!logIds) return [];
122
+ return Array.from(logIds).map((id) => this.index.get(id)).filter((log) => log !== void 0);
123
+ }
124
+ /**
125
+ * Get all indexed logs
126
+ */
127
+ getAllLogs() {
128
+ return Array.from(this.index.values());
129
+ }
130
+ initializeFieldIndices() {
131
+ for (const field of [
132
+ "level",
133
+ "appName",
134
+ "traceId",
135
+ "context",
136
+ "environment"
137
+ ]) this.fieldIndices.set(field, /* @__PURE__ */ new Map());
138
+ }
139
+ updateFieldIndices(logId, log) {
140
+ this.addToFieldIndex("level", log.level, logId);
141
+ if (log.appName) this.addToFieldIndex("appName", log.appName, logId);
142
+ if (log.traceId) this.addToFieldIndex("traceId", log.traceId, logId);
143
+ if (log.context) this.addToFieldIndex("context", log.context, logId);
144
+ if (log.environment) this.addToFieldIndex("environment", log.environment, logId);
145
+ }
146
+ addToFieldIndex(field, value, logId) {
147
+ const fieldIndex = this.fieldIndices.get(field);
148
+ if (!fieldIndex) return;
149
+ const normalizedValue = value.toLowerCase();
150
+ if (!fieldIndex.has(normalizedValue)) fieldIndex.set(normalizedValue, /* @__PURE__ */ new Set());
151
+ fieldIndex.get(normalizedValue).add(logId);
152
+ }
153
+ removeFromFieldIndices(logId) {
154
+ for (const fieldIndex of this.fieldIndices.values()) for (const logIds of fieldIndex.values()) logIds.delete(logId);
155
+ }
156
+ generateLogId(log) {
157
+ return `${log.timestamp}_${log.level}_${Math.random().toString(36).slice(2, 11)}`;
158
+ }
159
+ calculateIndexSize() {
160
+ return this.indexSizeBytes;
161
+ }
162
+ /** Insert into the main index and update the running size estimate. */
163
+ trackInsert(logId, log) {
164
+ const existing = this.logSizeById.get(logId);
165
+ if (existing !== void 0) this.indexSizeBytes -= existing;
166
+ const size = JSON.stringify(log).length;
167
+ this.index.set(logId, log);
168
+ this.logSizeById.set(logId, size);
169
+ this.indexSizeBytes += size;
170
+ }
171
+ /** Delete from the main index and update the running size estimate. */
172
+ trackDelete(logId) {
173
+ const size = this.logSizeById.get(logId);
174
+ if (size !== void 0) {
175
+ this.indexSizeBytes -= size;
176
+ this.logSizeById.delete(logId);
177
+ }
178
+ this.index.delete(logId);
179
+ }
180
+ async removeOldestLogs(count) {
181
+ const logs = Array.from(this.index.entries()).sort((a, b) => new Date(a[1].timestamp).getTime() - new Date(b[1].timestamp).getTime()).slice(0, count);
182
+ for (const [logId] of logs) {
183
+ this.trackDelete(logId);
184
+ this.removeFromFieldIndices(logId);
185
+ }
186
+ }
187
+ async clusterLogs(logs) {
188
+ const clusters = /* @__PURE__ */ new Map();
189
+ for (const log of logs) {
190
+ const patternKey = `${log.level}_${log.appName}`;
191
+ if (!clusters.has(patternKey)) clusters.set(patternKey, []);
192
+ clusters.get(patternKey).push(log);
193
+ }
194
+ return Array.from(clusters.entries()).map(([pattern, clusterLogs], index) => ({
195
+ id: `cluster_${index}`,
196
+ centroid: [],
197
+ logs: clusterLogs,
198
+ pattern,
199
+ frequency: clusterLogs.length,
200
+ labels: [pattern]
201
+ }));
202
+ }
203
+ };
204
+
205
+ //#endregion
206
+ //#region src/search/core/basic-search-engine.ts
207
+ /**
208
+ * Basic search engine implementation
209
+ */
210
+ var BasicSearchEngine = class {
211
+ constructor(options) {
212
+ this.options = options;
213
+ this.logs = [];
214
+ this.presets = /* @__PURE__ */ new Map();
215
+ this.searchHistory = [];
216
+ this.suggestionCache = /* @__PURE__ */ new Map();
217
+ this.options = {
218
+ maxHistorySize: 1e3,
219
+ cacheSize: 100,
220
+ maxLogs: 1e5,
221
+ ...options
222
+ };
223
+ }
224
+ /**
225
+ * Add logs to the search index.
226
+ *
227
+ * Bounded to `maxLogs` (default 100k): the buffer previously grew without
228
+ * limit, leaking memory in any long-running process feeding it logs. When the
229
+ * cap is exceeded the oldest entries are dropped (FIFO). We also append with a
230
+ * loop rather than `push(...logs)` to avoid a RangeError from spreading a very
231
+ * large array onto the call stack.
232
+ */
233
+ addLogs(logs) {
234
+ var _this$options;
235
+ for (const log of logs) this.logs.push(log);
236
+ const maxLogs = ((_this$options = this.options) === null || _this$options === void 0 ? void 0 : _this$options.maxLogs) ?? 1e5;
237
+ if (this.logs.length > maxLogs) this.logs.splice(0, this.logs.length - maxLogs);
238
+ }
239
+ /**
240
+ * Clear all logs from the index
241
+ */
242
+ clearLogs() {
243
+ this.logs = [];
244
+ }
245
+ /**
246
+ * Get all indexed logs
247
+ */
248
+ getLogs() {
249
+ return this.logs;
250
+ }
251
+ /**
252
+ * Perform a full-text search across logs
253
+ */
254
+ async search(query, filters, options) {
255
+ const filteredLogs = this.applyFilters(this.logs, filters);
256
+ const results = this.performTextSearch(filteredLogs, query, options);
257
+ this.addToSearchHistory(query);
258
+ const sorted = this.applySorting(results, options === null || options === void 0 ? void 0 : options.sortBy, options === null || options === void 0 ? void 0 : options.sortOrder);
259
+ const paginated = this.applyPagination(sorted, options === null || options === void 0 ? void 0 : options.offset, options === null || options === void 0 ? void 0 : options.limit);
260
+ if (options === null || options === void 0 ? void 0 : options.includeContext) await this.enrichWithContext(paginated, options.contextSize);
261
+ return paginated;
262
+ }
263
+ /**
264
+ * Natural language search (basic implementation)
265
+ */
266
+ async naturalLanguageSearch(query) {
267
+ const parsed = await this.parseNaturalLanguageQuery(query);
268
+ return this.search(parsed.originalQuery, parsed.filters, {
269
+ semanticSearch: true,
270
+ includeContext: true
271
+ });
272
+ }
273
+ /**
274
+ * Find logs correlated by trace ID
275
+ */
276
+ async correlateByTraceId(traceId) {
277
+ const correlatedLogs = this.logs.filter((log) => log.traceId === traceId);
278
+ correlatedLogs.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
279
+ const timeline = correlatedLogs.map((log) => {
280
+ let eventType = "info";
281
+ if (log.level === "error") eventType = "error";
282
+ else if (log.message.toLowerCase().includes("start")) eventType = "start";
283
+ else if (log.message.toLowerCase().includes("end") || log.message.toLowerCase().includes("complete")) eventType = "end";
284
+ else if (log.message.toLowerCase().includes("milestone")) eventType = "milestone";
285
+ return {
286
+ timestamp: new Date(log.timestamp),
287
+ log,
288
+ eventType
289
+ };
290
+ });
291
+ const summary = {
292
+ totalLogs: correlatedLogs.length,
293
+ errorCount: correlatedLogs.filter((l) => l.level === "error").length,
294
+ warningCount: correlatedLogs.filter((l) => l.level === "warn").length,
295
+ services: [...new Set(correlatedLogs.map((l) => l.appName))]
296
+ };
297
+ if (timeline.length > 0) {
298
+ const start = timeline[0].timestamp.getTime();
299
+ summary.duration = timeline[timeline.length - 1].timestamp.getTime() - start;
300
+ }
301
+ return {
302
+ traceId,
303
+ correlationKey: traceId,
304
+ logs: correlatedLogs,
305
+ timeline,
306
+ summary
307
+ };
308
+ }
309
+ /**
310
+ * Find similar logs based on content similarity
311
+ */
312
+ async findSimilarLogs(logEntry, limit = 10) {
313
+ const similarities = [];
314
+ for (const log of this.logs) {
315
+ if (log === logEntry) continue;
316
+ const similarity = this.calculateSimilarity(logEntry, log);
317
+ if (similarity > .3) similarities.push({
318
+ log,
319
+ similarity,
320
+ matchedPatterns: this.findMatchedPatterns(logEntry, log),
321
+ reason: this.generateSimilarityReason(logEntry, log, similarity)
322
+ });
323
+ }
324
+ return similarities.sort((a, b) => b.similarity - a.similarity).slice(0, limit);
325
+ }
326
+ /**
327
+ * Get search suggestions
328
+ */
329
+ async getSuggestions(partialQuery, limit = 10) {
330
+ var _this$options2;
331
+ const cacheKey = partialQuery.toLowerCase();
332
+ if (this.suggestionCache.has(cacheKey)) return this.suggestionCache.get(cacheKey).slice(0, limit);
333
+ const suggestions = [];
334
+ for (const field of [
335
+ "level",
336
+ "appName",
337
+ "traceId",
338
+ "message",
339
+ "timestamp"
340
+ ]) if (field.toLowerCase().includes(partialQuery.toLowerCase())) suggestions.push({
341
+ text: field,
342
+ type: "field",
343
+ category: "field"
344
+ });
345
+ const values = /* @__PURE__ */ new Set();
346
+ for (const log of this.logs.slice(-1e3)) {
347
+ var _log$level, _log$appName;
348
+ if ((_log$level = log.level) === null || _log$level === void 0 ? void 0 : _log$level.toLowerCase().includes(partialQuery.toLowerCase())) values.add(log.level);
349
+ if ((_log$appName = log.appName) === null || _log$appName === void 0 ? void 0 : _log$appName.toLowerCase().includes(partialQuery.toLowerCase())) values.add(log.appName);
350
+ }
351
+ for (const value of values) suggestions.push({
352
+ text: value,
353
+ type: "value",
354
+ category: "value"
355
+ });
356
+ for (const historyItem of this.searchHistory.slice(-50)) if (historyItem.toLowerCase().includes(partialQuery.toLowerCase())) suggestions.push({
357
+ text: historyItem,
358
+ type: "query_history",
359
+ category: "history"
360
+ });
361
+ this.suggestionCache.set(cacheKey, suggestions);
362
+ if (this.suggestionCache.size > (((_this$options2 = this.options) === null || _this$options2 === void 0 ? void 0 : _this$options2.cacheSize) || 100)) {
363
+ const firstKey = this.suggestionCache.keys().next().value;
364
+ if (firstKey !== void 0) this.suggestionCache.delete(firstKey);
365
+ }
366
+ return suggestions.slice(0, limit);
367
+ }
368
+ /**
369
+ * Get search statistics
370
+ */
371
+ async getStats() {
372
+ return {
373
+ totalResults: this.logs.length,
374
+ executionTime: 0,
375
+ indexSize: this.logs.length,
376
+ topTerms: this.getTopTerms()
377
+ };
378
+ }
379
+ /**
380
+ * Parse natural language query
381
+ */
382
+ async parseNaturalLanguageQuery(query) {
383
+ const filters = {};
384
+ const lowerQuery = query.toLowerCase();
385
+ const levels = [];
386
+ if (lowerQuery.includes("error")) levels.push("error");
387
+ if (lowerQuery.includes("warn")) levels.push("warn");
388
+ if (lowerQuery.includes("info")) levels.push("info");
389
+ if (levels.length > 0) filters.levels = levels;
390
+ const timeRange = this.extractTimeRange(query);
391
+ if (timeRange) filters.timeRange = timeRange;
392
+ const serviceMatch = query.match(/from\s+(?:the\s+)?(\w+)\s+service/i);
393
+ if (serviceMatch === null || serviceMatch === void 0 ? void 0 : serviceMatch[1]) filters.services = [serviceMatch[1]];
394
+ const userMatch = query.match(/user\s+(?:id\s+)?(\w+)/i);
395
+ if (userMatch === null || userMatch === void 0 ? void 0 : userMatch[1]) filters.userIds = [userMatch[1]];
396
+ let intent = "general_search";
397
+ if (lowerQuery.includes("error")) intent = "find_errors";
398
+ if (lowerQuery.includes("trace") || lowerQuery.includes("request")) intent = "trace_request";
399
+ if (lowerQuery.includes("user")) intent = "find_user_activity";
400
+ if (lowerQuery.includes("slow") || lowerQuery.includes("performance")) intent = "performance_analysis";
401
+ return {
402
+ originalQuery: query,
403
+ intent,
404
+ entities: [],
405
+ filters,
406
+ confidence: .7
407
+ };
408
+ }
409
+ /**
410
+ * Save a search preset
411
+ */
412
+ async savePreset(preset) {
413
+ const id = this.generateId();
414
+ const now = /* @__PURE__ */ new Date();
415
+ const fullPreset = {
416
+ ...preset,
417
+ id,
418
+ createdAt: now,
419
+ updatedAt: now
420
+ };
421
+ this.presets.set(id, fullPreset);
422
+ return fullPreset;
423
+ }
424
+ /**
425
+ * Get saved presets
426
+ */
427
+ async getPresets(userId) {
428
+ const allPresets = Array.from(this.presets.values());
429
+ if (userId) return allPresets.filter((p) => p.userId === userId || p.shared);
430
+ return allPresets;
431
+ }
432
+ /**
433
+ * Delete a preset
434
+ */
435
+ async deletePreset(presetId) {
436
+ this.presets.delete(presetId);
437
+ }
438
+ applyFilters(logs, filters) {
439
+ if (!filters) return logs;
440
+ return logs.filter((log) => {
441
+ if (filters.levels && !filters.levels.includes(log.level)) return false;
442
+ if (filters.services && !filters.services.includes(log.appName)) return false;
443
+ if (filters.traceIds && log.traceId && !filters.traceIds.includes(log.traceId)) return false;
444
+ if (filters.timeRange) {
445
+ const logTime = new Date(log.timestamp).getTime();
446
+ if (logTime < (typeof filters.timeRange.start === "number" ? filters.timeRange.start : filters.timeRange.start.getTime())) return false;
447
+ if (filters.timeRange.end) {
448
+ if (logTime > (typeof filters.timeRange.end === "number" ? filters.timeRange.end : filters.timeRange.end.getTime())) return false;
449
+ }
450
+ }
451
+ if (filters.hasError !== void 0) {
452
+ const hasError = log.level === "error" || !!log.error;
453
+ if (filters.hasError !== hasError) return false;
454
+ }
455
+ if (filters.contexts && log.context && !filters.contexts.includes(log.context)) return false;
456
+ return true;
457
+ });
458
+ }
459
+ performTextSearch(logs, query, options) {
460
+ if (!query) return logs.map((log) => ({
461
+ log,
462
+ score: 1
463
+ }));
464
+ const queryTerms = query.toLowerCase().split(/\s+/);
465
+ const results = [];
466
+ for (const log of logs) {
467
+ const searchableText = this.getSearchableText(log).toLowerCase();
468
+ let score = 0;
469
+ const highlights = [];
470
+ const matchedTerms = [];
471
+ for (const term of queryTerms) if (searchableText.includes(term)) {
472
+ score += 1;
473
+ matchedTerms.push(term);
474
+ }
475
+ if (score > 0) {
476
+ if (options === null || options === void 0 ? void 0 : options.highlightMatches) highlights.push({
477
+ field: "message",
478
+ fragments: this.getHighlightFragments(log.message, matchedTerms),
479
+ matchedTerms
480
+ });
481
+ const result = {
482
+ log,
483
+ score: score / queryTerms.length
484
+ };
485
+ if (highlights.length > 0) result.highlights = highlights;
486
+ results.push(result);
487
+ }
488
+ }
489
+ return results;
490
+ }
491
+ getSearchableText(log) {
492
+ const payloadText = log.payload ? require_coerce_utils.safeToString(log.payload) : "";
493
+ return [
494
+ log.message,
495
+ log.level,
496
+ log.appName,
497
+ log.context,
498
+ payloadText
499
+ ].filter(Boolean).join(" ");
500
+ }
501
+ getHighlightFragments(text, terms) {
502
+ const fragments = [];
503
+ const lowerText = text.toLowerCase();
504
+ for (const term of terms) {
505
+ const index = lowerText.indexOf(term);
506
+ if (index !== -1) {
507
+ const start = Math.max(0, index - 30);
508
+ const end = Math.min(text.length, index + term.length + 30);
509
+ fragments.push(text.slice(start, end));
510
+ }
511
+ }
512
+ return fragments;
513
+ }
514
+ applySorting(results, sortBy, sortOrder = "desc") {
515
+ const sorted = [...results];
516
+ sorted.sort((a, b) => {
517
+ let comparison;
518
+ switch (sortBy) {
519
+ case "timestamp":
520
+ comparison = new Date(a.log.timestamp).getTime() - new Date(b.log.timestamp).getTime();
521
+ break;
522
+ case "level":
523
+ comparison = a.log.level.localeCompare(b.log.level);
524
+ break;
525
+ case "score":
526
+ case "relevance":
527
+ default:
528
+ comparison = a.score - b.score;
529
+ break;
530
+ }
531
+ return sortOrder === "asc" ? comparison : -comparison;
532
+ });
533
+ return sorted;
534
+ }
535
+ applyPagination(results, offset = 0, limit = 100) {
536
+ return results.slice(offset, offset + limit);
537
+ }
538
+ async enrichWithContext(results, contextSize = 5) {
539
+ for (const result of results) {
540
+ const logIndex = this.logs.indexOf(result.log);
541
+ if (logIndex !== -1) {
542
+ const start = Math.max(0, logIndex - contextSize);
543
+ const end = Math.min(this.logs.length, logIndex + contextSize + 1);
544
+ result.context = this.logs.slice(start, end).filter((l) => l !== result.log);
545
+ }
546
+ }
547
+ }
548
+ calculateSimilarity(log1, log2) {
549
+ let score = 0;
550
+ let factors = 0;
551
+ if (log1.level === log2.level) score += .3;
552
+ factors++;
553
+ if (log1.appName === log2.appName) score += .2;
554
+ factors++;
555
+ if (log1.traceId && log1.traceId === log2.traceId) score += .3;
556
+ factors++;
557
+ const messageSimilarity = this.calculateTextSimilarity(log1.message, log2.message);
558
+ score += messageSimilarity * .2;
559
+ factors++;
560
+ return score / factors;
561
+ }
562
+ calculateTextSimilarity(text1, text2) {
563
+ const words1 = new Set(text1.toLowerCase().split(/\s+/));
564
+ const words2 = new Set(text2.toLowerCase().split(/\s+/));
565
+ const intersection = new Set([...words1].filter((x) => words2.has(x)));
566
+ const union = new Set([...words1, ...words2]);
567
+ return union.size > 0 ? intersection.size / union.size : 0;
568
+ }
569
+ findMatchedPatterns(log1, log2) {
570
+ const patterns = [];
571
+ if (log1.level === log2.level) patterns.push("same_level");
572
+ if (log1.appName === log2.appName) patterns.push("same_service");
573
+ if (log1.traceId === log2.traceId) patterns.push("same_trace");
574
+ if (log1.context === log2.context) patterns.push("same_context");
575
+ return patterns;
576
+ }
577
+ generateSimilarityReason(log1, log2, similarity) {
578
+ const reasons = [];
579
+ if (log1.level === log2.level) reasons.push("same log level");
580
+ if (log1.appName === log2.appName) reasons.push("same service");
581
+ if (log1.traceId === log2.traceId) reasons.push("same trace ID");
582
+ return reasons.length > 0 ? `Similar because: ${reasons.join(", ")}` : `${Math.round(similarity * 100)}% content similarity`;
583
+ }
584
+ extractTimeRange(query) {
585
+ const lowerQuery = query.toLowerCase();
586
+ if (lowerQuery.includes("last hour") || lowerQuery.includes("past hour")) return { start: /* @__PURE__ */ new Date(Date.now() - 3600 * 1e3) };
587
+ const hoursMatch = query.match(/last\s+(\d+)\s+hours?/i);
588
+ if (hoursMatch) return { start: /* @__PURE__ */ new Date(Date.now() - Number.parseInt(hoursMatch[1] ?? "0") * 60 * 60 * 1e3) };
589
+ if (lowerQuery.includes("today")) {
590
+ const today = /* @__PURE__ */ new Date();
591
+ today.setHours(0, 0, 0, 0);
592
+ return { start: today };
593
+ }
594
+ }
595
+ addToSearchHistory(query) {
596
+ var _this$options3;
597
+ this.searchHistory.push(query);
598
+ const maxSize = ((_this$options3 = this.options) === null || _this$options3 === void 0 ? void 0 : _this$options3.maxHistorySize) || 1e3;
599
+ if (this.searchHistory.length > maxSize) this.searchHistory = this.searchHistory.slice(-maxSize);
600
+ }
601
+ getTopTerms() {
602
+ const termCounts = /* @__PURE__ */ new Map();
603
+ for (const log of this.logs.slice(-1e3)) {
604
+ const words = log.message.toLowerCase().split(/\s+/);
605
+ for (const word of words) if (word.length > 3) termCounts.set(word, (termCounts.get(word) || 0) + 1);
606
+ }
607
+ return Array.from(termCounts.entries()).sort((a, b) => b[1] - a[1]).slice(0, 10).map(([term]) => term);
608
+ }
609
+ generateId() {
610
+ return `preset_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;
611
+ }
612
+ };
613
+
614
+ //#endregion
615
+ //#region src/search/engines/correlation-engine.ts
616
+ /**
617
+ * Correlation engine for log analysis
618
+ */
619
+ var CorrelationEngine = class {
620
+ constructor(options) {
621
+ this.options = options;
622
+ this.options = {
623
+ maxCorrelationDistance: 100,
624
+ temporalWindowMs: 300 * 1e3,
625
+ minSimilarityScore: .3,
626
+ ...options
627
+ };
628
+ }
629
+ /**
630
+ * Find logs related to a given log entry
631
+ */
632
+ async findRelatedLogs(log, allLogs, limit = 50) {
633
+ const related = [];
634
+ for (const otherLog of allLogs) {
635
+ if (otherLog === log) continue;
636
+ const relationships = this.findRelationships(log, otherLog);
637
+ for (const relationship of relationships) {
638
+ var _this$options;
639
+ const score = this.calculateRelationshipScore(relationship, log, otherLog);
640
+ if (score > (((_this$options = this.options) === null || _this$options === void 0 ? void 0 : _this$options.minSimilarityScore) || .3)) related.push({
641
+ log: otherLog,
642
+ relationship,
643
+ score
644
+ });
645
+ }
646
+ }
647
+ return this.deduplicateRelatedLogs(related).sort((a, b) => b.score - a.score).slice(0, limit);
648
+ }
649
+ /**
650
+ * Correlate logs by multiple criteria
651
+ */
652
+ async correlateByMultipleCriteria(logs, criteria) {
653
+ const correlations = /* @__PURE__ */ new Map();
654
+ if (criteria.traceId) {
655
+ const traceCorrelations = this.correlateByTraceId(logs);
656
+ for (const [key, value] of traceCorrelations) correlations.set(`trace_${key}`, value);
657
+ }
658
+ if (criteria.userId) {
659
+ const userCorrelations = this.correlateByUserId(logs);
660
+ for (const [key, value] of userCorrelations) correlations.set(`user_${key}`, value);
661
+ }
662
+ if (criteria.sessionId) {
663
+ const sessionCorrelations = this.correlateBySessionId(logs);
664
+ for (const [key, value] of sessionCorrelations) correlations.set(`session_${key}`, value);
665
+ }
666
+ if (criteria.temporal) {
667
+ const temporalCorrelations = this.correlateByTemporalProximity(logs);
668
+ for (const [key, value] of temporalCorrelations) correlations.set(`temporal_${key}`, value);
669
+ }
670
+ if (criteria.errorCascade) {
671
+ const errorCorrelations = this.correlateErrorCascades(logs);
672
+ for (const [key, value] of errorCorrelations) correlations.set(`error_${key}`, value);
673
+ }
674
+ return correlations;
675
+ }
676
+ /**
677
+ * Build a timeline from correlated logs
678
+ */
679
+ buildTimeline(logs) {
680
+ const timeline = [];
681
+ const sortedLogs = [...logs].sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
682
+ for (let i = 0; i < sortedLogs.length; i++) {
683
+ const log = sortedLogs[i];
684
+ const eventType = this.determineEventType(log, sortedLogs, i);
685
+ const event = {
686
+ timestamp: new Date(log.timestamp),
687
+ log,
688
+ eventType
689
+ };
690
+ if (eventType === "start" && i < sortedLogs.length - 1) {
691
+ const endEvent = sortedLogs.slice(i + 1).find((l) => this.determineEventType(l, sortedLogs, sortedLogs.indexOf(l)) === "end");
692
+ if (endEvent) event.duration = new Date(endEvent.timestamp).getTime() - new Date(log.timestamp).getTime();
693
+ }
694
+ timeline.push(event);
695
+ }
696
+ return timeline;
697
+ }
698
+ /**
699
+ * Analyze error cascades
700
+ */
701
+ async analyzeErrorCascade(logs) {
702
+ const errors = logs.filter((log) => log.level === "error");
703
+ if (errors.length === 0) return {
704
+ cascade: [],
705
+ impactedServices: []
706
+ };
707
+ const rootCause = errors.reduce((earliest, current) => new Date(current.timestamp) < new Date(earliest.timestamp) ? current : earliest);
708
+ const cascade = this.buildErrorCascade(rootCause, errors);
709
+ return {
710
+ rootCause,
711
+ cascade,
712
+ impactedServices: [...new Set(cascade.map((log) => log.appName))]
713
+ };
714
+ }
715
+ correlateByTraceId(logs) {
716
+ const correlations = /* @__PURE__ */ new Map();
717
+ for (const log of logs) {
718
+ if (!log.traceId) continue;
719
+ if (!correlations.has(log.traceId)) correlations.set(log.traceId, []);
720
+ correlations.get(log.traceId).push(log);
721
+ }
722
+ return this.convertToCorrelatedLogs(correlations, "trace");
723
+ }
724
+ correlateByUserId(logs) {
725
+ const correlations = /* @__PURE__ */ new Map();
726
+ for (const log of logs) {
727
+ var _log$payload;
728
+ const userId = (_log$payload = log.payload) === null || _log$payload === void 0 ? void 0 : _log$payload.userId;
729
+ if (!userId) continue;
730
+ if (!correlations.has(userId)) correlations.set(userId, []);
731
+ correlations.get(userId).push(log);
732
+ }
733
+ return this.convertToCorrelatedLogs(correlations, "user");
734
+ }
735
+ correlateBySessionId(logs) {
736
+ const correlations = /* @__PURE__ */ new Map();
737
+ for (const log of logs) {
738
+ var _log$payload2;
739
+ const sessionId = (_log$payload2 = log.payload) === null || _log$payload2 === void 0 ? void 0 : _log$payload2.sessionId;
740
+ if (!sessionId) continue;
741
+ if (!correlations.has(sessionId)) correlations.set(sessionId, []);
742
+ correlations.get(sessionId).push(log);
743
+ }
744
+ return this.convertToCorrelatedLogs(correlations, "session");
745
+ }
746
+ correlateByTemporalProximity(logs) {
747
+ const correlations = /* @__PURE__ */ new Map();
748
+ const sortedLogs = [...logs].sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
749
+ let currentGroup = [];
750
+ let groupStartTime = null;
751
+ for (const log of sortedLogs) {
752
+ var _this$options2;
753
+ const logTime = new Date(log.timestamp).getTime();
754
+ if (groupStartTime === null) {
755
+ groupStartTime = logTime;
756
+ currentGroup = [log];
757
+ } else if (logTime - groupStartTime <= (((_this$options2 = this.options) === null || _this$options2 === void 0 ? void 0 : _this$options2.temporalWindowMs) || 3e5)) currentGroup.push(log);
758
+ else {
759
+ if (currentGroup.length > 1) {
760
+ const groupKey = `${groupStartTime}`;
761
+ correlations.set(groupKey, currentGroup);
762
+ }
763
+ groupStartTime = logTime;
764
+ currentGroup = [log];
765
+ }
766
+ }
767
+ if (currentGroup.length > 1 && groupStartTime !== null) correlations.set(`${groupStartTime}`, currentGroup);
768
+ return this.convertToCorrelatedLogs(correlations, "temporal");
769
+ }
770
+ correlateErrorCascades(logs) {
771
+ const correlations = /* @__PURE__ */ new Map();
772
+ const errors = logs.filter((log) => log.level === "error");
773
+ for (const error of errors) {
774
+ const cascade = this.buildErrorCascade(error, logs);
775
+ if (cascade.length > 1) {
776
+ const key = `${error.timestamp}_${error.message.slice(0, 20)}`;
777
+ correlations.set(key, cascade);
778
+ }
779
+ }
780
+ return this.convertToCorrelatedLogs(correlations, "error_cascade");
781
+ }
782
+ buildErrorCascade(rootError, allLogs) {
783
+ var _this$options3;
784
+ const cascade = [rootError];
785
+ const rootTime = new Date(rootError.timestamp).getTime();
786
+ const windowMs = ((_this$options3 = this.options) === null || _this$options3 === void 0 ? void 0 : _this$options3.temporalWindowMs) || 3e5;
787
+ for (const log of allLogs) {
788
+ if (log === rootError) continue;
789
+ const timeDiff = new Date(log.timestamp).getTime() - rootTime;
790
+ if (timeDiff > 0 && timeDiff <= windowMs && (log.level === "error" || log.level === "warn") && (log.traceId === rootError.traceId || log.appName === rootError.appName)) cascade.push(log);
791
+ }
792
+ return cascade.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
793
+ }
794
+ findRelationships(log1, log2) {
795
+ var _log1$payload, _log2$payload, _log1$payload2, _log2$payload2, _this$options4, _this$options5;
796
+ const relationships = [];
797
+ if (log1.traceId && log1.traceId === log2.traceId) relationships.push("same_trace");
798
+ const user1 = (_log1$payload = log1.payload) === null || _log1$payload === void 0 ? void 0 : _log1$payload.userId;
799
+ const user2 = (_log2$payload = log2.payload) === null || _log2$payload === void 0 ? void 0 : _log2$payload.userId;
800
+ if (user1 && user1 === user2) relationships.push("same_user");
801
+ const session1 = (_log1$payload2 = log1.payload) === null || _log1$payload2 === void 0 ? void 0 : _log1$payload2.sessionId;
802
+ const session2 = (_log2$payload2 = log2.payload) === null || _log2$payload2 === void 0 ? void 0 : _log2$payload2.sessionId;
803
+ if (session1 && session1 === session2) relationships.push("same_session");
804
+ const time1 = new Date(log1.timestamp).getTime();
805
+ const time2 = new Date(log2.timestamp).getTime();
806
+ if (Math.abs(time1 - time2) <= (((_this$options4 = this.options) === null || _this$options4 === void 0 ? void 0 : _this$options4.temporalWindowMs) || 3e5)) relationships.push("temporal_proximity");
807
+ if ((log1.level === "error" || log2.level === "error") && time2 > time1 && time2 - time1 <= (((_this$options5 = this.options) === null || _this$options5 === void 0 ? void 0 : _this$options5.temporalWindowMs) || 3e5)) relationships.push("error_cascade");
808
+ if (this.haveSimilarPattern(log1, log2)) relationships.push("similar_pattern");
809
+ return relationships;
810
+ }
811
+ calculateRelationshipScore(relationship, log1, log2) {
812
+ let score = {
813
+ same_trace: .9,
814
+ same_user: .7,
815
+ same_session: .8,
816
+ temporal_proximity: .4,
817
+ error_cascade: .8,
818
+ similar_pattern: .5
819
+ }[relationship] || .3;
820
+ if (log1.appName === log2.appName) score += .1;
821
+ return Math.min(score, 1);
822
+ }
823
+ haveSimilarPattern(log1, log2) {
824
+ return this.normalizeMessage(log1.message) === this.normalizeMessage(log2.message);
825
+ }
826
+ normalizeMessage(message) {
827
+ return message.replace(/\d+/g, "<NUM>").replace(/[a-f0-9-]{36}/gi, "<UUID>").toLowerCase().trim();
828
+ }
829
+ determineEventType(log, _allLogs, _index) {
830
+ const message = log.message.toLowerCase();
831
+ if (message.includes("start") || message.includes("begin") || message.includes("initiated")) return "start";
832
+ if (message.includes("end") || message.includes("complete") || message.includes("finished")) return "end";
833
+ if (log.level === "error") return "error";
834
+ if (message.includes("milestone") || message.includes("checkpoint")) return "milestone";
835
+ return "info";
836
+ }
837
+ deduplicateRelatedLogs(related) {
838
+ const seen = /* @__PURE__ */ new Set();
839
+ const unique = [];
840
+ for (const item of related) if (!seen.has(item.log)) {
841
+ seen.add(item.log);
842
+ unique.push(item);
843
+ }
844
+ return unique;
845
+ }
846
+ convertToCorrelatedLogs(correlations, type) {
847
+ const result = /* @__PURE__ */ new Map();
848
+ for (const [key, logs] of correlations.entries()) {
849
+ if (logs.length < 2) continue;
850
+ const timeline = this.buildTimeline(logs);
851
+ const summary = this.generateSummary(logs);
852
+ result.set(key, {
853
+ correlationKey: key,
854
+ ...type === "trace" ? { traceId: key } : {},
855
+ logs,
856
+ timeline,
857
+ summary
858
+ });
859
+ }
860
+ return result;
861
+ }
862
+ generateSummary(logs) {
863
+ const errorCount = logs.filter((l) => l.level === "error").length;
864
+ const warningCount = logs.filter((l) => l.level === "warn").length;
865
+ const services = [...new Set(logs.map((l) => l.appName))];
866
+ let duration;
867
+ if (logs.length > 1) {
868
+ const sorted = [...logs].sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
869
+ const start = new Date(sorted[0].timestamp).getTime();
870
+ duration = new Date(sorted[sorted.length - 1].timestamp).getTime() - start;
871
+ }
872
+ return {
873
+ totalLogs: logs.length,
874
+ errorCount,
875
+ warningCount,
876
+ services,
877
+ ...duration !== void 0 ? { duration } : {}
878
+ };
879
+ }
880
+ };
881
+
882
+ //#endregion
883
+ //#region src/search/engines/nlp-search-engine.ts
884
+ /**
885
+ * NLP-enhanced search engine
886
+ */
887
+ var NLPSearchEngine = class extends BasicSearchEngine {
888
+ constructor(options) {
889
+ super(options);
890
+ this.initializePatterns();
891
+ }
892
+ /**
893
+ * Enhanced natural language query parsing
894
+ */
895
+ async parseNaturalLanguageQuery(query) {
896
+ const entities = [];
897
+ const filters = {};
898
+ const intent = this.detectIntent(query);
899
+ const extractedEntities = this.extractEntities(query);
900
+ entities.push(...extractedEntities);
901
+ for (const entity of entities) this.applyEntityToFilter(entity, filters);
902
+ const timeRange = this.extractAdvancedTimeRange(query);
903
+ if (timeRange) filters.timeRange = timeRange;
904
+ const confidence = this.calculateConfidence(intent, entities, query);
905
+ return {
906
+ originalQuery: query,
907
+ intent,
908
+ entities,
909
+ filters,
910
+ ...timeRange !== void 0 ? { timeRange } : {},
911
+ confidence
912
+ };
913
+ }
914
+ /**
915
+ * Enhanced natural language search
916
+ */
917
+ async naturalLanguageSearch(query) {
918
+ const parsed = await this.parseNaturalLanguageQuery(query);
919
+ const options = this.getOptionsForIntent(parsed.intent);
920
+ const cleanQuery = this.extractCleanQuery(query, parsed.entities);
921
+ return this.search(cleanQuery, parsed.filters, options);
922
+ }
923
+ initializePatterns() {
924
+ this.intentPatterns = new Map([
925
+ ["find_errors", [
926
+ /show.*errors?/i,
927
+ /find.*errors?/i,
928
+ /all.*errors?/i,
929
+ /errors?\s+(?:in|from|for)/i,
930
+ /what.*went wrong/i,
931
+ /failures?/i
932
+ ]],
933
+ ["trace_request", [
934
+ /trace\s+(?:request|id)/i,
935
+ /follow\s+request/i,
936
+ /track\s+request/i,
937
+ /request\s+(?:flow|path)/i,
938
+ /trace.*across/i
939
+ ]],
940
+ ["find_user_activity", [
941
+ /user\s+(?:\w+|id)/i,
942
+ /activity\s+(?:for|of)\s+user/i,
943
+ /what\s+did\s+user/i,
944
+ /user\s+journey/i,
945
+ /user\s+session/i
946
+ ]],
947
+ ["performance_analysis", [
948
+ /slow\s+(?:queries?|requests?|operations?)/i,
949
+ /performance\s+issues?/i,
950
+ /latency/i,
951
+ /response\s+time/i,
952
+ /took\s+(?:too\s+)?long/i
953
+ ]],
954
+ ["time_range_query", [
955
+ /(?:in|during|from)\s+the\s+last/i,
956
+ /(?:today|yesterday|this\s+week)/i,
957
+ /between.*and/i,
958
+ /in\s+the\s+past/i
959
+ ]],
960
+ ["correlation", [
961
+ /related\s+to/i,
962
+ /connected\s+with/i,
963
+ /caused\s+by/i,
964
+ /before.*happened/i,
965
+ /after.*occurred/i
966
+ ]]
967
+ ]);
968
+ this.entityPatterns = new Map([
969
+ ["level", /(error|warn|warning|info|debug|trace|verbose)/i],
970
+ ["service", /(?:from|in)\s+(?:the\s+)?(\w+)\s+(?:service|app|application)/i],
971
+ ["user_id", /user\s+(?:id\s+)?['"]?(\w+)['"]?/i],
972
+ ["trace_id", /trace\s+(?:id\s+)?['"]?([\w-]+)['"]?/i],
973
+ ["time", /(?:last|past|previous)\s+(\d+)\s+(second|minute|hour|day|week)s?/i],
974
+ ["error_type", /(\w+Error|\w+Exception)/i]
975
+ ]);
976
+ }
977
+ detectIntent(query) {
978
+ let maxScore = 0;
979
+ let detectedIntent = "general_search";
980
+ for (const [intent, patterns] of this.intentPatterns.entries()) {
981
+ let score = 0;
982
+ for (const pattern of patterns) if (pattern.test(query)) score++;
983
+ if (score > maxScore) {
984
+ maxScore = score;
985
+ detectedIntent = intent;
986
+ }
987
+ }
988
+ return detectedIntent;
989
+ }
990
+ extractEntities(query) {
991
+ const entities = [];
992
+ for (const [type, pattern] of this.entityPatterns.entries()) {
993
+ const matches = query.matchAll(new RegExp(pattern, "gi"));
994
+ for (const match of matches) {
995
+ const value = match[1] || match[0];
996
+ entities.push({
997
+ type,
998
+ value: value.trim(),
999
+ confidence: .8
1000
+ });
1001
+ }
1002
+ }
1003
+ return entities;
1004
+ }
1005
+ applyEntityToFilter(entity, filters) {
1006
+ switch (entity.type) {
1007
+ case "level":
1008
+ if (!filters.levels) filters.levels = [];
1009
+ filters.levels.push(entity.value.toLowerCase());
1010
+ break;
1011
+ case "service":
1012
+ if (!filters.services) filters.services = [];
1013
+ filters.services.push(entity.value);
1014
+ break;
1015
+ case "user_id":
1016
+ if (!filters.userIds) filters.userIds = [];
1017
+ filters.userIds.push(entity.value);
1018
+ break;
1019
+ case "trace_id":
1020
+ if (!filters.traceIds) filters.traceIds = [];
1021
+ filters.traceIds.push(entity.value);
1022
+ break;
1023
+ case "error_type": break;
1024
+ }
1025
+ }
1026
+ extractAdvancedTimeRange(query) {
1027
+ const lowerQuery = query.toLowerCase();
1028
+ for (const { pattern, unit } of [
1029
+ {
1030
+ pattern: /last\s+(\d+)\s+second/i,
1031
+ unit: "seconds"
1032
+ },
1033
+ {
1034
+ pattern: /last\s+(\d+)\s+minute/i,
1035
+ unit: "minutes"
1036
+ },
1037
+ {
1038
+ pattern: /last\s+(\d+)\s+hour/i,
1039
+ unit: "hours"
1040
+ },
1041
+ {
1042
+ pattern: /last\s+(\d+)\s+day/i,
1043
+ unit: "days"
1044
+ }
1045
+ ]) {
1046
+ const match = query.match(pattern);
1047
+ if (match) {
1048
+ const value = Number.parseInt(match[1] ?? "0");
1049
+ const multiplier = {
1050
+ seconds: 1e3,
1051
+ minutes: 60 * 1e3,
1052
+ hours: 3600 * 1e3,
1053
+ days: 1440 * 60 * 1e3
1054
+ }[unit];
1055
+ return {
1056
+ start: new Date(Date.now() - value * multiplier),
1057
+ relative: {
1058
+ value,
1059
+ unit
1060
+ }
1061
+ };
1062
+ }
1063
+ }
1064
+ if (lowerQuery.includes("today")) {
1065
+ const today = /* @__PURE__ */ new Date();
1066
+ today.setHours(0, 0, 0, 0);
1067
+ return { start: today };
1068
+ }
1069
+ if (lowerQuery.includes("yesterday")) {
1070
+ const yesterday = /* @__PURE__ */ new Date();
1071
+ yesterday.setDate(yesterday.getDate() - 1);
1072
+ yesterday.setHours(0, 0, 0, 0);
1073
+ const endOfYesterday = new Date(yesterday);
1074
+ endOfYesterday.setHours(23, 59, 59, 999);
1075
+ return {
1076
+ start: yesterday,
1077
+ end: endOfYesterday
1078
+ };
1079
+ }
1080
+ if (lowerQuery.includes("this week")) {
1081
+ const now = /* @__PURE__ */ new Date();
1082
+ const startOfWeek = new Date(now);
1083
+ startOfWeek.setDate(now.getDate() - now.getDay());
1084
+ startOfWeek.setHours(0, 0, 0, 0);
1085
+ return { start: startOfWeek };
1086
+ }
1087
+ }
1088
+ calculateConfidence(intent, entities, query) {
1089
+ let confidence = .5;
1090
+ if (intent !== "general_search") confidence += .2;
1091
+ confidence += Math.min(entities.length * .1, .3);
1092
+ const wordCount = query.split(/\s+/).length;
1093
+ if (wordCount < 3 || wordCount > 20) confidence -= .1;
1094
+ return Math.max(0, Math.min(1, confidence));
1095
+ }
1096
+ getOptionsForIntent(intent) {
1097
+ const baseOptions = {
1098
+ limit: 100,
1099
+ highlightMatches: true
1100
+ };
1101
+ switch (intent) {
1102
+ case "find_errors": return {
1103
+ ...baseOptions,
1104
+ includeContext: true,
1105
+ contextSize: 3,
1106
+ findSimilar: true
1107
+ };
1108
+ case "trace_request": return {
1109
+ ...baseOptions,
1110
+ includeContext: true,
1111
+ contextSize: 10,
1112
+ correlate: true,
1113
+ sortBy: "timestamp",
1114
+ sortOrder: "asc"
1115
+ };
1116
+ case "find_user_activity": return {
1117
+ ...baseOptions,
1118
+ includeContext: true,
1119
+ sortBy: "timestamp",
1120
+ sortOrder: "asc",
1121
+ limit: 200
1122
+ };
1123
+ case "performance_analysis": return {
1124
+ ...baseOptions,
1125
+ includeContext: true,
1126
+ contextSize: 5,
1127
+ sortBy: "timestamp"
1128
+ };
1129
+ case "correlation": return {
1130
+ ...baseOptions,
1131
+ includeContext: true,
1132
+ contextSize: 5,
1133
+ correlate: true,
1134
+ findSimilar: true
1135
+ };
1136
+ default: return baseOptions;
1137
+ }
1138
+ }
1139
+ extractCleanQuery(query, entities) {
1140
+ let cleanQuery = query;
1141
+ for (const entity of entities) cleanQuery = cleanQuery.replace(new RegExp(`\\b${entity.value}\\b`, "gi"), "");
1142
+ for (const word of [
1143
+ "show",
1144
+ "find",
1145
+ "get",
1146
+ "all",
1147
+ "from",
1148
+ "in",
1149
+ "the",
1150
+ "for",
1151
+ "with",
1152
+ "last",
1153
+ "past",
1154
+ "today",
1155
+ "yesterday",
1156
+ "service",
1157
+ "user",
1158
+ "trace",
1159
+ "error",
1160
+ "errors"
1161
+ ]) cleanQuery = cleanQuery.replace(new RegExp(`\\b${word}\\b`, "gi"), "");
1162
+ cleanQuery = cleanQuery.replace(/\s+/g, " ").trim();
1163
+ return cleanQuery || query;
1164
+ }
1165
+ };
1166
+
1167
+ //#endregion
1168
+ //#region src/search/engines/pattern-recognition-engine.ts
1169
+ /**
1170
+ * Pattern recognition engine for log analysis
1171
+ */
1172
+ var PatternRecognitionEngine = class {
1173
+ constructor(options) {
1174
+ this.options = options;
1175
+ this.patterns = /* @__PURE__ */ new Map();
1176
+ this.patternFrequencies = /* @__PURE__ */ new Map();
1177
+ this.options = {
1178
+ minFrequency: 3,
1179
+ maxPatterns: 1e3,
1180
+ anomalyThreshold: .3,
1181
+ ...options
1182
+ };
1183
+ }
1184
+ /**
1185
+ * Analyze logs and detect patterns
1186
+ */
1187
+ async analyzePatterns(logs) {
1188
+ var _this$options2;
1189
+ const messagePatterns = this.extractMessagePatterns(logs);
1190
+ const errorPatterns = this.extractErrorPatterns(logs);
1191
+ const timingPatterns = this.extractTimingPatterns(logs);
1192
+ const frequentPatterns = [
1193
+ ...messagePatterns,
1194
+ ...errorPatterns,
1195
+ ...timingPatterns
1196
+ ].filter((p) => {
1197
+ var _this$options;
1198
+ return p.frequency >= (((_this$options = this.options) === null || _this$options === void 0 ? void 0 : _this$options.minFrequency) || 3);
1199
+ });
1200
+ frequentPatterns.sort((a, b) => b.frequency - a.frequency);
1201
+ const limitedPatterns = frequentPatterns.slice(0, ((_this$options2 = this.options) === null || _this$options2 === void 0 ? void 0 : _this$options2.maxPatterns) || 1e3);
1202
+ for (const pattern of limitedPatterns) this.patterns.set(pattern.id, pattern);
1203
+ return limitedPatterns;
1204
+ }
1205
+ /**
1206
+ * Detect anomalies in logs
1207
+ */
1208
+ async detectAnomalies(logs) {
1209
+ const anomalies = [];
1210
+ for (const log of logs) {
1211
+ var _this$options3;
1212
+ const anomalyScore = await this.calculateAnomalyScore(log);
1213
+ if (anomalyScore > (((_this$options3 = this.options) === null || _this$options3 === void 0 ? void 0 : _this$options3.anomalyThreshold) || .3)) anomalies.push({
1214
+ log,
1215
+ anomalyScore,
1216
+ reason: this.generateAnomalyReason(log, anomalyScore),
1217
+ deviations: this.findDeviations(log)
1218
+ });
1219
+ }
1220
+ return anomalies.sort((a, b) => b.anomalyScore - a.anomalyScore);
1221
+ }
1222
+ /**
1223
+ * Find patterns matching a log entry
1224
+ */
1225
+ findMatchingPatterns(log) {
1226
+ const matching = [];
1227
+ for (const pattern of this.patterns.values()) if (this.doesLogMatchPattern(log, pattern)) matching.push(pattern);
1228
+ return matching;
1229
+ }
1230
+ /**
1231
+ * Get all detected patterns
1232
+ */
1233
+ getPatterns() {
1234
+ return Array.from(this.patterns.values());
1235
+ }
1236
+ /**
1237
+ * Get pattern by ID
1238
+ */
1239
+ getPattern(patternId) {
1240
+ return this.patterns.get(patternId);
1241
+ }
1242
+ extractMessagePatterns(logs) {
1243
+ const patternMap = /* @__PURE__ */ new Map();
1244
+ for (const log of logs) {
1245
+ const normalizedMessage = this.normalizeMessage(log.message);
1246
+ if (!patternMap.has(normalizedMessage)) patternMap.set(normalizedMessage, {
1247
+ examples: [],
1248
+ count: 0
1249
+ });
1250
+ const pattern = patternMap.get(normalizedMessage);
1251
+ if (pattern.examples.length < 3) pattern.examples.push(log);
1252
+ pattern.count++;
1253
+ }
1254
+ return Array.from(patternMap.entries()).map(([pattern, data], index) => {
1255
+ var _data$examples;
1256
+ return {
1257
+ id: `msg_pattern_${index}`,
1258
+ pattern,
1259
+ examples: data.examples,
1260
+ frequency: data.count,
1261
+ lastSeen: ((_data$examples = data.examples[data.examples.length - 1]) === null || _data$examples === void 0 ? void 0 : _data$examples.timestamp) ? new Date(data.examples[data.examples.length - 1].timestamp) : /* @__PURE__ */ new Date(),
1262
+ category: "message"
1263
+ };
1264
+ });
1265
+ }
1266
+ extractErrorPatterns(logs) {
1267
+ const errorLogs = logs.filter((log) => log.level === "error" || log.error);
1268
+ const patternMap = /* @__PURE__ */ new Map();
1269
+ for (const log of errorLogs) {
1270
+ const errorPattern = this.extractErrorPattern(log);
1271
+ if (!patternMap.has(errorPattern)) patternMap.set(errorPattern, {
1272
+ examples: [],
1273
+ count: 0
1274
+ });
1275
+ const pattern = patternMap.get(errorPattern);
1276
+ if (pattern.examples.length < 3) pattern.examples.push(log);
1277
+ pattern.count++;
1278
+ }
1279
+ return Array.from(patternMap.entries()).map(([pattern, data], index) => {
1280
+ var _data$examples2;
1281
+ return {
1282
+ id: `error_pattern_${index}`,
1283
+ pattern,
1284
+ examples: data.examples,
1285
+ frequency: data.count,
1286
+ lastSeen: ((_data$examples2 = data.examples[data.examples.length - 1]) === null || _data$examples2 === void 0 ? void 0 : _data$examples2.timestamp) ? new Date(data.examples[data.examples.length - 1].timestamp) : /* @__PURE__ */ new Date(),
1287
+ category: "error",
1288
+ severity: "high"
1289
+ };
1290
+ });
1291
+ }
1292
+ extractTimingPatterns(logs) {
1293
+ const patterns = [];
1294
+ const hourCounts = /* @__PURE__ */ new Map();
1295
+ for (const log of logs) {
1296
+ const hour = new Date(log.timestamp).getHours();
1297
+ hourCounts.set(hour, (hourCounts.get(hour) || 0) + 1);
1298
+ }
1299
+ const peakHour = Array.from(hourCounts.entries()).sort((a, b) => b[1] - a[1])[0];
1300
+ if (peakHour) patterns.push({
1301
+ id: "timing_peak",
1302
+ pattern: `Peak activity at hour ${peakHour[0]}`,
1303
+ examples: logs.slice(0, 3),
1304
+ frequency: peakHour[1],
1305
+ lastSeen: /* @__PURE__ */ new Date(),
1306
+ category: "timing"
1307
+ });
1308
+ return patterns;
1309
+ }
1310
+ normalizeMessage(message) {
1311
+ return message.replace(/\d+/g, "<NUM>").replace(/[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/gi, "<UUID>").replace(/[a-f0-9]{32}/gi, "<HASH>").replace(/"[^"]*"/g, "<STRING>").replace(/\b\w+@\w+\.\w+\b/g, "<EMAIL>").trim();
1312
+ }
1313
+ extractErrorPattern(log) {
1314
+ if (log.error) return `${log.error.name}: ${this.normalizeMessage(log.error.message || "")}`;
1315
+ return this.normalizeMessage(log.message);
1316
+ }
1317
+ async calculateAnomalyScore(log) {
1318
+ let score = 0;
1319
+ if (this.findMatchingPatterns(log).length === 0) score += .3;
1320
+ if (log.level === "error") {
1321
+ const errorPattern = this.extractErrorPattern(log);
1322
+ if ((this.patternFrequencies.get(errorPattern) || 0) < 2) score += .3;
1323
+ }
1324
+ const hour = new Date(log.timestamp).getHours();
1325
+ if (hour < 6 || hour > 22) score += .2;
1326
+ return Math.min(score, 1);
1327
+ }
1328
+ generateAnomalyReason(log, score) {
1329
+ const reasons = [];
1330
+ if (score > .7) reasons.push("Highly unusual log entry");
1331
+ else if (score > .5) reasons.push("Moderately unusual log entry");
1332
+ else reasons.push("Slightly unusual log entry");
1333
+ if (this.findMatchingPatterns(log).length === 0) reasons.push("does not match any known patterns");
1334
+ if (log.level === "error") reasons.push("rare error type");
1335
+ const hour = new Date(log.timestamp).getHours();
1336
+ if (hour < 6 || hour > 22) reasons.push("occurred during off-hours");
1337
+ return reasons.join(", ");
1338
+ }
1339
+ findDeviations(log) {
1340
+ const deviations = [];
1341
+ if (!log.traceId) deviations.push("Missing trace ID");
1342
+ if (!log.context) deviations.push("Missing context");
1343
+ if (log.payload && Object.keys(log.payload).length > 20) deviations.push("Unusually large payload");
1344
+ if (log.level !== "error" && log.message.includes("at ")) deviations.push("Stack trace in non-error log");
1345
+ return deviations;
1346
+ }
1347
+ doesLogMatchPattern(log, pattern) {
1348
+ const normalizedMessage = this.normalizeMessage(log.message);
1349
+ if (pattern.regex) return pattern.regex.test(log.message);
1350
+ return normalizedMessage === pattern.pattern;
1351
+ }
1352
+ };
1353
+
1354
+ //#endregion
1355
+ //#region src/search/search-manager.ts
1356
+ /**
1357
+ * Main search manager class
1358
+ */
1359
+ var SearchManager = class {
1360
+ constructor(config) {
1361
+ this.config = {
1362
+ enableNLP: true,
1363
+ enablePatternRecognition: true,
1364
+ enableCorrelation: true,
1365
+ maxIndexSize: 1e6,
1366
+ autoOptimize: true,
1367
+ ...config
1368
+ };
1369
+ this.searchEngine = this.config.enableNLP ? new NLPSearchEngine() : new BasicSearchEngine();
1370
+ this.indexer = new BasicLogIndexer({
1371
+ maxIndexSize: this.config.maxIndexSize,
1372
+ autoOptimize: this.config.autoOptimize
1373
+ });
1374
+ if (this.config.enablePatternRecognition) this.patternEngine = new PatternRecognitionEngine();
1375
+ if (this.config.enableCorrelation) this.correlationEngine = new CorrelationEngine();
1376
+ }
1377
+ /**
1378
+ * Index new logs
1379
+ */
1380
+ async indexLogs(logs) {
1381
+ await this.indexer.indexBatch(logs);
1382
+ this.searchEngine.addLogs(logs);
1383
+ if (this.patternEngine && logs.length > 10) await this.patternEngine.analyzePatterns(logs);
1384
+ }
1385
+ /**
1386
+ * Add a single log to the index
1387
+ */
1388
+ async indexLog(log) {
1389
+ await this.indexer.indexLog(log);
1390
+ this.searchEngine.addLogs([log]);
1391
+ }
1392
+ /**
1393
+ * Perform a search
1394
+ */
1395
+ async search(query, filters, options) {
1396
+ return this.searchEngine.search(query, filters, options);
1397
+ }
1398
+ /**
1399
+ * Perform a natural language search
1400
+ */
1401
+ async naturalLanguageSearch(query) {
1402
+ return this.searchEngine.naturalLanguageSearch(query);
1403
+ }
1404
+ /**
1405
+ * Find logs correlated by trace ID
1406
+ */
1407
+ async correlateByTraceId(traceId) {
1408
+ return this.searchEngine.correlateByTraceId(traceId);
1409
+ }
1410
+ /**
1411
+ * Find similar logs
1412
+ */
1413
+ async findSimilarLogs(logEntry, limit) {
1414
+ return this.searchEngine.findSimilarLogs(logEntry, limit);
1415
+ }
1416
+ /**
1417
+ * Find logs related to a given log
1418
+ */
1419
+ async findRelatedLogs(log, limit) {
1420
+ if (!this.correlationEngine) throw new Error("Correlation engine not enabled");
1421
+ const allLogs = this.searchEngine.getLogs();
1422
+ return this.correlationEngine.findRelatedLogs(log, allLogs, limit);
1423
+ }
1424
+ /**
1425
+ * Get search suggestions
1426
+ */
1427
+ async getSuggestions(partialQuery, limit) {
1428
+ return this.searchEngine.getSuggestions(partialQuery, limit);
1429
+ }
1430
+ /**
1431
+ * Get search statistics
1432
+ */
1433
+ async getStats() {
1434
+ return this.searchEngine.getStats();
1435
+ }
1436
+ /**
1437
+ * Parse natural language query
1438
+ */
1439
+ async parseNaturalLanguageQuery(query) {
1440
+ return this.searchEngine.parseNaturalLanguageQuery(query);
1441
+ }
1442
+ /**
1443
+ * Save a search preset
1444
+ */
1445
+ async savePreset(preset) {
1446
+ return this.searchEngine.savePreset(preset);
1447
+ }
1448
+ /**
1449
+ * Get saved presets
1450
+ */
1451
+ async getPresets(userId) {
1452
+ return this.searchEngine.getPresets(userId);
1453
+ }
1454
+ /**
1455
+ * Delete a preset
1456
+ */
1457
+ async deletePreset(presetId) {
1458
+ return this.searchEngine.deletePreset(presetId);
1459
+ }
1460
+ /**
1461
+ * Detect log patterns
1462
+ */
1463
+ async detectPatterns() {
1464
+ if (!this.patternEngine) throw new Error("Pattern recognition not enabled");
1465
+ const allLogs = this.searchEngine.getLogs();
1466
+ return this.patternEngine.analyzePatterns(allLogs);
1467
+ }
1468
+ /**
1469
+ * Get detected patterns
1470
+ */
1471
+ getPatterns() {
1472
+ if (!this.patternEngine) return [];
1473
+ return this.patternEngine.getPatterns();
1474
+ }
1475
+ /**
1476
+ * Detect anomalies in logs
1477
+ */
1478
+ async detectAnomalies() {
1479
+ if (!this.patternEngine) throw new Error("Pattern recognition not enabled");
1480
+ const allLogs = this.searchEngine.getLogs();
1481
+ return this.patternEngine.detectAnomalies(allLogs);
1482
+ }
1483
+ /**
1484
+ * Correlate logs by multiple criteria
1485
+ */
1486
+ async correlateByMultipleCriteria(criteria) {
1487
+ if (!this.correlationEngine) throw new Error("Correlation engine not enabled");
1488
+ const allLogs = this.searchEngine.getLogs();
1489
+ return this.correlationEngine.correlateByMultipleCriteria(allLogs, criteria);
1490
+ }
1491
+ /**
1492
+ * Analyze error cascades
1493
+ */
1494
+ async analyzeErrorCascade(traceId) {
1495
+ if (!this.correlationEngine) throw new Error("Correlation engine not enabled");
1496
+ const correlated = await this.correlateByTraceId(traceId);
1497
+ return this.correlationEngine.analyzeErrorCascade(correlated.logs);
1498
+ }
1499
+ /**
1500
+ * Export search results
1501
+ */
1502
+ async exportResults(results, options) {
1503
+ switch (options.format) {
1504
+ case "json": return this.exportAsJSON(results, options);
1505
+ case "csv": return this.exportAsCSV(results, options);
1506
+ case "text": return this.exportAsText(results, options);
1507
+ default: throw new Error(`Unsupported export format: ${options.format}`);
1508
+ }
1509
+ }
1510
+ /**
1511
+ * Clear all indexed data
1512
+ */
1513
+ async clearIndex() {
1514
+ await this.indexer.clearIndex();
1515
+ this.searchEngine.clearLogs();
1516
+ }
1517
+ /**
1518
+ * Optimize the index
1519
+ */
1520
+ async optimizeIndex() {
1521
+ await this.indexer.optimizeIndex();
1522
+ }
1523
+ /**
1524
+ * Get index statistics
1525
+ */
1526
+ async getIndexStats() {
1527
+ return this.indexer.getIndexStats();
1528
+ }
1529
+ /**
1530
+ * Remove old logs
1531
+ */
1532
+ async removeOldLogs(olderThan) {
1533
+ const removed = await this.indexer.removeOldLogs(olderThan);
1534
+ const filteredLogs = this.searchEngine.getLogs().filter((log) => new Date(log.timestamp) >= olderThan);
1535
+ this.searchEngine.clearLogs();
1536
+ this.searchEngine.addLogs(filteredLogs);
1537
+ return removed;
1538
+ }
1539
+ exportAsJSON(results, options) {
1540
+ const data = options.includeMetadata ? results : results.map((r) => r.log);
1541
+ if (options.fields) return JSON.stringify(data.map((item) => this.filterFields(item, options.fields)), null, 2);
1542
+ return JSON.stringify(data, null, 2);
1543
+ }
1544
+ exportAsCSV(results, options) {
1545
+ const logs = results.map((r) => r.log);
1546
+ if (logs.length === 0) return "";
1547
+ const fields = options.fields || [
1548
+ "timestamp",
1549
+ "level",
1550
+ "appName",
1551
+ "message"
1552
+ ];
1553
+ return [fields.join(","), ...logs.map((log) => {
1554
+ return fields.map((field) => {
1555
+ const value = log[field];
1556
+ return this.escapeCSVValue(value);
1557
+ }).join(",");
1558
+ })].join("\n");
1559
+ }
1560
+ exportAsText(results, options) {
1561
+ return results.map((result) => {
1562
+ const log = result.log;
1563
+ let text = `[${log.timestamp}] [${log.level.toUpperCase()}] ${log.appName}: ${log.message}`;
1564
+ if (options.includeMetadata) {
1565
+ text += `\n Score: ${result.score.toFixed(2)}`;
1566
+ if (result.highlights) text += `\n Matches: ${result.highlights.length}`;
1567
+ }
1568
+ return text;
1569
+ }).join("\n\n");
1570
+ }
1571
+ filterFields(obj, fields) {
1572
+ const filtered = {};
1573
+ for (const field of fields) if (obj !== null && typeof obj === "object" && field in obj) filtered[field] = obj[field];
1574
+ else if (field.includes(".")) {
1575
+ const value = this.getNestedValue(obj, field);
1576
+ if (value !== void 0) filtered[field] = value;
1577
+ }
1578
+ return filtered;
1579
+ }
1580
+ getNestedValue(obj, path) {
1581
+ return path.split(".").reduce((current, key) => {
1582
+ if (current !== null && typeof current === "object") return current[key];
1583
+ return current;
1584
+ }, obj);
1585
+ }
1586
+ escapeCSVValue(value) {
1587
+ if (value === null || value === void 0) return "";
1588
+ const str = typeof value === "object" ? JSON.stringify(value) : String(value);
1589
+ if (str.includes(",") || str.includes("\n") || str.includes("\"")) return `"${str.replace(/"/g, "\"\"")}"`;
1590
+ return str;
1591
+ }
1592
+ };
1593
+
1594
+ //#endregion
1595
+ Object.defineProperty(exports, 'BasicLogIndexer', {
1596
+ enumerable: true,
1597
+ get: function () {
1598
+ return BasicLogIndexer;
1599
+ }
1600
+ });
1601
+ Object.defineProperty(exports, 'BasicSearchEngine', {
1602
+ enumerable: true,
1603
+ get: function () {
1604
+ return BasicSearchEngine;
1605
+ }
1606
+ });
1607
+ Object.defineProperty(exports, 'CorrelationEngine', {
1608
+ enumerable: true,
1609
+ get: function () {
1610
+ return CorrelationEngine;
1611
+ }
1612
+ });
1613
+ Object.defineProperty(exports, 'NLPSearchEngine', {
1614
+ enumerable: true,
1615
+ get: function () {
1616
+ return NLPSearchEngine;
1617
+ }
1618
+ });
1619
+ Object.defineProperty(exports, 'PatternRecognitionEngine', {
1620
+ enumerable: true,
1621
+ get: function () {
1622
+ return PatternRecognitionEngine;
1623
+ }
1624
+ });
1625
+ Object.defineProperty(exports, 'SearchManager', {
1626
+ enumerable: true,
1627
+ get: function () {
1628
+ return SearchManager;
1629
+ }
1630
+ });
1631
+ //# sourceMappingURL=search-njTI2hdo.js.map