부동산·지원금·생활정책 업데이트 2026.06.05
IT

tail 명령어로 로그 실시간 확인하기: 서버 오류 원인 좁히는 순서

2026.05.11 issuebreaker

tail -f, tail -n, journalctl, Nginx 로그, PM2 로그를 함께 사용해 서버 오류를 실시간으로 확인하고 원인을 분리하는 방법을 정리했습니다.

배포 직후 웹사이트가 502를 내거나, Node.js 앱이 재시작을 반복하거나, Nginx는 살아 있는데 화면에는 오류만 보이는 상황에서는 브라우저 화면보다 로그를 먼저 확인하는 편이 원인을 빨리 좁힐 수 있습니다. 이 글은 tail 명령어로 로그 실시간 확인하기를 기준으로, 어떤 로그 파일을 봐야 하는지, 아무 내용이 안 나올 때 무엇을 의심해야 하는지, 권한이나 경로 문제를 어떻게 분리할지까지 실제 서버 점검 순서로 정리합니다.

이 글에서 해결할 문제

tail은 파일의 마지막 부분을 보여주는 리눅스 명령어입니다. 여기에 -f 옵션을 붙이면 파일에 새로 추가되는 내용을 계속 따라가며 볼 수 있습니다. 서버 운영에서는 배포 직후, 서비스 재시작 직후, 에러 재현 직후에 특히 자주 사용합니다.

다만 실제로 막히는 지점은 명령어 자체보다 다음과 같은 부분입니다.

  • 어떤 로그 파일을 봐야 하는지 모른다.
  • tail -f를 실행했는데 아무 내용도 추가되지 않는다.
  • 파일은 있는데 Permission denied가 나온다.
  • 서비스는 실행 중인데 다른 위치에 로그가 쌓인다.
  • Nginx, systemd, PM2, 애플리케이션 로그가 서로 달라서 어디부터 봐야 할지 헷갈린다.

서버를 운영하다 보면 처음에는 코드 오류처럼 보였지만 실제 원인은 로그 경로, 실행 사용자, 파일 권한, 서비스 실행 방식 차이인 경우가 많습니다. 그래서 tail은 단독 명령어라기보다 서비스 상태 확인과 함께 써야 효과가 좋습니다.

먼저 확인할 핵심 요약

확인 항목 명령어 예시 판단 기준
로그 파일 존재 여부 ls -l /var/log/nginx/error.log 파일 경로가 맞는지, 크기가 변하는지 확인
마지막 로그 확인 tail -n 50 /var/log/nginx/error.log 최근 오류가 남아 있는지 확인
실시간 로그 추적 tail -f /var/log/nginx/error.log 요청을 보낸 시점에 로그가 추가되는지 확인
서비스 상태 확인 systemctl status nginx 서비스가 실행 중인지, 재시작 중인지 확인
systemd 로그 확인 journalctl -u nginx -n 50 파일 로그가 아닌 journal에 에러가 남는지 확인

Debian/Ubuntu 계열에서는 시스템 로그로 /var/log/syslog를 보는 경우가 많습니다. CentOS/RHEL 계열에서는 환경에 따라 /var/log/messages를 먼저 확인할 수 있습니다. 서버 배포판과 서비스 설정에 따라 위치가 다를 수 있으므로, 파일명을 단정하기보다 실제 설정과 상태를 함께 확인해야 합니다.

기본 사용법: 마지막 줄 보기와 실시간 따라가기

파일의 마지막 10줄만 확인할 때는 옵션 없이 tail을 사용할 수 있습니다.

tail /var/log/nginx/error.log

최근 50줄을 확인하려면 -n 옵션을 사용합니다.

tail -n 50 /var/log/nginx/error.log

새 로그가 추가되는 것을 실시간으로 보려면 -f 옵션을 붙입니다.

tail -f /var/log/nginx/error.log

실시간 확인을 중단하려면 Ctrl + C를 누르면 됩니다. 이 명령은 로그 파일을 읽는 명령이라 비교적 안전한 편이지만, 화면에 출력되는 내용에 토큰, 세션, 개인정보가 포함될 수 있으므로 공유 화면이나 캡처를 만들 때는 주의해야 합니다.

실제 서버 운영 중 헷갈리기 쉬운 지점

로그 확인에서 가장 많이 헷갈리는 부분은 “서비스가 실행 중인 위치”와 “로그가 기록되는 위치”가 다를 수 있다는 점입니다. 예를 들어 Node.js 앱을 터미널에서 직접 실행할 때는 현재 프로젝트 디렉터리 기준으로 logs/app.log가 만들어질 수 있습니다. 반면 systemd나 PM2로 실행하면 작업 디렉터리, 사용자, 환경변수가 달라져 다른 위치에 로그가 생기거나 아예 파일 생성에 실패할 수 있습니다.

운영 중에는 다음 순서로 보는 것이 안전합니다.

  1. 서비스가 실제로 실행 중인지 확인한다.
  2. 로그 파일 경로가 맞는지 확인한다.
  3. 현재 사용자에게 읽기 권한이 있는지 확인한다.
  4. 요청을 다시 보내면서 tail -f 화면에 새 줄이 생기는지 본다.
  5. 파일 로그가 안 나오면 journalctl, PM2 로그, Nginx 로그를 나눠서 확인한다.

처음 의심하기 쉬운 원인과 실제 원인의 차이

처음 보기에는 실제로는 확인 방법
앱 코드가 죽은 것 같다 포트가 다르거나 Nginx가 다른 upstream을 보고 있다 systemctl status, ss -tulpen, Nginx error.log 확인
로그가 안 찍힌다 다른 파일에 로그를 쓰고 있다 설정 파일의 log path, PM2 로그, journalctl 확인
tail 명령어가 이상하다 현재 사용자에게 읽기 권한이 없다 whoami, id, ls -l 확인
요청이 서버까지 안 온다 Nginx access.log에는 들어오지만 앱까지 전달되지 않는다 access.log와 error.log를 나눠서 확인

화면에 보이는 오류보다 먼저 로그와 서비스 상태를 확인하는 편이 원인을 좁히기 쉽습니다. 특히 502, 403, 500 오류는 브라우저 메시지만으로는 원인을 알기 어렵고, Nginx 로그와 애플리케이션 로그를 함께 봐야 합니다.

실제로 자주 막히는 상황

1. Nginx 502가 나는데 앱 로그만 보고 있는 경우

도메인으로 접속하면 502 Bad Gateway가 나오는데 Node.js 앱 로그에는 아무것도 안 찍히는 경우가 있습니다. 이때는 요청이 앱까지 도착하지 않았을 수 있습니다. 먼저 Nginx error.log를 확인합니다.

tail -n 50 /var/log/nginx/error.log

tail -f /var/log/nginx/error.log

다른 터미널에서는 내부 포트가 응답하는지도 확인합니다.

ss -tulpen | grep 3000

curl -I http://127.0.0.1:3000

curl은 요청을 보내는 확인 명령입니다. 운영 서비스에 과도하게 반복 실행할 필요는 없고, 한두 번 응답 여부를 보는 용도로 사용하면 됩니다.

2. systemd 서비스는 active인데 파일 로그가 비어 있는 경우

systemd로 실행한 서비스는 표준 출력과 에러가 파일이 아니라 journal에 남을 수 있습니다. 이때는 파일만 보지 말고 서비스 단위 로그를 확인합니다.

systemctl status myapp

journalctl -u myapp -n 100

journalctl -u myapp -f

journalctl -ftail -f처럼 새 로그를 따라갑니다. 다만 journal 로그는 서비스 단위로 확인하므로, 파일 로그가 아닌 systemd 관리 서비스의 에러를 볼 때 유용합니다.

3. PM2로 실행한 Node.js 앱의 로그 위치를 착각한 경우

PM2로 실행한 앱은 프로젝트의 logs/app.log가 아니라 PM2 자체 로그에 에러가 남을 수 있습니다. 앱이 계속 재시작될 때는 재시작 명령을 반복하기보다 먼저 로그를 확인하는 편이 빠릅니다.

pm2 list

pm2 logs myapp --lines 100

PM2가 없는 서버에서는 위 명령이 동작하지 않습니다. PM2로 앱을 관리하는 환경에서만 사용하세요.

원인 분리: 로그가 안 보일 때 보는 순서

tail -f를 실행했는데 아무 내용도 추가되지 않는다고 해서 바로 로그 시스템이 문제라고 판단하면 안 됩니다. 아래 순서대로 분리하면 불필요한 설정 변경을 줄일 수 있습니다.

  1. 파일이 실제로 있는지 확인: 경로 오타나 다른 디렉터리를 보고 있을 수 있습니다.
  2. 파일 크기와 수정 시간이 변하는지 확인: 서비스가 해당 파일에 쓰고 있는지 판단합니다.
  3. 읽기 권한이 있는지 확인: 권한이 없으면 내용 확인이 막힙니다.
  4. 서비스 실행 사용자를 확인: 앱이 로그 파일을 만들 권한이 없을 수 있습니다.
  5. 파일 로그와 journal 로그를 구분: systemd 서비스는 journal에만 남을 수 있습니다.
ls -l /var/log/nginx/error.log

stat /var/log/nginx/error.log

whoami

id

stat 명령은 파일의 수정 시간과 크기 등을 보여줍니다. 요청을 보낸 뒤 수정 시간이 변하지 않는다면, 현재 보고 있는 파일이 실제 로그 대상이 아닐 가능성이 있습니다.

잘못된 예시

경로를 추측해서 tail을 실행하는 경우

tail -f /var/log/app.log

위 명령 자체가 틀린 것은 아니지만, 실제 앱이 그 파일에 로그를 쓰는지 확인하지 않았다면 의미가 없습니다. 아래처럼 파일 존재 여부와 최근 수정 시간을 먼저 확인하는 편이 좋습니다.

ls -l /var/log/app.log

stat /var/log/app.log

권한 오류를 chmod 777로 해결하려는 경우

tail -f /var/log/secure

tail: cannot open '/var/log/secure' for reading: Permission denied

이 상황에서 로그 파일 권한을 넓게 풀어버리는 방식은 피해야 합니다. 운영 서버의 로그 파일에는 민감한 정보가 포함될 수 있고, 잘못된 권한 변경은 보안 문제로 이어질 수 있습니다. 먼저 현재 사용자와 파일 소유자를 확인합니다.

whoami

id

ls -l /var/log/secure

Debian/Ubuntu 계열에서는 로그에 따라 adm 그룹 권한이 필요할 수 있습니다. 단, 사용자 그룹 변경은 접속 권한과 보안 정책에 영향을 줄 수 있으므로 서버 관리 정책을 확인한 뒤 진행해야 합니다. 임시 확인만 필요하다면 권한이 있는 계정에서 sudo tail로 읽는 방식을 사용할 수 있습니다.

sudo tail -n 50 /var/log/syslog

sudo tail -f /var/log/syslog

sudo는 필요한 경우에만 사용하고, 어떤 파일을 읽는지 확인한 뒤 실행하는 것이 좋습니다.

수정 예시: 로그 파일 위치와 권한을 바로잡는 흐름

예를 들어 Node.js 앱이 /var/www/myapp/logs/app.log에 로그를 남기도록 되어 있는데, 실제 파일이 생성되지 않는 상황을 가정해 보겠습니다. 먼저 현재 상태를 확인합니다.

cd /var/www/myapp

pwd

ls -ld logs

ls -l logs

디렉터리가 없으면 앱이 로그 파일을 만들지 못할 수 있습니다. 디렉터리를 새로 만들기 전에는 앱 설정에서 해당 경로가 맞는지 먼저 확인해야 합니다.

grep -R log ./config ./src 2>/dev/null | head -n 20

위 명령은 프로젝트 안에서 로그 관련 문자열을 찾아보는 예시입니다. 프로젝트 구조에 따라 config, src 디렉터리가 없을 수 있으므로 실제 경로에 맞게 조정해야 합니다.

로그 디렉터리가 필요하고 경로가 맞다면, 먼저 디렉터리 존재 여부를 확인한 뒤 생성합니다.

ls -ld /var/www/myapp/logs

mkdir -p /var/www/myapp/logs

mkdir -p는 없는 디렉터리를 만드는 명령입니다. 운영 서버에서는 엉뚱한 경로에 디렉터리를 만들지 않도록 pwd와 전체 경로를 확인한 뒤 실행하세요.

그 다음 중요한 것은 앱을 실행하는 사용자와 디렉터리 소유자가 맞는지 확인하는 것입니다.

ps -eo user,pid,cmd | grep node | grep -v grep

ls -ld /var/www/myapp/logs

실행 사용자가 www-data인지, 별도의 배포 사용자 계정인지에 따라 필요한 권한이 달라집니다. 무작정 권한을 넓히기보다, 실제 실행 사용자가 로그 디렉터리에 쓸 수 있는지 확인하는 것이 먼저입니다.

수정 후 확인 방법

경로와 권한을 정리한 뒤에는 로그가 실제로 추가되는지 확인해야 합니다. 한 터미널에서는 로그를 따라가고, 다른 터미널이나 브라우저에서 요청을 보냅니다.

tail -n 20 /var/www/myapp/logs/app.log

tail -f /var/www/myapp/logs/app.log

다른 터미널에서 내부 요청을 보냅니다.

curl -I http://127.0.0.1:3000

정상적으로 연결되면 요청 시점에 맞춰 로그가 추가되어야 합니다. 아무 변화가 없다면 다음을 다시 확인합니다.

  • 현재 보고 있는 파일이 앱 설정의 로그 파일과 같은지
  • 앱이 실제로 해당 요청을 받고 있는지
  • Nginx에서 앱으로 프록시가 전달되는지
  • systemd 또는 PM2 로그에만 에러가 남는지

Nginx를 함께 사용하는 경우에는 access.log와 error.log를 동시에 나눠서 보면 원인 분리가 쉽습니다.

tail -f /var/log/nginx/access.log
tail -f /var/log/nginx/error.log

access.log에는 요청이 들어오는데 앱 로그에는 아무것도 없다면, Nginx와 앱 사이의 프록시 설정 또는 앱 포트 상태를 확인해야 합니다. 반대로 access.log에도 요청이 없다면 DNS, 방화벽, 프록시, 클라우드 보안 그룹 등 외부 경로 문제일 수 있습니다.

tail -f와 tail -F 차이

운영 서버에서는 로그 로테이션 때문에 파일이 교체될 수 있습니다. 일반적인 tail -f는 기존 파일 핸들을 계속 따라가므로, 로그 파일이 회전되면 새 파일을 놓칠 수 있습니다. 이럴 때는 환경에 따라 tail -F가 더 적합할 수 있습니다.

tail -F /var/log/nginx/error.log

-F는 파일 이름을 기준으로 다시 열려고 시도합니다. 배포 직후 짧게 확인할 때는 -f로 충분한 경우가 많고, 로그 로테이션이 발생할 수 있는 장시간 모니터링에는 -F가 도움이 될 수 있습니다.

grep과 함께 특정 오류만 보기

로그가 너무 빠르게 올라오면 필요한 줄을 놓치기 쉽습니다. 이때는 grep과 함께 사용할 수 있습니다.

tail -f /var/log/nginx/error.log | grep error

대소문자를 구분하지 않고 찾으려면 다음처럼 사용할 수 있습니다.

tail -f /var/log/nginx/error.log | grep -i 'permission\|denied\|failed'

단, 필터를 너무 좁게 걸면 중요한 주변 로그를 놓칠 수 있습니다. 처음에는 전체 로그를 보고, 반복되는 패턴을 찾은 뒤 필터를 적용하는 편이 안전합니다.

재발 방지 체크리스트

  • 서비스별 로그 위치를 운영 문서나 메모에 남겨 두었는가
  • Nginx access.log, error.log, 앱 로그, systemd journal의 역할을 구분하고 있는가
  • 로그 파일 경로를 상대 경로가 아니라 명확한 절대 경로로 관리하고 있는가
  • 앱 실행 사용자와 로그 디렉터리 소유자가 맞는가
  • 권한 문제를 임시로 넓게 푸는 대신 필요한 최소 권한을 확인했는가
  • 배포 직후 systemctl status, journalctl, tail -f를 함께 확인하는가
  • 서버 시간대가 맞는지 확인했는가
  • 로그 로테이션 이후에도 새 로그를 놓치지 않는지 확인했는가

특히 서버 시간대가 맞지 않으면 에러 발생 시각을 잘못 판단할 수 있습니다. 로그 시간이 이상하게 보이면 다음 명령으로 현재 시간과 시간대를 확인합니다.

date

timedatectl

시간대 변경은 서버의 예약 작업이나 인증서 갱신, 애플리케이션 로그 기준에 영향을 줄 수 있으므로 필요 여부를 확인한 뒤 진행해야 합니다.

FAQ

Q1. tail -f를 실행했는데 화면이 멈춘 것처럼 보입니다. 문제가 있는 건가요?

반드시 문제라고 볼 수는 없습니다. tail -f는 새 로그가 추가될 때만 화면에 내용이 이어집니다. 다른 터미널에서 요청을 보내거나 서비스를 재시작했는데도 변화가 없다면, 현재 보고 있는 파일이 실제 로그 파일인지, 서비스가 실행 중인지, 로그가 journal이나 PM2 쪽에 남는지 확인해야 합니다.

Q2. Permission denied가 나오면 sudo로 보면 되나요?

임시 확인 목적이라면 sudo tail로 읽을 수 있습니다. 하지만 매번 권한 오류가 난다면 현재 사용자, 파일 소유자, 그룹 권한, 서비스 실행 사용자를 확인해야 합니다. 로그 파일 권한을 넓게 풀어 해결하는 방식은 보안상 좋지 않으며, 운영 서버에서는 필요한 최소 권한을 기준으로 조정하는 편이 안전합니다.

Q3. Nginx 로그와 애플리케이션 로그 중 무엇을 먼저 봐야 하나요?

브라우저에서 502, 403, 500 오류가 보인다면 먼저 Nginx error.log와 access.log를 확인하는 것이 좋습니다. 요청이 Nginx까지 들어오는지 본 뒤, 앱 포트와 애플리케이션 로그를 확인하면 원인을 나누기 쉽습니다. 앱이 PM2나 systemd로 실행 중이라면 pm2 logs 또는 journalctl -u 서비스명도 함께 확인해야 합니다.

파일 내용을 한 번만 확인하는 방식과 실시간으로 따라가는 방식이 헷갈린다면 cat과 less 명령어 차이를 함께 보면 좋습니다. 로그 안에서 특정 문구를 찾는 방법은 grep 명령어와 함께 익히면 장애 원인 추적에 도움이 됩니다.