여러 로그 파일을 지정하고, 해당 파일에 로그가 적재될 때 자동으로 수집되도록 한 예시코드입니다. 이 코드를 실행하는 데 필요한 Dockerfile
도 함께 제공합니다.
Python 코드 (monitor_logs.py)
import os
import re
import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
from googleapiclient.discovery import build
from google.oauth2.service_account import Credentials
# Google Sheets API 설정
SCOPES = ['https://www.googleapis.com/auth/spreadsheets']
SERVICE_ACCOUNT_FILE = '/path/to/credentials.json' # Google 서비스 계정 JSON 키 파일 경로
SPREADSHEET_ID = 'your_spreadsheet_id' # Google Sheet의 스프레드시트 ID
SHEET_NAME = 'Sheet1' # Sheet 이름
creds = Credentials.from_service_account_file(SERVICE_ACCOUNT_FILE, scopes=SCOPES)
service = build('sheets', 'v4', credentials=creds)
# 도메인과 카운트를 Google Sheets에 업데이트
def update_google_sheets(domain):
# 시트에서 데이터를 조회
result = service.spreadsheets().values().get(
spreadsheetId=SPREADSHEET_ID,
range=f"{SHEET_NAME}!A:B"
).execute()
values = result.get('values', [])
# 도메인이 시트에 있는지 확인
domain_exists = False
for i, row in enumerate(values):
if len(row) > 0 and row[0] == domain:
# 도메인이 이미 있으면 카운트 증가
current_count = int(row[1]) if len(row) > 1 else 0
new_count = current_count + 1
values[i][1] = new_count
domain_exists = True
break
# 도메인이 없으면 새로 추가
if not domain_exists:
values.append([domain, 1])
# Google Sheets에 업데이트
body = {
'values': values
}
service.spreadsheets().values().update(
spreadsheetId=SPREADSHEET_ID,
range=f"{SHEET_NAME}!A1",
valueInputOption="RAW",
body=body
).execute()
# 로그 파일에서 도메인 이름 추출
def extract_domain_from_log(log_entry):
# 정규식을 사용해 도메인 이름 추출 (예: "A IN example.com")
match = re.search(r'IN\s+([a-zA-Z0-9.-]+)', log_entry)
if match:
return match.group(1)
return None
# 파일 변화 감지 핸들러
class LogFileHandler(FileSystemEventHandler):
def __init__(self, log_file):
self.log_file = log_file
# 파일 포인터를 끝으로 이동
self.file_pointer = open(log_file, 'r')
self.file_pointer.seek(0, os.SEEK_END)
def on_modified(self, event):
if event.src_path == self.log_file:
while True:
line = self.file_pointer.readline()
if not line:
break
log_entry = line.strip()
domain = extract_domain_from_log(log_entry) # 도메인 추출
if domain:
update_google_sheets(domain) # 도메인 카운트 업데이트
def monitor_logs(log_files):
observers = []
for log_file in log_files:
event_handler = LogFileHandler(log_file)
observer = Observer()
directory = os.path.dirname(log_file)
observer.schedule(event_handler, directory, recursive=False)
observer.start()
observers.append(observer)
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
for observer in observers:
observer.stop()
for observer in observers:
observer.join()
if __name__ == "__main__":
# 모니터링할 로그 파일 목록
log_files = [
"/var/log/coredns/coredns.log",
"/path/to/another/log/file.log",
# 필요에 따라 더 많은 로그 파일 경로 추가
]
monitor_logs(log_files)
SERVICE_ACCOUNT_FILE
,SPREADSHEET_ID
,SHEET_NAME
를 실제 값으로 변경해야 합니다.- 로그 파일 경로 목록
log_files
에 모니터링할 모든 로그 파일의 경로를 추가하세요.
Dockerfile
# 베이스 이미지 선택
FROM python:3.8-slim
# 필요한 시스템 패키지 설치
RUN apt-get update && apt-get install -y \
build-essential \
&& rm -rf /var/lib/apt/lists/*
# 작업 디렉토리 설정
WORKDIR /app
# 필요한 Python 패키지 설치
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
# 애플리케이션 코드 복사
COPY . /app
# 실행 명령 설정
CMD ["python", "monitor_logs.py"]
requirements.txt
watchdog
google-api-python-client
google-auth
google-auth-httplib2
google-auth-oauthlib
사용 방법
- 코드 및 파일 준비
- 위의
monitor_logs.py
,Dockerfile
,requirements.txt
파일을 동일한 디렉토리에 저장합니다. monitor_logs.py
에서 필요한 부분 (SERVICE_ACCOUNT_FILE
,SPREADSHEET_ID
,SHEET_NAME
)을 실제 값으로 수정합니다.credentials.json
파일을 준비하고,monitor_logs.py
에서 지정한 경로에 위치시킵니다.
- 위의
- Docker 이미지 빌드
docker build -t log-monitor .
- Docker 컨테이너 실행
docker run -d \ -v /path/to/your/logs:/var/log/coredns \ # 로그 파일 디렉토리 마운트 -v /path/to/credentials.json:/path/to/credentials.json \ # 크레덴셜 파일 마운트 log-monitor
- 위 명령에서
/path/to/your/logs
는 호스트의 로그 파일 디렉토리 경로입니다. /path/to/credentials.json
은 호스트의 서비스 계정 JSON 키 파일 경로입니다.
- 위 명령에서
참고사항
- 보안상의 이유로,
credentials.json
파일을 Docker 이미지에 직접 포함하지 않고, 컨테이너 실행 시 볼륨 마운트를 통해 제공하는 것이 좋습니다. - 로그 파일 디렉토리도 마찬가지로 컨테이너 내부에서 접근할 수 있도록 볼륨 마운트를 사용해야 합니다.
monitor_logs.py
에서 지정한 로그 파일 경로가 컨테이너 내부의 경로와 일치하는지 확인하세요.
추가 설명
- 여러 로그 파일 모니터링: 수정된 코드는
log_files
리스트에 지정된 모든 로그 파일을 동시에 모니터링합니다. - Docker 환경에서 파일 접근: Docker 컨테이너는 기본적으로 호스트의 파일 시스템에 접근할 수 없으므로, 필요한 파일 및 디렉토리를 볼륨 마운트를 통해 컨테이너 내부에 연결해야 합니다.
- 의존성 관리:
requirements.txt
파일을 사용하여 필요한 Python 패키지를 설치합니다.
이렇게 구성하면 다양한 로그 파일을 지정하고, 해당 파일에 로그가 적재될 때 자동으로 수집하여 Google Sheets에 업데이트할 수 있습니다. 아래는 다양한 옵션을 제공하도록 개선된 코드와 업데이트된 Dockerfile
입니다. 이 코드는 명령줄 인자와 환경 변수를 통해 설정을 유연하게 변경할 수 있도록 하였으며, 로깅 기능과 에러 처리를 강화하였습니다.
개선된 Python 코드 (monitor_logs.py)
import os
import re
import time
import argparse
import logging
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
from googleapiclient.discovery import build
from google.oauth2.service_account import Credentials
# 로깅 설정
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
# 명령줄 인자 파서 설정
def parse_arguments():
parser = argparse.ArgumentParser(description='Log Monitor Script')
parser.add_argument('--log-files', nargs='+', required=True, help='모니터링할 로그 파일들의 경로를 공백으로 구분하여 입력')
parser.add_argument('--credentials', required=True, help='Google 서비스 계정 JSON 키 파일 경로')
parser.add_argument('--spreadsheet-id', required=True, help='Google Sheets의 스프레드시트 ID')
parser.add_argument('--sheet-name', default='Sheet1', help='Google Sheets의 시트 이름')
parser.add_argument('--regex', default=r'IN\s+([a-zA-Z0-9.-]+)', help='도메인 추출을 위한 정규 표현식')
parser.add_argument('--log-level', default='INFO', help='로깅 레벨 (DEBUG, INFO, WARNING, ERROR, CRITICAL)')
return parser.parse_args()
# Google Sheets API 설정
def initialize_google_sheets(credentials_path, scopes):
creds = Credentials.from_service_account_file(credentials_path, scopes=scopes)
service = build('sheets', 'v4', credentials=creds)
return service
# 도메인과 카운트를 Google Sheets에 업데이트
def update_google_sheets(service, spreadsheet_id, sheet_name, domain):
try:
# 시트에서 데이터를 조회
result = service.spreadsheets().values().get(
spreadsheetId=spreadsheet_id,
range=f"{sheet_name}!A:B"
).execute()
values = result.get('values', [])
# 도메인이 시트에 있는지 확인
domain_exists = False
for i, row in enumerate(values):
if len(row) > 0 and row[0] == domain:
# 도메인이 이미 있으면 카운트 증가
current_count = int(row[1]) if len(row) > 1 else 0
new_count = current_count + 1
values[i][1] = new_count
domain_exists = True
break
# 도메인이 없으면 새로 추가
if not domain_exists:
values.append([domain, 1])
# Google Sheets에 업데이트
body = {
'values': values
}
service.spreadsheets().values().update(
spreadsheetId=spreadsheet_id,
range=f"{sheet_name}!A1",
valueInputOption="RAW",
body=body
).execute()
logging.debug(f"Updated Google Sheets with domain: {domain}")
except Exception as e:
logging.error(f"Failed to update Google Sheets: {e}")
# 로그 파일에서 도메인 이름 추출
def extract_domain_from_log(log_entry, regex_pattern):
match = re.search(regex_pattern, log_entry)
if match:
return match.group(1)
return None
# 파일 변화 감지 핸들러
class LogFileHandler(FileSystemEventHandler):
def __init__(self, log_file, regex_pattern, service, spreadsheet_id, sheet_name):
self.log_file = log_file
self.regex_pattern = regex_pattern
self.service = service
self.spreadsheet_id = spreadsheet_id
self.sheet_name = sheet_name
try:
self.file_pointer = open(log_file, 'r')
self.file_pointer.seek(0, os.SEEK_END)
except Exception as e:
logging.error(f"Failed to open log file {log_file}: {e}")
def on_modified(self, event):
if event.src_path == self.log_file:
while True:
line = self.file_pointer.readline()
if not line:
break
log_entry = line.strip()
domain = extract_domain_from_log(log_entry, self.regex_pattern) # 도메인 추출
if domain:
update_google_sheets(self.service, self.spreadsheet_id, self.sheet_name, domain) # 도메인 카운트 업데이트
def monitor_logs(log_files, regex_pattern, service, spreadsheet_id, sheet_name):
observers = []
for log_file in log_files:
event_handler = LogFileHandler(log_file, regex_pattern, service, spreadsheet_id, sheet_name)
observer = Observer()
directory = os.path.dirname(log_file)
observer.schedule(event_handler, directory, recursive=False)
observer.start()
observers.append(observer)
logging.info(f"Started monitoring {log_file}")
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
for observer in observers:
observer.stop()
logging.info("Stopping observer")
for observer in observers:
observer.join()
if __name__ == "__main__":
args = parse_arguments()
# 로깅 레벨 설정
numeric_level = getattr(logging, args.log_level.upper(), None)
if isinstance(numeric_level, int):
logging.getLogger().setLevel(numeric_level)
else:
logging.error(f"Invalid log level: {args.log_level}")
SCOPES = ['https://www.googleapis.com/auth/spreadsheets']
# Google Sheets 서비스 초기화
service = initialize_google_sheets(args.credentials, SCOPES)
# 모니터링 시작
monitor_logs(args.log_files, args.regex, service, args.spreadsheet_id, args.sheet_name)
- 명령줄 인자 지원 (argparse 사용)
--log-files
: 모니터링할 로그 파일들의 경로를 공백으로 구분하여 입력합니다.--credentials
: Google 서비스 계정 JSON 키 파일 경로를 지정합니다.--spreadsheet-id
: 업데이트할 Google Sheets의 스프레드시트 ID를 지정합니다.--sheet-name
: 업데이트할 시트의 이름을 지정합니다.--regex
: 도메인 추출을 위한 정규 표현식을 지정합니다.--log-level
: 로깅 레벨을 설정합니다 (DEBUG, INFO, WARNING, ERROR, CRITICAL).
- 로깅 추가 (logging 모듈 사용)
- 스크립트의 동작 상태를 로그로 출력하여 모니터링 및 디버깅을 용이하게 합니다.
--log-level
인자를 통해 로깅 레벨을 조정할 수 있습니다.
- 에러 처리 강화
- 예외 처리를 통해 발생할 수 있는 오류를 캡처하고 로그에 기록합니다.
- 로그 파일을 열지 못하는 경우와 Google Sheets 업데이트 실패 시 에러를 로그로 출력합니다.
- 유연성 향상
- 정규 표현식을 명령줄 인자로 받아 다양한 로그 형식에 대응할 수 있도록 하였습니다.
- 로깅 레벨을 조정하여 필요에 따라 상세한 정보를 얻을 수 있습니다.
업데이트된 Dockerfile
# 베이스 이미지 선택
FROM python:3.8-slim
# 필요한 시스템 패키지 설치
RUN apt-get update && apt-get install -y \
build-essential \
&& rm -rf /var/lib/apt/lists/*
# 작업 디렉토리 설정
WORKDIR /app
# 필요한 Python 패키지 설치
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
# 애플리케이션 코드 복사
COPY monitor_logs.py /app/
# 실행 명령 설정 (명령줄 인자는 ENTRYPOINT로 처리)
ENTRYPOINT ["python", "monitor_logs.py"]
requirements.txt
watchdog
google-api-python-client
google-auth
google-auth-httplib2
google-auth-oauthlib
참고: argparse
는 표준 라이브러리이므로 requirements.txt
에 추가할 필요가 없습니다.
추가 옵션 및 유의사항
- 환경 변수 지원: 필요에 따라 코드를 수정하여 환경 변수를 통해 설정을 제공할 수 있습니다.
- 로그 레벨 조정:
--log-level
인자를 통해 로깅 레벨을 조정할 수 있습니다. 디버깅이 필요한 경우DEBUG
로 설정하면 상세한 로그를 확인할 수 있습니다. - 정규 표현식 커스터마이징:
--regex
인자를 통해 로그 파일 형식에 맞는 정규 표현식을 지정할 수 있습니다. 예를 들어, 로그 형식이 다를 경우 이에 맞는 정규 표현식을 입력하면 됩니다. - 에러 로깅 및 알림: 더 강화된 에러 처리를 통해 문제가 발생할 경우 이메일이나 슬랙으로 알림을 보내도록 코드를 확장할 수 있습니다.
- 환경 변수 사용 예시: Docker 실행 시
-e
옵션을 사용하여 환경 변수를 전달하고, 코드에서os.environ.get('ENV_VAR_NAME')
으로 가져올 수 있습니다.
이렇게 개선된 코드는 사용자가 다양한 옵션을 통해 설정을 유연하게 변경할 수 있도록 하였으며, 로깅과 에러 처리를 통해 안정성을 높였습니다. Docker 환경에서도 쉽게 설정을 변경하여 사용할 수 있도록 명령줄 인자와 볼륨 마운트를 활용하였습니다. 필요에 따라 코드를 더 확장하여 환경 변수 지원이나 알림 기능 등을 추가할 수 있습니다.
추가로, Python 데몬으로 실행되도록 개선된 코드와 업데이트된 Dockerfile
입니다. 이 코드는 python-daemon
모듈을 사용하여 백그라운드에서 데몬으로 실행되며, 필요한 경우 로그 파일을 통해 상태를 모니터링할 수 있습니다.
개선된 Python 코드 (monitor_logs.py)
import os
import re
import time
import argparse
import logging
import signal
import sys
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
from googleapiclient.discovery import build
from google.oauth2.service_account import Credentials
# 데몬 라이브러리 임포트
import daemon
from daemon import pidfile
# 로깅 설정
def setup_logging(log_file=None, log_level=logging.INFO):
logging.basicConfig(
level=log_level,
format='%(asctime)s - %(levelname)s - %(message)s',
filename=log_file,
filemode='a'
)
# 명령줄 인자 파서 설정
def parse_arguments():
parser = argparse.ArgumentParser(description='Log Monitor Daemon Script')
parser.add_argument('--log-files', nargs='+', required=True, help='모니터링할 로그 파일들의 경로를 공백으로 구분하여 입력')
parser.add_argument('--credentials', required=True, help='Google 서비스 계정 JSON 키 파일 경로')
parser.add_argument('--spreadsheet-id', required=True, help='Google Sheets의 스프레드시트 ID')
parser.add_argument('--sheet-name', default='Sheet1', help='Google Sheets의 시트 이름')
parser.add_argument('--regex', default=r'IN\s+([a-zA-Z0-9.-]+)', help='도메인 추출을 위한 정규 표현식')
parser.add_argument('--log-level', default='INFO', help='로깅 레벨 (DEBUG, INFO, WARNING, ERROR, CRITICAL)')
parser.add_argument('--daemon-log-file', default='/var/log/monitor_logs_daemon.log', help='데몬 로깅 파일 경로')
parser.add_argument('--pid-file', default='/var/run/monitor_logs.pid', help='데몬 PID 파일 경로')
return parser.parse_args()
# Google Sheets API 설정
def initialize_google_sheets(credentials_path, scopes):
creds = Credentials.from_service_account_file(credentials_path, scopes=scopes)
service = build('sheets', 'v4', credentials=creds)
return service
# 도메인과 카운트를 Google Sheets에 업데이트
def update_google_sheets(service, spreadsheet_id, sheet_name, domain):
try:
# 시트에서 데이터를 조회
result = service.spreadsheets().values().get(
spreadsheetId=spreadsheet_id,
range=f"{sheet_name}!A:B"
).execute()
values = result.get('values', [])
# 도메인이 시트에 있는지 확인
domain_exists = False
for i, row in enumerate(values):
if len(row) > 0 and row[0] == domain:
# 도메인이 이미 있으면 카운트 증가
current_count = int(row[1]) if len(row) > 1 else 0
new_count = current_count + 1
values[i][1] = new_count
domain_exists = True
break
# 도메인이 없으면 새로 추가
if not domain_exists:
values.append([domain, 1])
# Google Sheets에 업데이트
body = {
'values': values
}
service.spreadsheets().values().update(
spreadsheetId=spreadsheet_id,
range=f"{sheet_name}!A1",
valueInputOption="RAW",
body=body
).execute()
logging.debug(f"Updated Google Sheets with domain: {domain}")
except Exception as e:
logging.error(f"Failed to update Google Sheets: {e}")
# 로그 파일에서 도메인 이름 추출
def extract_domain_from_log(log_entry, regex_pattern):
match = re.search(regex_pattern, log_entry)
if match:
return match.group(1)
return None
# 파일 변화 감지 핸들러
class LogFileHandler(FileSystemEventHandler):
def __init__(self, log_file, regex_pattern, service, spreadsheet_id, sheet_name):
self.log_file = log_file
self.regex_pattern = regex_pattern
self.service = service
self.spreadsheet_id = spreadsheet_id
self.sheet_name = sheet_name
try:
self.file_pointer = open(log_file, 'r')
self.file_pointer.seek(0, os.SEEK_END)
except Exception as e:
logging.error(f"Failed to open log file {log_file}: {e}")
def on_modified(self, event):
if event.src_path == self.log_file:
while True:
line = self.file_pointer.readline()
if not line:
break
log_entry = line.strip()
domain = extract_domain_from_log(log_entry, self.regex_pattern) # 도메인 추출
if domain:
update_google_sheets(self.service, self.spreadsheet_id, self.sheet_name, domain) # 도메인 카운트 업데이트
def monitor_logs(log_files, regex_pattern, service, spreadsheet_id, sheet_name):
observers = []
for log_file in log_files:
event_handler = LogFileHandler(log_file, regex_pattern, service, spreadsheet_id, sheet_name)
observer = Observer()
directory = os.path.dirname(log_file)
observer.schedule(event_handler, directory, recursive=False)
observer.start()
observers.append(observer)
logging.info(f"Started monitoring {log_file}")
# 신호 처리 설정
def graceful_exit(signum, frame):
logging.info("Received termination signal, stopping observers...")
for observer in observers:
observer.stop()
sys.exit(0)
signal.signal(signal.SIGTERM, graceful_exit)
signal.signal(signal.SIGINT, graceful_exit)
while True:
time.sleep(1)
def main():
args = parse_arguments()
# 로깅 레벨 설정
numeric_level = getattr(logging, args.log_level.upper(), None)
if not isinstance(numeric_level, int):
logging.error(f"Invalid log level: {args.log_level}")
numeric_level = logging.INFO
setup_logging(log_file=args.daemon_log_file, log_level=numeric_level)
SCOPES = ['https://www.googleapis.com/auth/spreadsheets']
# Google Sheets 서비스 초기화
service = initialize_google_sheets(args.credentials, SCOPES)
# 모니터링 시작
monitor_logs(args.log_files, args.regex, service, args.spreadsheet_id, args.sheet_name)
if __name__ == "__main__":
args = parse_arguments()
# 데몬 컨텍스트 설정
with daemon.DaemonContext(
working_directory='/',
umask=0o002,
pidfile=pidfile.TimeoutPIDLockFile(args.pid_file),
stdout=sys.stdout,
stderr=sys.stderr,
):
main()
- 데몬 모듈 사용 (python-daemon):
daemon
모듈을 사용하여 스크립트를 데몬으로 실행합니다. - PID 파일 관리:
--pid-file
인자를 추가하여 데몬의 PID 파일 경로를 지정할 수 있습니다. - 데몬 로그 파일 설정:
--daemon-log-file
인자를 통해 데몬의 로그 출력 경로를 지정합니다. - 신호 처리 추가:
SIGTERM
및SIGINT
신호를 처리하여 안전하게 종료할 수 있도록 하였습니다. - 로깅 설정 개선:
setup_logging
함수를 통해 로깅 설정을 파일로 출력하도록 수정하였습니다.
업데이트된 Dockerfile
# 베이스 이미지 선택
FROM python:3.8-slim
# 필요한 시스템 패키지 설치
RUN apt-get update && apt-get install -y \
build-essential \
&& rm -rf /var/lib/apt/lists/*
# 작업 디렉토리 설정
WORKDIR /app
# 필요한 Python 패키지 설치
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
# 애플리케이션 코드 복사
COPY monitor_logs.py /app/
# 로그 디렉토리 생성
RUN mkdir -p /var/log
# 실행 명령 설정
CMD ["python", "monitor_logs.py"]
requirements.txt
watchdog
google-api-python-client
google-auth
google-auth-httplib2
google-auth-oauthlib
python-daemon
주의: python-daemon
패키지를 추가하여 데몬 기능을 지원합니다.
사용 방법
- 코드 및 파일 준비
monitor_logs.py
,Dockerfile
,requirements.txt
파일을 동일한 디렉토리에 저장합니다.credentials.json
파일을 준비하고 적절한 위치에 저장합니다.
- Docker 이미지 빌드
docker build -t log-monitor-daemon .
- Docker 컨테이너 실행 설명
docker run -d \ -v /path/to/your/logs:/logs \ # 로그 파일 디렉토리 마운트 -v /path/to/credentials.json:/app/credentials.json \ # 크레덴셜 파일 마운트 -v /var/log/monitor_logs_daemon.log:/var/log/monitor_logs_daemon.log \ # 데몬 로그 파일 마운트 -v /var/run/monitor_logs.pid:/var/run/monitor_logs.pid \ # PID 파일 마운트 log-monitor-daemon \ --log-files /logs/coredns.log /logs/another.log \ # 모니터링할 로그 파일 지정 --credentials /app/credentials.json \ # 컨테이너 내에서의 크레덴셜 파일 경로 --spreadsheet-id your_spreadsheet_id \ # 실제 스프레드시트 ID로 변경 --sheet-name Sheet1 \ # 시트 이름 지정 --regex 'IN\s+([a-zA-Z0-9.-]+)' \ # 필요에 따라 정규 표현식 변경 --log-level INFO \ # 로깅 레벨 설정 --daemon-log-file /var/log/monitor_logs_daemon.log \ # 데몬 로그 파일 경로 --pid-file /var/run/monitor_logs.pid # PID 파일 경로
-v /path/to/your/logs:/logs
: 호스트의 로그 파일 디렉토리를 컨테이너의/logs
디렉토리에 마운트합니다.-v /path/to/credentials.json:/app/credentials.json
: 호스트의 크레덴셜 파일을 컨테이너의/app/credentials.json
에 마운트합니다.-v /var/log/monitor_logs_daemon.log:/var/log/monitor_logs_daemon.log
: 데몬의 로그 파일을 호스트에서 접근할 수 있도록 마운트합니다.-v /var/run/monitor_logs.pid:/var/run/monitor_logs.pid
: PID 파일을 호스트에서 접근할 수 있도록 마운트합니다.--daemon-log-file
,--pid-file
: 데몬의 로그 파일과 PID 파일의 경로를 지정합니다.
추가 설명
- 데몬으로 실행되는 이유: 데몬으로 실행하면 프로세스가 백그라운드에서 독립적으로 동작하며, 시스템 재시작 시 자동으로 시작하도록 설정할 수 있습니다.
- 신호 처리:
SIGTERM
및SIGINT
신호를 처리하여 데몬이 종료될 때 리소스를 적절히 정리합니다. - 로그 파일 관리: 데몬의 로그 출력을 파일로 지정하여 백그라운드에서 실행되는 동안 발생하는 이벤트를 추적할 수 있습니다.
- PID 파일: PID 파일을 생성하여 데몬의 프로세스 ID를 추적하고, 중복 실행을 방지하거나 프로세스를 제어하는 데 사용할 수 있습니다.
유의사항
- Docker에서 데몬 실행 고려사항: 일반적으로 Docker 컨테이너는 하나의 포그라운드 프로세스를 실행하도록 설계되었습니다. 따라서 컨테이너 내부에서 데몬을 실행하는 것은 권장되지 않을 수 있습니다. 그러나 사용자가 특별히 데몬으로 실행되기를 원하는 경우 위와 같이 구성할 수 있습니다.
- 시스템 데몬으로 실행: 만약 Docker를 사용하지 않고 시스템 데몬으로 실행하고자 한다면, 이 스크립트를 서비스로 등록하여 사용하면 됩니다.
- 권한 문제: 로그 파일이나 PID 파일의 경로가 시스템에 따라 접근 권한 문제가 발생할 수 있으므로, 필요에 따라 경로나 권한을 조정해야 합니다.
- 보안: 크레덴셜 파일과 로그 파일이 외부에 노출되지 않도록 권한 관리에 유의해야 합니다.
이렇게 개선된 코드는 Python 데몬으로 동작하며, 다양한 옵션을 제공하여 사용자의 요구에 맞게 설정할 수 있습니다. 데몬으로 실행됨에 따라 시스템 리소스를 효율적으로 사용하고, 백그라운드에서 안정적으로 로그를 모니터링할 수 있습니다.
필요에 따라 코드를 더 확장하여 서비스 관리 도구(systemd 등)와 연동하거나 모니터링 및 알림 기능을 강화할 수 있습니다.
댓글