Docker 파일
This commit is contained in:
@@ -1,15 +1,14 @@
|
||||
import { getDb } from '../../utils/db'
|
||||
import { query } from '../../utils/db'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const db = getDb()
|
||||
const DEVIATION_THRESHOLD = 2.0
|
||||
|
||||
const servers = db.prepare(`
|
||||
SELECT target_id, server_name
|
||||
const servers = await query<any>(`
|
||||
SELECT target_id, name as server_name
|
||||
FROM server_targets
|
||||
WHERE is_active = 1
|
||||
ORDER BY server_name
|
||||
`).all() as any[]
|
||||
ORDER BY name
|
||||
`)
|
||||
|
||||
const now = new Date()
|
||||
const currentHour = now.getHours()
|
||||
@@ -20,41 +19,32 @@ export default defineEventHandler(async (event) => {
|
||||
const anomalies: any[] = []
|
||||
const serverResults: any[] = []
|
||||
|
||||
// 로그 저장용
|
||||
const insertLog = db.prepare(`
|
||||
INSERT INTO anomaly_logs (target_id, server_name, detect_type, metric, level, current_value, threshold_value, message)
|
||||
VALUES (?, ?, 'baseline', ?, ?, ?, ?, ?)
|
||||
`)
|
||||
|
||||
const recentLogExists = db.prepare(`
|
||||
SELECT 1 FROM anomaly_logs
|
||||
WHERE target_id = ? AND detect_type = 'baseline' AND metric = ?
|
||||
AND detected_at > datetime('now', '-1 minute', 'localtime')
|
||||
LIMIT 1
|
||||
`)
|
||||
|
||||
for (const server of servers) {
|
||||
const historicalData = db.prepare(`
|
||||
SELECT cpu_percent, memory_percent, collected_at
|
||||
FROM server_snapshots
|
||||
WHERE target_id = ?
|
||||
AND collected_at >= datetime('now', '-14 days', 'localtime')
|
||||
AND strftime('%H', collected_at) = ?
|
||||
// 최근 14일 동일 시간대 데이터
|
||||
const historicalData = await query<any>(`
|
||||
SELECT cpu_usage as cpu_percent, memory_usage as memory_percent, checked_at as collected_at
|
||||
FROM server_logs
|
||||
WHERE target_id = $1
|
||||
AND checked_at >= NOW() - INTERVAL '14 days'
|
||||
AND EXTRACT(HOUR FROM checked_at) = $2
|
||||
AND (
|
||||
(? = 'weekend' AND strftime('%w', collected_at) IN ('0', '6'))
|
||||
($3 = 'weekend' AND EXTRACT(DOW FROM checked_at) IN (0, 6))
|
||||
OR
|
||||
(? = 'weekday' AND strftime('%w', collected_at) NOT IN ('0', '6'))
|
||||
($3 = 'weekday' AND EXTRACT(DOW FROM checked_at) NOT IN (0, 6))
|
||||
)
|
||||
ORDER BY collected_at DESC
|
||||
`).all(server.target_id, currentHour.toString().padStart(2, '0'), dayType, dayType) as any[]
|
||||
ORDER BY checked_at DESC
|
||||
`, [server.target_id, currentHour, dayType])
|
||||
|
||||
const current = db.prepare(`
|
||||
SELECT cpu_percent, memory_percent
|
||||
FROM server_snapshots
|
||||
WHERE target_id = ?
|
||||
ORDER BY collected_at DESC
|
||||
// 현재 값
|
||||
const currentRows = await query<any>(`
|
||||
SELECT cpu_usage as cpu_percent, memory_usage as memory_percent
|
||||
FROM server_logs
|
||||
WHERE target_id = $1
|
||||
ORDER BY checked_at DESC
|
||||
LIMIT 1
|
||||
`).get(server.target_id) as any
|
||||
`, [server.target_id])
|
||||
|
||||
const current = currentRows[0]
|
||||
|
||||
if (!current || historicalData.length < 5) {
|
||||
serverResults.push({
|
||||
@@ -74,17 +64,17 @@ export default defineEventHandler(async (event) => {
|
||||
continue
|
||||
}
|
||||
|
||||
const currCpu = current.cpu_percent ?? 0
|
||||
const currMem = current.memory_percent ?? 0
|
||||
const currCpu = Number(current.cpu_percent) || 0
|
||||
const currMem = Number(current.memory_percent) || 0
|
||||
|
||||
const cpuValues = historicalData.map(s => s.cpu_percent ?? 0)
|
||||
const memValues = historicalData.map(s => s.memory_percent ?? 0)
|
||||
const cpuValues = historicalData.map((s: any) => Number(s.cpu_percent) || 0)
|
||||
const memValues = historicalData.map((s: any) => Number(s.memory_percent) || 0)
|
||||
|
||||
const cpuAvg = cpuValues.reduce((a, b) => a + b, 0) / cpuValues.length
|
||||
const memAvg = memValues.reduce((a, b) => a + b, 0) / memValues.length
|
||||
const cpuAvg = cpuValues.reduce((a: number, b: number) => a + b, 0) / cpuValues.length
|
||||
const memAvg = memValues.reduce((a: number, b: number) => a + b, 0) / memValues.length
|
||||
|
||||
const cpuVariance = cpuValues.reduce((sum, val) => sum + Math.pow(val - cpuAvg, 2), 0) / cpuValues.length
|
||||
const memVariance = memValues.reduce((sum, val) => sum + Math.pow(val - memAvg, 2), 0) / memValues.length
|
||||
const cpuVariance = cpuValues.reduce((sum: number, val: number) => sum + Math.pow(val - cpuAvg, 2), 0) / cpuValues.length
|
||||
const memVariance = memValues.reduce((sum: number, val: number) => sum + Math.pow(val - memAvg, 2), 0) / memValues.length
|
||||
const cpuStd = Math.sqrt(cpuVariance)
|
||||
const memStd = Math.sqrt(memVariance)
|
||||
|
||||
@@ -111,12 +101,9 @@ export default defineEventHandler(async (event) => {
|
||||
status
|
||||
})
|
||||
|
||||
// CPU 이상감지 + 로그 저장
|
||||
// CPU 이상감지
|
||||
if (Math.abs(cpuDeviation) >= DEVIATION_THRESHOLD) {
|
||||
const level = Math.abs(cpuDeviation) >= 3.0 ? 'danger' : 'warning'
|
||||
const direction = cpuDeviation >= 0 ? '높음' : '낮음'
|
||||
const dayLabel = isWeekend ? '주말' : '평일'
|
||||
const message = `CPU ${dayLabel} ${currentHour}시 베이스라인 대비 ${Math.abs(cpuDeviation).toFixed(1)}σ ${direction} (기준: ${cpuAvg.toFixed(1)}%, 현재: ${currCpu.toFixed(1)}%)`
|
||||
|
||||
anomalies.push({
|
||||
target_id: server.target_id,
|
||||
@@ -130,18 +117,11 @@ export default defineEventHandler(async (event) => {
|
||||
hour: currentHour,
|
||||
day_type: dayType
|
||||
})
|
||||
|
||||
if (!recentLogExists.get(server.target_id, 'CPU')) {
|
||||
insertLog.run(server.target_id, server.server_name, 'CPU', level, currCpu, cpuDeviation, message)
|
||||
}
|
||||
}
|
||||
|
||||
// Memory 이상감지 + 로그 저장
|
||||
// Memory 이상감지
|
||||
if (Math.abs(memDeviation) >= DEVIATION_THRESHOLD) {
|
||||
const level = Math.abs(memDeviation) >= 3.0 ? 'danger' : 'warning'
|
||||
const direction = memDeviation >= 0 ? '높음' : '낮음'
|
||||
const dayLabel = isWeekend ? '주말' : '평일'
|
||||
const message = `Memory ${dayLabel} ${currentHour}시 베이스라인 대비 ${Math.abs(memDeviation).toFixed(1)}σ ${direction} (기준: ${memAvg.toFixed(1)}%, 현재: ${currMem.toFixed(1)}%)`
|
||||
|
||||
anomalies.push({
|
||||
target_id: server.target_id,
|
||||
@@ -155,10 +135,6 @@ export default defineEventHandler(async (event) => {
|
||||
hour: currentHour,
|
||||
day_type: dayType
|
||||
})
|
||||
|
||||
if (!recentLogExists.get(server.target_id, 'Memory')) {
|
||||
insertLog.run(server.target_id, server.server_name, 'Memory', level, currMem, memDeviation, message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user