מדריך logrotate

לוג רוטייט הוא כלי אוטומטי שמכווץ קבצי לוג ישנים ומוחק אותם כשהם ממש ישנים. לוג רוטייט הוא אחד הכלים החשובים בעבודה על מכונות לינוקס כי בלעדיו קבצי הלוג יכולים להגיע לנפח עצום ולמלא את כל השרת. במדריך זה אסביר איך הוא עובד ואיך להוסיף קבצים שלכם לניקוי באמצעות logrotate.

1. התקנה ובדיקת סטטוס

משורת הפקודה, אפילו בתור משתמש רגיל, אפשר להפעיל:

$ logrotate --version

כדי לראות אם הכלי מותקן אצלכם (מותקן ב Ubuntu אוטומטית, אז כנראה שכן). אם לא מותקן אפשר להתקין אותו עם:

$ sudo apt install logrotate

אני משתמש בגירסה 3.14.0.

בשביל לעבוד logrotate צריך לקבל קובץ הגדרות. הפעלה שלו בלי קובץ הגדרות מציגה פיסקת עזרה קצרה:

logrotate 3.14.0 - Copyright (C) 1995-2001 Red Hat, Inc.
This may be freely redistributed under the terms of the GNU General Public License

Usage: logrotate [-dfv?] [-d|--debug] [-f|--force] [-m|--mail=command] [-s|--state=statefile] [-v|--verbose] [-l|--log=logfile] [--version]
        [-?|--help] [--usage] [OPTION...] <configfile>

קובץ ההגדרות הוא המפתח להצלחה ובו נספר ל logrotate מיהם קבצי הלוג שלנו, מתי לכווץ אותם ומתי למחוק אותם.

לוגרוטייט מופעל אוטומטית מתוך Cron Job יומי. אני יכול למצוא את פרטי הג'וב בקובץ /etc/cron.daily/logrotate. ככה זה נראה במכונה שלי:

$ cat /etc/cron.daily/logrotate
#!/bin/sh

# skip in favour of systemd timer
if [ -d /run/systemd/system ]; then
    exit 0
fi

# this cronjob persists removals (but not purges)
if [ ! -x /usr/sbin/logrotate ]; then
    exit 0
fi

/usr/sbin/logrotate /etc/logrotate.conf
EXITVALUE=$?
if [ $EXITVALUE != 0 ]; then
    /usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]"
fi
exit $EXITVALUE

2. הגדרת לוגים

קובץ ההגדרות שמופעל בברירת מחדל הוא /etc/logrotate.conf. נכנס לראות מה כתוב בו:

# see "man logrotate" for details
# rotate log files weekly
weekly

# use the adm group by default, since this is the owning group
# of /var/log/syslog.
su root adm

# keep 4 weeks worth of backlogs
rotate 4

# create new (empty) log files after rotating old ones
create

# use date as a suffix of the rotated file
#dateext

# uncomment this if you want your log files compressed
#compress

# packages drop log rotation information into this directory
include /etc/logrotate.d

# system-specific logs may be also be configured here.

הנה עיקרי הדברים בתרגום:

  1. המילה weekly אומרת שאנחנו מקדמים את הלוגים פעם בשבוע ביום ראשון. אפשר לציין את היום אם נכתוב מספר אחרי המילה weekly.

  2. את הפעולה יבצע משתמש root בקבוצת adm.

  3. הפקודה rotate 4 אומרת שיהיו 4 סבבים של "שמירת לוג" לפני שמוחקים אותו, כלומר לוגים יישמרו ל 4 שבועות. כל שבוע לשם הקובץ יתווסף מספר שעולה ב-1 כל סיבוב.

  4. אחרי סיבוב באופן אוטומטי יוצרים קובץ לוג חדש בשם המקורי.

  5. המילה compress היא בהערה לכן ברירת המחדל אצלי על המכונה היא לא לכווץ לוגים.

  6. הגדרות נוספות לפי סרביסים אפשר למצוא בתיקיית /etc/logrotate.d.

בעצם אנחנו רואים כאן שמבנה קובץ ההגדרות מתאים לזה שכל תוכנית שאני מתקין צריכה להוסיף את ההגדרות שלה לתיקיית /etc/logrotate.d ואז logrotate יעשה את הקסם שלו וינקה את הלוגים של אותה התוכנית.

על אותה מכונת אובונטו בתיקיית /etc/logrotate.d אני מוצא את קבצי ההגדרות הבאים:

# ls
alternatives  btmp         rsyslog                 unattended-upgrades
apport        cups-daemon  speech-dispatcher       wtmp
apt           dpkg         ubuntu-advantage-tools
bootlog       ppp          ufw

נפתח אחד מהם בשביל לראות איך לכתוב הגדרות לסרביס:

# cat /etc/logrotate.d/dpkg
/var/log/dpkg.log {
        monthly
        rotate 12
        compress
        delaycompress
        missingok
        notifempty
        create 644 root root
}

הסרביס dpkg שומר לוגים אחרת מברירת המחדל:

  1. הוא מגדיר מהו קובץ הלוג שלו.

  2. הרוטציה קורית פעם בחודש, ולוגים ישנים נשמרים 12 רוטציות, כלומר לשנה.

  3. לוגים ישנים מכווצים.

  4. הכיווץ לא קורה מיד אלא רק ברוטציה הבאה (נועד להתמודד עם תוכניות שמשאירות קובץ לוג פתוח וממשיכות לכתוב אליו גם אחרי ששינו לו את השם).

  5. לא צריך לעשות עניינים אם הקובץ חסר.

  6. לא לכווץ או להזיז אם הקובץ ריק

  7. כשיוצרים קובץ חדש ההרשאות יהיו 644 למשתמש וקבוצה root.

מבט בתיקיה מראה לי את הלוגים והרוטציות:

# ls -l /var/log/dpkg.log*
-rw-r--r-- 1 root root  7010 Aug  3 06:14 /var/log/dpkg.log
-rw-r--r-- 1 root root 50427 Jul 30 13:44 /var/log/dpkg.log.1
-rw-r--r-- 1 root root  5053 Jun 30 08:36 /var/log/dpkg.log.2.gz
-rw-r--r-- 1 root root  4512 May 28 06:14 /var/log/dpkg.log.3.gz
-rw-r--r-- 1 root root  8898 Apr 30 06:05 /var/log/dpkg.log.4.gz
-rw-r--r-- 1 root root   979 Mar  2 15:38 /var/log/dpkg.log.5.gz
-rw-r--r-- 1 root root  5376 Feb 25 10:52 /var/log/dpkg.log.6.gz
-rw-r--r-- 1 root root  4158 Jan 28  2022 /var/log/dpkg.log.7.gz
-rw-r--r-- 1 root root  2966 Dec 22  2021 /var/log/dpkg.log.8.gz
-rw-r--r-- 1 root root 55022 Nov 28  2021 /var/log/dpkg.log.9.gz

אנחנו רואים איך הלוג התקדם כל חודש, את הלוגים המכווצים ואת הלוג עם סיומת .1 שעדיין לא כווץ.

3. יצירת קונפיגורציה ללוגים שלי

בשביל להוסיף תוכנית שלי להגדרות logrotate אני בסך הכל צריך להוסיף עוד קובץ לתיקיית ה include. לדוגמה נניח שיש לי שרת ווב שמגיש אפליקציה בשם mysite וכותב הרבה לוגים בכל מיני שמות לתיקיית /var/log/mysite/. אני יכול להוסיף את הקובץ /etc/logrotate.d/mysite ובתוכו לכתוב את התוכן הבא:

/var/log/your-app/*.log {
    daily
    missingok
    rotate 14
    compress
    notifempty
    create 0640 www-data www-data
    sharedscripts
    postrotate
        systemctl reload your-app
    endscript
}

נתרגם:

  1. רוטציית לוגים מבוצעת כל יום, ולוגים נשמרים 14 רוטציות, כלומר שבועיים.

  2. לוגים ישנים מכווצים.

  3. לא נורא אם אין לוגים.

  4. לא נוגעים בקבצים ריקים.

  5. הלוגים נוצרים תחת משתמש www-data.

  6. הפקודות postrotate ו sharedscripts אומרות שאחרי שעשינוי רוטציה לכל הלוגים נריץ את הפקודה שכתובה ב postrotate, כלומר טעינה מחדש של השרת. זה נועד להתמודד עם זה ששרת ממשיך לכתוב לקובץ לוג אפילו אחרי שנמחק כי הוא החזיק את הקובץ פתוח. הסקריפט מסתיים בפקודה endscript.

רוצים ללמוד עוד על logrotate ואפשרויות השימוש בו? שווה לבקר בדף העזרה של דיגיטל אושן על הכלי (משם גם לקחתי את הדוגמה האחרונה בפוסט): https://www.digitalocean.com/community/tutorials/how-to-manage-logfiles-with-logrotate-on-ubuntu-20-04

וכמובן ב man page של logrotate עצמה בקישור: https://www.man7.org/linux/man-pages/man8/logrotate.8.html