소스 수정
This commit is contained in:
@@ -32,7 +32,15 @@ export default defineEventHandler(async (event) => {
|
|||||||
SELECT
|
SELECT
|
||||||
snapshot_id,
|
snapshot_id,
|
||||||
cpu_percent,
|
cpu_percent,
|
||||||
|
cpu_temp,
|
||||||
|
load_percent,
|
||||||
memory_percent,
|
memory_percent,
|
||||||
|
memory_total,
|
||||||
|
memory_used,
|
||||||
|
memory_free,
|
||||||
|
swap_percent,
|
||||||
|
swap_total,
|
||||||
|
swap_used,
|
||||||
is_online,
|
is_online,
|
||||||
collected_at
|
collected_at
|
||||||
FROM server_snapshots
|
FROM server_snapshots
|
||||||
|
|||||||
@@ -455,10 +455,10 @@ async function collectServerData(target: ServerTarget) {
|
|||||||
await execute(`
|
await execute(`
|
||||||
INSERT INTO server_snapshots (
|
INSERT INTO server_snapshots (
|
||||||
target_id, os_name, os_version, host_name, uptime_seconds, uptime_str, ip_address,
|
target_id, os_name, os_version, host_name, uptime_seconds, uptime_str, ip_address,
|
||||||
cpu_name, cpu_count, cpu_percent, memory_total, memory_used, memory_percent,
|
cpu_name, cpu_count, cpu_percent, memory_total, memory_used, memory_free, memory_percent,
|
||||||
swap_total, swap_used, swap_percent, is_online, api_version, cpu_temp,
|
swap_total, swap_used, swap_percent, is_online, api_version, cpu_temp,
|
||||||
load_1, load_5, load_15, load_percent, collected_at
|
load_1, load_5, load_15, load_percent, collected_at
|
||||||
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24)
|
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25)
|
||||||
`, [
|
`, [
|
||||||
target.target_id,
|
target.target_id,
|
||||||
system?.os_name || system?.linux_distro || null,
|
system?.os_name || system?.linux_distro || null,
|
||||||
@@ -472,6 +472,7 @@ async function collectServerData(target: ServerTarget) {
|
|||||||
cpu?.total ?? quicklook?.cpu ?? null,
|
cpu?.total ?? quicklook?.cpu ?? null,
|
||||||
mem?.total || null,
|
mem?.total || null,
|
||||||
mem?.used || null,
|
mem?.used || null,
|
||||||
|
mem?.free || null,
|
||||||
mem?.percent || null,
|
mem?.percent || null,
|
||||||
memswap?.total || null,
|
memswap?.total || null,
|
||||||
memswap?.used || null,
|
memswap?.used || null,
|
||||||
|
|||||||
@@ -413,15 +413,21 @@ async function fetchSnapshots() {
|
|||||||
{ label: 'Swap %', data: swapData, borderColor: chartColors[2] }
|
{ label: 'Swap %', data: swapData, borderColor: chartColors[2] }
|
||||||
])
|
])
|
||||||
|
|
||||||
// 평균 계산 (Memory, Swap) + 사용량/전체용량
|
// 평균 계산 (Memory, Swap) + 사용량/전체용량 (BigInt는 문자열로 반환되므로 Number로 변환)
|
||||||
|
// 메모리 사용량 = total - free (free가 있으면 사용, 없으면 used 사용)
|
||||||
const validMem = memData.filter((v: number) => v > 0)
|
const validMem = memData.filter((v: number) => v > 0)
|
||||||
const validSwap = swapData.filter((v: number) => v >= 0)
|
const validSwap = swapData.filter((v: number) => v >= 0)
|
||||||
const memUsedData = data.map((d: any) => d.memory_used || 0).filter((v: number) => v > 0)
|
const memUsedData = data.map((d: any) => {
|
||||||
|
const total = Number(d.memory_total) || 0
|
||||||
|
const free = Number(d.memory_free) || 0
|
||||||
|
const used = Number(d.memory_used) || 0
|
||||||
|
return free > 0 ? (total - free) : used
|
||||||
|
}).filter((v: number) => v > 0)
|
||||||
const avgMemUsedGB = memUsedData.length ? (memUsedData.reduce((a: number, b: number) => a + b, 0) / memUsedData.length / (1024 * 1024 * 1024)).toFixed(1) : '-'
|
const avgMemUsedGB = memUsedData.length ? (memUsedData.reduce((a: number, b: number) => a + b, 0) / memUsedData.length / (1024 * 1024 * 1024)).toFixed(1) : '-'
|
||||||
const memTotalGB = data[0]?.memory_total ? (data[0].memory_total / (1024 * 1024 * 1024)).toFixed(1) : '-'
|
const memTotalGB = data[0]?.memory_total ? (Number(data[0].memory_total) / (1024 * 1024 * 1024)).toFixed(1) : '-'
|
||||||
const swapUsedData = data.map((d: any) => d.swap_used || 0).filter((v: number) => v >= 0)
|
const swapUsedData = data.map((d: any) => Number(d.swap_used) || 0).filter((v: number) => v >= 0)
|
||||||
const avgSwapUsedGB = swapUsedData.length ? (swapUsedData.reduce((a: number, b: number) => a + b, 0) / swapUsedData.length / (1024 * 1024 * 1024)).toFixed(1) : '0'
|
const avgSwapUsedGB = swapUsedData.length ? (swapUsedData.reduce((a: number, b: number) => a + b, 0) / swapUsedData.length / (1024 * 1024 * 1024)).toFixed(1) : '0'
|
||||||
const swapTotalGB = data[0]?.swap_total ? (data[0].swap_total / (1024 * 1024 * 1024)).toFixed(1) : '0'
|
const swapTotalGB = data[0]?.swap_total ? (Number(data[0].swap_total) / (1024 * 1024 * 1024)).toFixed(1) : '0'
|
||||||
memAvg.value = {
|
memAvg.value = {
|
||||||
mem: validMem.length ? (validMem.reduce((a: number, b: number) => a + b, 0) / validMem.length).toFixed(1) : '-',
|
mem: validMem.length ? (validMem.reduce((a: number, b: number) => a + b, 0) / validMem.length).toFixed(1) : '-',
|
||||||
swap: validSwap.length ? (validSwap.reduce((a: number, b: number) => a + b, 0) / validSwap.length).toFixed(1) : '-',
|
swap: validSwap.length ? (validSwap.reduce((a: number, b: number) => a + b, 0) / validSwap.length).toFixed(1) : '-',
|
||||||
@@ -449,10 +455,10 @@ async function fetchDisks() {
|
|||||||
diskChart?.destroy()
|
diskChart?.destroy()
|
||||||
diskChart = createLineChart(diskChartRef.value!, timeLabels, datasets)
|
diskChart = createLineChart(diskChartRef.value!, timeLabels, datasets)
|
||||||
|
|
||||||
// 평균 계산 (전체 디스크) + 사용량/전체용량
|
// 평균 계산 (전체 디스크) + 사용량/전체용량 (BigInt는 문자열로 반환되므로 Number로 변환)
|
||||||
const allPercents = data.map((d: any) => d.disk_percent || 0).filter((v: number) => v > 0)
|
const allPercents = data.map((d: any) => d.disk_percent || 0).filter((v: number) => v > 0)
|
||||||
const allUsed = data.map((d: any) => d.disk_used || 0).filter((v: number) => v > 0)
|
const allUsed = data.map((d: any) => Number(d.disk_used) || 0).filter((v: number) => v > 0)
|
||||||
const allTotal = data.map((d: any) => d.disk_total || 0).filter((v: number) => v > 0)
|
const allTotal = data.map((d: any) => Number(d.disk_total) || 0).filter((v: number) => v > 0)
|
||||||
const avgUsedGB = allUsed.length ? (allUsed.reduce((a: number, b: number) => a + b, 0) / allUsed.length / (1024 * 1024 * 1024)).toFixed(1) : '-'
|
const avgUsedGB = allUsed.length ? (allUsed.reduce((a: number, b: number) => a + b, 0) / allUsed.length / (1024 * 1024 * 1024)).toFixed(1) : '-'
|
||||||
const avgTotalGB = allTotal.length ? (allTotal.reduce((a: number, b: number) => a + b, 0) / allTotal.length / (1024 * 1024 * 1024)).toFixed(1) : '-'
|
const avgTotalGB = allTotal.length ? (allTotal.reduce((a: number, b: number) => a + b, 0) / allTotal.length / (1024 * 1024 * 1024)).toFixed(1) : '-'
|
||||||
diskAvg.value = {
|
diskAvg.value = {
|
||||||
@@ -489,14 +495,14 @@ async function fetchContainers() {
|
|||||||
const cpuValues = containerRows.map((d: any) => d.cpu_percent || 0)
|
const cpuValues = containerRows.map((d: any) => d.cpu_percent || 0)
|
||||||
const cpuAvgVal = cpuValues.length ? (cpuValues.reduce((a: number, b: number) => a + b, 0) / cpuValues.length).toFixed(1) : '0'
|
const cpuAvgVal = cpuValues.length ? (cpuValues.reduce((a: number, b: number) => a + b, 0) / cpuValues.length).toFixed(1) : '0'
|
||||||
|
|
||||||
// Memory 평균 (bytes -> MB)
|
// Memory 평균 (bytes -> MB, BigInt는 문자열로 반환되므로 Number로 변환)
|
||||||
const memValues = containerRows.map((d: any) => (d.memory_usage || 0) / 1024 / 1024)
|
const memValues = containerRows.map((d: any) => (Number(d.memory_usage) || 0) / 1024 / 1024)
|
||||||
const memAvgVal = memValues.length ? (memValues.reduce((a: number, b: number) => a + b, 0) / memValues.length) : 0
|
const memAvgVal = memValues.length ? (memValues.reduce((a: number, b: number) => a + b, 0) / memValues.length) : 0
|
||||||
const memLimit = latest.memory_limit ? (latest.memory_limit / 1024 / 1024 / 1024).toFixed(1) + ' GB' : '-'
|
const memLimit = latest.memory_limit ? (Number(latest.memory_limit) / 1024 / 1024 / 1024).toFixed(1) + ' GB' : '-'
|
||||||
|
|
||||||
// Network 평균 (bytes/s -> KB/s)
|
// Network 평균 (bytes/s -> KB/s)
|
||||||
const rxValues = containerRows.map((d: any) => (d.network_rx || 0) / 1024)
|
const rxValues = containerRows.map((d: any) => (Number(d.network_rx) || 0) / 1024)
|
||||||
const txValues = containerRows.map((d: any) => (d.network_tx || 0) / 1024)
|
const txValues = containerRows.map((d: any) => (Number(d.network_tx) || 0) / 1024)
|
||||||
const rxAvgVal = rxValues.length ? (rxValues.reduce((a: number, b: number) => a + b, 0) / rxValues.length) : 0
|
const rxAvgVal = rxValues.length ? (rxValues.reduce((a: number, b: number) => a + b, 0) / rxValues.length) : 0
|
||||||
const txAvgVal = txValues.length ? (txValues.reduce((a: number, b: number) => a + b, 0) / txValues.length) : 0
|
const txAvgVal = txValues.length ? (txValues.reduce((a: number, b: number) => a + b, 0) / txValues.length) : 0
|
||||||
|
|
||||||
@@ -526,22 +532,22 @@ async function fetchContainers() {
|
|||||||
|
|
||||||
if (!containerCharts[name]) containerCharts[name] = {}
|
if (!containerCharts[name]) containerCharts[name] = {}
|
||||||
|
|
||||||
// CPU 차트 (0-100%)
|
// CPU 차트 (0-200% - 컨테이너는 멀티코어로 100% 초과 가능)
|
||||||
if (refs.cpu) {
|
if (refs.cpu) {
|
||||||
const cpuData = containerRows.map((d: any) => d.cpu_percent || 0)
|
const cpuData = containerRows.map((d: any) => d.cpu_percent || 0)
|
||||||
containerCharts[name].cpu = createLineChart(refs.cpu, timeLabels, [{ label: 'CPU %', data: cpuData, borderColor: '#3b82f6' }], 100)
|
containerCharts[name].cpu = createLineChart(refs.cpu, timeLabels, [{ label: 'CPU %', data: cpuData, borderColor: '#3b82f6' }], 200)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Memory 차트 (MB 단위) - 자동 스케일
|
// Memory 차트 (MB 단위) - 자동 스케일 (BigInt 문자열 변환)
|
||||||
if (refs.mem) {
|
if (refs.mem) {
|
||||||
const memData = containerRows.map((d: any) => (d.memory_usage || 0) / 1024 / 1024)
|
const memData = containerRows.map((d: any) => (Number(d.memory_usage) || 0) / 1024 / 1024)
|
||||||
containerCharts[name].mem = createLineChart(refs.mem, timeLabels, [{ label: 'Memory MB', data: memData, borderColor: '#22c55e' }], null)
|
containerCharts[name].mem = createLineChart(refs.mem, timeLabels, [{ label: 'Memory MB', data: memData, borderColor: '#22c55e' }], null)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Network 차트 (KB/s 단위) - 자동 스케일
|
// Network 차트 (KB/s 단위) - 자동 스케일 (BigInt 문자열 변환)
|
||||||
if (refs.net) {
|
if (refs.net) {
|
||||||
const rxData = containerRows.map((d: any) => (d.network_rx || 0) / 1024)
|
const rxData = containerRows.map((d: any) => (Number(d.network_rx) || 0) / 1024)
|
||||||
const txData = containerRows.map((d: any) => (d.network_tx || 0) / 1024)
|
const txData = containerRows.map((d: any) => (Number(d.network_tx) || 0) / 1024)
|
||||||
containerCharts[name].net = createLineChart(refs.net, timeLabels, [
|
containerCharts[name].net = createLineChart(refs.net, timeLabels, [
|
||||||
{ label: 'RX KB/s', data: rxData, borderColor: '#06b6d4' },
|
{ label: 'RX KB/s', data: rxData, borderColor: '#06b6d4' },
|
||||||
{ label: 'TX KB/s', data: txData, borderColor: '#f59e0b' }
|
{ label: 'TX KB/s', data: txData, borderColor: '#f59e0b' }
|
||||||
|
|||||||
Reference in New Issue
Block a user