1. 概要

このチュートリアルでは、logrotateツールについて説明します。 具体的には、Linuxでlogrotateを使用してログローテーションを自動化する方法を学習します。

2. ログローテーション

Linuxでは、アプリケーションとバックグラウンドプロセスが常にログを生成しています。 これらのログを特定のスケジュールでトリミングしてチェックすることが重要です。 ただし、手動で行うのは手間がかかります。 手作業による介入を減らすために、logrotateを使用してプロセスを自動化できます。

logrotateは、Linuxのログ管理コマンドラインツールです。 管理者は、さまざまなログファイルを処理するためのルールとポリシーを構成ファイルに書き込みます。 logrotate は、構成ファイルを介して適切な機能を実行し、一致するログファイルを管理します。

logrotate はあらゆる種類のファイルで機能しますが、通常はログファイルの管理に使用されます。

2.1. インストール

logrotate をインストールするには、さまざまなLinuxディストリビューションでパッケージマネージャーを使用できます。

Ubuntuでは、apt-getを使用してパッケージをインストールできます。

$ sudo apt-get update
$ sudo apt-get install -y logrotate

CentOSなどのRHELベースのLinuxの場合、yumパッケージマネージャーを使用できます。

$ sudo yum update
$ sudo yum install -y logrotate

最後に、 apk パッケージマネージャーを使用して、logrotateをアルパインにインストールできます。

$ sudo apk update
$ sudo apk add logrotate

2.2. コマンド構文

通常、 logrotate コマンドを実行するには、オプションのリストの後に各構成ファイルへのパスを指定します。

logrotate [OPTION...] <config file1> <config file2>...

複数の構成ファイルがある場合、後者の定義が前の定義を上書きします。つまり、最初の構成ファイルの優先順位が最も低くなります。

2.3. ディレクティブ

ディレクティブはlogrotate構成の基本的な構成要素であり、さまざまな機能を定義します。次に、これらを組み合わせて、さまざまなログファイルに適用される構成ファイルを形成します。 さらに、これらの各ディレクティブを使用すると、logrotateのさまざまな側面を構成できます。 たとえば、copyディレクティブはローテーションプロセスを変更します。 一方、 compress ディレクティブは、ローテーションされたファイルの処理方法を変更します。

さらに、これらのディレクティブのほとんどには、対応する否定ディレクティブがあります。 これらの否定ディレクティブは、指定されたときに対応する効果をキャンセルします 。 たとえば、構成ブロック内で nocompress ディレクティブを指定すると、グローバルcompressディレクティブがキャンセルされます。

ディレクティブの包括的なリストについては、公式マニュアルページにあります。

2.4. 構成ファイル

ディレクティブを使用して、logrotateで使用できる構成ファイルのセットを作成できます。 通常、構成ファイルは次の形式で構成されます。

<global directive 1>
<global directive 2>

<file path matchers 1> {
    <directive 1>
    <directive 2>
    ...
    <directive n>
}

<file path matchers 2a> <file path matchers 2b> {
    <directive 1>
    <directive 2>
    ...
    <directive n>
}

構成ファイルの先頭で、0個以上のグローバルディレクティブを指定できます。 グローバルディレクティブは、logrotateによって管理されるすべてのログファイルに影響します。

次に、回転させたいファイルに一致するように複数のグロブパターンを指定します。 さらに、パターンに一致するファイルに固有の中括弧内に一連のディレクティブを定義します。

構成ファイルの例を見てみましょう。

compress

/var/log/nginx/* {
    rotate 3
    daily
}

/var/log/nginx/error.log {
    rotate 3
    size 1M
    lastaction
        /usr/bin/killall -HUP nginx
    endscript
    nocompress
}

この例では、グローバルcompressディレクティブが上部にあることがわかります。 具体的には、一致するログファイルはローテーション時に圧縮されます。

次に、/var/log/nginx/*/var/log/nginx/error.logの2つのパターンが定義されていることがわかります。 最初のマッチャーはワイルドカードを使用して、 / var / log /nginxディレクトリ内のすべてのファイルを照合します。 一方、2番目のマッチャーは、 / var / log /nginx内の特定のerror.logファイルにのみ一致します。

2番目の構成ブロック内で、 nocompress ディレクティブを指定して、グローバルcompressディレクティブをオーバーライドします。

2.5. デフォルト設定

logrotate をインストールすると、/etc/logrotate.confにデフォルト構成が作成されます。 この構成ファイルには、logrotateのデフォルトの動作の一部を定義するいくつかのグローバルディレクティブが含まれています。 logrotate の構成ファイルは加算的であるため、必要に応じてオーバーライドできるように、デフォルトの構成を覚えておく必要があります。

たとえば、Ubuntuへの logrotate のインストールには、 weekly rotate 4 createなどのグローバルディレクティブが付属しています。

2.6. 構成ファイルの適用

構成ファイルにローテーションポリシーを記述したら、それを有効にするためにlogrotateコマンドを実行する必要があります。 具体的には、 log-rotation.conf 構成ファイルを適用するには、logrotateコマンドの後に構成ファイルパスを実行します。

$ logrotate log-rotation.conf

logrotate で条件をすぐに評価する場合は、-fオプションを渡して強制的に実行できます。

$ logrotate -f log-rotation.conf

3. 回転条件

logrotate を使用すると、さまざまな条件下でログファイルをローテーションできます。 特に、ログファイルを一定の期間、またはファイルが特定のサイズに拡大した場合にローテーションできます。

3.1. 期間に基づいたログファイルのローテーション

期間に基づいてファイルをローテーションするには、4つのディレクティブの1つを指定できます: daily weekly monthly 、およびyearly。 たとえば、構成ファイルで daily ディレクティブを指定することで、/var/log/nginx/access.logを毎日ローテーションできます。

/var/log/nginx/access.log {
    daily
}

または、毎週ローテーションするには、weeklyディレクティブを指定するだけです。

/var/log/nginx/access.log {
    weekly
}

3.2. サイズに基づいたログファイルのローテーション

ほとんどの場合、ログファイルが特定のサイズに達したら、ログファイルをローテーションする必要があります。 これを実現するために、sizeディレクティブの後にサイズ制限を指定できます。 たとえば、 /var/log/nginx/access.log が1メガバイトに達したときにローテーションするには、 size 1Mディレクティブを使用できます。

/var/log/nginx/access.log {
    size 1M
}

接尾辞Mをメガバイトとして認識するほか、このディレクティブは接尾辞k をキロバイトとして、Gをギガバイトとして認識します。 具体的には、 size 1000k を指定すると、 size1Mを指定した場合と同じ効果があります。

4. ローテーションされたファイルの処理

ログファイルがローテーションされると、別のディレクティブのセットを介してログファイルに何が起こるかを指定できます。 たとえば、ローテーションされたファイルを電子メールに送信したり、単に破棄したりできます。

4.1. 少数のローテーションされたログファイルのみを保持する

rotate n ディレクティブを使用して、システムに保持するローテーションされたファイルの数を制限できます。ここで、nは整数値です。 制限nに達すると、それ以上ローテーションすると、制限が守られるように、最も古いローテーションされたログファイルが削除されます。 たとえば、3つの回転した/var/log/nginx/access.logファイルのみを保持するには次のようにします。

/var/log/nginx/access.log {
    size 1M
    rotate 3
}

ローテーション時に、 logrotate は、システムにすでに3つのローテーションされたaccess.logがあるかどうかを確認します。 存在する場合は、最も古いものを破棄して、新しいローテーションされたファイル用のスペースを作成します。 最終的に、この構成により、システム内で回転する/var/log/nginx/access.logが3つ以下になるようになります。

4.2. 年齢別のローテーションされたファイルの削除

さらに、ローテーションされたファイルを年齢別に削除できます。 特に、 maxageディレクティブを使用して、特定の日数より古いファイルを破棄できます。 ディレクティブは、日数を指定する追加の整数引数を取ります。

たとえば、すでにシステムに5日以上存在するローテーションされたログを破棄できます。

/var/log/nginx/access.log {
    size 1M
    maxage 5
}

4.3. 回転したファイルの圧縮

logrotate ツールは、オプションで、各ローテーション後に古いログファイルを圧縮します。 具体的には、 compressディレクティブを使用して、logrotateにローテーションされたログファイルを圧縮させることができます。

/var/log/nginx/access.log {
    size 1M
    compress
}

上記の例では、 logrotate は、サイズが1メガバイトに達するとログファイルをローテーションします。 その後、gzipコマンドを使用して古いログファイルを圧縮します。 グローバルに適用されるcompressディレクティブを無効にするには、nocompressディレクティブを使用できます。

compress

/var/log/nginx/access.log {
    size 1M
}

/var/log/nginx/error.log {
    size 1M
    nocompress
}

上記の例では、 logrotate は、各ローテーション後にaccess.logファイルを圧縮します。 ただし、 nocompress ディレクティブにより、error.logは圧縮から除外されます。

4.4. ローテーションされたファイルの郵送

ローテーションのたびに、メールディレクティブを使用して、ローテーションされたファイルを一部の受信者にlogrotateで電子メールで送信できます。 これを有効にするには、まずシステム上で動作する電子メールクライアントを構成する必要があります。 次に、 mail ディレクティブを指定して、ローテーションのために破棄されようとしているログファイルをメールで送信できます。

/var/log/nginx/error.log {
    size 1M
    rotate 2
    mail
}

上記の構成では、 logrotate は、/var/log/nginx/error.logのローテーションされたログファイルの最大2つのコピーを保持します。 さらに、ローテーションされたログを破棄する直前に、logrotateは指定された受信者にログをメールで送信します。

期限切れのログをメールで送信する代わりに、mailfirstディレクティブを使用して新しくローテーションされたログファイルをメールで送信できます

/var/log/nginx/error.log {
    size 1M
    rotate 2
    mail
    mailfirst
}

ローテーションが発生すると、 logrotate は、最も古いものではなく、最新のローテーションされたログファイルを電子メールで送信します。

5. アクティブログファイルの処理

デフォルトの動作では、ローテーションプロセスはlogrotateによってアクティブなログファイルの名前を別の名前に変更します。 次に、同じ名前の新しいログファイルを作成します。 最後に、compressmailなどの他のロジックを呼び出して、ローテーションプロセスを完了します。

一部のアプリケーションでは、このデフォルトの動作は混乱を招きすぎます。 特に、新しいファイルへの移行を処理するのに十分な柔軟性がない場合、アプリケーションがクラッシュする可能性があります。 そのような場合、3つのディレクティブの1つを使用して動作を変更できます。 作成 コピー 、 と copytruncate。 

5.1. 新しいログファイルの作成

createディレクティブは、logrotateがデフォルトでローテーションを処理する方法です。このポリシーでは、ログファイルの名前を変更し、同じ名前でログファイルを再作成します。 表面的には、ローテーション後もログファイルは同じように見えます。 ただし、ローテーション後、同じファイルに対して異なるiノード値を取得します。

/tmp/logs/error.logcreateディレクティブを構成しましょう。

/tmp/logs/error.log {
    size 100k
    rotate 2
    create
}

次に、200キロバイトに相当するデータを error.log ファイルに入力し、そのiノード値を書き留めます。

$ ls -hil /tmp/logs
total 200K
402882 -rw-r--r-- 1 user user 200K Sep  5 12:45 error.log

次に、 logrotate コマンドを実行して、ローテーションをトリガーします。

$ logrotate logrotate.conf
$ ls -hil /tmp/logs
total 200K
402878 -rw-r--r-- 1 user user    0 Sep  5 13:00 error.log
402882 -rw-r--r-- 1 user user 200K Sep  5 12:59 error.log.1

ご覧のとおり、iノード値が402882のファイルは、error.log.1に名前が変更されています。 一方、error.logファイルには新しいiノード値があります。 つまり、 logrotate コマンドは、最初にログファイルの名前をerror.log.1に変更します。 続いて、新しいerror.logを作成します。

5.2. アクティブログファイルのコピーを作成する

ローテーションプロセスの中断を少なくするために、古いログを別のファイルにコピーしてコンテンツをクリアすることにより、ログをローテーションできます。

このローテーションのフレーバーは、copytruncatecopyの2つの異なるディレクティブの形式で提供されます。 作成とは逆に、コピーとコピートランケートの両方で、名前を変更する代わりにメインログファイルのコピーを作成します。

ただし、メインファイルのコンテンツがどうなるかについては、copycopytruncateには違いがあります。 一方では 、copytruncateディレクティブは、元のログファイルの内容をクリアします。 一方、copyディレクティブは、元のログファイルの内容をクリアしません。

例を見て、それらの正確な動作を詳細に学習しましょう。 まず、/tmp/logs/error.logを200キロバイトのファイルとして作成します。

$ ls -hil /tmp/logs
total 200K
402878 -rw-r--r-- 1 user user 200K Sep  5 13:10 error.log

次に、 /tmp/logs/error.log の構成ファイルを作成し、copytruncateディレクティブを使用してサイズ100キロバイトでローテーションします。

/tmp/logs/error.log {
    size 100k
    rotate 2
    copytruncate
}

最後に、 logrotate コマンドを実行して、ローテーションをトリガーします。

$ logrotate logrotate.conf
ls -hil /tmp/logs
total 200K
402878 -rw-r--r-- 1 user user    0 Sep  5 13:13 error.log
402882 -rw-r--r-- 1 user user 200K Sep  5 13:13 error.log.1

調べてみると、error.logはiノード値402878の同じファイルのままであることがわかります。 さらに、 logrotate は、ローテーション中に error.log の内容をクリアし、サイズは0バイトになりました。

copyディレクティブを使用して実験を繰り返しましょう。

$ cat logrotate.conf
/tmp/logs/error.log {
    size 100k
    rotate 2
    copy
}
$ logrotate logrotate.conf
$ ls -hil /tmp/logs
total 400K
402878 -rw-r--r-- 1 user user 200K Sep  5 13:16 error.log
402882 -rw-r--r-- 1 user user 200K Sep  5 13:16 error.log.1

copytruncate と同様に、error.logも同じファイルです。 ただし、 error.log の内容をクリアする代わりに、ローテーション後もログファイルのサイズは200キロバイトのままです。

特におしゃべりなログの場合は、コピーディレクティブを注意して使用する必要がありますこれは、コピーディレクティブの非削除の性質により、メインログとローテーションログの両方のサイズが大きくなり続けるためです。最終的に、システムのディスク領域が不足する可能性があります。

6. ローテーション中にスクリプトを実行する

事前定義されたディレクティブに加えて、 logrotate は、ローテーション中にさまざまなフックポイントでカスタムスクリプトを実行する可能性を提供します。 具体的には、回転中に4つの異なるフックポイントでアタッチスクリプトを実行できます。

  • ローテーションの前
  • 各ローテーションの前
  • 各回転後
  • やっぱりローテーション

6.1. すべてのローテーションの前または後

firstactionディレクティブを使用すると、ローテーションが行われる前にいくつかのカスタムスクリプトを実行できます。 一方、 logrotateは、すべてのローテーションが行われた直後にlastactionディレクティブでスクリプトを実行します。どちらの場合も、logrotateは最初の引数としてファイルパスパターンを渡します。スクリプトに。

たとえば、次のディレクティブを使用して、ローテーションの前後のタイムスタンプをログに記録できます。

/tmp/logs/*.log {
    size 100k
    firstaction
        echo "start rotation $(date)" >> /tmp/rotation.log
    endscript
    lastaction
        echo "complete rotation $(date)" >> /tmp/rotation.log
    endscript
}

上記の構成では、ローテーションが発生する直前にタイムスタンプを/tmp/rotation.logに書き込みます。 すべてのローテーションが完了したら、タイムスタンプを/tmp/rotation.logファイルに再度追加します。

6.2. 各ローテーションの前または後

各ローテーションの直前にスクリプトを実行するには、prerotateディレクティブを使用してスクリプトを記述します。 同様に、 postrotate ディレクティブを使用して、各ローテーション後にスクリプトを実行できます。 logrotate がスクリプトを実行すると、最初の引数として各ログファイルのファイルパスがスクリプトに渡されます。

たとえば、prerotateおよびpostrotateディレクティブを使用して、各ログファイルのローテーションが発生した瞬間をログに記録するスクリプトを作成できます。

/tmp/logs/*.log {
    size 100k
    prerotate
        echo "start rotation for $1 $(date)" >> /tmp/rotation.log
    endscript
    postrotate
        echo "complete rotation for $1 $(date)" >> /tmp/rotation.log
    endscript
}

上記の構成では、ローテーションされたログファイルごとに/tmp/rotation.logファイルに2つのログ行が生成されます。

6.3. firstaction /lastactionprerotate/postrotateの違い

表面的には、 firstaction /lastactionprerotate / postrotate はどちらも同じことをしているように見えます。つまり、ローテーションの前後にスクリプトを実行します。 ただし、ディレクティブのペアの違いは、1つのマッチャーのローテーション中に実行される回数です。

firstaction / lastaction ディレクティブのペアのスクリプトは、マッチャーごとに1回だけ実行されます。 一方、 logrotate は、一致したファイルパスごとに prerotate /postrotateのスクリプトを実行します。

たとえば、パターンが3つのファイルに一致する場合、 firstaction / lastaction は、3つのファイルがローテーションされる前後に1回だけ実行されます。 一方、 prerotate / postrotate のスクリプトは、ローテーションするファイルが3つあるため、3回実行されます。

それらをよりよく理解するために、例を見てみましょう。 まず、 logrotate 構成を作成して、違いを示します。

$ cat logrotate.conf
/tmp/logs/*.log {
  size 100k
  firstaction
    echo "on first action. first argument: $1" >> /tmp/event-hooks.log
  endscript
  lastaction
    echo "on last action. first argument: $1" >> /tmp/event-hooks.log
  endscript
  prerotate
    echo "on prerotate. first argument: $1" >> /tmp/event-hooks.log
  endscript
  postrotate
    echo "on postrotate. first argument: $1" >> /tmp/event-hooks.log
  endscript
}

サイズが100キロバイトに達すると、構成を通じて、パス/tmp/logs/*.logに一致するすべてのファイルをローテーションします。 次に、イベント名と最初の引数をファイル/tmp/event-hooks.logに出力するスクリプトを定義します。

次に、 / tmp /logsディレクトリ内に3つの異なるファイルを作成します。 さらに、各ファイルは977キロバイトのデータで作成され、ローテーションをトリガーします。

ls -hl
total 2.9M
-rw-r--r-- 1 user user 977K  Sep  5 14:57 access.log
-rw-r--r-- 1 user user 977K  Sep  5 14:57 auth.log
-rw-r--r-- 1 user user 977K  Sep  5 14:57 error.log

最後に、コマンドを実行して、logsディレクトリ内のファイルをローテーションできます。

$ logrotate logrotate.conf

その後、 /tmp/event-hooks.log を調べて、各スクリプトの実行順序を確認できます。

$ cat /tmp/event-hooks.log
on first action. first argument: /tmp/logrotate/logs/*.log
on prerotate. first argument: /tmp/logrotate/logs/access.log
on postrotate. first argument: /tmp/logrotate/logs/access.log
on prerotate. first argument: /tmp/logrotate/logs/auth.log
on postrotate. first argument: /tmp/logrotate/logs/auth.log
on prerotate. first argument: /tmp/logrotate/logs/error.log
on postrotate. first argument: /tmp/logrotate/logs/error.log
on last action. first argument: /tmp/logrotate/logs/*.log

7. 概要

このチュートリアルでは、Linuxのlogrotateコマンドラインツールについて説明しました。 logrotate、の簡単な紹介から始め、その後にインストールガイドを示しました。 次に、ディレクティブやその構成ファイルの構造など、 logrotate、のさまざまな側面を学びました。

次に、実行中のいくつかのディレクティブの確認に進みます。 たとえば、時間やサイズの条件に基づいてログをローテーションする方法を確認します。 それに加えて、ローテーションされたファイルを操作できるようにする一連のディレクティブも調べました。 その後、デフォルトのローテーションプロセスの破壊的な性質について説明しました。 次に、代替のcopycopytruncateを調べました。

最後に、 firstaction /lastactionおよびprerotate/ postrotate ディレクティブのペアについて説明しました。これにより、ローテーションの合間にスクリプトを実行できます。