Project/개인 Project

[개인 Project] NAS 를 이용한 개인 모니터링 시스템 구축하기 -2 편 (데이터 DB 저장)

강_토발즈 2025. 5. 20. 22:39

 

 

 

 

 

지난 번에 SNMP 프로토콜과 Shell Script 를 이용해서 시스템 정보를 추출했다. 파이썬의 라이브러리를 활용하면 ( 한 줄 추가하는 것으로) 간단하게 시스템 정보를 추출하고 출력할 수 있지만, 네트워크를 공부하는 입장에서 프로토콜을 직접 사용해보고, 스크립트 파일도 직접 작성해보는데 의의가 있기 때문에 조금 불편한 방법을 고수하기로 한다.

 

 

 

1. 쉘 스크립트에 저장 정보 추가

이미 작성된 스크립트가 원하는 정보를 잘 출력하고 있으므로, 이 정보들이 특정 폴더에 파일로 저장되도록 추가해준다.

 

#!/bin/bash

COMMUNITY="public"
TARGET="127.0.0.1"
LOG_DIR="$HOME/문서/monitoringProject/csv_logs"
mkdir -p "$LOG_DIR"

# CPU Load
CPU_LOAD=$(snmpget -v2c -c $COMMUNITY $TARGET UCD-SNMP-MIB::laLoad.1 | awk '{print $NF}')

# Memory (strip kB)
MEM_TOTAL=$(snmpget -v2c -c $COMMUNITY $TARGET UCD-SNMP-MIB::memTotalReal.0 | awk '{print $(NF-1)}')
MEM_AVAIL=$(snmpget -v2c -c $COMMUNITY $TARGET UCD-SNMP-MIB::memAvailReal.0 | awk '{print $(NF-1)}')
MEM_USED=$((MEM_TOTAL - MEM_AVAIL))

# Disk
DISK_USED=$(snmpget -v2c -c $COMMUNITY $TARGET UCD-SNMP-MIB::dskPercent.1 | awk '{print $NF}')

# Network
NET_IN=$(snmpget -v2c -c $COMMUNITY $TARGET IF-MIB::ifInOctets.2 | awk '{print $NF}')
NET_OUT=$(snmpget -v2c -c $COMMUNITY $TARGET IF-MIB::ifOutOctets.2 | awk '{print $NF}')

# GPU
GPU_INFO=$(nvidia-smi --query-gpu=utilization.gpu,memory.used,temperature.gpu --format=csv,noheader,nounits 2>/dev/null)
IFS=',' read -r GPU_UTIL GPU_MEM GPU_TEMP <<< "$GPU_INFO"

# Timestamp
NOW=$(date '+%Y-%m-%d %H:%M:%S')
DATE_FILE=$(date '+%Y-%m-%d')

CSV_LINE="$NOW,$CPU_LOAD,$MEM_USED,$MEM_TOTAL,$DISK_USED,$NET_IN,$NET_OUT,$GPU_UTIL,$GPU_MEM,$GPU_TEMP"
echo "$CSV_LINE" >> "$LOG_DIR/$DATE_FILE.csv"

#echo "[$NOW]"
#echo "CPU Load (1min):        $CPU_LOAD"
#echo "Memory Used (KB):       $MEM_USED / $MEM_TOTAL"
#echo "Disk Used (%):          $DISK_USED"
#echo "Network In (bytes):     $NET_IN"
#echo "Network Out (bytes):    $NET_OUT"
#echo "GPU Util (%):           $GPU_UTIL"
#echo "GPU Memory Used (MB):   $GPU_MEM"
#echo "GPU Temp (°C):          $GPU_TEMP"

 

 

로그를 따로 파일로 확인할 것이기 때문에 터미널에서 확인 할 필요가 없다. ( echo 주석 처리)

스크립트 파일을 실행하니, csv 파일이 생성되고, 실행한 시간에 대한 시스템 정보를 가져오는 것을 확인할 수 있다.

 

 

 

 

2. Crontab으로 스크립트 자동 실행 등록

 

crontab -e

 

 

 

컴퓨터가 켜져있을때 15분마다 데이터를 쌓도록 한다.

 

 

 

3. 파이썬 스크립트 파일 작성

 

데스크탑에 저장된 csv 파일을 보고, NAS의 DB 로 저장하는 파이썬 파일을 만든다. 저장 위치는 데스크탑이다. ( DHCP 때문에 IP가 변경될 수 있기 때문, NAS 는 IP 를 고정 해 두었다)

 

import csv
import os
import pymysql
from datetime import datetime

# CSV 파일 경로
DATE = datetime.now().strftime('%Y-%m-%d')
CSV_PATH = f'/home/kang/문서/monitoringProject/csv_logs/{DATE}.csv'

# DB 연결 설정 (NAS 쪽)
DB_HOST = '192.168.0.20'
DB_PORT = 3306
DB_USER = 
DB_PASS = 
DB_NAME = 'monitoring'

# 테이블명
TABLE = 'sys_metrics'

# 연결
conn = pymysql.connect(
    host=DB_HOST,
    port=DB_PORT,
    user=DB_USER,
    password=DB_PASS,
    database=DB_NAME,
    charset='utf8'
)

with conn:
    with conn.cursor() as cur:
        with open(CSV_PATH, newline='') as csvfile:
            reader = csv.reader(csvfile)
            inserted = 0
            for row in reader:
                timestamp = row[0]
                cur.execute(f"SELECT COUNT(*) FROM {TABLE} WHERE timestamp=%s", (timestamp,))
                if cur.fetchone()[0] == 0:
                    sql = f"""INSERT INTO {TABLE} (
                        timestamp, cpu_load, mem_used, mem_total, disk_used,
                        net_in, net_out, gpu_util, gpu_mem, gpu_temp
                    ) VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)"""
                    cur.execute(sql, tuple(row))
                    inserted += 1
        conn.commit()

print(f"{inserted} new rows inserted.")

 

DB 아이디와 비밀번호는 가렸다.

이 스크립트 파일을 실험 해보기 전에 DB 에서 먼저 테이블이 있어야 한다.

 

 

4. DB 테이블 생성

 

터미널을 통해 NAS 로 접속한다. (ssh 접속)
이후 MariaDB 에 접속하여 테이블을 생성해준다

NAS 접속 후 MariaDB 접속

 

 

CREATE DATABASE IF NOT EXISTS monitoring;
USE monitoring;

CREATE TABLE sys_metrics (
    id INT AUTO_INCREMENT PRIMARY KEY,
    timestamp DATETIME,
    cpu_load FLOAT,
    mem_used INT,
    mem_total INT,
    disk_used INT,
    net_in BIGINT,
    net_out BIGINT,
    gpu_util INT,
    gpu_mem INT,
    gpu_temp INT
);

 

 

 

테이블이 제대로 생성된 것을 확인할 수 있다.

참고로 NAS 의 MariaDB 에서는 기본적으로 root 계정이 사용자로서 외부에서 DB를 사용할 수 없다. 즉 새로운 외부 접속용 계정을 만들어서 데이터를 넣어야 한다. (root 계정의 보안 이유)

하지만 계정을 하나 또 만들기도 귀찮고, DB의 password 생성 규칙이 좀 까다롭기 때문에 (대문자, 숫자, 특수문자 다 쓰라고 함) root 계정도 외부에서 접속하여 DB 를 사용할 수 있게 권한을 부여해준다.

 

CREATE USER 'root'@'192.168.0.%' IDENTIFIED BY '현재_비밀번호';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'192.168.0.%' WITH GRANT OPTION;
FLUSH PRIVILEGES;

 

 

 

 

 

5. python 파일 실행 후 DB 확인하기

python /home/kang/문서/monitoringProject/insert_to_mariadb.py

 

 

(venv) 환경은 이전에 git 자동 push 에서 다뤘다.

파이썬 파일을 실행하니 6 new rows inserted 라는 문구가 반환되었다. 이제 DB 를 확인해보자.

 

USE monitoring;

SELECT * FROM sys_metrics ORDER BY timestamp DESC LIMIT 10;

 

 

 

 

데스크탑에 저장된 raw 데이터들이 DB로 잘 저장되는 것을 확인하였다.

 

 

 

6. 마무리

 

*/15 * * * * /home/kang/venv-monitoring/bin/python3 /home/kang/문서/monitoringProject/insert_to_mariadb.py

 

 

 

DB 저장 일을 하는 파이썬 파일도 crontab 에 등록해주었다. 수집, 저장 순서대로 진행되어야 하기 때문에 수집 명령이 위, 저장 명령이 아래로 가도록 작성하고 저장해주었다.

 

이제 컴퓨터가 켜지고 꺼지는 사이 동안은, 15분 마다 데이터를 수집하고 DB에 저장하는 작업이 실행된다. 다음 포스팅에서는 이 데이터들을 간단하게 볼 수 있는 웹 페이지를 만들어서 배포 해보도록 하자!