🔧 修复代码审查反馈·磁盘验证·日志截断·SSH安全·危险命令·动态错误模式
Agent-Logs-Url: https://github.com/qinfendebingshuo/guanghulab/sessions/29df49f6-bbbb-49af-8e63-96704b11d9c5 Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com>
This commit is contained in:
parent
c9c0327127
commit
3ce4bb8514
|
|
@ -50,6 +50,16 @@ function ensureDir(dir) {
|
|||
}
|
||||
}
|
||||
|
||||
// 智能截断日志:保留头部和尾部,确保错误信息不丢失
|
||||
function truncateLog(content, maxLen) {
|
||||
if (!content || content.length <= maxLen) return content;
|
||||
const headSize = Math.floor(maxLen * 0.3); // 30%给头部
|
||||
const tailSize = maxLen - headSize - 100; // 70%给尾部(错误通常在末尾)
|
||||
const head = content.slice(0, headSize);
|
||||
const tail = content.slice(-tailSize);
|
||||
return `${head}\n\n... [截断 ${content.length - headSize - tailSize} 字符] ...\n\n${tail}`;
|
||||
}
|
||||
|
||||
// ── GitHub API 请求 ────────────────────────────
|
||||
function githubApi(endpoint) {
|
||||
const token = process.env.GH_TOKEN || process.env.GITHUB_TOKEN;
|
||||
|
|
@ -225,7 +235,7 @@ async function collectLogs() {
|
|||
conclusion: s.conclusion,
|
||||
number: s.number
|
||||
})),
|
||||
log_content: logContent.slice(0, 10000) // 限制日志大小
|
||||
log_content: truncateLog(logContent, 10000) // 智能截断:保留头部和尾部
|
||||
});
|
||||
console.log(` ✅ 日志采集成功 (${logContent.length} 字符)`);
|
||||
} catch (err) {
|
||||
|
|
@ -330,6 +340,7 @@ async function collectLogs() {
|
|||
|
||||
// ── 简单错误分析 (模式匹配) ────────────────────
|
||||
function simpleAnalysis(logContent) {
|
||||
// 基础错误模式 + 动态加载经验库中的错误模式
|
||||
const patterns = [
|
||||
{ regex: /EADDRINUSE/i, name: '端口被占用', fix: '重启PM2进程释放端口', severity: 'medium' },
|
||||
{ regex: /ECONNREFUSED/i, name: '服务连接被拒绝', fix: '检查PM2进程是否运行', severity: 'high' },
|
||||
|
|
@ -349,6 +360,27 @@ function simpleAnalysis(logContent) {
|
|||
{ regex: /exit code [1-9]/i, name: '命令执行失败', fix: '查看上方具体错误信息', severity: 'medium' }
|
||||
];
|
||||
|
||||
// 尝试从经验数据库动态加载错误模式
|
||||
try {
|
||||
const errPatternsDb = JSON.parse(fs.readFileSync(ERROR_PATTERNS_DB, 'utf8'));
|
||||
if (errPatternsDb.patterns) {
|
||||
for (const p of errPatternsDb.patterns) {
|
||||
// 提取经验库中的关键词作为匹配模式
|
||||
const keywords = p.pattern.split(/[·\s+]/g).filter(k => k.length > 3);
|
||||
if (keywords.length > 0) {
|
||||
patterns.push({
|
||||
regex: new RegExp(keywords.join('|'), 'i'),
|
||||
name: `[经验库] ${p.pattern}`,
|
||||
fix: (p.prevention || []).join(' → ') || '参考经验库',
|
||||
severity: p.severity || 'medium'
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// 经验库加载失败不影响基础分析
|
||||
}
|
||||
|
||||
const matched = [];
|
||||
for (const p of patterns) {
|
||||
if (p.regex.test(logContent)) {
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ const REPAIR_STRATEGIES = [
|
|||
'sudo find /tmp -type f -mtime +1 -delete 2>/dev/null || true',
|
||||
'df -h /'
|
||||
],
|
||||
verify: 'AVAIL=$(df / | tail -1 | awk \'{print $5}\' | tr -d \'%\'); [ "$AVAIL" -lt 90 ] || exit 1',
|
||||
verify: 'USED=$(df / | tail -1 | awk \'{print $5}\' | tr -d \'%\'); [ "$USED" -lt 90 ] || exit 1',
|
||||
severity: 'high',
|
||||
success_rate: '中 · 取决于可清理的文件量'
|
||||
},
|
||||
|
|
@ -132,7 +132,7 @@ function sshExec(command) {
|
|||
}
|
||||
|
||||
try {
|
||||
const sshCmd = `ssh -i ~/.ssh/zy_key -o ConnectTimeout=10 -o StrictHostKeyChecking=no ${user}@${host} '${command.replace(/'/g, "'\\''")}'`;
|
||||
const sshCmd = `ssh -i ~/.ssh/zy_key -o ConnectTimeout=10 ${user}@${host} '${command.replace(/'/g, "'\\''")}'`;
|
||||
const output = execSync(sshCmd, {
|
||||
timeout: 60000, // 60秒超时
|
||||
encoding: 'utf8',
|
||||
|
|
@ -463,7 +463,7 @@ async function repair() {
|
|||
// ── 危险命令检测 ────────────────────────────
|
||||
function isDangerousCommand(cmd) {
|
||||
const dangerous = [
|
||||
/rm\s+-rf\s+\//, // rm -rf /
|
||||
/rm\s+-r[fF]*\s+(\/|~|\$HOME)/, // rm -rf / or ~ or $HOME
|
||||
/mkfs/, // 格式化
|
||||
/dd\s+if=/, // 磁盘写入
|
||||
/shutdown/, // 关机
|
||||
|
|
@ -474,6 +474,7 @@ function isDangerousCommand(cmd) {
|
|||
/chmod\s+-R\s+777\s+\//, // 全局777
|
||||
/userdel/, // 删除用户
|
||||
/passwd/, // 修改密码
|
||||
/rm\s+-r[fF]*\s+\/\w/, // rm -rf /home etc
|
||||
];
|
||||
return dangerous.some(regex => regex.test(cmd));
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue