1. 시작하며
회사에서 진행한 프로젝트에서 Nginx 로그 파일을 관리할 필요가 있었습니다. 특히, 클라이언트 요청 값들을 검토해야 하는 상황이었는데, 로그 파일(access.log
, error.log
)이 지나치게 커져 있어 파일을 열어보는 것조차 어려운 상태였습니다.
문제 상황은 다음과 같았습니다.
access.log
파일이 6GB 이상 쌓여 있어 텍스트 에디터로 열 수 없음- 로그 파일이 커질수록 Nginx의 성능 저하 및 디스크 용량 증가 문제 발생
- 오래된 로그 파일이 자동으로 삭제되지 않아 불필요한 용량 차지
이를 해결하기 위해 Nginx 로그 파일을 일자별로 관리하는 방식이 필요했습니다.
이번 글에서는 Windows 환경에서 로그 파일을 자동으로 일자별로 관리하고, 불필요한 오래된 로그를 자동으로 삭제하는 방법을 공유하려고 합니다.
1.1 서버에서 Nginx 로그를 일자별로 관리하는 방법
리눅스 환경에서는 보통logrotate
를 사용하여 자동으로 로그를 회전(rotate)하고 일정 기간이 지나면 삭제할 수 있습니다.
그러나 Windows 서버에서는 logrotate
를 사용할 수 없기 때문에 다른 방법이 필요했습니다.
해당 문제를 해결하기 위해 생각해 낸 방법은 Windows 작업 스케줄러(Task Scheduler)를 이용하여 자동으로 로그를 관리하는 것이었습니다.
PowerShell 스크립트를 작성하여 매일 자정에 실행되도록 설정하고, OS 단에서 직접 관리하도록 구성하였습니다.
2. 목표
Nginx 로그 파일을 자동 관리하는 목표는 다음과 같습니다.
- 로그 파일을 일자별로 백업
- 매일 00:00(자정)에 실행되도록 설정
- Nginx의
access.log
,error.log
파일을 YYYYMMDD 형식으로 이름을 변경하여 저장 - 예)
access-20250219.log
,error-20250219.log
- 7일이 지난 로그 파일은 자동 삭제
- 오래된 로그 파일이 계속 쌓이면 디스크 용량을 차지하므로, 일정 기간이 지난 파일은 삭제
- 자동으로 수행되도록 Windows 작업 스케줄러(Task Scheduler) 사용
- 애플리케이션(Spring Boot 등)에서 처리하는 것이 아니라 OS 단에서 관리
- 매일 자동 실행되도록 설정
3. 개발 과정
3.1 PowerShell 스크립트 작성
Windows 환경에서 로그 파일을 자동으로 백업 및 삭제하는 PowerShell 스크립트를 작성합니다.
이 파일의 이름은 rotate_nginx_logs.ps1
이며, Nginx 경로 (ex. C:\Project\nginx\
)에 저장합니다.
- PowerShell 스크립트 코드 (rotate_logs.ps1) 예제
# --------------------------
# rotate_nginx_logs.ps1 - Nginx 로그 파일을 일자별로 백업 및 관리하는 스크립트
# --------------------------
# 1) 로그 파일이 저장된 경로 설정
# 로그 파일이 위치한 디렉터리 경로를 지정합니다.
$logDir = "C:\Project\nginx\logs"
# 현재 Nginx에서 사용 중인 로그 파일 경로
$accessLogFile = Join-Path $logDir "access.log"
$errorLogFile = Join-Path $logDir "error.log"
# 2) Nginx 실행 파일 및 설정 파일 경로 설정
# 로그를 갱신하기 위해 Nginx를 다시 로드해야 하므로, 실행 파일 및 설정 파일 경로를 지정합니다.
$nginxExe = "C:\Project\nginx\nginx.exe"
$nginxConf = "C:\Project\nginx\conf\nginx.conf"
$nginxPrefix = "C:\Project\nginx\nginx"
# 3) 전날 날짜(yyyyMMdd 포맷) 생성
# 로그 파일 이름에 사용될 날짜를 현재 날짜에서 -1일을 뺀 값으로 설정합니다.
$date = (Get-Date).AddDays(-1).ToString("yyyyMMdd")
# 4) 백업용 로그 파일 이름 지정
# 기존 로그 파일을 해당 날짜가 포함된 새로운 파일명으로 변경할 것입니다.
$accessBackup = Join-Path $logDir ("access-{0}.log" -f $date)
$errorBackup = Join-Path $logDir ("error-{0}.log" -f $date)
Write-Host "[1/5] Renaming current logs to date-based files..."
# 5) access.log를 날짜 기반 파일명으로 변경 (기존 로그 백업)
if (Test-Path $accessLogFile) { # access.log 파일이 존재하는 경우
if (-Not (Test-Path $accessBackup)) { # 동일한 백업 파일이 없는 경우에만 변경 수행
Rename-Item -Path $accessLogFile -NewName (Split-Path $accessBackup -Leaf) -Force
Write-Host " > Renamed access.log -> $accessBackup"
} else {
Write-Host " > $accessBackup already exists. Skipping rename."
}
}
# 6) error.log를 날짜 기반 파일명으로 변경 (기존 로그 백업)
if (Test-Path $errorLogFile) { # error.log 파일이 존재하는 경우
if (-Not (Test-Path $errorBackup)) { # 동일한 백업 파일이 없는 경우에만 변경 수행
Rename-Item -Path $errorLogFile -NewName (Split-Path $errorBackup -Leaf) -Force
Write-Host " > Renamed error.log -> $errorBackup"
} else {
Write-Host " > $errorBackup already exists. Skipping rename."
}
}
# 7) 새 로그 파일 생성
Write-Host "[2/5] Creating fresh access.log / error.log..."
# 로그 파일이 변경되었으므로, 새로운 빈 로그 파일을 생성합니다.
New-Item -ItemType File -Path $accessLogFile -Force | Out-Null
New-Item -ItemType File -Path $errorLogFile -Force | Out-Null
Write-Host " > Created: $accessLogFile, $errorLogFile"
# 8) Nginx에 로그 파일 변경을 알림
Write-Host "[3/5] Reopening Nginx logs to switch to new files..."
# Nginx는 실행 중인 상태에서 새로운 로그 파일을 인식하지 않으므로,
# "-s reopen" 명령을 사용하여 열린 로그 파일 핸들을 갱신하도록 지시합니다.
& "$nginxExe" -p $nginxPrefix -c $nginxConf -s reopen
# 9) 오래된 로그(7일 이상된 파일) 삭제
Write-Host "[4/5] Cleaning up old logs (older than 7 days)..."
$daysToKeep = 7 # 로그 보관 기간 설정 (7일)
# access 로그 삭제
Get-ChildItem -Path $logDir -Filter "access-*.log" `
| Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-$daysToKeep) } `
| Remove-Item -Force -ErrorAction SilentlyContinue
# error 로그 삭제
Get-ChildItem -Path $logDir -Filter "error-*.log" `
| Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-$daysToKeep) } `
| Remove-Item -Force -ErrorAction SilentlyContinue
Write-Host "[5/5] Done. Logs rotated successfully."
참고) PowerShell 스크립트 저장 시 주의할 점
- 스크립트 저장 시 반드시 "LF(Line Feed)" 형식으로 저장해야 합니다.
- "CRLF(Carriage Return + Line Feed)"로 저장하면 실행 시 오류가 발생할 수 있습니다.
CRLF로 저장하면 안 되는 이유는 다음과 같습니다.
- PowerShell 실행 오류 발생 가능
- Windows의 기본 메모장 등에서 저장하면 기본적으로 CRLF 형식으로 저장되는데,PowerShell 실행 시 예상치 못한 줄바꿈 문제가 발생하여 스크립트가 정상적으로 실행되지 않을 수 있습니다.
- Bash 환경과의 호환성 문제
- 일부 환경에서는 CRLF 줄바꿈이 있는 PowerShell 스크립트를 제대로 실행하지 못하는 경우가 있습니다.
- 특히 Git Bash, WSL(Windows Subsystem for Linux) 같은 환경에서 실행할 경우 문법 오류가 발생할 가능성이 큽니다.
- 실행 정책(Execution Policy) 문제 발생 가능성
- PowerShell에서 스크립트를 실행할 때 보안 정책(Execution Policy)에 따라 파일 무결성을 검사하는데, CRLF 줄바꿈이 포함된 경우 예상하지 못한 실행 오류가 발생할 수 있습니다.
3.2 Windows 작업 스케줄러 (Task Scheduler) 설정
이제 PowerShell 스크립트를 매일 자동 실행되도록 설정하겠습니다.
- 작업 스케줄러 열기
Win + R
→taskschd.msc
입력 후 Enter- 왼쪽에서 "작업 스케줄러 라이브러리" 선택
- "새 작업 만들기" 클릭
- 새 작업 만들기
- "작업 스케줄러 라이브러리" 선택
- "새 작업 만들기" 클릭
- [일반] 탭 설정
- 이름:
Nginx 로그 자동 정리
- 설명:
Nginx 로그를 날짜별로 변경하고 7일 이상 된 로그를 삭제합니다.
- 사용자 계정 변경 (기본 Admin → SYSTEM 계정 설정)
- "사용자 또는 그룹 변경(U)..." 버튼 클릭
- "개체 이름 입력" 필드에
SYSTEM
입력 후 "이름 확인(C)" 클릭 - 확인(O) 버튼 클릭하여 적용
- "사용자가 로그온했는지 여부에 관계없이 실행(W)" 체크
- "가장 높은 수준의 권한으로 실행(R)" 체크
- 이름:
- [트리거] 탭 - 실행 주기 설정
- "새로 만들기" 버튼 클릭
- 시작 시간:
매일 00:00
(자정) - 반복 주기:
매일
- "사용" 체크 후 확인 클릭
- [동작] 탭 - PowerShell 스크립트 실행
- "새로 만들기" 버튼 클릭
- 동작:
프로그램 시작
- 프로그램/스크립트:
powershell.exe
- 인수 추가
- 동작:
- "새로 만들기" 버튼 클릭
-ExecutionPolicy Bypass -File "C:\Project\nginx\rotate_nginx_logs.ps1"
참고) 사용자 또는 그룹 변경에서 SYSTEM 계정으로 설정해야 하는 이유
Windows 작업 스케줄러에서 PowerShell 스크립트를 실행할 때 사용자 계정을 잘못 설정하면 실행 오류가 발생할 수 있습니다.
특히, Nginx와 같은 웹 서버의 로그 파일을 다루는 작업은 최고 관리자 권한이 필요하므로 적절한 계정을 설정해야 합니다.
일반 관리자 계정(Admin)으로 실행하면 발생하는 문제는 다음과 같습니다.
access.log
또는error.log
파일이 변경되지 않음 (읽기 전용 또는 권한 부족 문제 발생)nginx.exe -s reopen
명령 실행 시 "Access Denied" (액세스 거부)" 오류 발생- 작업 스케줄러에서 실행 기록에 (0x1) 오류 발생 → 실행 실패
4. 확인하기
설정한 PowerShell 스크립트가 정상적으로 실행되었는지 Windows 작업 스케줄러 실행 결과와 로그 파일 변경 사항을 확인하였습니다.
- Windows 작업 스케줄러(Task Scheduler) 실행 결과
- 작업이 정상적으로 완료되었으며, 마지막 실행 결과가
(0x0)
으로 표시됨 (정상 실행)
- 작업이 정상적으로 완료되었으며, 마지막 실행 결과가
- Nginx 로그 파일 변경 사항 확인
access.log
및error.log
파일이 정상적으로 날짜별로 백업되었으며, 새로운 로그 파일이 생성됨
이를 통해 PowerShell 스크립트가 정상적으로 실행되어, Nginx 로그가 자동으로 회전(rotate) 및 백업됨을 확인할 수 있습니다.
5. 결론
이번 작업을 통해 Windows 서버에서도 Nginx 로그를 효율적으로 관리할 수 있는 방법을 배울 수 있었습니다.
처음에는 리눅스 환경에서 사용되는 logrotate
와 같은 기능을 Windows에서 구현하는 것이 쉽지 않을 것 같았지만, PowerShell과 Windows 작업 스케줄러(Task Scheduler)를 활용하면 자동으로 로그를 백업하고 관리할 수 있다는 점을 깨달았습니다.
- 윈도우 서버에서도 PowerShell을 활용하면 OS 단에서 자동화 처리가 가능하다.
- 작업 스케줄러(Task Scheduler)를 활용하면 특정 작업을 자동 실행하도록 쉽게 설정할 수 있다.
- 서버 운영 시, 로그 관리는 매우 중요하며 자동화하면 관리 비용을 줄일 수 있다.
'DevOps' 카테고리의 다른 글
[React + Nginx] Nginx에서 React(Vite) 배포 시 캐싱 문제 해결 및 최신 화면 자동 반영 적용 (0) | 2025.03.10 |
---|