
مقدمه
لاگهای Nginx دادههایی را در اختیار شما میگذارند که برای عیبیابی خطاها، تحلیل ترافیک و تأیید رفتار اپلیکیشن لازم دارید. بدون یک راهاندازی درست لاگینگ، تشخیص مشکلات محیط پروداکشن به حدس و گمان تبدیل میشود.
این آموزش به شما نشان میدهد چگونه لاگهای دسترسی (Access) و خطا (Error) را پیکربندی کنید، چرخش لاگ (Log Rotation) را برای جلوگیری از پر شدن دیسک راه بیندازید و پیکربندیتان را با دستورات واقعی اعتبارسنجی کنید.
بهصورت پیشفرض، Nginx لاگها را در /var/log/nginx/ ذخیره میکند و از ابزار logrotate برای مدیریت خودکار فایلهای لاگ استفاده میکند. در این آموزش از یک سرور مجازی خصوصی اوبونتویی بهعنوان نمونه استفاده میشود، اما این پیکربندی روی هر توزیع مدرن لینوکسی که Nginx روی آن اجرا میشود، کاربرد دارد.
این آموزش آخرین بار روی اوبونتو 24.04 LTS با نسخه پایدار Nginx از مخازن اوبونتو اعتبارسنجی شده است و روی اوبونتو 22.04 LTS و نسخههای جدیدتر هم بدون تغییر کار میکند.
نکات کلیدی
- Nginx از دو نوع لاگ اصلی استفاده میکند: لاگ دسترسی برای دیدن درخواستها و لاگ خطا برای عیبیابی عملیاتی.
- سطح لاگ خطا را آگاهانه انتخاب کنید: سطح
warnیک پیشفرض عملی برای مشاهدهپذیری پروداکشن است، سطحerrorنویز را کم میکند و سطحdebugرا فقط برای عیبیابی کوتاهمدت نگه دارید. - چرخش لاگ روی سرورهای پروداکشن ضروری است: ابزار logrotate در اوبونتو از رشد بیرویه دیسک جلوگیری میکند و امکان نگهداری بلندمدت لاگها را فراهم میکند.
- فرمتهای لاگ سفارشی، مشاهدهپذیری را بهتر میکنند: لاگهای JSON ورود داده به پلتفرمهای لاگینگ متمرکز مانند Elasticsearch و Datadog را ساده میکنند.
- لاگینگ بافرشده سربار I/O را کاهش میدهد: فعال کردن
buffer=32kبرای محیطهای پرترافیک توصیه میشود. - همیشه قبل از ریلود اعتبارسنجی کنید: از
nginx -tاستفاده کنید تا جلوی خرابیهای ناشی از خطای پیکربندی و قطعی سرویس گرفته شود. - لاگینگ شرطی نویز را کم میکند: هلتچکها و فایلهای استاتیک را حذف کنید تا لاگها روی ترافیک مهم متمرکز بمانند.
- برای شفافیت، برای هر سایت لاگ جداگانه بسازید: فایلهای لاگ جدا برای هر دامنه، عیبیابی و واکنش به حوادث را ساده میکنند.
- مصرف دیسک را پیشگیرانه مانیتور کنید: قبل از عبور پارتیشن لاگ از آستانه امن، هشدار بگیرید.
- لاگینگ متمرکز در مقیاس بزرگ ضروری است: استقرارهای چندسروری باید لاگها را با syslog یا ایجنتهای ارسال لاگ تجمیع کنند.
مرجع سریع
از این برگه تقلب برای اعتبارسنجی سریع تغییرات استفاده کنید:
- دایرکتوری لاگها:
/var/log/nginx/ - لاگ دسترسی:
/var/log/nginx/access.log - لاگ خطا:
/var/log/nginx/error.log - فایل PID:
/run/nginx.pid - تست پیکربندی:
sudo nginx -t - ریلود Nginx:
sudo systemctl reload nginx - اجرای آزمایشی logrotate:
sudo logrotate -d /etc/logrotate.d/nginx - اجرای اجباری logrotate:
sudo logrotate -f /etc/logrotate.d/nginx
پیشنیازها
برای دنبال کردن این آموزش به این موارد نیاز دارید:
- یک سرور اوبونتو با نسخه 22.04 LTS یا جدیدتر، همراه با یک کاربر غیر root با دسترسی sudo و فایروال پیکربندیشده. برای شروع، راهنمای راهاندازی اولیه سرور با اوبونتو در پارمین کلود را دنبال کنید.
- Nginx نصبشده روی سرور. برای نصب، آموزش نصب Nginx روی اوبونتو را در پارمین کلود دنبال کنید.
با اجرای Nginx روی سرور اوبونتوی خودتان، آماده شروع هستید.
پایه سریع: لاگینگ مناسب پروداکشن
اگر به یک پیکربندی امن میخواهید که بلافاصله دیپلوی کنید، از اینجا شروع کنید و بعداً آن را بهبود بدهید:
# /etc/nginx/nginx.conf
# این مقادیر را داخل بلاک http { } قرار دهید
error_log /var/log/nginx/error.log warn;
access_log /var/log/nginx/access.log combined buffer=32k;
map $request_uri $log_healthcheck {
default 1;
~^/healthz$ 0;
}
سپس لاگینگ هر سایت را در بلاک server {} اعمال کنید (معمولاً در /etc/nginx/sites-available/your_site):
# /etc/nginx/sites-available/your_site
server {
access_log /var/log/nginx/access.log combined if=$log_healthcheck;
location = /healthz {
access_log off;
return 200;
}
}
این پیکربندی برای بیشتر استقرارهای پروداکشن اوبونتویی، تعادلی بین کیفیت سیگنال، I/O دیسک و ایمنی عملیاتی برقرار میکند.
درک انواع لاگ در Nginx
Nginx از دو لاگ اصلی استفاده میکند: لاگ دسترسی (برای هر درخواست) و لاگ خطا (برای عیبیابی). هر کدام نقشی متفاوت در مانیتورینگ و عیبیابی دارند.
دایرکتیوهای لاگینگ باید کجا قرار بگیرند
از این قوانین جایگذاری استفاده کنید تا از بازنویسیهای غیرمنتظره جلوگیری شود:
- از بلاک
http {}برای پیشفرضهای سراسری استفاده کنید (فرمتهای لاگ، مسیرهای پیشفرض). - از بلاکهای
server {}برای جدا کردن لاگها به ازای هر سایت یا دامنه استفاده کنید. - از بلاکهای
location {}فقط برای بازنویسیهای هدفمند استفاده کنید؛ مانند غیرفعال کردن لاگ برای هلتچکها یا فایلهای استاتیک.
Nginx در مقابل Apache: لاگینگ در یک نگاه
اگر به Apache عادت دارید: دایرکتیو error_log در Nginx معادل ErrorLog در Apache است؛ access_log بههمراه log_format در Nginx معادل CustomLog و LogFormat در Apache است. هر دو از لاگینگ شرطی و چرخش لاگ با ابزارهای خارجی (مثل logrotate) پشتیبانی میکنند. یک تفاوت عملی این است که Nginx خودش لاگها را نمیچرخاند—باید از logrotate یا یک اسکریپت استفاده کنید و بعد به Nginx سیگنال بدهید (مثلاً kill -USR1) تا فایلها را دوباره باز کند. ابزار rotatelogs در آپاچی لاگها را به یک پروسه چرخش پایپ میکند؛ در Nginx به سیستمعامل یا logrotate تکیه دارید تا فایلها را جابهجا و فشرده کند و بعد به پروسه سیگنال بدهید.
لاگهای دسترسی (Access Logs)
لاگهای دسترسی هر درخواستی که Nginx پردازش میکند را ثبت میکنند؛ از جمله IP کلاینت، متد درخواست، URI، کد وضعیت پاسخ، بایتهای ارسالی، یوزر ایجنت و ریفرر. این لاگها برای این موارد ارزشمندند:
- روندهای ترافیک: شناسایی endpointهای پرترافیک، ریفررها و الگوهای کد وضعیت
- دیباگ عملکرد: پیدا کردن درخواستهای کند و پاسخهای پرمصرف از نظر پهنای باند
- دید امنیتی: تشخیص الگوهای درخواست مشکوک و سوءاستفاده
بهصورت پیشفرض، Nginx لاگهای دسترسی را در /var/log/nginx/access.log با فرمت combined مینویسد که دادههای جامع درخواست را در قالبی استاندارد ثبت میکند و با بیشتر ابزارهای تحلیل لاگ سازگار است.
لاگهای خطا (Error Logs)
لاگهای خطا هنگام بروز مشکلات، اطلاعات تشخیصی را ثبت میکنند؛ از هشدارهای جزئی تا خرابیهای بحرانی سیستم. این لاگها شامل موارد زیر هستند:
- خطاهای سرور: مشکلات پیکربندی، خرابی upstream یا اتمام منابع
- خطاهای کلاینت: درخواستهای نامعتبر، فایلهای موجود نیستنخته (404) یا مشکلات مجوز (403)
- هشدارهای سیستم: مشکلات غیربحرانی که ممکن است نشانه مشکلات آینده باشند
- اطلاعات دیباگ: ردیابیهای دقیق هنگام عیبیابی مسائل خاص
لاگهای خطا بهصورت پیشفرض در /var/log/nginx/error.log نوشته میشوند و از سطوح شدت (debug، info، notice، warn، error، crit، alert، emerg) برای دستهبندی پیامها استفاده میکنند.
مکان و مجوزهای لاگ
در اوبونتو، لاگهای Nginx بهصورت پیشفرض در /var/log/nginx/ ذخیره میشوند و مالک آنها کاربر www-data است. دایرکتوری لاگ به مجوزهای درست نیاز دارد:
ls -la /var/log/nginx/
خروجی:
total 12
drwxr-x--- 2 www-data adm 4096 Feb 2 10:00 .
drwxrwxr-x 8 root syslog 4096 Feb 2 09:45 ..
-rw-r----- 1 www-data adm 0 Feb 2 10:00 access.log
-rw-r----- 1 www-data adm 0 Feb 2 10:00 error.log
گروه adm به مدیران سیستم اجازه میدهد بدون دسترسی root لاگها را بخوانند. اگر بهعنوان کاربر عادی به لاگها دسترسی میخواهید، خودتان را به گروه adm اضافه کنید:
sudo usermod -aG adm your_username
نکته: برای اعمال شدن تغییرات گروه، باید یکبار خارج و دوباره وارد سیستم شوید.
ملاحظات فضای دیسک
لاگهای Nginx روی سرورهای پرترافیک میتوانند بهسرعت بزرگ شوند. یک روز ترافیک روی یک سایت با ترافیک متوسط ممکن است تولید کند:
- لاگهای دسترسی: ۱۰۰ تا ۵۰۰ مگابایت در روز (بسته به ترافیک متغیر است)
- لاگهای خطا: ۱۰ تا ۵۰ مگابایت در روز (بسته به نرخ خطا)
بدون چرخش لاگ، لاگها میتوانند طی چند هفته گیگابایتها فضای دیسک را مصرف کنند. ابزار logrotate که در ادامه این آموزش بررسی میشود، بهطور خودکار لاگهای قدیمی را آرشیو و فشرده میکند تا مشکل فضای دیسک پیش نیاید.
درک دایرکتیو error_log
دایرکتیو error_log تعیین میکند Nginx پیامهای خطا و تشخیصی را کجا و با چه سطحی بنویسد. مسیر و سطح (مثلاً warn) را در پیکربندی تنظیم کنید؛ اگر با Apache آشنا هستید، رفتاری شبیه ErrorLog در Apache دارد.
سینتکس error_log
دایرکتیو error_log از این سینتکس پیروی میکند:
# /etc/nginx/nginx.conf
error_log log_file log_level;
مقدار log_file فایلی را مشخص میکند که لاگها در آن نوشته میشوند. log_level پایینترین سطحی از لاگینگ است که میخواهید ثبت شود.
سطوح لاگینگ
دایرکتیو error_log را میتوان طوری پیکربندی کرد که اطلاعات بیشتر یا کمتری ثبت کند. سطح لاگینگ میتواند یکی از موارد زیر باشد:
- emerg: وضعیتهای اضطراری که سیستم در حالت غیرقابل استفاده است.
- alert: وضعیتهای شدید که نیاز به اقدام فوری دارند.
- crit: مشکلات مهم که باید رسیدگی شوند.
- error: خطایی رخ داده و کاری ناموفق بوده است.
- warn: اتفاقی خارج از عادت رخ داده، اما نگرانکننده نیست.
- notice: چیزی عادی است، اما ارزش ثبت دارد.
- info: پیام اطلاعاتی که شاید خوب باشد بدانید.
- debug: اطلاعات دیباگ که برای تشخیص محل مشکل مفید است.
سطوح بالاتر در این فهرست، اولویت بالاتری دارند. اگر سطحی مشخص کنید، لاگ همان سطح و همه سطوح بالاتر از آن را ثبت میکند.
مثلاً اگر error را مشخص کنید، لاگ پیامهای برچسبخورده error، crit، alert و emerg را ثبت میکند.
تأثیر سطوح لاگینگ بر کارایی
سطوح مختلف لاگ، پیامدهای متفاوتی روی کارایی دارند:
- warn (پیشنهادی برای پروداکشن): حداقل تأثیر بر کارایی، همراه با حفظ سیگنالهای هشدار اولیه مانند خرابی upstream و مشکلات پیکربندی.
- info و notice: تأثیر متوسط بر کارایی و تولید عملیات I/O بیشتر. وقتی استفاده کنید که به دید عملیاتی جزئیاتتری نیاز دارید.
- debug: تأثیر زیاد بر کارایی و تولید خروجی گسترده. فقط برای عیبیابی فعال استفاده کنید و هرگز در پروداکشن روشنش نگذارید؛ چون سرورتان را کند میکند و دیسک را بهسرعت پر میکند.
برای تغییر سطح لاگ، پیکربندی Nginx را ویرایش کنید. یک نمونه از کاربرد این دایرکتیو در فایل پیکربندی اصلی است. با ویرایشگر متن مورد علاقهتان این فایل را باز کنید. این مثال از nano استفاده میکند:
sudo nano /etc/nginx/nginx.conf
بخش # Logging Settings را پیدا کنید (معمولاً در بخش پایینی بلاک اصلی) و به این دایرکتیوها دقت کنید:
# /etc/nginx/nginx.conf
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
اگر نمیخواهید error_log چیزی ثبت کند، باید خروجی را به /dev/null بفرستید:
# /etc/nginx/nginx.conf
error_log /dev/null crit;
دایرکتیو لاگینگ دیگر یعنی access_log در بخش بعدی بررسی میشود.
درک دایرکتیوهای لاگینگ HttpLogModule
در حالی که دایرکتیو error_log بخشی از ماژول core است، دایرکتیو access_log بخشی از ماژول HttpLogModule است. این ماژول امکان سفارشیسازی لاگها را فراهم میکند.
چند دایرکتیو دیگر هم در این ماژول وجود دارند که به پیکربندی لاگهای سفارشی کمک میکنند.
دایرکتیو log_format
دایرکتیو log_format برای توصیف قالب یک ورودی لاگ با استفاده از متن ساده و متغیرها استفاده میشود.
یک فرمت از پیش در Nginx تعریف شده به نام combined وجود دارد. این یک فرمت رایج است که بسیاری از سرورها استفاده میکنند.
مثال زیر فرمت combined است؛ آنطور که اگر بهصورت داخلی تعریف نشده بود، باید با دایرکتیو log_format مشخص میشد:
# /etc/nginx/nginx.conf
log_format combined '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
این تعریف روی چند خط گسترش مییابد تا اینکه به سمیکالن (;) برسد.
خطوطی که با علامت دلار ($) شروع میشوند نشاندهنده متغیر هستند، در حالی که کاراکترهایی مثل -، [ و ] بهصورت تحتاللفظی تفسیر میشوند.
سینتکس کلی دایرکتیو به این شکل است:
# /etc/nginx/nginx.conf
log_format format_name 'string_describing_formatting';
میتوانید از متغیرهای پشتیبانیشده توسط ماژول core برای ساخت رشتههای لاگینگ خود استفاده کنید.
فرمت لاگ JSON برای مانیتورینگ مدرن
برای یکپارچهسازی با ابزارهای مدرن تجمیع لاگ مانند Elasticsearch، Logstash، Grafana یا Datadog، میتوانید Nginx را طوری پیکربندی کنید که لاگها را با فرمت JSON خروجی بدهد. این کار پارس و کوئری گرفتن از لاگها را بسیار سادهتر میکند.
این فرمت لاگ سفارشی را به بلاک http در /etc/nginx/nginx.conf اضافه کنید:
# /etc/nginx/nginx.conf
log_format json_combined escape=json
'{'
'"time_local":"$time_local",'
'"remote_addr":"$remote_addr",'
'"remote_user":"$remote_user",'
'"request":"$request",'
'"status": "$status",'
'"body_bytes_sent":"$body_bytes_sent",'
'"request_time":"$request_time",'
'"http_referrer":"$http_referer",'
'"http_user_agent":"$http_user_agent"'
'}';
سپس آن را روی یک بلاک server یا location مشخص اعمال کنید:
# /etc/nginx/sites-available/your_site
server {
listen 80;
server_name example.com;
access_log /var/log/nginx/example.com_access.log json_combined;
# ادامه پیکربندی شما
}
پارامتر escape=json تضمین میکند کاراکترهای خاص بهدرستی escape شوند و از خطاهای پارس JSON جلوگیری میشود.
ارسال لاگهای JSON به پایپلاین مانیتورینگ: وقتی Nginx لاگ JSON را در فایل نوشت، میتوانید آن را با یک ایجنت لاگ بدون نیاز به پارس ارسال کنید. مثالها: Filebeat یا Fluentd به سمت Elasticsearch؛ یا Promtail به سمت Grafana Loki. ایجنت را به مسیر /var/log/nginx/*.log (یا مسیرهای هر سایت) اشاره دهید، فرمت ورودی را روی JSON بگذارید و نگهداری و ایندکسگذاری را در مقصد پیکربندی کنید. این روش پیکربندی Nginx را ساده نگه میدارد و پارس و نگهداری را به پایپلاین منتقل میکند.
فرمتهای لاگ سفارشی برای نیازهای خاص
میتوانید برای اهداف مختلف، چندین فرمت سفارشی بسازید. اینجا مثالی است که زمانهای پاسخ و عملکرد upstream را ردیابی میکند:
# /etc/nginx/nginx.conf
log_format performance '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'rt=$request_time uct="$upstream_connect_time" '
'uht="$upstream_header_time" urt="$upstream_response_time"';
این فرمت این موارد را اضافه میکند:
$request_time: کل زمان پردازش درخواست$upstream_connect_time: زمان صرفشده برای برقراری اتصال به سرور upstream$upstream_header_time: زمان دریافت هدرها از upstream$upstream_response_time: زمان دریافت کامل پاسخ از upstream
این متریکها هنگام عیبیابی زمانهای پاسخ کند اپلیکیشن یا شناسایی گلوگاهها بین Nginx و سرویسهای بکاند بسیار ارزشمندند.
درک دایرکتیو access_log
دایرکتیو access_log سینتکسی شبیه به error_log دارد، اما انعطافپذیرتر است و برای پیکربندی لاگینگ سفارشی استفاده میشود.
دایرکتیو access_log از این سینتکس پیروی میکند:
# /etc/nginx/nginx.conf
access_log /path/to/log/location [ format_name [ buffer=size ] ];
مقدار پیشفرض access_log همان فرمت combined است که در بخش log_format اشاره شد. میتوانید از هر فرمت تعریفشده با log_format استفاده کنید.
حجم بافر، حداکثر مقدار دادهای است که Nginx قبل از نوشتن همه آن در لاگ نگه میدارد. همچنین میتوانید فشردهسازی فایل لاگ را با اضافه کردن gzip به تعریف مشخص کنید:
# /etc/nginx/nginx.conf
access_log /var/log/nginx/access.log combined gzip=1;
برخلاف دایرکتیو error_log، اگر لاگینگ نمیخواهید، میتوانید آن را در فایل پیکربندی خاموش کنید:
# /etc/nginx/nginx.conf
##
# Logging Settings
##
access_log off;
error_log /var/log/nginx/error.log;
در این مورد نیازی به نوشتن در /dev/null نیست.
لاگینگ شرطی
میتوانید از پارامتر if با access_log استفاده کنید تا فقط درخواستهای خاصی ثبت شوند. این برای حذف هلتچکها، فایلهای استاتیک یا ترافیک شناختهشده باتها برای کاهش حجم لاگ مفید است:
# /etc/nginx/nginx.conf
# نگاشت برای تعیین اینکه آیا درخواست باید ثبت شود یا نه
map $request_uri $loggable {
~^/health-check 0;
~^/ping 0;
default 1;
}
server {
listen 80;
server_name example.com;
# فقط وقتی ثبت کن که $loggable برابر 1 باشد
access_log /var/log/nginx/access.log combined if=$loggable;
}
این پیکربندی endpointهای /health-check و /ping را از لاگها حذف میکند؛ چیزی که بهویژه وقتی از لود بالانسرها یا سیستمهای مانیتورینگ استفاده میکنید که این endpointها را مدام صدا میزنند، کاربردی است.
لاگهای جداگانه برای سایتهای مختلف
وقتی چندین وبسایت یا اپلیکیشن هاست میکنید، داشتن فایلهای لاگ جداگانه برای هر سایت، عیبیابی و تحلیل را بسیار سادهتر میکند:
# /etc/nginx/sites-available/site1.conf
server {
listen 80;
server_name site1.example.com;
access_log /var/log/nginx/site1_access.log combined;
error_log /var/log/nginx/site1_error.log warn;
# ادامه پیکربندی
}
# /etc/nginx/sites-available/site2.conf
server {
listen 80;
server_name site2.example.com;
access_log /var/log/nginx/site2_access.log combined;
error_log /var/log/nginx/site2_error.log warn;
# ادامه پیکربندی
}
این رویکرد لاگهای هر سایت را ایزوله میکند و کار این موارد را سادهتر میکند:
- ردیابی الگوهای ترافیک برای هر اپلیکیشن بهصورت جداگانه
- شناسایی اینکه کدام سایت دچار خطا شده است
- تعیین سیاستهای نگهداری متفاوت برای هر سایت
- سادهتر شدن تحلیل لاگ با ابزارهایی مثل goaccess یا awstats
مدیریت چرخش لاگ
لاگها را بچرخانید تا دیسک را پر نکنند. از logrotate داخلی اوبونتو (پیکربندیشده در /etc/logrotate.d/nginx) استفاده کنید، یا بهصورت دستی لاگها را جابهجا کنید و سیگنال kill -USR1 به پروسه اصلی Nginx بفرستید تا فایلهای لاگ را دوباره باز کند. Nginx خودش فایلها را نمیچرخاند، اما با دریافت سیگنال USR1 دستِ همکاری برای چرخش میدهد و هندلهای فایل لاگ را دوباره باز میکند.
چرخش دستی لاگ
برای چرخش دستی لاگها، میتوانید اسکریپتی بسازید که آنها را بچرخاند. مثلاً، لاگ فعلی را به یک فایل جدید برای آرشیو منتقل کنید. یک طرح رایج این است که جدیدترین فایل لاگ را با پسوند .0 و فایلهای قدیمیتر را با .1 و به همین شکل نامگذاری کنید:
mv /var/log/nginx/access.log /var/log/nginx/access.log.0
دستوری که بعد از انتقال فایلها، در واقع فایلهای لاگ Nginx را دوباره باز میکند، kill -USR1 $(cat /run/nginx.pid) است. این دستور پروسه Nginx را نمیکشد؛ سیگنالی میفرستد تا Nginx هندلهای فایل لاگ خود را دوباره باز کند. درخواستهای جدید بعد از آن در فایل لاگ جدید ثبت میشوند:
kill -USR1 $(cat /run/nginx.pid)
فایل /run/nginx.pid جایی است که Nginx شناسه (PID) پروسه اصلی را در آن ذخیره میکند. این مسیر در بالای فایل پیکربندی /etc/nginx/nginx.conf با خطی که با pid شروع میشود، مشخص شده است:
sudo nano /etc/nginx/nginx.conf
# /etc/nginx/nginx.conf
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
...
بعد از چرخش، دستور sleep 1 را اجرا کنید تا به پروسه فرصت کامل شدن انتقال داده شود. بعد میتوانید فایلهای قدیمی را فشرده کنید یا هر پردازش پس از چرخشی که میخواهید انجام دهید:
sleep 1
gzip /var/log/nginx/access.log.0
چرخش لاگ با logrotate
اپلیکیشن logrotate برنامهای برای چرخش لاگهاست. این ابزار بهصورت پیشفرض روی اوبونتو نصب است و Nginx در اوبونتو با یک اسکریپت logrotate اختصاصی عرضه میشود.
با ویرایشگر متن مورد علاقهتان به اسکریپت چرخش دسترسی پیدا کنید. این مثال از nano استفاده میکند:
sudo nano /etc/logrotate.d/nginx
خط اول فایل مکانی را مشخص میکند که خطوط بعدی روی آن اعمال میشوند. اگر مکان لاگینگ را در فایلهای پیکربندی Nginx تغییر دادید، به این نکته توجه کنید.
بقیه فایل مشخص میکند که لاگها روزانه چرخانده میشوند و ۱۴ نسخه قدیمیتر نگهداری خواهند شد.
یک سیاست نگهداری متناسب با محیط خودتان انتخاب کنید:
- بیشتر سرورهای پروداکشن: روزانه با
rotate 14یاrotate 30 - انطباق / فورنزیک: روزانه با
rotate 90(یا بیشتر) - ترافیک بسیار بالا: چرخش بر اساس حجم (مثلاً
size 100M) یا ساعتی با مقدار rotate کوچک
دقت کنید که بخش postrotate دستوری مشابه سازوکار چرخش دستی قبلی دارد:
# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
[ ! -f /run/nginx.pid ] || kill -USR1 $(cat /run/nginx.pid)
endscript
}
این بخش به Nginx میگوید پس از تکمیل چرخش، فایلهای لاگ را دوباره باز کند.
بهترین روشهای لاگینگ در Nginx
بیشتر مشکلات لاگینگ پروداکشن به سه چیز خلاصه میشوند: نویز زیاد، مصرف زیاد دیسک، یا لاگهایی که کوئری گرفتن ازشان سخت است. روشهای زیر روی کاهش I/O، قابل پیشبینی کردن نگهداری و بهبود سرعت عیبیابی تمرکز دارند.
۱. استفاده از سطوح لاگ مناسب برای هر محیط
محیطهای مختلف استراتژیهای لاگینگ متفاوتی لازم دارند:
پروداکشن:
# /etc/nginx/nginx.conf
error_log /var/log/nginx/error.log warn;
از warn بهعنوان پیشفرض متعادل پروداکشن استفاده کنید. این سطح سیگنالهای هشدار اولیه مانند خرابی upstream و مشکلات پیکربندی را ثبت میکند، بدون نویز و سربار لاگینگ verbose.
استیجینگ / QA:
# /etc/nginx/nginx.conf
error_log /var/log/nginx/error.log warn;
هشدارها را هم شامل شوید تا مشکلات احتمالی قبل از رسیدن به پروداکشن شناسایی شوند. استفاده از همان سطح warn پروداکشن به اعتبارسنجی رفتار واقعی قبل از دیپلوی کمک میکند.
توسعه (Development):
# /etc/nginx/nginx.conf
error_log /var/log/nginx/error.log debug;
از سطح debug برای عیبیابی جزئیات استفاده کنید، اما هرگز در پروداکشن نه.
۲. پیادهسازی بافرینگ لاگ برای سایتهای پرترافیک
روی سرورهای شلوغ، نوشتن روی دیسک با هر درخواست میتواند به گلوگاه کارایی تبدیل شود. بافرینگ را فعال کنید:
# /etc/nginx/nginx.conf
access_log /var/log/nginx/access.log combined buffer=32k flush=5s;
این تنظیم تا ۳۲ کیلوبایت داده لاگ را بافر میکند و بعد روی دیسک مینویسد؛ یا هر ۵ ثانیه یکبار فلاش میکند؛ هر کدام که زودتر اتفاق بیفتد. مزایا:
- کاهش عملیات I/O دیسک
- کاهش سربار فراخوانیهای سیستمی
- بهبود سرعت پردازش درخواست
نکته: در صورت کرش، ممکن است تا ۵ ثانیه از دادههای لاگ را از دست بدهید.
۳. تعیین سیاستهای نگهداری بر اساس انطباق و فضای ذخیرهسازی
logrotate را با همان بلاک استاندارد /etc/logrotate.d/nginx که قبلاً دیدید پیکربندی کنید و فقط مقادیر rotate، size و تعداد دفعات (روزانه/ساعتی) را بر اساس نیازهای نگهداری خودتان تنظیم کنید.
توضیح پارامترهای کلیدی:
rotate 14: نگهداری ۱۴ روز لاگ (بر اساس نیازتان تنظیم کنید)compress: فشردهسازی لاگهای قدیمی با Gzip برای صرفهجویی حدود ۹۰ درصدی در فضای دیسکdelaycompress: فشرده نکردن جدیدترین لاگ چرخاندهشده (برای تحلیل فعال مفید است)notifempty: چرخاندن فایلهای لاگ خالیcreate 0640 www-data adm: تنظیم مجوزهای درست روی فایلهای لاگ جدید
برنامهریزی ذخیرهسازی: سایتی که روزانه ۱ میلیون درخواست سرو میکند ممکن است تولید کند:
- لاگهای خام دسترسی: حدود ۴۰۰ مگابایت در روز
- لاگهای فشرده: حدود ۴۰ مگابایت در روز
- نگهداری ۳۰ روزه: حدود ۱.۲ گیگابایت مجموع
۴. استفاده از لاگهای جداگانه برای تحلیل امنیتی
یک لاگ اختصاصی برای رویدادهای مرتبط با امنیت بسازید:
# /etc/nginx/nginx.conf
# فرمت لاگ که فیلدهای بیشتری مرتبط با امنیت دارد
log_format security '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $ssl_protocol $ssl_cipher';
server {
listen 443 ssl;
server_name example.com;
# لاگ دسترسی معمولی
access_log /var/log/nginx/access.log combined;
# لاگ متمرکز بر امنیت با فیلدهای اضافی
access_log /var/log/nginx/security.log security;
}
این کار به ابزارهای امنیتی اجازه میدهد یک لاگ تخصصی را تحلیل کنند بدون اینکه کل لاگهای دسترسی را پردازش کنند؛ و شامل اطلاعات SSL/TLS است که برای ممیزیهای امنیتی مفید است.
۵. غیرفعال کردن لاگ برای فایلهای استاتیک (اختیاری)
برای کاهش حجم لاگ در سایتهایی که فایلهای استاتیک زیادی سرو میکنند:
# /etc/nginx/nginx.conf
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2)$ {
access_log off;
expires 30d;
}
نکته مهم: دید شما به درخواستهای فایلهای استاتیک از بین میرود. فقط در این موارد این کار را انجام دهید:
- فایلهای استاتیک از یک CDN سرو میشوند که تحلیل جداگانه ارائه میدهد
- تأیید کردهاید که این لاگها برای هوش تجاری (Business Intelligence) لازم نیستند
- فضای دیسک یا کارایی واقعاً یک دغدغه است
۶. متمرکز کردن لاگها برای استقرارهای چندسروری
برای اپلیکیشنهایی که روی چند instance از Nginx اجرا میشوند، لاگها را با syslog متمرکز کنید:
# /etc/nginx/nginx.conf
access_log syslog:server=logserver.example.com:514,tag=nginx_access combined;
error_log syslog:server=logserver.example.com:514,tag=nginx_error warn;
یا لاگها را به یک سرویس لاگینگ اختصاصی بفرستید:
- Elasticsearch + Filebeat: پارس لاگهای JSON و مصورسازی با Kibana
- Logstash: تبدیل و مسیریابی لاگها به چند مقصد
- سرویسهای ابری: AWS CloudWatch، Google Cloud Logging یا Datadog
۷. مانیتور مصرف دیسک لاگ با هشدار
مانیتورینگی راه بیندازید که قبل از پر شدن دیسک هشدار بدهد:
df -h /var/log/nginx/
یک اسکریپت مانیتورینگ ساده بسازید:
# /usr/local/bin/check_log_disk.sh
#!/bin/bash
THRESHOLD=80
USAGE=$(df /var/log | awk 'NR==2 {print $5}' | sed 's/%//')
if [ "$USAGE" -gt "$THRESHOLD" ]; then
echo "WARNING: /var/log disk usage is at ${USAGE}%" | mail -s "Log Disk Alert" admin@example.com
fi
این اسکریپت را با cron هر ساعت اجرا کنید:
0 * * * * /usr/local/bin/check_log_disk.sh
عیبیابی مشکلات رایج لاگینگ
بیشتر مشکلات لاگینگ Nginx در سه دسته جای میگیرند: لاگها نوشته نمیشوند، چرخش لاگ اجرا نمیشود، یا مصرف دیسک بهطور غیرمنتظره رشد میکند. با بررسیهای زیر علت اصلی را قبل از تغییر پیکربندی تأیید کنید.
مشکل ۱: لاگها نوشته نمیشوند
نشانهها: فایلهای لاگ وجود دارند اما بهروز نمیشوند، یا اصلاً وجود ندارند.
تشخیص:
بررسی کنید Nginx در حال اجراست:
sudo systemctl status nginx
مجوزهای فایل لاگ را بررسی کنید:
ls -la /var/log/nginx/
لاگ خطای Nginx را برای مشکلات مجوز بررسی کنید:
sudo tail -n 20 /var/log/nginx/error.log
راهحلها:
اگر دایرکتوری وجود ندارد، بسازیدش:
sudo mkdir -p /var/log/nginx/
sudo chown www-data:adm /var/log/nginx/
sudo chmod 750 /var/log/nginx/
اگر فایل لاگ مجوز اشتباه دارد:
sudo chown www-data:adm /var/log/nginx/*.log
sudo chmod 640 /var/log/nginx/*.log
اگر SELinux فعال است (در CentOS/RHEL)، کانتکست درست را تنظیم کنید:
sudo semanage fcontext -a -t httpd_log_t "/var/log/nginx(/.*)?"
sudo restorecon -Rv /var/log/nginx/
بعد از رفع مجوزها، Nginx را ریلود کنید:
sudo systemctl reload nginx
مشکل ۲: چرخش لاگ کار نمیکند
نشانهها: فایلهای لاگ بینهایت بزرگ میشوند؛ لاگهای قدیمی فشرده یا حذف نمیشوند.
تشخیص:
بررسی کنید logrotate نصب است:
which logrotate
پیکربندی logrotate مربوط به Nginx را ببینید:
cat /etc/logrotate.d/nginx
logrotate را بهصورت دستی در حالت دیباگ تست کنید:
sudo logrotate -d /etc/logrotate.d/nginx
وضعیت logrotate را بررسی کنید:
sudo cat /var/lib/logrotate/status | grep nginx
راهحلها:
اگر logrotate نصب نیست:
sudo apt update
sudo apt install logrotate
اگر پیکربندی خطای سینتکس دارد، با خروجی حالت دیباگ مشکلات نمایشدادهشده را رفع کنید.
اگر زمانبندی چرخش اشتباه است، پیکربندی اصلی logrotate را بررسی کنید:
cat /etc/cron.daily/logrotate
برای تأیید عملکرد، یک چرخش اجباری اجرا کنید:
sudo logrotate -f /etc/logrotate.d/nginx
اگر اسکریپت postrotate شکست میخورد (Nginx لاگها را دوباره باز نمیکند)، مکان فایل PID را تأیید کنید:
cat /run/nginx.pid
مشکل ۳: فضای دیسک بهسرعت پر میشود
نشانهها: پارتیشن ریشه پر میشود؛ لاگها فضای دیسک زیادی مصرف میکنند.
تشخیص:
مصرف دیسک را بررسی کنید:
df -h /var/log
بزرگترین فایلهای لاگ را پیدا کنید:
sudo du -sh /var/log/nginx/* | sort -h
نرخ رشد لاگ را بررسی کنید:
sudo watch -n 1 'ls -lh /var/log/nginx/access.log'
راهحلها:
چرخش تهاجمیتری پیاده کنید:
# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily
rotate 7
size 100M
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
[ ! -f /run/nginx.pid ] || kill -USR1 $(cat /run/nginx.pid)
endscript
}
میزان تفصیل لاگینگ را در /etc/nginx/nginx.conf عادی کنید تا از مصرف زیاد دیسک جلوگیری شود:
# /etc/nginx/nginx.conf
error_log /var/log/nginx/error.log warn;
لاگینگ دسترسی را برای فایلهای استاتیک غیرفعال کنید (بخش بهترین روشها را ببینید).
لاگینگ شرطی را برای حذف هلتچکها و باتها فعال کنید.
اگر لاگها از قبل خیلی بزرگ شدهاند، قدیمیها را بهصورت دستی فشرده کنید:
sudo gzip /var/log/nginx/access.log.1
sudo gzip /var/log/nginx/error.log.1
مشکل ۴: خواندن لاگها ممکن نیست (Permission Denied)
نشانهها: دستورات tail یا cat خطای Permission denied میدهند.
راهحل:
کاربر خود را به گروه adm اضافه کنید:
sudo usermod -aG adm $USER
خارج و دوباره وارد شوید، سپس تأیید کنید:
groups
باید adm را در فهرست گروههایتان ببینید. حالا میتوانید بدون sudo لاگها را بخوانید:
tail -f /var/log/nginx/access.log
مشکل ۵: فرمت لاگ باعث خطاهای پارس میشود
نشانهها: ابزارهای تحلیل لاگ در پارس شکست میخورند؛ خطاهای فرمت JSON.
تشخیص:
ورودیهای اخیر لاگ را ببینید:
sudo tail -n 5 /var/log/nginx/access.log
اگر از فرمت JSON استفاده میکنید، با jq تست کنید:
sudo tail -n 1 /var/log/nginx/access.log | jq .
راهحلها:
مطمئن شوید escape=json در دایرکتیو log_format شما تنظیم شده است:
# /etc/nginx/nginx.conf
log_format json_combined escape=json
'{'
'"time":"$time_local",'
# ادامه فرمت
'}';
فرمت لاگ خود را با تولید یک درخواست و بررسی فوری قالب خروجی تست کنید.
برای مشکلات فرمت combined، بررسی کنید که فرمت پیشفرض را بهطور غیرمنتظره تغییر نداده باشید.
مشکل ۶: ریاستارت/ریلود Nginx بعد از تغییرات پیکربندی لاگ شکست میخورد
نشانهها: Nginx بعد از تغییر دایرکتیوهای لاگینگ راهاندازی نمیشود.
تشخیص:
همیشه پیکربندی را قبل از اعمال تست کنید:
sudo nginx -t
لاگهای systemd را برای خطاهای خاص بررسی کنید:
sudo journalctl -xeu nginx
علل رایج:
- سینتکس نامعتبر فرمت لاگ: کوتیشن جاافتاده، آکولاد بستهنشده یا متغیرهای نامعتبر
- مسیرهای فایل نامعتبر: دایرکتوری وجود ندارد یا مجوزها اشتباه است
- دایرکتیوهای متناقض: چند دایرکتیو
error_logیاaccess_logدر یک سطح context بدون درک درست وراثت (inheritance)
راهحل:
پیام خطای nginx -t را بررسی کنید که معمولاً به خط دقیق و مشکل اشاره میکند. سینتکس را رفع کنید، مجوزها را تأیید کنید و قبل از ریلود دوباره تست بگیرید.
سوالات متداول
لاگهای Nginx در اوبونتو کجا ذخیره میشوند؟
بهصورت پیشفرض، Nginx لاگها را در /var/log/nginx/ ذخیره میکند:
- لاگهای دسترسی:
/var/log/nginx/access.log - لاگهای خطا:
/var/log/nginx/error.log
میتوانید این مکانها را در /etc/nginx/nginx.conf یا در پیکربندیهای هر سایت زیر /etc/nginx/sites-available/ سفارشی کنید. هر بلاک server میتواند فایلهای لاگ خودش را داشته باشد تا مدیریت و تحلیل سادهتر شود.
لاگهای Nginx باید هر چند وقت یکبار چرخانده شوند؟
تعداد بهینه چرخش به حجم ترافیک و الزامات نگهداری بستگی دارد:
- بیشتر سرورهای پروداکشن: چرخش روزانه با
rotate 14یاrotate 30 - بارهای کاری پرترافیک: چرخش بر اساس حجم (مثلاً
size 100M) یا چرخش ساعتی با بازه نگهداری کوچک - الزامات انطباق و ممیزی: نگهداری لاگها برای ۹۰ روز یا بیشتر
مقادیر rotate، size و تعداد دفعات را در /etc/logrotate.d/nginx مطابق نیازهای عملیاتی و قانونی خود تنظیم کنید.
چطور فرمت لاگ سفارشی در Nginx بسازم؟
فرمتهای سفارشی را با دایرکتیو log_format در بلاک http فایل /etc/nginx/nginx.conf بسازید:
log_format custom_format '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'rt=$request_time';
سپس با access_log اعمالش کنید:
access_log /var/log/nginx/custom_access.log custom_format;
میتوانید از هر متغیر Nginx در فرمت خود استفاده کنید. موارد رایج برای مانیتورینگ کارایی و امنیت شامل $request_time، $upstream_response_time، $ssl_protocol و $ssl_cipher هستند.
چرا لاگهای Nginx من چرخانده نمیشوند؟
علل و راهحلهای رایج:
- logrotate نصب نیست: با
sudo apt install logrotateنصبش کنید - جاب cron مربوط به logrotate غیرفعال است: بررسی کنید
/etc/cron.daily/logrotateوجود دارد و قابل اجراست - خطاهای پیکربندی: با
sudo logrotate -d /etc/logrotate.d/nginxتست کنید - Nginx هندل فایلها را آزاد نمیکند: اسکریپت postrotate باید سیگنال USR1 برای باز کردن مجدد لاگها بفرستد
- مسیرهای فایل اشتباه: مطمئن شوید مسیرهای
/etc/logrotate.d/nginxبا مکانهای واقعی لاگ مطابقت دارند
برای دیباگ، sudo logrotate -dv /etc/logrotate.d/nginx را اجرا کنید تا خروجی تفصیلی اقدامات logrotate را ببینید.
آیا Nginx میتواند با فرمت JSON لاگ ثبت کند؟
بله، Nginx میتواند لاگها را با فرمت JSON خروجی بدهد که برای ابزارهای مدرن تجمیع و تحلیل لاگ ایدهآل است. فرمت JSON را در /etc/nginx/nginx.conf تعریف کنید:
log_format json_combined escape=json
'{'
'"timestamp":"$time_local",'
'"client":"$remote_addr",'
'"method":"$request_method",'
'"uri":"$request_uri",'
'"status":"$status",'
'"bytes_sent":"$body_bytes_sent",'
'"response_time":"$request_time",'
'"user_agent":"$http_user_agent"'
'}';
آن را روی لاگ دسترسی اعمال کنید:
access_log /var/log/nginx/access.log json_combined;
پارامتر escape=json تضمین میکند کاراکترهای خاص بهدرستی escape شوند. لاگهای JSON بهراحتی با Elasticsearch، Splunk، Datadog و دیگر پلتفرمهای تحلیل لاگ کار میکنند.
چطور لاگینگ دسترسی را برای درخواستهای خاص غیرفعال کنم؟
از لاگینگ شرطی با map استفاده کنید:
map $request_uri $loggable {
~^/health 0;
~^/status 0;
~*\.(gif|jpg|png)$ 0;
default 1;
}
server {
access_log /var/log/nginx/access.log combined if=$loggable;
}
این کار endpointهای هلتچک و درخواستهای تصاویر را از لاگها حذف میکند. روش دیگر، غیرفعال کردن کامل لاگ برای یک location است:
location /health-check {
access_log off;
return 200 "OK";
}
تأثیر لاگینگ verbose بر کارایی چقدر است؟
تأثیر کارایی لاگینگ بسته به سطح و ترافیک متفاوت است:
- سطح warn: پیشفرض پیشنهادی برای پروداکشن. سربار کم همراه با حفظ سیگنالهای هشدار اولیه.
- سطوح info و notice: سربار متوسط بهدلیل I/O دیسک بالاتر. بهصورت موقت برای بررسی استفاده کنید.
- سطح debug: سربار بالا و نوشتنهای سنگین روی دیسک. فقط هنگام عیبیابی فعال استفاده کنید و بلافاصله بعدش غیرفعالش کنید.
تأثیر واقعی به سرعت I/O دیسک، حجم ترافیک و استفاده از بافر بستگی دارد. روی سایتهای پرترافیک، بافرینگ را فعال کنید (buffer=32k flush=5s) تا نوشتنهای دیسک کمتر و سربار کارایی حداقل شود.
لاگهای Nginx را چقدر نگه دارم؟
نگهداری لاگ باید تعادلی بین الزامات انطباق، هزینه ذخیرهسازی و کاربرد بودن برقرار کند:
حداقلهای پیشنهادی:
- سایتهای پروداکشن: ۳۰ روز برای عیبیابی و تحلیل روندها
- الزامات انطباق (PCI DSS، HIPAA، GDPR): ۹۰ روز تا ۱ سال
- نیازهای فورنزیک/امنیتی: بیش از ۹۰ روز برای بررسی حوادث
کارایی ذخیرهسازی:
- از
compressدر logrotate استفاده کنید تا فضای ذخیرهسازی حدود ۹۰ درصد کاهش یابد - لاگهای قدیمیتر را به فضای ذخیرهسازی ارزانتر آرشیو کنید (مانند S3 Glacier)
- از نگهداری چندلایهای استفاده کنید: ۳۰ روز محلی، ۹۰ روز آرشیو، ۱ سال ذخیرهسازی سرد
نمونه سیاست نگهداری:
/var/log/nginx/*.log {
daily
rotate 30 # 30 روز محلی
compress
dateext
# آرشیو هر چیز قدیمیتر با یک اسکریپت به S3
lastaction
/usr/local/bin/archive_old_logs.sh
endscript
}
نتیجهگیری
پیکربندی و مدیریت درست لاگ مستقیماً بر توانایی شما در عیبیابی قطعیها، تشخیص ترافیک غیرعادی و جلوگیری از خرابیهای مرتبط با دیسک تأثیر میگذارد. با پیادهسازی استراتژیهای لاگینگی که در این آموزش پوشش داده شد، دید عملی به رفتار واقعی سرور به دست میآورید.
یاد گرفتید چگونه دایرکتیوهای error_log و access_log را پیکربندی کنید، فرمتهای لاگ سفارشی برای نیازهای مانیتورینگ خاص بسازید، چرخش لاگ را برای جلوگیری از مشکلات فضای دیسک پیاده کنید و مشکلات رایج لاگینگ را عیبیابی کنید. این قابلیتها به شما کمک میکنند مشکلات را سریع تشخیص دهید، الگوهای ترافیک را درک کنید و امنیت سرور را حفظ کنید.




