Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- ansible
- build
- Flask
- javascript
- RDP
- 알고리즘
- LLM
- React
- docker
- turbo
- modbus
- BFS
- DP
- Two Pointer
- python
- AI
- monorepo
- Infra
- frontend
- Algorithm
- 프로그래머스
- 파이썬
- VectoreStore
- jenkins
- queue
- javascirpt
- CI/CD
- dfs
- rag
- typescript
Archives
- Today
- Total
DM Log
[RDP 모니터링 프로젝트 #5] 운영 서버 - Flask API & SQLite 메타데이터 저장 본문
PJT/영상 파일 재생 PJT
[RDP 모니터링 프로젝트 #5] 운영 서버 - Flask API & SQLite 메타데이터 저장
Dev. Dong 2025. 11. 30. 22:31개요
녹화 종료 시 Window 서버가 전달하는 메타데이터를 중앙 서버에 저장하고, 영상 조회를 위한 API를 제공하는 운영 서버 구조 구축
- SQLite DB 스키마 설계
- Flask API 구축
- record_stop.bat 수정(운영 서버 메타데이터 POST 전송)
- record_stop_test.bat 테스트 도구 제공
- 파일 전송 완료 후 DB 상태 업데이트
- React 영상 목록 / 재생을 위한 API제공
SQLite DB 설계
- DB는 영상 파일의 메타데이터만 저장
- rdp_server 스키마
| 필드 | 타입 | 설명 |
| id | PK | PK, 자동 증가 |
| name | TEXT | server1 / server2 ... |
| ip | TEXT | 서버 ip |
- rdp_video 스키마
| 필드 | 타입 | 설명 |
| id | PK | PK, 자동 증가 |
| server_name | TEXT | server1 / server2 ... |
| user | TEXT | RDP 사용자 |
| session | TEXT | 세션 ID |
| date | TEXT | 녹화 시작 날짜 YYYYMMDD |
| filename | TEXT | 파일명 |
| filepath | TEXT | Docker 내부 저장 경로 |
| uploaded | INTEGER | 0=전송 전 / 1=전송 완료 |
| time | TEXT | 녹화 시작 시간 |
| upload_time | TEXT | YYMMDDHHMMSS (전송 완료 시각) |
SQLite 테이블 생성 스크립트
- /app/db/init_db.py
import sqlite3
DB_PATH = "rdp.db"
conn = sqlite3.connect(DB_PATH)
cur = conn.cursor()
cur.execute("""
CREATE TABLE IF NOT EXISTS rdp_server (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT UNIQUE,
ip TEXT
)
""")
cur.execute("""
CREATE TABLE IF NOT EXISTS rdp_video (
id INTEGER PRIMARY KEY AUTOINCREMENT,
server_name TEXT,
user TEXT,
session TEXT,
date TEXT,
filename TEXT,
filepath TEXT,
uploaded INTEGER,
time TEXT,
upload_time TEXT
)
""")
conn.commit()
conn.close()
print("[INFO] Database initialized successfully.")
녹화 영상 저장 스크립트 수정
- record_stop.bat (메타데이터 POST 포함)
@echo off
setlocal enabledelayedexpansion
set BASE_DIR=C:\rdp_monitor
set RECORD_DIR=%BASE_DIR%\record
set LOG_DIR=%BASE_DIR%\logs
:: 인자: 사용자명/세션ID
set USER_NAME=%1
set SESSION_ID=%2
:: 날짜 계산
for /f "tokens=1-3 delims=- " %%a in ("%date%") do (
set YYYY=%%c
set MM=%%a
set DD=%%b
)
set TODAY=%YYYY%%MM%%DD%
:: 시간 계산
for /f "tokens=1-3 delims=:." %%a in ("%time%") do (
set HH=%%a
set MI=%%b
set SS=%%c
)
set TS=%YYYY%%MM%%DD%%HH%%MI%%SS%
:: 서버 이름
set SERVER_NAME=server1
:: 파일명 생성
set FILE_NAME=%USER_NAME%_%TS%.webm
set FILE_RELATIVE=%TODAY%/%USER_NAME%/%FILE_NAME%
:: PID 파일
set USER_FOLDER=%RECORD_DIR%\%TODAY%\%USER_NAME%
set PID_FILE=%USER_FOLDER%\%SESSION_ID%.pid
if exist "%PID_FILE%" (
set /p PID=<"%PID_FILE%"
taskkill /PID !PID! /F >nul 2>&1
del "%PID_FILE%"
)
:: 로그 기록
if not exist "%LOG_DIR%\%TODAY%" mkdir "%LOG_DIR%\%TODAY%"
echo [%date% %time%] STOP USER=%USER_NAME% SESSION=%SESSION_ID% FILE=%FILE_NAME% >> "%LOG_DIR%\%TODAY%\logoff.log"
:: 메타데이터 POST
powershell -Command ^
"Invoke-WebRequest -Uri 'http://운영 서버 IP/api/rdp/metadata' ^
-Method POST ^
-Body '{\"server\":\"%SERVER_NAME%\",\"user\":\"%USER_NAME%\",\"session\":\"%SESSION_ID%\",\"date\":\"%TODAY%\",\"filename\":\"%FILE_NAME%\",\"filepath\":\"%FILE_RELATIVE%\",\"uploaded\":0,\"time\":\"%HH%%MI%%SS%\"}' ^
-ContentType 'application/json'"
exit /b 0
- record_stop_test.bat (실제 녹화 없이 API 동작 확인 용)
@echo off
setlocal enabledelayedexpansion
echo ------------------------------
echo METADATA POST TEST START
echo ------------------------------
set USER_NAME=testuser
set SESSION_ID=0x99999
set SERVER_NAME=server1
:: 날짜
for /f "tokens=1-3 delims=- " %%a in ("%date%") do (
set YYYY=%%c
set MM=%%a
set DD=%%b
)
set TODAY=%YYYY%%MM%%DD%
:: 시간
for /f "tokens=1-3 delims=:." %%a in ("%time%") do (
set HH=%%a
set MI=%%b
set SS=%%c
)
set TS=%YYYY%%MM%%DD%%HH%%MI%%SS%
set FILE_NAME=%USER_NAME%_%TS%.webm
set FILE_RELATIVE=%TODAY%/%USER_NAME%/%FILE_NAME%
powershell -Command ^
"Invoke-WebRequest -Uri 'http://운영 서버 IP/api/rdp/metadata' ^
-Method POST ^
-Body '{\"server\":\"%SERVER_NAME%\",\"user\":\"%USER_NAME%\",\"session\":\"%SESSION_ID%\",\"date\":\"%TODAY%\",\"filename\":\"%FILE_NAME%\",\"filepath\":\"%FILE_RELATIVE%\",\"uploaded\":0,\"time\":\"%HH%%MI%%SS%\"}' ^
-ContentType 'application/json'"
echo TEST COMPLETE
pause
exit /b 0
Flask API
전체 코드 구조 요약
backend/
└── source/
├── modules.py
├── rdp_monitor_API.py
└── views.py
└── db/
├── init_db.py
└── rdp.db
modules.py - DB 공동 모듈
import sqlite3
def connect_to_rdpDB():
conn = sqlite3.connect('..\db\rdp.db')
conn.row_factory = sqlite3.Row
return conn
def rdpDB_query(sql, args=()):
conn = connect_to_rdpDB()
cur = conn.cursor()
cur.execute(sql, args)
sql_upper = sql.strip().upper()
if sql_upper.startswith("SELECT"):
rows = cur.fetchall()
rows = [dict(row) for row in rows]
else:
conn.commit()
rows = []
conn.close()
return rows
views.py - flask 실행 및 Blueprint 등록
from flask import Flask
from flask_cors import CORS
from rdp_monitor_API import rdp_monitor_api
app = Flask(__name__)
CORS(app)
# Blueprint 등록
app.register_blueprint(rdp_monitor_api, url_prefix="/rdp")
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5001, debug=True)
rdp_monitor_API.py - API 라우트 구현
from flask import Blueprint, request, jsonify, send_file
import os
from modules import rdpDB_query
rdp_monitor_api = Blueprint('rdp_monitor_api', __name__)
- 서버 리스트 조회 - GET /rdp/servers
@rdp_monitor_api.route("/servers", methods=["GET"])
def get_servers():
rows = rdpDB_query("""
SELECT name
FROM rdp_server
""")
return jsonify(rows)
- 메타데이터 저장 - POST /rdp/metadata
@rdp_monitor_api.route("/metadata", methods=["POST"])
def metadata():
data = request.json
rdpDB_query("""
INSERT INTO rdp_video
(server_name, user, session, date, filename, filepath, uploaded, time)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
""", (
data["server"],
data["user"],
data["session"],
data["date"],
data["filename"],
data["filepath"],
data.get("uploaded", 0),
data["time"]
))
return jsonify({"result":"ok"})
- 서버 별 녹화된 날짜 리스트 API - GET /rdp/dates?server=server1
@rdp_monitor_api.route("/dates", methods=["GET"])
def get_dates():
server = request.args.get("server")
rows = rdpDB_query("""
SELECT DISTINCT date
FROM rdp_video
WHERE server_name=?
ORDER BY date DESC
""", (server,))
dates = [r[0] for r in rows]
return jsonify(dates)
- 날짜 별 영상 목록 - GET /rdp/list?server=server1&date=20250312
@rdp_monitor_api.route("/list", methods=["GET"])
def get_list():
server = request.args.get("server")
date = request.args.get("date")
rows = rdpDB_query("""
SELECT id, filename, filepath, uploaded, user
FROM rdp_video
WHERE server_name=? AND date=?
ORDER BY time ASC
""", (server, date))
return jsonify(rows)
- 영상 재생 API - GET /api/rdp/video/<path>
@rdp_monitor_api.route("/video/<path:filepath>")
def serve_video(filepath):
full_path = f"../data/rdp-video/{filepath}"
if not os.path.exists(full_path):
return jsonify({"error": "file not found"}), 404
return send_file(full_path)
API 호출 정리
| 서버 리스트 | GET | /rdp/servers |
| 날짜 리스트 | GET | /rdp/dates?server=server1 |
| 날짜별 영상 목록 | GET | /rdp/list?server=server1&date=YYYYMMDD |
| 메타데이터 저장 | POST | /rdp/metadata |
| 영상 재생 | GET | /rdp/video/<path> |
'PJT > 영상 파일 재생 PJT' 카테고리의 다른 글
| [RDP 모니터링 프로젝트 #6] 운영 서버 - React 영상 재생 UI 구축 (0) | 2025.12.06 |
|---|---|
| [RDP 모니터링 프로젝트 #4] Window Scheduler + SFTP 자동 전송 시스템 구축 (0) | 2025.11.30 |
| [RDP 모니터링 프로젝트 #3] 다중 RDP 접속 대응 및 세션별 PID 관리 전략 (0) | 2025.11.30 |
| [RDP 모니터링 프로젝트 #2] ffmpeg 기반 화면 녹화 Batch 스크립트 구현 (0) | 2025.11.30 |
| [RDP 모니터링 프로젝트 #1] Window Server - RDP 접속 이벤트 기반 녹화 구조 설계 (0) | 2025.11.30 |