grafana-mcp-analyzer
Version:
让AI助手直接分析你的Grafana监控数据 - A Model Context Protocol server for Grafana data analysis
2 lines (1 loc) • 6.65 kB
JavaScript
import f from"fs";import A from"path";import m from"os";const x=A.join(m.homedir(),".grafana-mcp-analyzer","data-store"),$=A.join(x,"cache"),g=A.join($,"cache-index.json");function C(){try{if(f.existsSync(x)||(f.mkdirSync(x,{recursive:!0}),console.error("\u{1F4C1} \u521B\u5EFA\u57FA\u7840\u5B58\u50A8\u76EE\u5F55:",x)),f.existsSync($)||(f.mkdirSync($,{recursive:!0}),console.error("\u{1F4C1} \u521B\u5EFA\u7F13\u5B58\u76EE\u5F55:",$)),!f.existsSync(g)){const e={};f.writeFileSync(g,JSON.stringify(e,null,2),"utf-8"),console.error("\u{1F4C4} \u521B\u5EFA\u7F13\u5B58\u7D22\u5F15\u6587\u4EF6:",g)}}catch(e){throw console.error("\u274C \u7F13\u5B58\u7CFB\u7EDF\u521D\u59CB\u5316\u5931\u8D25:",e),new Error(`\u7F13\u5B58\u7CFB\u7EDF\u521D\u59CB\u5316\u5931\u8D25: ${e}`)}}C();function j(){try{C(),console.error("\u2705 \u7F13\u5B58\u7CFB\u7EDF\u68C0\u67E5\u5B8C\u6210")}catch(e){throw console.error("\u274C \u7F13\u5B58\u7CFB\u7EDF\u68C0\u67E5\u5931\u8D25:",e),e}}function I(e,t,n){const c=JSON.stringify(t).replace(/[^a-zA-Z0-9]/g,""),o=e.replace(/[^a-zA-Z0-9]/g,""),r=Date.now().toString(36),d=n?n.replace(/[^a-zA-Z0-9]/g,"").substring(0,4):"";return`cache-${o}-${c.substring(0,8)}-${r}${d?`-${d}`:""}`}function S(e){const t=new Date,n=new Date(e.expiresAt);return t<n}async function h(){try{if(C(),!f.existsSync(g))return console.error("\u26A0\uFE0F \u7F13\u5B58\u7D22\u5F15\u6587\u4EF6\u4E0D\u5B58\u5728\uFF0C\u521B\u5EFA\u65B0\u7D22\u5F15"),{};const e=await f.promises.readFile(g,"utf-8");return JSON.parse(e)}catch(e){console.error("\u274C \u8BFB\u53D6\u7F13\u5B58\u7D22\u5F15\u5931\u8D25\uFF0C\u521B\u5EFA\u65B0\u7D22\u5F15:",e);try{const t={};return await f.promises.writeFile(g,JSON.stringify(t,null,2),"utf-8"),console.error("\u2705 \u91CD\u65B0\u521B\u5EFA\u7F13\u5B58\u7D22\u5F15\u6587\u4EF6\u6210\u529F"),t}catch(t){return console.error("\u274C \u91CD\u65B0\u521B\u5EFA\u7F13\u5B58\u7D22\u5F15\u6587\u4EF6\u5931\u8D25:",t),{}}}}async function w(e){try{C(),await f.promises.writeFile(g,JSON.stringify(e,null,2),"utf-8")}catch(t){throw console.error("\u274C \u4FDD\u5B58\u7F13\u5B58\u7D22\u5F15\u5931\u8D25:",t),new Error(`\u4FDD\u5B58\u7F13\u5B58\u7D22\u5F15\u5931\u8D25: ${t}`)}}async function v(e,t,n){const c=I(e,t,n),o=await h();let r=o[c];if(!r){const d=`cache-${e.replace(/[^a-zA-Z0-9]/g,"")}-${JSON.stringify(t).replace(/[^a-zA-Z0-9]/g,"").substring(0,8)}`,i=Object.entries(o).filter(([a,l])=>a.startsWith(d)&&l.queryName===e&&S(l)).sort(([,a],[,l])=>new Date(l.lastAccessed).getTime()-new Date(a.lastAccessed).getTime());i.length>0&&(r=i[0][1],console.error(`\u{1F4CB} \u627E\u5230\u5339\u914D\u7684\u5386\u53F2\u7F13\u5B58: ${i[0][0]} (\u8BBF\u95EE\u65F6\u95F4: ${r.lastAccessed})`))}return r?S(r)?(r.lastAccessed=new Date().toISOString(),r.accessCount+=1,o[r.id]=r,await w(o),r):(await O(r.id),null):null}async function T(e,t,n,c,o,r){const d=r.sessionId,i=I(e,t,d),a=new Date,l=new Date(a.getTime()+24*60*60*1e3),u={id:i,queryName:e,queryConfig:t,requestId:n,dataSize:c,chunks:o,created:a.toISOString(),lastAccessed:a.toISOString(),accessCount:1,expiresAt:l.toISOString(),metadata:{...r,dataType:r.dataType||"unknown",storageType:r.storageType||"unknown"}},s=await h(),p=`cache-${e.replace(/[^a-zA-Z0-9]/g,"")}-${JSON.stringify(t).replace(/[^a-zA-Z0-9]/g,"").substring(0,8)}`,z=Object.keys(s).filter(y=>y.startsWith(p)&&s[y].queryName===e);for(const y of z)y!==i&&(delete s[y],console.error(`\u{1F5D1}\uFE0F \u5220\u9664\u65E7\u7F13\u5B58: ${y}`));return s[i]=u,await w(s),console.error(`\u{1F4BE} \u521B\u5EFA\u65B0\u7F13\u5B58: ${i} (\u4F1A\u8BDD: ${d||"\u65E0"})`),i}async function O(e){try{const t=await h();return t[e]?(delete t[e],await w(t),!0):!1}catch(t){return console.error(`\u5220\u9664\u7F13\u5B58 ${e} \u5931\u8D25:`,t),!1}}async function F(){const e=await h();let t=0;for(const[n,c]of Object.entries(e))S(c)||(delete e[n],t++,console.error(`\u{1F5D1}\uFE0F \u6E05\u7406\u8FC7\u671F\u7F13\u5B58: ${n}`));return t>0&&await w(e),t}async function k(e=50,t=100*1024*1024){const n=await h(),c=Object.entries(n).filter(([,a])=>S(a));let o=0,r=0,d="";const i=c.reduce((a,[,l])=>a+l.dataSize,0);if(c.length>e){const l=c.sort(([,u],[,s])=>{const p=u.accessCount-s.accessCount;return p!==0?p:new Date(u.created).getTime()-new Date(s.created).getTime()}).slice(0,c.length-e);for(const[u,s]of l)delete n[u],r+=s.dataSize,o++;d=`\u7F13\u5B58\u6761\u76EE\u6570\u91CF\u8D85\u8FC7\u9650\u5236 (${c.length} > ${e})`}else if(i>t){const a=c.sort(([,u],[,s])=>s.dataSize-u.dataSize);let l=i;for(const[u,s]of a){if(l<=t)break;delete n[u],r+=s.dataSize,l-=s.dataSize,o++}d=`\u7F13\u5B58\u603B\u5927\u5C0F\u8D85\u8FC7\u9650\u5236 (${(i/1024/1024).toFixed(2)}MB > ${(t/1024/1024).toFixed(2)}MB)`}return o>0&&(await w(n),console.error(`\u{1F9F9} \u667A\u80FD\u6E05\u7406\u5B8C\u6210: \u5220\u9664 ${o} \u4E2A\u7F13\u5B58\uFF0C\u91CA\u653E ${(r/1024/1024).toFixed(2)}MB\uFF0C\u539F\u56E0: ${d}`)),{deletedCount:o,freedSize:r,reason:d}}async function N(){try{const e=await h(),t=Object.keys(e).length,n=Object.values(e).reduce((o,r)=>o+r.dataSize,0);return await w({}),console.error(`\u{1F5D1}\uFE0F \u6E05\u7A7A\u6240\u6709\u7F13\u5B58\u5B8C\u6210: \u5220\u9664 ${t} \u4E2A\u7F13\u5B58\uFF0C\u91CA\u653E ${(n/1024/1024).toFixed(2)}MB`),{deletedCount:t,freedSize:n}}catch(e){throw console.error("\u274C \u6E05\u7A7A\u7F13\u5B58\u5931\u8D25:",e),new Error(`\u6E05\u7A7A\u7F13\u5B58\u5931\u8D25: ${e}`)}}async function B(e){try{const t=await h(),n=[];let c=0;for(const[o,r]of Object.entries(t))r.queryName===e&&(delete t[o],n.push(o),c+=r.dataSize);return n.length>0&&(await w(t),console.error(`\u{1F5D1}\uFE0F \u5220\u9664\u67E5\u8BE2\u7F13\u5B58\u5B8C\u6210: \u5220\u9664 ${n.length} \u4E2A\u7F13\u5B58\uFF0C\u91CA\u653E ${(c/1024/1024).toFixed(2)}MB`)),{deletedCount:n.length,freedSize:c,deletedEntries:n}}catch(t){throw console.error("\u274C \u5220\u9664\u67E5\u8BE2\u7F13\u5B58\u5931\u8D25:",t),new Error(`\u5220\u9664\u67E5\u8BE2\u7F13\u5B58\u5931\u8D25: ${t}`)}}async function J(e=20){const t=await h();return Object.values(t).filter(n=>S(n)).sort((n,c)=>new Date(c.lastAccessed).getTime()-new Date(n.lastAccessed).getTime()).slice(0,e)}async function Z(){const e=await h(),t=Object.values(e).filter(o=>S(o)),n=t.reduce((o,r)=>o+r.dataSize,0),c=t.length>0?t.reduce((o,r)=>o+r.accessCount,0)/t.length:0;return{totalEntries:Object.keys(e).length,validEntries:t.length,totalSize:n,averageAccessCount:Math.round(c*100)/100}}export{j as checkAndInitializeCache,F as cleanupExpiredCache,N as clearAllCache,T as createCache,O as deleteCache,B as deleteCacheByQueryName,v as findValidCache,Z as getCacheStats,J as listCache,k as smartCleanupCache};