Information Security Study
반복문으로 파일 내에 있는 모든 로그를 DB에 저장하기(시도중) 본문
반복문으로 파일 내에 있는 모든 로그를 DB에 저장하기(시도중)
log_aggr 디렉토리에 날짜별로 집계된 로그 파일을 db에 저장해볼 것이다.
우선 db 인스턴스를 생성했다.
3306 포트도 열어두었다.
인스턴스에 접속해서 root 계정의 비밀번호 설정을 해주었다.
사용할 유저를 생성하고 실습을 위해 우선 모든 권한을 부여했다.
권한 부여 후 적용을 위해 Flush privileges를 입력해야 한다.
select host, user form mysql.user where user = '유저명';
으로 유저의 권한을 확인할 수 있다.
%로 뜨는 것으로 보아 권한이 잘 부여되었다.
db 인스턴스에 root가 아닌 사용자로 접속한다.
데이터베이스를 생성하고 use해주었다.
위와 같은 구조로 sequence number, 데이터, 접속한 유저, 접속 엔드포인트를 저장할 수 있도록 테이블을 생성했다.
생성되었다.
/home/ubuntu/log/log-db.sh
집계된 로그 파일을 데이터베이스 스키마에 맞게 수정 후 별도의 디렉토리에 저장하는 스크립트
#!/bin/sh
# 1. 작업 경로 설정
aggr_dir="/home/ubuntu/log_aggr"
db_dir="/home/ubuntu/log_db"
# 작업 디렉토리 생성 (디렉토리가 없을 경우에만 생성)
mkdir -p "$aggr_dir"
mkdir -p "$db_dir"
# 2. 날짜별 파일명 설정
aggr_file="$aggr_dir"/$(date +%Y%m%d).log
db_file="$db_dir"/$(date +%Y%m%d)_for_db.log
# 3. 순번 초기화
count=1
# 4. 로그 파일 파싱 및 변환
# log_aggr 디렉토리에 있는 파일을 이용해 db 파일 생성
if [ -f "$aggr_file" ]; then
while IFS= read -r line; do
# 필요한 정보를 추출 (날짜/시간, 엔드포인트, 사용자)
date=$(echo "$line" | awk '{print $2}')
endpoint=$(echo "$line" | awk '{print $3}')
user=$(echo "$line" | awk '{print $NF}')
# 추출된 정보를 순번과 함께 원하는 형식으로 저장
echo "$count $date $user $endpoint" >> "$db_file"
# 순번 증가
count=$((count + 1))
done < "$aggr_file"
# 5. 작업 완료 메시지 출력
echo "데이터베이스 파일 생성이 완료되었습니다. 생성된 파일: $db_file"
else
echo "집계된 로그 파일($aggr_file)을 찾을 수 없습니다."
fi
db_dir은 집계된 로그 파일을 db 스키마에 맞게 수정한 후 저장될 경로다.
순번을 부여하기 위해 count를 선언했다.
# 4. 로그 파일 파싱 및 변환
# log_aggr 디렉토리에 있는 파일을 이용해 db 파일 생성
if [ -f "$aggr_file" ]; then
while IFS= read -r line; do
# 필요한 정보를 추출 (날짜/시간, 엔드포인트, 사용자)
date=$(echo "$line" | awk '{print $2}')
endpoint=$(echo "$line" | awk '{print $3}')
user=$(echo "$line" | awk '{print $NF}')
# 추출된 정보를 순번과 함께 원하는 형식으로 저장
echo "$count $date $user $endpoint" >> "$db_file"
# 순번 증가
count=$((count + 1))
done < "$aggr_file"
# 5. 작업 완료 메시지 출력
echo "데이터베이스 파일 생성이 완료되었습니다. 생성된 파일: $db_file"
else
echo "집계된 로그 파일($aggr_file)을 찾을 수 없습니다."
fi
집계 로그 파일이 존재하는지 확인한 후
while IFS= read -r line로 집계 로그 파일을 한 줄씩 읽어들인다.
date=$(echo "$line" | awk '{print $2}')는 awk로 로그 파일의 두 번째 필드를 추출하여 date 변수에 저장한다.
endpoint와 user도 동일한 방식으로 변수에 저장한다.
echo "$count $date $user $endpoint" >> "$db_file" 은 추출된 정보를 순번과 함께 지정된 형식으로 db_file에 추가한다.
실행권한 부여 후 실행하면
생성되었다고 뜬다.
해당 디렉토리에서 파일을 확인하면 db 스키마에 맞게 저장되었다.
이제 log_db에 있는 로그 파일을 데이터베이스에 삽입하는 스크립트를 작성할 것이다.
/home/ubuntu/log/log-db-store.sh
#!/bin/bash
# MySQL 클라이언트 경로
MYSQL_CMD="/usr/bin/mysql"
# 데이터베이스 설정
DB_HOST="ip"
DB_USER="db 유저명"
DB_PASS="db 패스워드"
DB_NAME="db명"
# 로그 파일 경로 설정
db_dir="/home/ubuntu/log_db"
LOG_FILE="$db_dir/$(date +%Y%m%d)_for_db.log"
ERROR_LOG="/tmp/mysql_error.log"
# 로그 파일이 있는지 확인
if [ -f "$LOG_FILE" ]; then
echo "로그 파일이 발견되었습니다: $LOG_FILE"
# 로그 파일의 총 줄 수를 확인
total_lines=$(wc -l < "$LOG_FILE")
echo "로그 파일 총 줄 수: $total_lines"
# 로그 파일을 한 줄씩 읽어서 처리
while IFS=' ' read -r count logdate loguser logendpoint; do
echo "처리 중 데이터: $count, $logdate, $loguser, $logendpoint"
# loguser가 'null'일 경우 실제 SQL의 NULL로 변환
if [ "$loguser" == "null" ]; then
loguser="NULL"
else
loguser="'$loguser'"
fi
# 중복된 데이터가 있는지 확인
DUPLICATE_CHECK=$(ssh ubuntu@$DB_HOST "$MYSQL_CMD -h $DB_HOST -u $DB_USER -p$DB_PASS -D $DB_NAME -e \"SELECT COUNT(*) FROM a_log WHERE sequence_number='$count';\"" 2>&1 | tail -n 1)
echo "중복 확인 결과: $DUPLICATE_CHECK" >> $ERROR_LOG
if [ "$DUPLICATE_CHECK" -eq 0 ]; then
# 데이터 삽입
INSERT_RESULT=$(ssh ubuntu@$DB_HOST "$MYSQL_CMD -h $DB_HOST -u $DB_USER -p$DB_PASS -D $DB_NAME -e \"INSERT INTO a_log (sequence_number, log_date, log_user, log_endpoint) VALUES ('$count', '$logdate', $loguser, '$logendpoint');\"" 2>&1)
echo "삽입 결과: $INSERT_RESULT" >> $ERROR_LOG
echo "데이터 삽입 완료: $count"
else
echo "중복된 데이터가 발견되었습니다: $count" >> $ERROR_LOG
fi
done < "$LOG_FILE"
echo "로그 파일을 성공적으로 데이터베이스에 삽입했습니다."
else
echo "로그 파일을 찾을 수 없습니다: $LOG_FILE"
fi
각 로그 항목에 대해 시퀀스 넘버로 중복인 로그 목록인지 확인하고
중복이 아닌 경우에만 데이터를 삽입하는 스크립트이다.
# 로그 파일이 있는지 확인
if [ -f "$LOG_FILE" ]; then
echo "로그 파일이 발견되었습니다: $LOG_FILE"
로그 파일이 존재하는지 확인한다.
# 로그 파일의 총 줄 수를 확인
total_lines=$(wc -l < "$LOG_FILE")
echo "로그 파일 총 줄 수: $total_lines"
로그 파일의 총 줄 수를 출력해서 로그별로 줄바꿈이 되어있는지 확인한다.
# 로그 파일을 한 줄씩 읽어서 처리
while IFS=' ' read -r count logdate loguser logendpoint; do
echo "처리 중 데이터: $count, $logdate, $loguser, $logendpoint"
로그 파일을 한 줄씩 읽고 공백을 기준으로 데이터를 분리해서 변수에 저장한다.
# 중복된 데이터가 있는지 확인
DUPLICATE_CHECK=$(ssh ubuntu@$DB_HOST "$MYSQL_CMD -h $DB_HOST -u $DB_USER -p$DB_PASS -D $DB_NAME -e \"SELECT COUNT(*) FROM a_log WHERE sequence_number='$count';\"" 2>&1 | tail -n 1)
echo "중복 확인 결과: $DUPLICATE_CHECK" >> $ERROR_LOG
변수에 중복된 데이터가 있는지 확인하고 결과를 오류 로그에 기록한다.
if [ "$DUPLICATE_CHECK" -eq 0 ]; then
# 데이터 삽입
INSERT_RESULT=$(ssh ubuntu@$DB_HOST "$MYSQL_CMD -h $DB_HOST -u $DB_USER -p$DB_PASS -D $DB_NAME -e \"INSERT INTO a_log (sequence_number, log_date, log_user, log_endpoint) VALUES ('$count', '$logdate', $loguser, '$logendpoint');\"" 2>&1)
echo "삽입 결과: $INSERT_RESULT" >> $ERROR_LOG
echo "데이터 삽입 완료: $count"
else
echo "중복된 데이터가 발견되었습니다: $count" >> $ERROR_LOG
fi
중복 값이 없다면 데이터를 삽입한다.
실행했지만 로그 파일의 첫 행만 db에 저장되는 문제가 발생했다.
'네트워크 캠퍼스 > 3차 프로젝트' 카테고리의 다른 글
블루/그린 방식으로 무중단 배포하기 (0) | 2024.08.13 |
---|---|
Infile Load 방식으로 병합된 로그 MySQL에 저장하기 (0) | 2024.08.12 |
젠킨스 파이프라인으로 배포 시 로그 파일이 다른 위치에 생기는 문제 해결 (0) | 2024.08.09 |
롤링 방식으로 무중단 배포하기, 젠킨스-nginx 설정파일 수정을 위한 공개키 복사 (0) | 2024.08.09 |
일반 배포 방식으로 앱 서버 두 개에 배포하기 (0) | 2024.08.09 |