@mcp-consultant-tools/log-analytics 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/LogAnalyticsService.d.ts +117 -0
- package/build/LogAnalyticsService.d.ts.map +1 -0
- package/build/LogAnalyticsService.js +410 -0
- package/build/LogAnalyticsService.js.map +1 -0
- package/build/index.d.ts +5 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +17 -0
- package/build/index.js.map +1 -0
- package/build/utils/loganalytics-formatters.d.ts +68 -0
- package/build/utils/loganalytics-formatters.d.ts.map +1 -0
- package/build/utils/loganalytics-formatters.js +372 -0
- package/build/utils/loganalytics-formatters.js.map +1 -0
- package/package.json +25 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
export interface LogAnalyticsResourceConfig {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
workspaceId: string;
|
|
5
|
+
active: boolean;
|
|
6
|
+
apiKey?: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface LogAnalyticsConfig {
|
|
10
|
+
resources: LogAnalyticsResourceConfig[];
|
|
11
|
+
tenantId?: string;
|
|
12
|
+
clientId?: string;
|
|
13
|
+
clientSecret?: string;
|
|
14
|
+
authMethod: 'entra-id' | 'api-key';
|
|
15
|
+
}
|
|
16
|
+
export interface QueryResult {
|
|
17
|
+
tables: {
|
|
18
|
+
name: string;
|
|
19
|
+
columns: {
|
|
20
|
+
name: string;
|
|
21
|
+
type: string;
|
|
22
|
+
}[];
|
|
23
|
+
rows: any[][];
|
|
24
|
+
}[];
|
|
25
|
+
}
|
|
26
|
+
export interface MetadataResult {
|
|
27
|
+
tables: {
|
|
28
|
+
name: string;
|
|
29
|
+
columns: {
|
|
30
|
+
name: string;
|
|
31
|
+
type: string;
|
|
32
|
+
description?: string;
|
|
33
|
+
}[];
|
|
34
|
+
}[];
|
|
35
|
+
}
|
|
36
|
+
export declare class LogAnalyticsService {
|
|
37
|
+
private config;
|
|
38
|
+
private msalClient;
|
|
39
|
+
private accessToken;
|
|
40
|
+
private tokenExpirationTime;
|
|
41
|
+
private readonly baseUrl;
|
|
42
|
+
constructor(config: LogAnalyticsConfig);
|
|
43
|
+
/**
|
|
44
|
+
* Get access token for Log Analytics API using Microsoft Entra ID OAuth
|
|
45
|
+
* Implements token caching with 5-minute buffer before expiry
|
|
46
|
+
*/
|
|
47
|
+
private getAccessToken;
|
|
48
|
+
/**
|
|
49
|
+
* Get authorization headers based on authentication method
|
|
50
|
+
*/
|
|
51
|
+
private getAuthHeaders;
|
|
52
|
+
/**
|
|
53
|
+
* Execute a KQL query against a Log Analytics workspace
|
|
54
|
+
*/
|
|
55
|
+
executeQuery(resourceId: string, query: string, timespan?: string): Promise<QueryResult>;
|
|
56
|
+
/**
|
|
57
|
+
* Get workspace metadata (schema)
|
|
58
|
+
*/
|
|
59
|
+
getMetadata(resourceId: string): Promise<MetadataResult>;
|
|
60
|
+
/**
|
|
61
|
+
* Test workspace access by executing a simple query
|
|
62
|
+
*/
|
|
63
|
+
testWorkspaceAccess(resourceId: string): Promise<{
|
|
64
|
+
success: boolean;
|
|
65
|
+
message: string;
|
|
66
|
+
details?: any;
|
|
67
|
+
}>;
|
|
68
|
+
/**
|
|
69
|
+
* Get recent events from any table
|
|
70
|
+
*/
|
|
71
|
+
getRecentEvents(resourceId: string, tableName: string, timespan?: string, limit?: number): Promise<QueryResult>;
|
|
72
|
+
/**
|
|
73
|
+
* Search logs across tables or specific table
|
|
74
|
+
*/
|
|
75
|
+
searchLogs(resourceId: string, searchText: string, tableName?: string, timespan?: string, limit?: number): Promise<QueryResult>;
|
|
76
|
+
/**
|
|
77
|
+
* Get Azure Function logs from FunctionAppLogs table
|
|
78
|
+
*/
|
|
79
|
+
getFunctionLogs(resourceId: string, functionName?: string, timespan?: string, severityLevel?: number, limit?: number): Promise<QueryResult>;
|
|
80
|
+
/**
|
|
81
|
+
* Get Azure Function errors
|
|
82
|
+
*/
|
|
83
|
+
getFunctionErrors(resourceId: string, functionName?: string, timespan?: string, limit?: number): Promise<QueryResult>;
|
|
84
|
+
/**
|
|
85
|
+
* Get Azure Function execution statistics
|
|
86
|
+
*/
|
|
87
|
+
getFunctionStats(resourceId: string, functionName?: string, timespan?: string): Promise<QueryResult>;
|
|
88
|
+
/**
|
|
89
|
+
* Get Azure Function invocations from traces or requests table
|
|
90
|
+
*/
|
|
91
|
+
getFunctionInvocations(resourceId: string, functionName?: string, timespan?: string, limit?: number): Promise<QueryResult>;
|
|
92
|
+
/**
|
|
93
|
+
* Get all configured resources
|
|
94
|
+
*/
|
|
95
|
+
getAllResources(): LogAnalyticsResourceConfig[];
|
|
96
|
+
/**
|
|
97
|
+
* Get only active resources
|
|
98
|
+
*/
|
|
99
|
+
getActiveResources(): LogAnalyticsResourceConfig[];
|
|
100
|
+
/**
|
|
101
|
+
* Get resource by ID and validate it's active
|
|
102
|
+
*/
|
|
103
|
+
getResourceById(resourceId: string): LogAnalyticsResourceConfig;
|
|
104
|
+
/**
|
|
105
|
+
* Convert ISO 8601 duration to KQL timespan format
|
|
106
|
+
* PT1H -> 1h, P1D -> 1d, PT30M -> 30m, etc.
|
|
107
|
+
*/
|
|
108
|
+
convertTimespanToKQL(iso8601Duration: string): string;
|
|
109
|
+
/**
|
|
110
|
+
* Validate KQL query (basic check)
|
|
111
|
+
*/
|
|
112
|
+
validateQuery(query: string): {
|
|
113
|
+
valid: boolean;
|
|
114
|
+
error?: string;
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=LogAnalyticsService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LogAnalyticsService.d.ts","sourceRoot":"","sources":["../src/LogAnalyticsService.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,0BAA0B;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,0BAA0B,EAAE,CAAC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,UAAU,GAAG,SAAS,CAAC;CACpC;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAC1C,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC;KACf,EAAE,CAAC;CACL;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,WAAW,CAAC,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;KACjE,EAAE,CAAC;CACL;AAED,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,UAAU,CAA8C;IAChE,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,mBAAmB,CAAa;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoC;gBAEhD,MAAM,EAAE,kBAAkB;IAmBtC;;;OAGG;YACW,cAAc;IA+B5B;;OAEG;YACW,cAAc;IAoB5B;;OAEG;IACG,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IA6E9F;;OAEG;IACG,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAkB9D;;OAEG;IACG,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IA2B5G;;OAEG;IACG,eAAe,CACnB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,QAAQ,GAAE,MAAe,EACzB,KAAK,GAAE,MAAY,GAClB,OAAO,CAAC,WAAW,CAAC;IAWvB;;OAEG;IACG,UAAU,CACd,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,MAAM,EAClB,QAAQ,GAAE,MAAe,EACzB,KAAK,GAAE,MAAY,GAClB,OAAO,CAAC,WAAW,CAAC;IAavB;;OAEG;IACG,eAAe,CACnB,UAAU,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,MAAM,EACrB,QAAQ,GAAE,MAAe,EACzB,aAAa,CAAC,EAAE,MAAM,EACtB,KAAK,GAAE,MAAY,GAClB,OAAO,CAAC,WAAW,CAAC;IAuBvB;;OAEG;IACG,iBAAiB,CACrB,UAAU,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,MAAM,EACrB,QAAQ,GAAE,MAAe,EACzB,KAAK,GAAE,MAAY,GAClB,OAAO,CAAC,WAAW,CAAC;IAoBvB;;OAEG;IACG,gBAAgB,CACpB,UAAU,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,MAAM,EACrB,QAAQ,GAAE,MAAe,GACxB,OAAO,CAAC,WAAW,CAAC;IAiCvB;;OAEG;IACG,sBAAsB,CAC1B,UAAU,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,MAAM,EACrB,QAAQ,GAAE,MAAe,EACzB,KAAK,GAAE,MAAY,GAClB,OAAO,CAAC,WAAW,CAAC;IAoBvB;;OAEG;IACH,eAAe,IAAI,0BAA0B,EAAE;IAI/C;;OAEG;IACH,kBAAkB,IAAI,0BAA0B,EAAE;IAIlD;;OAEG;IACH,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,0BAA0B;IAmB/D;;;OAGG;IACH,oBAAoB,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM;IAwCrD;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;CAoBjE"}
|
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
import { ConfidentialClientApplication } from '@azure/msal-node';
|
|
2
|
+
import axios from 'axios';
|
|
3
|
+
export class LogAnalyticsService {
|
|
4
|
+
config;
|
|
5
|
+
msalClient = null;
|
|
6
|
+
accessToken = null;
|
|
7
|
+
tokenExpirationTime = 0;
|
|
8
|
+
baseUrl = 'https://api.loganalytics.io/v1';
|
|
9
|
+
constructor(config) {
|
|
10
|
+
this.config = config;
|
|
11
|
+
// Initialize MSAL client if using Entra ID auth
|
|
12
|
+
if (this.config.authMethod === 'entra-id') {
|
|
13
|
+
if (!this.config.tenantId || !this.config.clientId || !this.config.clientSecret) {
|
|
14
|
+
throw new Error('Entra ID authentication requires tenantId, clientId, and clientSecret');
|
|
15
|
+
}
|
|
16
|
+
this.msalClient = new ConfidentialClientApplication({
|
|
17
|
+
auth: {
|
|
18
|
+
clientId: this.config.clientId,
|
|
19
|
+
clientSecret: this.config.clientSecret,
|
|
20
|
+
authority: `https://login.microsoftonline.com/${this.config.tenantId}`,
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Get access token for Log Analytics API using Microsoft Entra ID OAuth
|
|
27
|
+
* Implements token caching with 5-minute buffer before expiry
|
|
28
|
+
*/
|
|
29
|
+
async getAccessToken() {
|
|
30
|
+
if (!this.msalClient) {
|
|
31
|
+
throw new Error('MSAL client not initialized. Use Entra ID authentication method.');
|
|
32
|
+
}
|
|
33
|
+
// Return cached token if still valid (with 5-minute buffer)
|
|
34
|
+
const currentTime = Date.now();
|
|
35
|
+
const bufferTime = 5 * 60 * 1000; // 5 minutes in milliseconds
|
|
36
|
+
if (this.accessToken && this.tokenExpirationTime > currentTime + bufferTime) {
|
|
37
|
+
return this.accessToken;
|
|
38
|
+
}
|
|
39
|
+
// Acquire new token
|
|
40
|
+
try {
|
|
41
|
+
const result = await this.msalClient.acquireTokenByClientCredential({
|
|
42
|
+
scopes: ['https://api.loganalytics.io/.default'],
|
|
43
|
+
});
|
|
44
|
+
if (!result || !result.accessToken) {
|
|
45
|
+
throw new Error('Failed to acquire access token');
|
|
46
|
+
}
|
|
47
|
+
this.accessToken = result.accessToken;
|
|
48
|
+
this.tokenExpirationTime = result.expiresOn ? result.expiresOn.getTime() : 0;
|
|
49
|
+
return this.accessToken;
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
throw new Error(`Failed to acquire access token: ${error.message}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Get authorization headers based on authentication method
|
|
57
|
+
*/
|
|
58
|
+
async getAuthHeaders(resource) {
|
|
59
|
+
if (this.config.authMethod === 'entra-id') {
|
|
60
|
+
const token = await this.getAccessToken();
|
|
61
|
+
return {
|
|
62
|
+
Authorization: `Bearer ${token}`,
|
|
63
|
+
'Content-Type': 'application/json',
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
else if (this.config.authMethod === 'api-key') {
|
|
67
|
+
if (!resource.apiKey) {
|
|
68
|
+
throw new Error(`API key not configured for resource: ${resource.id}`);
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
'X-Api-Key': resource.apiKey,
|
|
72
|
+
'Content-Type': 'application/json',
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
throw new Error(`Unsupported authentication method: ${this.config.authMethod}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Execute a KQL query against a Log Analytics workspace
|
|
81
|
+
*/
|
|
82
|
+
async executeQuery(resourceId, query, timespan) {
|
|
83
|
+
const resource = this.getResourceById(resourceId);
|
|
84
|
+
try {
|
|
85
|
+
const headers = await this.getAuthHeaders(resource);
|
|
86
|
+
const url = `${this.baseUrl}/workspaces/${resource.workspaceId}/query`;
|
|
87
|
+
const requestBody = { query };
|
|
88
|
+
if (timespan) {
|
|
89
|
+
requestBody.timespan = timespan;
|
|
90
|
+
}
|
|
91
|
+
const response = await axios.post(url, requestBody, {
|
|
92
|
+
headers,
|
|
93
|
+
timeout: 30000, // 30-second timeout
|
|
94
|
+
});
|
|
95
|
+
return response.data;
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
// Enhanced error handling
|
|
99
|
+
let errorMessage = 'Unknown error';
|
|
100
|
+
let errorDetails = {};
|
|
101
|
+
if (error.response) {
|
|
102
|
+
const status = error.response.status;
|
|
103
|
+
const data = error.response.data;
|
|
104
|
+
switch (status) {
|
|
105
|
+
case 401:
|
|
106
|
+
errorMessage = 'Authentication failed. Check your credentials and ensure the app registration has proper permissions.';
|
|
107
|
+
break;
|
|
108
|
+
case 403:
|
|
109
|
+
errorMessage = 'Access denied. Ensure the service principal has "Log Analytics Reader" role on the workspace.';
|
|
110
|
+
break;
|
|
111
|
+
case 429:
|
|
112
|
+
errorMessage = 'Rate limit exceeded. Reduce query frequency or upgrade authentication method.';
|
|
113
|
+
if (error.response.headers['retry-after']) {
|
|
114
|
+
errorMessage += ` Retry after ${error.response.headers['retry-after']} seconds.`;
|
|
115
|
+
}
|
|
116
|
+
break;
|
|
117
|
+
case 400:
|
|
118
|
+
if (data && data.error) {
|
|
119
|
+
if (data.error.code === 'SyntaxError') {
|
|
120
|
+
errorMessage = `KQL syntax error: ${data.error.message}`;
|
|
121
|
+
}
|
|
122
|
+
else if (data.error.code === 'SemanticError') {
|
|
123
|
+
errorMessage = `KQL semantic error: ${data.error.message}. Check table/column names.`;
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
errorMessage = `Bad request: ${data.error.message}`;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
errorMessage = 'Bad request. Check your query syntax.';
|
|
131
|
+
}
|
|
132
|
+
break;
|
|
133
|
+
case 504:
|
|
134
|
+
errorMessage = 'Query timeout. Try reducing the time range or simplifying the query.';
|
|
135
|
+
break;
|
|
136
|
+
default:
|
|
137
|
+
errorMessage = `HTTP ${status}: ${data?.error?.message || error.message}`;
|
|
138
|
+
}
|
|
139
|
+
errorDetails = {
|
|
140
|
+
status,
|
|
141
|
+
code: data?.error?.code,
|
|
142
|
+
message: data?.error?.message,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
else if (error.code === 'ENOTFOUND' || error.code === 'ECONNREFUSED') {
|
|
146
|
+
errorMessage = 'Network error: Unable to reach Log Analytics API. Check your internet connection.';
|
|
147
|
+
}
|
|
148
|
+
else if (error.code === 'ETIMEDOUT') {
|
|
149
|
+
errorMessage = 'Request timeout. The query took too long to execute.';
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
errorMessage = error.message;
|
|
153
|
+
}
|
|
154
|
+
throw new Error(errorMessage);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Get workspace metadata (schema)
|
|
159
|
+
*/
|
|
160
|
+
async getMetadata(resourceId) {
|
|
161
|
+
const resource = this.getResourceById(resourceId);
|
|
162
|
+
try {
|
|
163
|
+
const headers = await this.getAuthHeaders(resource);
|
|
164
|
+
const url = `${this.baseUrl}/workspaces/${resource.workspaceId}/metadata`;
|
|
165
|
+
const response = await axios.get(url, {
|
|
166
|
+
headers,
|
|
167
|
+
timeout: 15000,
|
|
168
|
+
});
|
|
169
|
+
return response.data;
|
|
170
|
+
}
|
|
171
|
+
catch (error) {
|
|
172
|
+
throw new Error(`Failed to get metadata: ${error.message}`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Test workspace access by executing a simple query
|
|
177
|
+
*/
|
|
178
|
+
async testWorkspaceAccess(resourceId) {
|
|
179
|
+
const resource = this.getResourceById(resourceId);
|
|
180
|
+
try {
|
|
181
|
+
// Execute a minimal query to test access
|
|
182
|
+
const result = await this.executeQuery(resourceId, 'print test="success"');
|
|
183
|
+
return {
|
|
184
|
+
success: true,
|
|
185
|
+
message: `Successfully connected to workspace: ${resource.name}`,
|
|
186
|
+
details: {
|
|
187
|
+
workspaceId: resource.workspaceId,
|
|
188
|
+
authMethod: this.config.authMethod,
|
|
189
|
+
},
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
catch (error) {
|
|
193
|
+
return {
|
|
194
|
+
success: false,
|
|
195
|
+
message: `Failed to access workspace: ${error.message}`,
|
|
196
|
+
details: {
|
|
197
|
+
workspaceId: resource.workspaceId,
|
|
198
|
+
error: error.message,
|
|
199
|
+
},
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Get recent events from any table
|
|
205
|
+
*/
|
|
206
|
+
async getRecentEvents(resourceId, tableName, timespan = 'PT1H', limit = 100) {
|
|
207
|
+
const query = `
|
|
208
|
+
${tableName}
|
|
209
|
+
| where TimeGenerated > ago(${this.convertTimespanToKQL(timespan)})
|
|
210
|
+
| order by TimeGenerated desc
|
|
211
|
+
| take ${limit}
|
|
212
|
+
`.trim();
|
|
213
|
+
return this.executeQuery(resourceId, query, timespan);
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Search logs across tables or specific table
|
|
217
|
+
*/
|
|
218
|
+
async searchLogs(resourceId, searchText, tableName, timespan = 'PT1H', limit = 100) {
|
|
219
|
+
const tableFilter = tableName || '*';
|
|
220
|
+
const query = `
|
|
221
|
+
${tableFilter}
|
|
222
|
+
| where TimeGenerated > ago(${this.convertTimespanToKQL(timespan)})
|
|
223
|
+
| where * contains "${searchText}"
|
|
224
|
+
| order by TimeGenerated desc
|
|
225
|
+
| take ${limit}
|
|
226
|
+
`.trim();
|
|
227
|
+
return this.executeQuery(resourceId, query, timespan);
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Get Azure Function logs from FunctionAppLogs table
|
|
231
|
+
*/
|
|
232
|
+
async getFunctionLogs(resourceId, functionName, timespan = 'PT1H', severityLevel, limit = 100) {
|
|
233
|
+
let query = `
|
|
234
|
+
FunctionAppLogs
|
|
235
|
+
| where TimeGenerated > ago(${this.convertTimespanToKQL(timespan)})
|
|
236
|
+
`;
|
|
237
|
+
if (functionName) {
|
|
238
|
+
query += `\n | where FunctionName == "${functionName}"`;
|
|
239
|
+
}
|
|
240
|
+
if (severityLevel !== undefined) {
|
|
241
|
+
query += `\n | where SeverityLevel >= ${severityLevel}`;
|
|
242
|
+
}
|
|
243
|
+
query += `
|
|
244
|
+
| order by TimeGenerated desc
|
|
245
|
+
| take ${limit}
|
|
246
|
+
| project TimeGenerated, FunctionName, Message, SeverityLevel, ExceptionDetails, HostInstanceId
|
|
247
|
+
`.trim();
|
|
248
|
+
return this.executeQuery(resourceId, query, timespan);
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Get Azure Function errors
|
|
252
|
+
*/
|
|
253
|
+
async getFunctionErrors(resourceId, functionName, timespan = 'PT1H', limit = 100) {
|
|
254
|
+
let query = `
|
|
255
|
+
FunctionAppLogs
|
|
256
|
+
| where TimeGenerated > ago(${this.convertTimespanToKQL(timespan)})
|
|
257
|
+
| where ExceptionDetails != ""
|
|
258
|
+
`;
|
|
259
|
+
if (functionName) {
|
|
260
|
+
query += `\n | where FunctionName == "${functionName}"`;
|
|
261
|
+
}
|
|
262
|
+
query += `
|
|
263
|
+
| order by TimeGenerated desc
|
|
264
|
+
| take ${limit}
|
|
265
|
+
| project TimeGenerated, FunctionName, Message, ExceptionDetails, SeverityLevel, HostInstanceId
|
|
266
|
+
`.trim();
|
|
267
|
+
return this.executeQuery(resourceId, query, timespan);
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Get Azure Function execution statistics
|
|
271
|
+
*/
|
|
272
|
+
async getFunctionStats(resourceId, functionName, timespan = 'PT1H') {
|
|
273
|
+
let query = `
|
|
274
|
+
FunctionAppLogs
|
|
275
|
+
| where TimeGenerated > ago(${this.convertTimespanToKQL(timespan)})
|
|
276
|
+
`;
|
|
277
|
+
if (functionName) {
|
|
278
|
+
query += `\n | where FunctionName == "${functionName}"`;
|
|
279
|
+
query += `
|
|
280
|
+
| summarize
|
|
281
|
+
TotalExecutions = count(),
|
|
282
|
+
ErrorCount = countif(ExceptionDetails != ""),
|
|
283
|
+
SuccessCount = countif(ExceptionDetails == ""),
|
|
284
|
+
UniqueHosts = dcount(HostInstanceId)
|
|
285
|
+
| extend SuccessRate = round(100.0 * SuccessCount / TotalExecutions, 2)
|
|
286
|
+
`.trim();
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
query += `
|
|
290
|
+
| summarize
|
|
291
|
+
TotalExecutions = count(),
|
|
292
|
+
ErrorCount = countif(ExceptionDetails != ""),
|
|
293
|
+
SuccessCount = countif(ExceptionDetails == ""),
|
|
294
|
+
UniqueFunctions = dcount(FunctionName),
|
|
295
|
+
UniqueHosts = dcount(HostInstanceId)
|
|
296
|
+
by FunctionName
|
|
297
|
+
| extend SuccessRate = round(100.0 * SuccessCount / TotalExecutions, 2)
|
|
298
|
+
| order by TotalExecutions desc
|
|
299
|
+
`.trim();
|
|
300
|
+
}
|
|
301
|
+
return this.executeQuery(resourceId, query, timespan);
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Get Azure Function invocations from traces or requests table
|
|
305
|
+
*/
|
|
306
|
+
async getFunctionInvocations(resourceId, functionName, timespan = 'PT1H', limit = 100) {
|
|
307
|
+
// Try requests table first (for HTTP-triggered functions)
|
|
308
|
+
let query = `
|
|
309
|
+
union isfuzzy=true requests, traces
|
|
310
|
+
| where TimeGenerated > ago(${this.convertTimespanToKQL(timespan)})
|
|
311
|
+
`;
|
|
312
|
+
if (functionName) {
|
|
313
|
+
query += `\n | where operation_Name contains "${functionName}" or name contains "${functionName}"`;
|
|
314
|
+
}
|
|
315
|
+
query += `
|
|
316
|
+
| order by TimeGenerated desc
|
|
317
|
+
| take ${limit}
|
|
318
|
+
| project TimeGenerated, operation_Name, name, success, resultCode, duration, timestamp
|
|
319
|
+
`.trim();
|
|
320
|
+
return this.executeQuery(resourceId, query, timespan);
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Get all configured resources
|
|
324
|
+
*/
|
|
325
|
+
getAllResources() {
|
|
326
|
+
return this.config.resources;
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Get only active resources
|
|
330
|
+
*/
|
|
331
|
+
getActiveResources() {
|
|
332
|
+
return this.config.resources.filter((r) => r.active);
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Get resource by ID and validate it's active
|
|
336
|
+
*/
|
|
337
|
+
getResourceById(resourceId) {
|
|
338
|
+
const resource = this.config.resources.find((r) => r.id === resourceId);
|
|
339
|
+
if (!resource) {
|
|
340
|
+
const availableIds = this.config.resources.map((r) => r.id).join(', ');
|
|
341
|
+
throw new Error(`Resource '${resourceId}' not found. Available resources: ${availableIds || 'none'}`);
|
|
342
|
+
}
|
|
343
|
+
if (!resource.active) {
|
|
344
|
+
throw new Error(`Resource '${resourceId}' is inactive. Set 'active: true' in configuration to enable it.`);
|
|
345
|
+
}
|
|
346
|
+
return resource;
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Convert ISO 8601 duration to KQL timespan format
|
|
350
|
+
* PT1H -> 1h, P1D -> 1d, PT30M -> 30m, etc.
|
|
351
|
+
*/
|
|
352
|
+
convertTimespanToKQL(iso8601Duration) {
|
|
353
|
+
// Handle common patterns
|
|
354
|
+
const patterns = {
|
|
355
|
+
'PT15M': '15m',
|
|
356
|
+
'PT30M': '30m',
|
|
357
|
+
'PT1H': '1h',
|
|
358
|
+
'PT2H': '2h',
|
|
359
|
+
'PT6H': '6h',
|
|
360
|
+
'PT12H': '12h',
|
|
361
|
+
'PT24H': '24h',
|
|
362
|
+
'P1D': '1d',
|
|
363
|
+
'P2D': '2d',
|
|
364
|
+
'P7D': '7d',
|
|
365
|
+
'P30D': '30d',
|
|
366
|
+
};
|
|
367
|
+
if (patterns[iso8601Duration]) {
|
|
368
|
+
return patterns[iso8601Duration];
|
|
369
|
+
}
|
|
370
|
+
// Parse ISO 8601 duration
|
|
371
|
+
const regex = /P(?:(\d+)D)?T?(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?/;
|
|
372
|
+
const match = iso8601Duration.match(regex);
|
|
373
|
+
if (!match) {
|
|
374
|
+
// If no match, return as-is (might be KQL format already)
|
|
375
|
+
return iso8601Duration;
|
|
376
|
+
}
|
|
377
|
+
const [, days, hours, minutes, seconds] = match;
|
|
378
|
+
// Convert to KQL format (use largest unit)
|
|
379
|
+
if (days)
|
|
380
|
+
return `${days}d`;
|
|
381
|
+
if (hours)
|
|
382
|
+
return `${hours}h`;
|
|
383
|
+
if (minutes)
|
|
384
|
+
return `${minutes}m`;
|
|
385
|
+
if (seconds)
|
|
386
|
+
return `${seconds}s`;
|
|
387
|
+
return '1h'; // Default fallback
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Validate KQL query (basic check)
|
|
391
|
+
*/
|
|
392
|
+
validateQuery(query) {
|
|
393
|
+
if (!query || query.trim().length === 0) {
|
|
394
|
+
return { valid: false, error: 'Query cannot be empty' };
|
|
395
|
+
}
|
|
396
|
+
// Check for dangerous operations (optional - KQL is read-only by nature)
|
|
397
|
+
const dangerousKeywords = ['invoke', 'execute', 'evaluate'];
|
|
398
|
+
const lowerQuery = query.toLowerCase();
|
|
399
|
+
for (const keyword of dangerousKeywords) {
|
|
400
|
+
if (lowerQuery.includes(keyword)) {
|
|
401
|
+
return {
|
|
402
|
+
valid: false,
|
|
403
|
+
error: `Query contains potentially dangerous keyword: ${keyword}`
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
return { valid: true };
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
//# sourceMappingURL=LogAnalyticsService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LogAnalyticsService.js","sourceRoot":"","sources":["../src/LogAnalyticsService.ts"],"names":[],"mappings":"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"}
|
package/build/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { LogAnalyticsService } from "./LogAnalyticsService.js";
|
|
3
|
+
export declare function registerLogAnalyticsTools(server: any, service?: LogAnalyticsService): void;
|
|
4
|
+
export { LogAnalyticsService } from "./LogAnalyticsService.js";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAGA,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,mBAAmB,QAEnF;AAED,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC"}
|
package/build/index.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
+
import { createMcpServer, createEnvLoader } from "@mcp-consultant-tools/core";
|
|
4
|
+
export function registerLogAnalyticsTools(server, service) {
|
|
5
|
+
console.error("Log Analytics tools registered (tool extraction pending)");
|
|
6
|
+
}
|
|
7
|
+
export { LogAnalyticsService } from "./LogAnalyticsService.js";
|
|
8
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
9
|
+
const loadEnv = createEnvLoader();
|
|
10
|
+
loadEnv();
|
|
11
|
+
const server = createMcpServer({ name: "@mcp-consultant-tools/log-analytics", version: "1.0.0", capabilities: { tools: {} } });
|
|
12
|
+
registerLogAnalyticsTools(server);
|
|
13
|
+
const transport = new StdioServerTransport();
|
|
14
|
+
server.connect(transport).catch((error) => { console.error("Failed to start Log Analytics server:", error); process.exit(1); });
|
|
15
|
+
console.error("@mcp-consultant-tools/log-analytics server running");
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAG9E,MAAM,UAAU,yBAAyB,CAAC,MAAW,EAAE,OAA6B;IAClF,OAAO,CAAC,KAAK,CAAC,0DAA0D,CAAC,CAAC;AAC5E,CAAC;AAED,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,UAAU,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACpD,MAAM,OAAO,GAAG,eAAe,EAAE,CAAC;IAClC,OAAO,EAAE,CAAC;IACV,MAAM,MAAM,GAAG,eAAe,CAAC,EAAE,IAAI,EAAE,qCAAqC,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IAC/H,yBAAyB,CAAC,MAAM,CAAC,CAAC;IAClC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,KAAY,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,uCAAuC,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACvI,OAAO,CAAC,KAAK,CAAC,oDAAoD,CAAC,CAAC;AACtE,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for formatting Log Analytics query results
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Format Log Analytics table result as markdown table
|
|
6
|
+
*/
|
|
7
|
+
export declare function formatTableAsMarkdown(table: {
|
|
8
|
+
columns: {
|
|
9
|
+
name: string;
|
|
10
|
+
type: string;
|
|
11
|
+
}[];
|
|
12
|
+
rows: any[][];
|
|
13
|
+
}): string;
|
|
14
|
+
/**
|
|
15
|
+
* Convert Log Analytics query result to CSV
|
|
16
|
+
*/
|
|
17
|
+
export declare function formatTableAsCSV(table: {
|
|
18
|
+
columns: {
|
|
19
|
+
name: string;
|
|
20
|
+
type: string;
|
|
21
|
+
}[];
|
|
22
|
+
rows: any[][];
|
|
23
|
+
}): string;
|
|
24
|
+
/**
|
|
25
|
+
* Extract key insights from generic log data
|
|
26
|
+
*/
|
|
27
|
+
export declare function analyzeLogs(logsTable: any, tableName?: string): string;
|
|
28
|
+
/**
|
|
29
|
+
* Extract key insights from Azure Function logs
|
|
30
|
+
*/
|
|
31
|
+
export declare function analyzeFunctionLogs(logsTable: any): string;
|
|
32
|
+
/**
|
|
33
|
+
* Extract key insights from Azure Function errors
|
|
34
|
+
*/
|
|
35
|
+
export declare function analyzeFunctionErrors(errorsTable: any): string;
|
|
36
|
+
/**
|
|
37
|
+
* Analyze function execution statistics
|
|
38
|
+
*/
|
|
39
|
+
export declare function analyzeFunctionStats(statsTable: any): string;
|
|
40
|
+
/**
|
|
41
|
+
* Generate recommendations based on log analysis
|
|
42
|
+
*/
|
|
43
|
+
export declare function generateRecommendations(analysis: {
|
|
44
|
+
errorCount?: number;
|
|
45
|
+
successRate?: number;
|
|
46
|
+
severityDistribution?: Record<string, number>;
|
|
47
|
+
exceptionTypes?: Record<string, number>;
|
|
48
|
+
}): string[];
|
|
49
|
+
/**
|
|
50
|
+
* Sanitize error messages to remove sensitive information
|
|
51
|
+
*/
|
|
52
|
+
export declare function sanitizeErrorMessage(message: string): string;
|
|
53
|
+
/**
|
|
54
|
+
* Parse and validate ISO 8601 duration strings
|
|
55
|
+
*/
|
|
56
|
+
export declare function parseTimespan(timespan: string): {
|
|
57
|
+
valid: boolean;
|
|
58
|
+
error?: string;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Get common timespan presets
|
|
62
|
+
*/
|
|
63
|
+
export declare function getTimespanPresets(): Record<string, string>;
|
|
64
|
+
/**
|
|
65
|
+
* Format a single log entry for display
|
|
66
|
+
*/
|
|
67
|
+
export declare function formatLogEntry(timestamp: string, severity: number | string, message: string, additionalFields?: Record<string, any>): string;
|
|
68
|
+
//# sourceMappingURL=loganalytics-formatters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loganalytics-formatters.d.ts","sourceRoot":"","sources":["../../src/utils/loganalytics-formatters.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE;IAC3C,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC1C,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC;CACf,GAAG,MAAM,CAwBT;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE;IACtC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC1C,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC;CACf,GAAG,MAAM,CAuBT;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,GAAG,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAiDtE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,GAAG,GAAG,MAAM,CAyD1D;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,GAAG,GAAG,MAAM,CAgE9D;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,GAAG,GAAG,MAAM,CAyC5D;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE;IAChD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9C,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC,GAAG,MAAM,EAAE,CAyCX;AA0BD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAe5D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAYlF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAW3D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GAAG,MAAM,EACzB,OAAO,EAAE,MAAM,EACf,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GACrC,MAAM,CAaR"}
|
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for formatting Log Analytics query results
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Format Log Analytics table result as markdown table
|
|
6
|
+
*/
|
|
7
|
+
export function formatTableAsMarkdown(table) {
|
|
8
|
+
if (!table || !table.rows || table.rows.length === 0) {
|
|
9
|
+
return '*No results*';
|
|
10
|
+
}
|
|
11
|
+
// Create header row
|
|
12
|
+
const header = '| ' + table.columns.map(c => c.name).join(' | ') + ' |';
|
|
13
|
+
const separator = '| ' + table.columns.map(() => '---').join(' | ') + ' |';
|
|
14
|
+
// Create data rows
|
|
15
|
+
const rows = table.rows.map(row => {
|
|
16
|
+
return '| ' + row.map(cell => {
|
|
17
|
+
if (cell === null || cell === undefined)
|
|
18
|
+
return '';
|
|
19
|
+
if (typeof cell === 'object')
|
|
20
|
+
return JSON.stringify(cell);
|
|
21
|
+
// Truncate very long strings for readability
|
|
22
|
+
const str = String(cell);
|
|
23
|
+
if (str.length > 200) {
|
|
24
|
+
return str.substring(0, 197) + '...';
|
|
25
|
+
}
|
|
26
|
+
return str;
|
|
27
|
+
}).join(' | ') + ' |';
|
|
28
|
+
});
|
|
29
|
+
return [header, separator, ...rows].join('\n');
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Convert Log Analytics query result to CSV
|
|
33
|
+
*/
|
|
34
|
+
export function formatTableAsCSV(table) {
|
|
35
|
+
if (!table || !table.rows || table.rows.length === 0) {
|
|
36
|
+
return '';
|
|
37
|
+
}
|
|
38
|
+
// Create header row
|
|
39
|
+
const header = table.columns.map(c => c.name).join(',');
|
|
40
|
+
// Create data rows
|
|
41
|
+
const rows = table.rows.map(row => {
|
|
42
|
+
return row.map(cell => {
|
|
43
|
+
if (cell === null || cell === undefined)
|
|
44
|
+
return '';
|
|
45
|
+
if (typeof cell === 'object')
|
|
46
|
+
return JSON.stringify(cell);
|
|
47
|
+
const str = String(cell);
|
|
48
|
+
// Escape CSV values
|
|
49
|
+
if (str.includes(',') || str.includes('"') || str.includes('\n')) {
|
|
50
|
+
return `"${str.replace(/"/g, '""')}"`;
|
|
51
|
+
}
|
|
52
|
+
return str;
|
|
53
|
+
}).join(',');
|
|
54
|
+
});
|
|
55
|
+
return [header, ...rows].join('\n');
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Extract key insights from generic log data
|
|
59
|
+
*/
|
|
60
|
+
export function analyzeLogs(logsTable, tableName) {
|
|
61
|
+
if (!logsTable || !logsTable.rows || logsTable.rows.length === 0) {
|
|
62
|
+
return 'No logs found in the specified time range.';
|
|
63
|
+
}
|
|
64
|
+
const insights = [];
|
|
65
|
+
// Count total entries
|
|
66
|
+
insights.push(`- Total log entries: ${logsTable.rows.length}`);
|
|
67
|
+
// Analyze severity level distribution if available
|
|
68
|
+
const severityIndex = logsTable.columns.findIndex((c) => c.name === 'SeverityLevel' || c.name === 'Level' || c.name === 'severity');
|
|
69
|
+
if (severityIndex >= 0) {
|
|
70
|
+
const severityCounts = {};
|
|
71
|
+
logsTable.rows.forEach((r) => {
|
|
72
|
+
const severity = r[severityIndex];
|
|
73
|
+
const key = getSeverityLabel(severity);
|
|
74
|
+
severityCounts[key] = (severityCounts[key] || 0) + 1;
|
|
75
|
+
});
|
|
76
|
+
if (Object.keys(severityCounts).length > 0) {
|
|
77
|
+
insights.push('- Severity distribution:');
|
|
78
|
+
Object.entries(severityCounts)
|
|
79
|
+
.sort((a, b) => b[1] - a[1])
|
|
80
|
+
.forEach(([severity, count]) => {
|
|
81
|
+
insights.push(` - ${severity}: ${count}`);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// Identify time range
|
|
86
|
+
const timeIndex = logsTable.columns.findIndex((c) => c.name === 'TimeGenerated' || c.name === 'timestamp');
|
|
87
|
+
if (timeIndex >= 0 && logsTable.rows.length > 0) {
|
|
88
|
+
const timestamps = logsTable.rows
|
|
89
|
+
.map((r) => new Date(r[timeIndex]))
|
|
90
|
+
.filter((d) => !isNaN(d.getTime()));
|
|
91
|
+
if (timestamps.length > 0) {
|
|
92
|
+
const earliest = new Date(Math.min(...timestamps.map((d) => d.getTime())));
|
|
93
|
+
const latest = new Date(Math.max(...timestamps.map((d) => d.getTime())));
|
|
94
|
+
insights.push(`- Time range: ${earliest.toISOString()} to ${latest.toISOString()}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return insights.join('\n');
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Extract key insights from Azure Function logs
|
|
101
|
+
*/
|
|
102
|
+
export function analyzeFunctionLogs(logsTable) {
|
|
103
|
+
if (!logsTable || !logsTable.rows || logsTable.rows.length === 0) {
|
|
104
|
+
return 'No function logs found in the specified time range.';
|
|
105
|
+
}
|
|
106
|
+
const insights = [];
|
|
107
|
+
// Count total entries
|
|
108
|
+
insights.push(`- Total function log entries: ${logsTable.rows.length}`);
|
|
109
|
+
// Count unique function names
|
|
110
|
+
const functionIndex = logsTable.columns.findIndex((c) => c.name === 'FunctionName');
|
|
111
|
+
if (functionIndex >= 0) {
|
|
112
|
+
const functions = new Set(logsTable.rows.map((r) => r[functionIndex]));
|
|
113
|
+
insights.push(`- Unique functions: ${functions.size}`);
|
|
114
|
+
}
|
|
115
|
+
// Count errors (ExceptionDetails present)
|
|
116
|
+
const exceptionIndex = logsTable.columns.findIndex((c) => c.name === 'ExceptionDetails');
|
|
117
|
+
if (exceptionIndex >= 0) {
|
|
118
|
+
const errorCount = logsTable.rows.filter((r) => r[exceptionIndex] && r[exceptionIndex] !== '').length;
|
|
119
|
+
insights.push(`- Error count: ${errorCount}`);
|
|
120
|
+
if (errorCount > 0) {
|
|
121
|
+
const successCount = logsTable.rows.length - errorCount;
|
|
122
|
+
const successRate = ((successCount / logsTable.rows.length) * 100).toFixed(2);
|
|
123
|
+
insights.push(`- Success rate: ${successRate}%`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// Severity distribution
|
|
127
|
+
const severityIndex = logsTable.columns.findIndex((c) => c.name === 'SeverityLevel');
|
|
128
|
+
if (severityIndex >= 0) {
|
|
129
|
+
const severityCounts = {};
|
|
130
|
+
logsTable.rows.forEach((r) => {
|
|
131
|
+
const severity = r[severityIndex];
|
|
132
|
+
const key = getSeverityLabel(severity);
|
|
133
|
+
severityCounts[key] = (severityCounts[key] || 0) + 1;
|
|
134
|
+
});
|
|
135
|
+
if (Object.keys(severityCounts).length > 0) {
|
|
136
|
+
insights.push('- Severity distribution:');
|
|
137
|
+
Object.entries(severityCounts)
|
|
138
|
+
.sort((a, b) => b[1] - a[1])
|
|
139
|
+
.forEach(([severity, count]) => {
|
|
140
|
+
insights.push(` - ${severity}: ${count}`);
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
// Count unique hosts
|
|
145
|
+
const hostIndex = logsTable.columns.findIndex((c) => c.name === 'HostInstanceId');
|
|
146
|
+
if (hostIndex >= 0) {
|
|
147
|
+
const hosts = new Set(logsTable.rows.map((r) => r[hostIndex]));
|
|
148
|
+
insights.push(`- Unique host instances: ${hosts.size}`);
|
|
149
|
+
}
|
|
150
|
+
return insights.join('\n');
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Extract key insights from Azure Function errors
|
|
154
|
+
*/
|
|
155
|
+
export function analyzeFunctionErrors(errorsTable) {
|
|
156
|
+
if (!errorsTable || !errorsTable.rows || errorsTable.rows.length === 0) {
|
|
157
|
+
return 'No function errors found in the specified time range.';
|
|
158
|
+
}
|
|
159
|
+
const insights = [];
|
|
160
|
+
// Count total errors
|
|
161
|
+
insights.push(`- Total errors: ${errorsTable.rows.length}`);
|
|
162
|
+
// Identify most affected function
|
|
163
|
+
const functionIndex = errorsTable.columns.findIndex((c) => c.name === 'FunctionName');
|
|
164
|
+
if (functionIndex >= 0) {
|
|
165
|
+
const functionCounts = {};
|
|
166
|
+
errorsTable.rows.forEach((r) => {
|
|
167
|
+
const func = r[functionIndex];
|
|
168
|
+
functionCounts[func] = (functionCounts[func] || 0) + 1;
|
|
169
|
+
});
|
|
170
|
+
const mostAffected = Object.entries(functionCounts).sort((a, b) => b[1] - a[1])[0];
|
|
171
|
+
if (mostAffected) {
|
|
172
|
+
insights.push(`- Most affected function: ${mostAffected[0]} (${mostAffected[1]} errors)`);
|
|
173
|
+
}
|
|
174
|
+
// Show distribution
|
|
175
|
+
if (Object.keys(functionCounts).length > 1) {
|
|
176
|
+
insights.push('- Error distribution by function:');
|
|
177
|
+
Object.entries(functionCounts)
|
|
178
|
+
.sort((a, b) => b[1] - a[1])
|
|
179
|
+
.slice(0, 5) // Top 5
|
|
180
|
+
.forEach(([func, count]) => {
|
|
181
|
+
insights.push(` - ${func}: ${count}`);
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
// Analyze exception patterns (if ExceptionDetails is JSON or structured)
|
|
186
|
+
const exceptionIndex = errorsTable.columns.findIndex((c) => c.name === 'ExceptionDetails');
|
|
187
|
+
if (exceptionIndex >= 0) {
|
|
188
|
+
const exceptionTypes = {};
|
|
189
|
+
errorsTable.rows.forEach((r) => {
|
|
190
|
+
const details = r[exceptionIndex];
|
|
191
|
+
if (details) {
|
|
192
|
+
// Try to extract exception type from the details string
|
|
193
|
+
const typeMatch = String(details).match(/Exception:\s*([A-Za-z.]+Exception)/);
|
|
194
|
+
if (typeMatch) {
|
|
195
|
+
const type = typeMatch[1];
|
|
196
|
+
exceptionTypes[type] = (exceptionTypes[type] || 0) + 1;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
if (Object.keys(exceptionTypes).length > 0) {
|
|
201
|
+
insights.push('- Common exception types:');
|
|
202
|
+
Object.entries(exceptionTypes)
|
|
203
|
+
.sort((a, b) => b[1] - a[1])
|
|
204
|
+
.slice(0, 5)
|
|
205
|
+
.forEach(([type, count]) => {
|
|
206
|
+
insights.push(` - ${type}: ${count}`);
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return insights.join('\n');
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Analyze function execution statistics
|
|
214
|
+
*/
|
|
215
|
+
export function analyzeFunctionStats(statsTable) {
|
|
216
|
+
if (!statsTable || !statsTable.rows || statsTable.rows.length === 0) {
|
|
217
|
+
return 'No function statistics available.';
|
|
218
|
+
}
|
|
219
|
+
const insights = [];
|
|
220
|
+
// Get column indices
|
|
221
|
+
const functionIndex = statsTable.columns.findIndex((c) => c.name === 'FunctionName');
|
|
222
|
+
const totalIndex = statsTable.columns.findIndex((c) => c.name === 'TotalExecutions');
|
|
223
|
+
const errorIndex = statsTable.columns.findIndex((c) => c.name === 'ErrorCount');
|
|
224
|
+
const successRateIndex = statsTable.columns.findIndex((c) => c.name === 'SuccessRate');
|
|
225
|
+
if (statsTable.rows.length === 1 && functionIndex === -1) {
|
|
226
|
+
// Single function stats (aggregated)
|
|
227
|
+
const row = statsTable.rows[0];
|
|
228
|
+
if (totalIndex >= 0)
|
|
229
|
+
insights.push(`- Total executions: ${row[totalIndex]}`);
|
|
230
|
+
if (errorIndex >= 0)
|
|
231
|
+
insights.push(`- Error count: ${row[errorIndex]}`);
|
|
232
|
+
if (successRateIndex >= 0)
|
|
233
|
+
insights.push(`- Success rate: ${row[successRateIndex]}%`);
|
|
234
|
+
}
|
|
235
|
+
else if (functionIndex >= 0) {
|
|
236
|
+
// Multiple functions
|
|
237
|
+
insights.push(`- Functions analyzed: ${statsTable.rows.length}`);
|
|
238
|
+
// Find function with most errors
|
|
239
|
+
if (errorIndex >= 0) {
|
|
240
|
+
const sorted = [...statsTable.rows].sort((a, b) => b[errorIndex] - a[errorIndex]);
|
|
241
|
+
const mostErrors = sorted[0];
|
|
242
|
+
if (mostErrors[errorIndex] > 0) {
|
|
243
|
+
insights.push(`- Function with most errors: ${mostErrors[functionIndex]} (${mostErrors[errorIndex]} errors)`);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
// Find function with lowest success rate
|
|
247
|
+
if (successRateIndex >= 0) {
|
|
248
|
+
const sorted = [...statsTable.rows].sort((a, b) => a[successRateIndex] - b[successRateIndex]);
|
|
249
|
+
const lowestSuccess = sorted[0];
|
|
250
|
+
insights.push(`- Lowest success rate: ${lowestSuccess[functionIndex]} (${lowestSuccess[successRateIndex]}%)`);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
return insights.join('\n');
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Generate recommendations based on log analysis
|
|
257
|
+
*/
|
|
258
|
+
export function generateRecommendations(analysis) {
|
|
259
|
+
const recommendations = [];
|
|
260
|
+
if (analysis.errorCount && analysis.errorCount > 0) {
|
|
261
|
+
recommendations.push('🔍 Investigate error patterns to identify root causes');
|
|
262
|
+
if (analysis.successRate !== undefined && analysis.successRate < 95) {
|
|
263
|
+
recommendations.push('⚠️ Success rate below 95% - consider implementing retry logic and better error handling');
|
|
264
|
+
}
|
|
265
|
+
if (analysis.successRate !== undefined && analysis.successRate < 80) {
|
|
266
|
+
recommendations.push('🚨 Critical: Success rate below 80% - immediate investigation required');
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
if (analysis.severityDistribution) {
|
|
270
|
+
const warnings = analysis.severityDistribution['Warning'] || 0;
|
|
271
|
+
const errors = analysis.severityDistribution['Error'] || 0;
|
|
272
|
+
const critical = analysis.severityDistribution['Critical'] || 0;
|
|
273
|
+
if (critical > 0) {
|
|
274
|
+
recommendations.push(`🚨 ${critical} critical-level log(s) - immediate action required`);
|
|
275
|
+
}
|
|
276
|
+
if (errors > warnings * 2) {
|
|
277
|
+
recommendations.push('⚠️ High error-to-warning ratio - consider adding more defensive logging');
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
if (analysis.exceptionTypes) {
|
|
281
|
+
const types = Object.keys(analysis.exceptionTypes);
|
|
282
|
+
if (types.length > 5) {
|
|
283
|
+
recommendations.push('📊 Multiple exception types detected - consider exception handling consolidation');
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
if (recommendations.length === 0) {
|
|
287
|
+
recommendations.push('✅ No critical issues detected in the analyzed timeframe');
|
|
288
|
+
}
|
|
289
|
+
return recommendations;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Convert numeric severity level to label
|
|
293
|
+
*/
|
|
294
|
+
function getSeverityLabel(severity) {
|
|
295
|
+
const level = typeof severity === 'number' ? severity : parseInt(severity, 10);
|
|
296
|
+
if (isNaN(level))
|
|
297
|
+
return 'Unknown';
|
|
298
|
+
switch (level) {
|
|
299
|
+
case 0:
|
|
300
|
+
return 'Verbose';
|
|
301
|
+
case 1:
|
|
302
|
+
return 'Information';
|
|
303
|
+
case 2:
|
|
304
|
+
return 'Warning';
|
|
305
|
+
case 3:
|
|
306
|
+
return 'Error';
|
|
307
|
+
case 4:
|
|
308
|
+
return 'Critical';
|
|
309
|
+
default:
|
|
310
|
+
return `Level ${level}`;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Sanitize error messages to remove sensitive information
|
|
315
|
+
*/
|
|
316
|
+
export function sanitizeErrorMessage(message) {
|
|
317
|
+
// Remove potential connection strings
|
|
318
|
+
message = message.replace(/Server=.+?;/gi, 'Server=***;');
|
|
319
|
+
message = message.replace(/Password=.+?;/gi, 'Password=***;');
|
|
320
|
+
message = message.replace(/ApiKey=.+?;/gi, 'ApiKey=***;');
|
|
321
|
+
message = message.replace(/workspaceId=.+?;/gi, 'workspaceId=***;');
|
|
322
|
+
// Remove potential API keys and tokens
|
|
323
|
+
message = message.replace(/Bearer\s+[A-Za-z0-9\-._~+/]+=*/gi, 'Bearer ***');
|
|
324
|
+
message = message.replace(/[A-Za-z0-9]{32,}/g, '***'); // Remove long alphanumeric strings
|
|
325
|
+
// Remove potential workspace IDs (GUIDs)
|
|
326
|
+
message = message.replace(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi, '***-***-***-***-***');
|
|
327
|
+
return message;
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Parse and validate ISO 8601 duration strings
|
|
331
|
+
*/
|
|
332
|
+
export function parseTimespan(timespan) {
|
|
333
|
+
const iso8601Pattern = /^P(?:(\d+)D)?T?(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?$/;
|
|
334
|
+
const match = timespan.match(iso8601Pattern);
|
|
335
|
+
if (!match) {
|
|
336
|
+
return {
|
|
337
|
+
valid: false,
|
|
338
|
+
error: 'Invalid timespan format. Use ISO 8601 duration (e.g., PT1H, P1D, PT30M)',
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
return { valid: true };
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Get common timespan presets
|
|
345
|
+
*/
|
|
346
|
+
export function getTimespanPresets() {
|
|
347
|
+
return {
|
|
348
|
+
'15min': 'PT15M',
|
|
349
|
+
'30min': 'PT30M',
|
|
350
|
+
'1hour': 'PT1H',
|
|
351
|
+
'6hours': 'PT6H',
|
|
352
|
+
'12hours': 'PT12H',
|
|
353
|
+
'1day': 'P1D',
|
|
354
|
+
'7days': 'P7D',
|
|
355
|
+
'30days': 'P30D',
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Format a single log entry for display
|
|
360
|
+
*/
|
|
361
|
+
export function formatLogEntry(timestamp, severity, message, additionalFields) {
|
|
362
|
+
const severityLabel = typeof severity === 'number' ? getSeverityLabel(severity) : severity;
|
|
363
|
+
const time = new Date(timestamp).toISOString();
|
|
364
|
+
let formatted = `**${time}** [${severityLabel}] ${message}`;
|
|
365
|
+
if (additionalFields && Object.keys(additionalFields).length > 0) {
|
|
366
|
+
formatted += '\n ' + Object.entries(additionalFields)
|
|
367
|
+
.map(([key, value]) => `${key}: ${value}`)
|
|
368
|
+
.join(', ');
|
|
369
|
+
}
|
|
370
|
+
return formatted;
|
|
371
|
+
}
|
|
372
|
+
//# sourceMappingURL=loganalytics-formatters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loganalytics-formatters.js","sourceRoot":"","sources":["../../src/utils/loganalytics-formatters.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mcp-consultant-tools/log-analytics",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP server for Azure Log Analytics - workspace queries and Azure Functions monitoring",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./build/index.js",
|
|
7
|
+
"types": "./build/index.d.ts",
|
|
8
|
+
"bin": { "mcp-loganalytics": "./build/index.js" },
|
|
9
|
+
"exports": { ".": { "import": "./build/index.js", "types": "./build/index.d.ts" } },
|
|
10
|
+
"files": ["build", "README.md"],
|
|
11
|
+
"scripts": { "build": "tsc", "clean": "rm -rf build *.tsbuildinfo", "prepublishOnly": "npm run build" },
|
|
12
|
+
"keywords": ["mcp", "model-context-protocol", "azure", "log-analytics", "azure-functions", "monitoring"],
|
|
13
|
+
"author": "Michal Sobieraj",
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"repository": { "type": "git", "url": "git+https://github.com/klemensms/mcp-consultant-tools.git", "directory": "packages/log-analytics" },
|
|
16
|
+
"engines": { "node": ">=16.0.0" },
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@azure/msal-node": "^3.3.0",
|
|
19
|
+
"@mcp-consultant-tools/core": "^1.0.0",
|
|
20
|
+
"@modelcontextprotocol/sdk": "^1.0.4",
|
|
21
|
+
"axios": "^1.8.3",
|
|
22
|
+
"zod": "^3.24.1"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": { "@types/node": "^22.10.5", "typescript": "^5.8.2" }
|
|
25
|
+
}
|