All checks were successful
Docker Build and Push / build-image (push) Successful in 2m53s
37 lines
1.7 KiB
JavaScript
37 lines
1.7 KiB
JavaScript
// 定时任务失败报警: 向 Alert 表插入一条错误记录
|
|
// 供 server/cron.js 与 scripts/scheduler/index.js 共用
|
|
// 首页报警 tab 会展示 Alert 表, 字段按错误语义填充 (indicatorName=任务+错误摘要)
|
|
import 'dotenv/config'
|
|
import mysql from 'mysql2/promise'
|
|
|
|
function parseUrl(url) {
|
|
const u = new URL(url)
|
|
return { host: u.hostname, port: Number(u.port) || 3306, user: decodeURIComponent(u.username), password: decodeURIComponent(u.password), database: u.pathname.replace(/^\//, '') }
|
|
}
|
|
|
|
export async function insertCronAlert(taskName, message) {
|
|
if (!process.env.DATABASE_URL) {
|
|
console.error('[cron-alert] 缺少 DATABASE_URL, 跳过报警写入')
|
|
return
|
|
}
|
|
let conn = null
|
|
try {
|
|
conn = await mysql.createConnection(parseUrl(process.env.DATABASE_URL))
|
|
// 用 Asia/Shanghai 时区的当天日期, 避免 UTC 偏移导致 period 显示成昨天
|
|
const today = new Date().toLocaleDateString('en-CA', { timeZone: 'Asia/Shanghai' })
|
|
const cleanMsg = String(message || '').replace(/\s+/g, ' ').trim()
|
|
const name = ('[cron] ' + taskName + ' 失败: ' + cleanMsg).slice(0, 180)
|
|
await conn.execute(
|
|
'INSERT INTO `Alert` (`indicatorName`, `period`, `valueA`, `valueB`, `sourceA`, `sourceB`, `diff`, `diffRatio`, `createdAt`) ' +
|
|
'VALUES (?, ?, 0, 0, ?, ?, 0, 0, NOW(3))',
|
|
[name, today, 'cron', 'error'],
|
|
)
|
|
console.error('[cron-alert] 已写入报警:', name)
|
|
} catch (e) {
|
|
// 报警写入本身失败 (如 DB 不可达) 不能反噬主流程/再次抛错, 只记录
|
|
console.error('[cron-alert] 写入报警失败:', e.message)
|
|
} finally {
|
|
if (conn) await conn.end().catch(() => {})
|
|
}
|
|
}
|