resolve-solo 1.2.1 → 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +46 -5
- package/dist/cli.js.map +1 -1
- package/dist/handlers.d.ts +4 -0
- package/dist/handlers.d.ts.map +1 -1
- package/dist/handlers.js +44 -0
- package/dist/handlers.js.map +1 -1
- package/dist/investigation-engine/task-definitions.d.ts +1 -1
- package/dist/investigation-engine/task-definitions.d.ts.map +1 -1
- package/dist/investigation-engine/task-definitions.js +144 -99
- package/dist/investigation-engine/task-definitions.js.map +1 -1
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +6 -0
- package/dist/parser.js.map +1 -1
- package/dist/query-parser.d.ts +33 -0
- package/dist/query-parser.d.ts.map +1 -0
- package/dist/query-parser.js +328 -0
- package/dist/query-parser.js.map +1 -0
- package/dist/realistic-findings.d.ts.map +1 -1
- package/dist/realistic-findings.js +178 -7
- package/dist/realistic-findings.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Natural Language Query Parser
|
|
3
|
+
*
|
|
4
|
+
* Extracts entities, intent, and context from investigation queries.
|
|
5
|
+
*/
|
|
6
|
+
// Common service name patterns
|
|
7
|
+
const KNOWN_SERVICES = [
|
|
8
|
+
'api-gateway', 'api gateway', 'apigateway',
|
|
9
|
+
'payment-service', 'payment service', 'payments',
|
|
10
|
+
'auth-service', 'auth service', 'authentication',
|
|
11
|
+
'config-service', 'config service',
|
|
12
|
+
'user-service', 'user service', 'users',
|
|
13
|
+
'order-service', 'order service', 'orders',
|
|
14
|
+
'notification-service', 'notification service', 'notifications',
|
|
15
|
+
'brokerage', 'brokerage-service', 'brokerage service',
|
|
16
|
+
'financing', 'financing-service', 'financing service',
|
|
17
|
+
'portfolio', 'portfolio-service', 'portfolio service',
|
|
18
|
+
'trading', 'trading-service', 'trading service',
|
|
19
|
+
'redis', 'redis-cache', 'cache',
|
|
20
|
+
'postgres', 'postgresql', 'database', 'db',
|
|
21
|
+
'kafka', 'message-queue', 'mq',
|
|
22
|
+
'kubernetes', 'k8s',
|
|
23
|
+
'nginx', 'load-balancer', 'lb',
|
|
24
|
+
];
|
|
25
|
+
// Normalize service names to canonical form
|
|
26
|
+
const SERVICE_ALIASES = {
|
|
27
|
+
'api gateway': 'api-gateway',
|
|
28
|
+
'apigateway': 'api-gateway',
|
|
29
|
+
'payment service': 'payment-service',
|
|
30
|
+
'payments': 'payment-service',
|
|
31
|
+
'auth service': 'auth-service',
|
|
32
|
+
'authentication': 'auth-service',
|
|
33
|
+
'config service': 'config-service',
|
|
34
|
+
'user service': 'user-service',
|
|
35
|
+
'users': 'user-service',
|
|
36
|
+
'order service': 'order-service',
|
|
37
|
+
'orders': 'order-service',
|
|
38
|
+
'notification service': 'notification-service',
|
|
39
|
+
'notifications': 'notification-service',
|
|
40
|
+
'brokerage service': 'brokerage-service',
|
|
41
|
+
'brokerage': 'brokerage-service',
|
|
42
|
+
'financing service': 'financing-service',
|
|
43
|
+
'financing': 'financing-service',
|
|
44
|
+
'portfolio service': 'portfolio-service',
|
|
45
|
+
'portfolio': 'portfolio-service',
|
|
46
|
+
'trading service': 'trading-service',
|
|
47
|
+
'trading': 'trading-service',
|
|
48
|
+
'redis-cache': 'redis',
|
|
49
|
+
'cache': 'redis',
|
|
50
|
+
'postgresql': 'postgres',
|
|
51
|
+
'database': 'postgres',
|
|
52
|
+
'db': 'postgres',
|
|
53
|
+
'message-queue': 'kafka',
|
|
54
|
+
'mq': 'kafka',
|
|
55
|
+
'k8s': 'kubernetes',
|
|
56
|
+
'load-balancer': 'nginx',
|
|
57
|
+
'lb': 'nginx',
|
|
58
|
+
};
|
|
59
|
+
// Intent detection patterns
|
|
60
|
+
const INTENT_PATTERNS = [
|
|
61
|
+
// Help/meta queries
|
|
62
|
+
{ pattern: /what can i ask|what.*available|help me|what.*resolve/i, intent: 'help' },
|
|
63
|
+
// Logs
|
|
64
|
+
{ pattern: /error logs?|show.*logs?|logs? for/i, intent: 'logs' },
|
|
65
|
+
{ pattern: /errors? in|exceptions?|stack trace/i, intent: 'logs' },
|
|
66
|
+
// Metrics
|
|
67
|
+
{ pattern: /latency|throughput|p99|p95|p50|response time/i, intent: 'metrics' },
|
|
68
|
+
{ pattern: /metrics?|trends?|performance/i, intent: 'metrics' },
|
|
69
|
+
{ pattern: /error rate|success rate|availability/i, intent: 'metrics' },
|
|
70
|
+
// Changes
|
|
71
|
+
{ pattern: /code changes?|what changed|changes? (to|in|for)/i, intent: 'changes' },
|
|
72
|
+
{ pattern: /commits?|pull requests?|prs?|merged/i, intent: 'changes' },
|
|
73
|
+
// Deployments
|
|
74
|
+
{ pattern: /deploy(ed|ment|s)?|released?|rolled out/i, intent: 'deployments' },
|
|
75
|
+
{ pattern: /what.*shipped|went (live|out)/i, intent: 'deployments' },
|
|
76
|
+
// Dependencies - check before config since "config-service" contains "config"
|
|
77
|
+
{ pattern: /depend(s|encies|ency)?(\s+on)?|upstream|downstream/i, intent: 'dependencies' },
|
|
78
|
+
{ pattern: /what.*calls?|connects? to|uses?/i, intent: 'dependencies' },
|
|
79
|
+
// Config - be specific to avoid matching service names like "config-service"
|
|
80
|
+
{ pattern: /config(uration)?\s+(changes?|history|settings?)/i, intent: 'config' },
|
|
81
|
+
{ pattern: /kubernetes|k8s|helm|yaml/i, intent: 'config' },
|
|
82
|
+
{ pattern: /\bsettings?\b|\benvironment\b|env vars?/i, intent: 'config' },
|
|
83
|
+
];
|
|
84
|
+
// Time range patterns
|
|
85
|
+
const TIME_PATTERNS = [
|
|
86
|
+
{ pattern: /past (\d+) hours?/i, hours: -1, description: '' }, // Dynamic
|
|
87
|
+
{ pattern: /last (\d+) hours?/i, hours: -1, description: '' },
|
|
88
|
+
{ pattern: /past (\d+) days?/i, hours: -1, description: '' },
|
|
89
|
+
{ pattern: /last (\d+) days?/i, hours: -1, description: '' },
|
|
90
|
+
{ pattern: /past (\d+) weeks?/i, hours: -1, description: '' },
|
|
91
|
+
{ pattern: /last (\d+) weeks?/i, hours: -1, description: '' },
|
|
92
|
+
{ pattern: /today/i, hours: 24, description: 'today' },
|
|
93
|
+
{ pattern: /yesterday/i, hours: 48, description: 'since yesterday' },
|
|
94
|
+
{ pattern: /this week/i, hours: 168, description: 'this week' },
|
|
95
|
+
{ pattern: /last week/i, hours: 336, description: 'last week' },
|
|
96
|
+
];
|
|
97
|
+
// Date patterns like "January 23rd", "Jan 23", "2024-01-23"
|
|
98
|
+
const SPECIFIC_DATE_PATTERN = /(?:january|february|march|april|may|june|july|august|september|october|november|december|jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\s+\d{1,2}(?:st|nd|rd|th)?(?:,?\s*\d{4})?|\d{4}-\d{2}-\d{2}/i;
|
|
99
|
+
// Environment patterns
|
|
100
|
+
const ENVIRONMENT_PATTERNS = [
|
|
101
|
+
{ pattern: /\bprod(uction)?\b/i, env: 'production' },
|
|
102
|
+
{ pattern: /\bstag(ing|e)?\b/i, env: 'staging' },
|
|
103
|
+
{ pattern: /\bdev(elopment)?\b/i, env: 'development' },
|
|
104
|
+
{ pattern: /\btest(ing)?\b/i, env: 'testing' },
|
|
105
|
+
];
|
|
106
|
+
/**
|
|
107
|
+
* Parse a natural language query into structured components
|
|
108
|
+
*/
|
|
109
|
+
export function parseQuery(query) {
|
|
110
|
+
const lowerQuery = query.toLowerCase();
|
|
111
|
+
return {
|
|
112
|
+
intent: detectIntent(lowerQuery),
|
|
113
|
+
services: extractServices(lowerQuery),
|
|
114
|
+
timeRange: extractTimeRange(query),
|
|
115
|
+
environment: extractEnvironment(lowerQuery),
|
|
116
|
+
keywords: extractKeywords(lowerQuery),
|
|
117
|
+
originalQuery: query,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Detect the primary intent of the query
|
|
122
|
+
*/
|
|
123
|
+
function detectIntent(query) {
|
|
124
|
+
for (const { pattern, intent } of INTENT_PATTERNS) {
|
|
125
|
+
if (pattern.test(query)) {
|
|
126
|
+
return intent;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return 'investigate'; // Default to general investigation
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Extract service names from the query
|
|
133
|
+
*/
|
|
134
|
+
function extractServices(query) {
|
|
135
|
+
const found = new Set();
|
|
136
|
+
for (const service of KNOWN_SERVICES) {
|
|
137
|
+
if (query.includes(service.toLowerCase())) {
|
|
138
|
+
// Normalize to canonical name
|
|
139
|
+
const canonical = SERVICE_ALIASES[service] || service;
|
|
140
|
+
found.add(canonical);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// If no services found, return empty (will use context or default)
|
|
144
|
+
return Array.from(found);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Extract time range from the query
|
|
148
|
+
*/
|
|
149
|
+
function extractTimeRange(query) {
|
|
150
|
+
const lowerQuery = query.toLowerCase();
|
|
151
|
+
// Check for specific date mentions
|
|
152
|
+
const dateMatch = SPECIFIC_DATE_PATTERN.exec(query);
|
|
153
|
+
if (dateMatch) {
|
|
154
|
+
const parsedDate = parseSpecificDate(dateMatch[0]);
|
|
155
|
+
if (parsedDate) {
|
|
156
|
+
const now = new Date();
|
|
157
|
+
const hours = Math.ceil((now.getTime() - parsedDate.getTime()) / (1000 * 60 * 60));
|
|
158
|
+
return {
|
|
159
|
+
description: `since ${dateMatch[0]}`,
|
|
160
|
+
startDate: parsedDate,
|
|
161
|
+
endDate: now,
|
|
162
|
+
hours: Math.max(hours, 24), // At least 24 hours
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
// Check for relative time patterns
|
|
167
|
+
for (const { pattern } of TIME_PATTERNS) {
|
|
168
|
+
const match = pattern.exec(lowerQuery);
|
|
169
|
+
if (match) {
|
|
170
|
+
const num = parseInt(match[1]) || 1;
|
|
171
|
+
let hours;
|
|
172
|
+
let description;
|
|
173
|
+
if (/hours?/.test(match[0])) {
|
|
174
|
+
hours = num;
|
|
175
|
+
description = `past ${num} hour${num > 1 ? 's' : ''}`;
|
|
176
|
+
}
|
|
177
|
+
else if (/days?/.test(match[0])) {
|
|
178
|
+
hours = num * 24;
|
|
179
|
+
description = `past ${num} day${num > 1 ? 's' : ''}`;
|
|
180
|
+
}
|
|
181
|
+
else if (/weeks?/.test(match[0])) {
|
|
182
|
+
hours = num * 168;
|
|
183
|
+
description = `past ${num} week${num > 1 ? 's' : ''}`;
|
|
184
|
+
}
|
|
185
|
+
else if (/today/.test(match[0])) {
|
|
186
|
+
hours = 24;
|
|
187
|
+
description = 'today';
|
|
188
|
+
}
|
|
189
|
+
else if (/yesterday/.test(match[0])) {
|
|
190
|
+
hours = 48;
|
|
191
|
+
description = 'since yesterday';
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
hours = 48;
|
|
195
|
+
description = 'past 2 days';
|
|
196
|
+
}
|
|
197
|
+
const now = new Date();
|
|
198
|
+
return {
|
|
199
|
+
description,
|
|
200
|
+
startDate: new Date(now.getTime() - hours * 60 * 60 * 1000),
|
|
201
|
+
endDate: now,
|
|
202
|
+
hours,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
// Default: last 48 hours
|
|
207
|
+
const now = new Date();
|
|
208
|
+
return {
|
|
209
|
+
description: 'past 48 hours',
|
|
210
|
+
startDate: new Date(now.getTime() - 48 * 60 * 60 * 1000),
|
|
211
|
+
endDate: now,
|
|
212
|
+
hours: 48,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Parse a specific date string
|
|
217
|
+
*/
|
|
218
|
+
function parseSpecificDate(dateStr) {
|
|
219
|
+
try {
|
|
220
|
+
// Handle "January 23rd" format
|
|
221
|
+
const cleaned = dateStr.replace(/(st|nd|rd|th)/i, '');
|
|
222
|
+
const parsed = new Date(cleaned);
|
|
223
|
+
if (!isNaN(parsed.getTime())) {
|
|
224
|
+
// If no year specified, assume current year
|
|
225
|
+
if (!/\d{4}/.test(dateStr)) {
|
|
226
|
+
parsed.setFullYear(new Date().getFullYear());
|
|
227
|
+
}
|
|
228
|
+
return parsed;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
catch {
|
|
232
|
+
// Fall through
|
|
233
|
+
}
|
|
234
|
+
return null;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Extract environment from the query
|
|
238
|
+
*/
|
|
239
|
+
function extractEnvironment(query) {
|
|
240
|
+
for (const { pattern, env } of ENVIRONMENT_PATTERNS) {
|
|
241
|
+
if (pattern.test(query)) {
|
|
242
|
+
return env;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return undefined;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Extract keywords for search
|
|
249
|
+
*/
|
|
250
|
+
function extractKeywords(query) {
|
|
251
|
+
// Remove common words and extract meaningful terms
|
|
252
|
+
const stopWords = new Set([
|
|
253
|
+
'show', 'me', 'the', 'a', 'an', 'in', 'on', 'for', 'to', 'of', 'and', 'or',
|
|
254
|
+
'what', 'which', 'where', 'when', 'how', 'why', 'is', 'are', 'was', 'were',
|
|
255
|
+
'has', 'have', 'had', 'been', 'be', 'being', 'do', 'does', 'did', 'doing',
|
|
256
|
+
'can', 'could', 'would', 'should', 'will', 'shall', 'may', 'might', 'must',
|
|
257
|
+
'past', 'last', 'recent', 'latest', 'new', 'old', 'first', 'second',
|
|
258
|
+
'days', 'day', 'hours', 'hour', 'minutes', 'minute', 'weeks', 'week',
|
|
259
|
+
]);
|
|
260
|
+
const words = query.toLowerCase().split(/\s+/);
|
|
261
|
+
return words.filter(word => word.length > 2 &&
|
|
262
|
+
!stopWords.has(word) &&
|
|
263
|
+
!/^\d+$/.test(word));
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Generate a human-readable interpretation of the parsed query
|
|
267
|
+
*/
|
|
268
|
+
export function describeQuery(parsed) {
|
|
269
|
+
const parts = [];
|
|
270
|
+
// Intent
|
|
271
|
+
const intentDescriptions = {
|
|
272
|
+
investigate: 'Investigating',
|
|
273
|
+
logs: 'Searching logs for',
|
|
274
|
+
metrics: 'Analyzing metrics for',
|
|
275
|
+
changes: 'Finding changes in',
|
|
276
|
+
deployments: 'Checking deployments for',
|
|
277
|
+
dependencies: 'Mapping dependencies of',
|
|
278
|
+
config: 'Reviewing configuration for',
|
|
279
|
+
help: 'Available queries',
|
|
280
|
+
};
|
|
281
|
+
parts.push(intentDescriptions[parsed.intent]);
|
|
282
|
+
// Services
|
|
283
|
+
if (parsed.services.length > 0) {
|
|
284
|
+
parts.push(parsed.services.join(', '));
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
parts.push('all services');
|
|
288
|
+
}
|
|
289
|
+
// Environment
|
|
290
|
+
if (parsed.environment) {
|
|
291
|
+
parts.push(`in ${parsed.environment}`);
|
|
292
|
+
}
|
|
293
|
+
// Time range
|
|
294
|
+
parts.push(`(${parsed.timeRange.description})`);
|
|
295
|
+
return parts.join(' ');
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Get available query examples based on connected data sources
|
|
299
|
+
*/
|
|
300
|
+
export function getAvailableQueries() {
|
|
301
|
+
return [
|
|
302
|
+
// Logs
|
|
303
|
+
'Show me error logs for [service-name] in the past 2 days',
|
|
304
|
+
'What errors occurred in production yesterday?',
|
|
305
|
+
// Metrics
|
|
306
|
+
'Show me latency trends for [service-name] in the past 24 hours',
|
|
307
|
+
'What is the error rate for [service-name]?',
|
|
308
|
+
'Show me p99 latency for the API gateway',
|
|
309
|
+
// Changes
|
|
310
|
+
'What code changes were deployed to [service-name] on [date]?',
|
|
311
|
+
'Show me recent commits to the payment service',
|
|
312
|
+
'What changed in the last 2 hours?',
|
|
313
|
+
// Deployments
|
|
314
|
+
'What was deployed to production today?',
|
|
315
|
+
'Show me deployment history for [service-name]',
|
|
316
|
+
// Config
|
|
317
|
+
'Show me Kubernetes configuration changes in production',
|
|
318
|
+
'What config changes happened in the past week?',
|
|
319
|
+
// Dependencies
|
|
320
|
+
'What services depend on [service-name]?',
|
|
321
|
+
'What does [service-name] connect to?',
|
|
322
|
+
// General investigation
|
|
323
|
+
'Investigate timeouts on [service-name]',
|
|
324
|
+
'Why is [service-name] slow?',
|
|
325
|
+
'Debug connection errors in [service-name]',
|
|
326
|
+
];
|
|
327
|
+
}
|
|
328
|
+
//# sourceMappingURL=query-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-parser.js","sourceRoot":"","sources":["../src/query-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"realistic-findings.d.ts","sourceRoot":"","sources":["../src/realistic-findings.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAA4B,UAAU,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAC/G,OAAO,EAAE,QAAQ,EAAwB,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"realistic-findings.d.ts","sourceRoot":"","sources":["../src/realistic-findings.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAA4B,UAAU,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAC/G,OAAO,EAAE,QAAQ,EAAwB,MAAM,sBAAsB,CAAC;AAItE,UAAU,uBAAuB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,iBAAiB,EACvB,OAAO,EAAE,uBAAuB,GAC/B,UAAU,CAsEZ"}
|
|
@@ -5,19 +5,17 @@
|
|
|
5
5
|
* commits, and realistic metrics data.
|
|
6
6
|
*/
|
|
7
7
|
import { SeededRandom } from './seeded-random.js';
|
|
8
|
+
import { parseQuery } from './query-parser.js';
|
|
8
9
|
/**
|
|
9
10
|
* Generate realistic findings for a task based on mock repo context
|
|
10
11
|
*/
|
|
11
12
|
export function generateRealisticFindings(task, context) {
|
|
12
13
|
const random = new SeededRandom(context.seed + hashString(task.id));
|
|
13
14
|
const findings = [];
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
targetService = 'payment-service';
|
|
19
|
-
if (queryLower.includes('auth'))
|
|
20
|
-
targetService = 'auth-service';
|
|
15
|
+
// Parse query for context-aware findings
|
|
16
|
+
const parsed = parseQuery(context.query);
|
|
17
|
+
const targetService = parsed.services[0] || 'api-gateway';
|
|
18
|
+
const timeRange = parsed.timeRange;
|
|
21
19
|
switch (task.id) {
|
|
22
20
|
case 'task-git-scan':
|
|
23
21
|
findings.push(...generateGitFindings(context.repo, targetService, random));
|
|
@@ -49,6 +47,15 @@ export function generateRealisticFindings(task, context) {
|
|
|
49
47
|
case 'task-ticket-search':
|
|
50
48
|
findings.push(...generateTicketFindings(targetService, context.query, random));
|
|
51
49
|
break;
|
|
50
|
+
case 'task-error-logs':
|
|
51
|
+
findings.push(...generateErrorLogFindings(targetService, timeRange, random));
|
|
52
|
+
break;
|
|
53
|
+
case 'task-config-changes':
|
|
54
|
+
findings.push(...generateConfigFindings(targetService, timeRange, random));
|
|
55
|
+
break;
|
|
56
|
+
case 'task-dependencies':
|
|
57
|
+
findings.push(...generateDependencyFindings(targetService, random));
|
|
58
|
+
break;
|
|
52
59
|
}
|
|
53
60
|
return {
|
|
54
61
|
findings,
|
|
@@ -575,6 +582,170 @@ function generateTicketFindings(service, query, random) {
|
|
|
575
582
|
});
|
|
576
583
|
return findings;
|
|
577
584
|
}
|
|
585
|
+
/**
|
|
586
|
+
* Generate error log findings
|
|
587
|
+
*/
|
|
588
|
+
function generateErrorLogFindings(service, timeRange, random) {
|
|
589
|
+
const findings = [];
|
|
590
|
+
const errorTypes = [
|
|
591
|
+
{ type: 'NullPointerException', severity: 'P1', count: Math.round(random.next() * 50) + 10 },
|
|
592
|
+
{ type: 'ConnectionTimeout', severity: 'P1', count: Math.round(random.next() * 30) + 5 },
|
|
593
|
+
{ type: 'AuthenticationError', severity: 'P2', count: Math.round(random.next() * 20) + 2 },
|
|
594
|
+
{ type: 'RateLimitExceeded', severity: 'P2', count: Math.round(random.next() * 15) + 1 },
|
|
595
|
+
];
|
|
596
|
+
const primaryError = errorTypes[Math.floor(random.next() * errorTypes.length)];
|
|
597
|
+
findings.push({
|
|
598
|
+
priority: primaryError.severity,
|
|
599
|
+
title: `Logs: ${primaryError.count} ${primaryError.type} errors (${timeRange.description})`,
|
|
600
|
+
description: `Found ${primaryError.count} instances of ${primaryError.type} in ${service} logs`,
|
|
601
|
+
service,
|
|
602
|
+
source: 'cloudwatch',
|
|
603
|
+
category: 'errors',
|
|
604
|
+
evidence: [
|
|
605
|
+
`Error type: ${primaryError.type}`,
|
|
606
|
+
`Count: ${primaryError.count} in ${timeRange.description}`,
|
|
607
|
+
`First occurrence: ${Math.round(random.next() * timeRange.hours)}h ago`,
|
|
608
|
+
`Last occurrence: ${Math.round(random.next() * 2)}h ago`,
|
|
609
|
+
],
|
|
610
|
+
suggestedAction: `Investigate ${primaryError.type} in ${service} - check recent code changes`,
|
|
611
|
+
});
|
|
612
|
+
// Summary finding
|
|
613
|
+
const totalErrors = errorTypes.reduce((sum, e) => sum + e.count, 0);
|
|
614
|
+
findings.push({
|
|
615
|
+
priority: 'P3',
|
|
616
|
+
title: `Logs: ${totalErrors} total errors in ${service} (${timeRange.description})`,
|
|
617
|
+
description: `Error breakdown across ${errorTypes.length} error types`,
|
|
618
|
+
service,
|
|
619
|
+
source: 'cloudwatch',
|
|
620
|
+
category: 'errors',
|
|
621
|
+
evidence: errorTypes.map(e => `${e.type}: ${e.count}`),
|
|
622
|
+
suggestedAction: 'Review error distribution for patterns',
|
|
623
|
+
});
|
|
624
|
+
return findings;
|
|
625
|
+
}
|
|
626
|
+
/**
|
|
627
|
+
* Generate Kubernetes/config change findings
|
|
628
|
+
*/
|
|
629
|
+
function generateConfigFindings(service, timeRange, random) {
|
|
630
|
+
const findings = [];
|
|
631
|
+
const configChanges = [
|
|
632
|
+
{ resource: 'Deployment', field: 'replicas', oldValue: '3', newValue: '5' },
|
|
633
|
+
{ resource: 'ConfigMap', field: 'MAX_CONNECTIONS', oldValue: '100', newValue: '200' },
|
|
634
|
+
{ resource: 'HPA', field: 'maxReplicas', oldValue: '10', newValue: '15' },
|
|
635
|
+
{ resource: 'Ingress', field: 'rate-limit', oldValue: '1000/s', newValue: '500/s' },
|
|
636
|
+
];
|
|
637
|
+
const change = configChanges[Math.floor(random.next() * configChanges.length)];
|
|
638
|
+
const hoursAgo = Math.round(random.next() * Math.min(timeRange.hours, 24)) + 1;
|
|
639
|
+
findings.push({
|
|
640
|
+
priority: 'P2',
|
|
641
|
+
title: `K8s: ${change.resource} changed ${hoursAgo}h ago`,
|
|
642
|
+
description: `${service} ${change.resource} ${change.field} changed from ${change.oldValue} to ${change.newValue}`,
|
|
643
|
+
service,
|
|
644
|
+
source: 'kubernetes',
|
|
645
|
+
category: 'configuration',
|
|
646
|
+
evidence: [
|
|
647
|
+
`Resource: ${change.resource}/${service}`,
|
|
648
|
+
`Field: ${change.field}`,
|
|
649
|
+
`Change: ${change.oldValue} → ${change.newValue}`,
|
|
650
|
+
`Changed by: platform-bot via ArgoCD`,
|
|
651
|
+
`Time: ${hoursAgo}h ago`,
|
|
652
|
+
],
|
|
653
|
+
suggestedAction: `Review if ${change.resource} change correlates with the issue`,
|
|
654
|
+
});
|
|
655
|
+
// Helm release info
|
|
656
|
+
findings.push({
|
|
657
|
+
priority: 'P3',
|
|
658
|
+
title: `K8s: ${service} running helm chart v2.4.1`,
|
|
659
|
+
description: 'Current deployment configuration summary',
|
|
660
|
+
service,
|
|
661
|
+
source: 'kubernetes',
|
|
662
|
+
category: 'configuration',
|
|
663
|
+
evidence: [
|
|
664
|
+
'Chart version: 2.4.1',
|
|
665
|
+
'Replicas: 5/5 ready',
|
|
666
|
+
'Last rollout: succeeded',
|
|
667
|
+
'Image: registry.company.com/' + service + ':v1.42.0',
|
|
668
|
+
],
|
|
669
|
+
suggestedAction: 'No action needed - deployment is healthy',
|
|
670
|
+
});
|
|
671
|
+
return findings;
|
|
672
|
+
}
|
|
673
|
+
/**
|
|
674
|
+
* Generate service dependency findings
|
|
675
|
+
*/
|
|
676
|
+
function generateDependencyFindings(service, random) {
|
|
677
|
+
const findings = [];
|
|
678
|
+
// Define service dependency graph
|
|
679
|
+
const dependencyGraph = {
|
|
680
|
+
'api-gateway': {
|
|
681
|
+
upstream: ['nginx', 'cloudflare'],
|
|
682
|
+
downstream: ['auth-service', 'user-service', 'order-service', 'payment-service'],
|
|
683
|
+
},
|
|
684
|
+
'payment-service': {
|
|
685
|
+
upstream: ['api-gateway', 'order-service'],
|
|
686
|
+
downstream: ['stripe-api', 'postgres', 'kafka'],
|
|
687
|
+
},
|
|
688
|
+
'auth-service': {
|
|
689
|
+
upstream: ['api-gateway'],
|
|
690
|
+
downstream: ['redis', 'postgres', 'okta-api'],
|
|
691
|
+
},
|
|
692
|
+
'config-service': {
|
|
693
|
+
upstream: ['api-gateway'],
|
|
694
|
+
downstream: ['consul', 'vault'],
|
|
695
|
+
},
|
|
696
|
+
'brokerage-service': {
|
|
697
|
+
upstream: ['api-gateway', 'trading-service'],
|
|
698
|
+
downstream: ['market-data-api', 'postgres', 'kafka'],
|
|
699
|
+
},
|
|
700
|
+
'financing-service': {
|
|
701
|
+
upstream: ['api-gateway', 'portfolio-service'],
|
|
702
|
+
downstream: ['risk-engine', 'postgres', 'kafka'],
|
|
703
|
+
},
|
|
704
|
+
'portfolio-service': {
|
|
705
|
+
upstream: ['api-gateway', 'trading-service'],
|
|
706
|
+
downstream: ['postgres', 'redis', 'kafka'],
|
|
707
|
+
},
|
|
708
|
+
};
|
|
709
|
+
const deps = dependencyGraph[service] || {
|
|
710
|
+
upstream: ['api-gateway'],
|
|
711
|
+
downstream: ['postgres', 'redis'],
|
|
712
|
+
};
|
|
713
|
+
findings.push({
|
|
714
|
+
priority: 'P3',
|
|
715
|
+
title: `Dependencies: ${service} dependency map`,
|
|
716
|
+
description: `${deps.upstream.length} upstream, ${deps.downstream.length} downstream dependencies`,
|
|
717
|
+
service,
|
|
718
|
+
source: 'service-mesh',
|
|
719
|
+
category: 'configuration',
|
|
720
|
+
evidence: [
|
|
721
|
+
`Upstream (calls ${service}): ${deps.upstream.join(', ')}`,
|
|
722
|
+
`Downstream (${service} calls): ${deps.downstream.join(', ')}`,
|
|
723
|
+
'Source: Service mesh telemetry',
|
|
724
|
+
],
|
|
725
|
+
suggestedAction: 'Check downstream services for cascading failures',
|
|
726
|
+
});
|
|
727
|
+
// Health status of dependencies
|
|
728
|
+
const unhealthyDep = deps.downstream[Math.floor(random.next() * deps.downstream.length)];
|
|
729
|
+
const isUnhealthy = random.next() > 0.6;
|
|
730
|
+
if (isUnhealthy) {
|
|
731
|
+
findings.push({
|
|
732
|
+
priority: 'P2',
|
|
733
|
+
title: `Dependencies: ${unhealthyDep} showing elevated latency`,
|
|
734
|
+
description: `Downstream dependency ${unhealthyDep} has p99 latency of 850ms (threshold: 500ms)`,
|
|
735
|
+
service: unhealthyDep,
|
|
736
|
+
source: 'service-mesh',
|
|
737
|
+
category: 'latency',
|
|
738
|
+
evidence: [
|
|
739
|
+
`Dependency: ${unhealthyDep}`,
|
|
740
|
+
'P99 latency: 850ms',
|
|
741
|
+
'Error rate: 0.5%',
|
|
742
|
+
`Impact: May affect ${service} response times`,
|
|
743
|
+
],
|
|
744
|
+
suggestedAction: `Investigate ${unhealthyDep} as potential root cause`,
|
|
745
|
+
});
|
|
746
|
+
}
|
|
747
|
+
return findings;
|
|
748
|
+
}
|
|
578
749
|
// Helper functions
|
|
579
750
|
function determinePriority(message, random) {
|
|
580
751
|
const msg = message.toLowerCase();
|