mcp-log-query-server 3.6.1 → 3.7.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/config.js +25 -1
- package/index.js +6 -6
- package/loki-client.js +13 -5
- package/package.json +3 -3
package/config.js
CHANGED
|
@@ -586,10 +586,26 @@ export const LOKI_ENVIRONMENTS = {
|
|
|
586
586
|
orgId: parseInt(process.env.MCP_GRAFANA_ORG_ID || '1'),
|
|
587
587
|
username: process.env.MCP_GRAFANA_USER || 'loki',
|
|
588
588
|
password: process.env.MCP_GRAFANA_PASSWORD || 'nihao123!!',
|
|
589
|
-
defaultProject: 'senior',
|
|
589
|
+
defaultProject: 'senior', // 用于 {project="senior"} label 过滤
|
|
590
|
+
pathProject: 'senior', // 用于 filename 路径中的 project 段
|
|
590
591
|
hasProjectLabel: true // CMS 有 project 标签,可用 {project="senior"} 查询
|
|
591
592
|
},
|
|
592
593
|
|
|
594
|
+
// 预发布环境(华为云)— 共享 CMS 的 Grafana / Loki,仅 project 标签为 pre-senior
|
|
595
|
+
// 注意:filename 路径里的 project 段仍然是 'senior'(不是 'pre-senior'),所以 pathProject 单独配置
|
|
596
|
+
'pre': {
|
|
597
|
+
description: '预发布环境(华为云,与 CMS 共用 Grafana)',
|
|
598
|
+
grafanaUrl: process.env.MCP_GRAFANA_URL || 'http://10.6.14.2:3000',
|
|
599
|
+
datasourceUid: process.env.MCP_GRAFANA_LOKI_UID || 'af2718a2-9c32-4364-a495-3bb29035199c',
|
|
600
|
+
datasourceId: parseInt(process.env.MCP_GRAFANA_DATASOURCE_ID || '35'),
|
|
601
|
+
orgId: parseInt(process.env.MCP_GRAFANA_ORG_ID || '1'),
|
|
602
|
+
username: process.env.MCP_GRAFANA_USER || 'loki',
|
|
603
|
+
password: process.env.MCP_GRAFANA_PASSWORD || 'nihao123!!',
|
|
604
|
+
defaultProject: 'pre-senior', // 用于 {project="pre-senior"} label 过滤
|
|
605
|
+
pathProject: 'senior', // filename 路径里仍是 senior(注意:与 label 不同)
|
|
606
|
+
hasProjectLabel: true
|
|
607
|
+
},
|
|
608
|
+
|
|
593
609
|
// ---- 私有化环境(均无 project 标签,通过 filename 正则匹配) ----
|
|
594
610
|
|
|
595
611
|
// 城阳私有化
|
|
@@ -669,6 +685,14 @@ export const LOKI_ENV_ALIASES = {
|
|
|
669
685
|
'生产': 'cms',
|
|
670
686
|
'生产环境': 'cms',
|
|
671
687
|
'cms': 'cms',
|
|
688
|
+
// 预发布
|
|
689
|
+
'pre': 'pre',
|
|
690
|
+
'preprod': 'pre',
|
|
691
|
+
'pre-prod': 'pre',
|
|
692
|
+
'staging': 'pre',
|
|
693
|
+
'预发': 'pre',
|
|
694
|
+
'预发布': 'pre',
|
|
695
|
+
'预发布环境': 'pre',
|
|
672
696
|
// 城阳
|
|
673
697
|
'城阳': 'chengyang',
|
|
674
698
|
'chengyang': 'chengyang',
|
package/index.js
CHANGED
|
@@ -84,7 +84,7 @@ process.on('uncaughtException', (err) => log(`[uncaughtException] ${err && err.s
|
|
|
84
84
|
const server = new Server(
|
|
85
85
|
{
|
|
86
86
|
name: 'mcp-log-query',
|
|
87
|
-
version: '3.
|
|
87
|
+
version: '3.7.0',
|
|
88
88
|
},
|
|
89
89
|
{
|
|
90
90
|
capabilities: {
|
|
@@ -118,7 +118,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
118
118
|
},
|
|
119
119
|
env: {
|
|
120
120
|
type: 'string',
|
|
121
|
-
description: '环境标识,不指定则查询测试环境(走 SSH)。可选值:cms/prod/生产(CMS
|
|
121
|
+
description: '环境标识,不指定则查询测试环境(走 SSH)。可选值:cms/prod/生产(CMS生产环境)、pre/预发/预发布(预发布环境,与 CMS 共用 Grafana)、城阳/cy/chengyang、临颖/ly/linying、漯河/lh/luohe、德阳/dy/deyang、旌阳/jy/jingyang(私有化环境)'
|
|
122
122
|
},
|
|
123
123
|
from: {
|
|
124
124
|
type: 'string',
|
|
@@ -162,7 +162,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
162
162
|
},
|
|
163
163
|
env: {
|
|
164
164
|
type: 'string',
|
|
165
|
-
description: '环境标识,不指定则查询测试环境(走 SSH)。可选值:cms/prod/生产(CMS
|
|
165
|
+
description: '环境标识,不指定则查询测试环境(走 SSH)。可选值:cms/prod/生产(CMS生产环境)、pre/预发/预发布(预发布环境,与 CMS 共用 Grafana)、城阳/cy/chengyang、临颖/ly/linying、漯河/lh/luohe、德阳/dy/deyang、旌阳/jy/jingyang(私有化环境)'
|
|
166
166
|
},
|
|
167
167
|
from: {
|
|
168
168
|
type: 'string',
|
|
@@ -303,7 +303,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
303
303
|
},
|
|
304
304
|
env: {
|
|
305
305
|
type: 'string',
|
|
306
|
-
description: '环境标识,不指定则查询测试环境(走 SSH)。可选值:cms/prod/生产(CMS
|
|
306
|
+
description: '环境标识,不指定则查询测试环境(走 SSH)。可选值:cms/prod/生产(CMS生产环境)、pre/预发/预发布(预发布环境,与 CMS 共用 Grafana)、城阳/cy/chengyang、临颖/ly/linying、漯河/lh/luohe、德阳/dy/deyang、旌阳/jy/jingyang(私有化环境)'
|
|
307
307
|
},
|
|
308
308
|
from: {
|
|
309
309
|
type: 'string',
|
|
@@ -349,7 +349,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
349
349
|
properties: {
|
|
350
350
|
env: {
|
|
351
351
|
type: 'string',
|
|
352
|
-
description: '环境标识。可选值:cms/prod/生产(CMS
|
|
352
|
+
description: '环境标识。可选值:cms/prod/生产(CMS生产环境)、pre/预发/预发布(预发布环境,与 CMS 共用 Grafana)、城阳/cy/chengyang、临颖/ly/linying、漯河/lh/luohe、德阳/dy/deyang、旌阳/jy/jingyang(私有化环境)',
|
|
353
353
|
default: 'cms'
|
|
354
354
|
},
|
|
355
355
|
project: {
|
|
@@ -900,7 +900,7 @@ async function main() {
|
|
|
900
900
|
const transport = new StdioServerTransport();
|
|
901
901
|
await server.connect(transport);
|
|
902
902
|
const logPath = getLogFilePath();
|
|
903
|
-
log(`[MCP] Log Query Server v3.
|
|
903
|
+
log(`[MCP] Log Query Server v3.7.0 已启动 (仅文件日志,避免 stderr backpressure 阻塞 event loop)`);
|
|
904
904
|
if (logPath) log(`[MCP] 本地日志文件: ${logPath}`);
|
|
905
905
|
}
|
|
906
906
|
|
package/loki-client.js
CHANGED
|
@@ -362,21 +362,29 @@ export function groupLogsByService(lokiResult) {
|
|
|
362
362
|
/**
|
|
363
363
|
* 构建按服务查询的 LogQL 表达式
|
|
364
364
|
* 根据环境是否有 project 标签,自动选择不同的 filename 路径格式:
|
|
365
|
-
* - 有 project 标签(CMS
|
|
365
|
+
* - 有 project 标签(CMS / 预发布): /data/services/logs/senior/clife-senior-health-app/normal_logs/normal.log
|
|
366
366
|
* - 无 project 标签(私有化): /data/services/logs/clife-senior-health-app/normal_logs/normal.log
|
|
367
367
|
*
|
|
368
|
-
*
|
|
368
|
+
* 注意 path 与 label 的差异:
|
|
369
|
+
* - 预发布 label 是 'pre-senior'(用于 LogQL 标签匹配,不在这里)
|
|
370
|
+
* - 预发布 path 仍然是 'senior'(写在 filename 路径里)
|
|
371
|
+
* 通过环境配置的 pathProject 字段单独控制路径段,避免与 label 混用
|
|
372
|
+
*
|
|
373
|
+
* @param {string} project - 项目 label,如 'senior' / 'pre-senior'(仅当环境无 pathProject 字段时回退使用)
|
|
369
374
|
* @param {string} servicePodPattern - 服务目录名,如 'clife-senior-health-app'
|
|
370
375
|
* @param {string} keyword - 搜索关键词(可选)
|
|
371
|
-
* @param {string} envName - 环境名称,如 'cms'、'chengyang'
|
|
376
|
+
* @param {string} envName - 环境名称,如 'cms'、'pre'、'chengyang'
|
|
372
377
|
*/
|
|
373
378
|
export function buildServiceLogQL(project, servicePodPattern, keyword = '', envName = '') {
|
|
374
379
|
const env = envName ? LOKI_ENVIRONMENTS[envName] : null;
|
|
375
380
|
const hasProject = env ? env.hasProjectLabel !== false : true;
|
|
381
|
+
// 路径段优先使用 env.pathProject(预发布需要 label='pre-senior' 但 path='senior'),回退到 project
|
|
382
|
+
const pathSegment = (env && env.pathProject) || project;
|
|
376
383
|
|
|
377
|
-
//
|
|
384
|
+
// 有 project 标签的环境: /data/services/logs/{pathSegment}/xxx-app/...
|
|
385
|
+
// 无 project 标签的环境: /data/services/logs/xxx-app/...
|
|
378
386
|
const filename = hasProject
|
|
379
|
-
? `/data/services/logs/${
|
|
387
|
+
? `/data/services/logs/${pathSegment}/${servicePodPattern}/normal_logs/normal.log`
|
|
380
388
|
: `/data/services/logs/${servicePodPattern}/normal_logs/normal.log`;
|
|
381
389
|
|
|
382
390
|
let expr = `{filename="${filename}"}`;
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-log-query-server",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.7.0",
|
|
4
4
|
"description": "MCP Server for querying server logs via SSH jump host and Grafana Loki API",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
8
|
-
"mcp-log-query": "
|
|
8
|
+
"mcp-log-query": "index.js"
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
11
|
"index.js",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"license": "MIT",
|
|
38
38
|
"repository": {
|
|
39
39
|
"type": "git",
|
|
40
|
-
"url": "https://github.com/huawang1258/mcp-services.git"
|
|
40
|
+
"url": "git+https://github.com/huawang1258/mcp-services.git"
|
|
41
41
|
},
|
|
42
42
|
"homepage": "https://github.com/huawang1258/mcp-services#readme"
|
|
43
43
|
}
|