White Box技術部

WEB開発のあれこれ(と何か)

【logrotate】CentOSでログローテする

ログローテはたまにやろうとすると、あれどうだっけ?となるので logrotateを使ったログのローテーション方法をまとめました。

前提

  • 環境(OS):CentOS 6.6
  • 利用機能:logrotate、cron

今回は、ローテーションしたいログ、例えばアプリケーションログを /var/log/app配下に吐いているとして考えていきます。

※作業はsudoユーザで実施してください。

手順

/etc/logrotate.dディレクトリにappファイルを作成し、ログローテ設定をします。

なので、まずはこのディレクトリをlogrotateが読むようになっているかを確認しましょう。

logrotate.dの読み込み確認

logrotate.confに以下の記述があること確認してください。
もしなければ、適当な位置に追記をしてください。

  • /etc/logrotate.conf
include /etc/logrotate.d

これが設定されていれば、logrotate.dディレクトリの設定も読み込まれます。

ローテーション設定の記述

logrotate.dディレクトリ配下にファイルを作ってローテーションの設定を記述します。 ファイル名は何でもよいのですが、logが作成されるディレクトリ名など、 何のログのローテーション設定が書かれたものか分かるように様な名前が良いです。 (ここではlogディレクトリ名からappという名前にしています)

appファイルについて

  • /etc/logrotate.d/app
  • 権限:644、root:root
/var/log/app/*.log {
    copytruncate
    daily
    rotate 30
    compress
    missingok
    ifempty
}

以下の流れで実施すると、設定確認まできてGOODです

cd /etc/logrotate.d/
sudo vi app
logrotate -dv app

※エラーが出たら設定を見直してください。

cronの設定確認

ローテーションの設定自体は終わっているのですが、 一応cronでlogrotateが動かされているかを確認しておきましょう。

確認ポイントは、# service crond statusの結果がrunningになっていることと、 /etc/cron.daily/logrotateが存在していることです。

もしlogrotateファイルがなければ、権限:755で、root:rootの所有となるlogrotateファイルを、 以下の内容で作成してください。

#!/bin/sh

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

まとめ

これで一旦ローテーション設定は有効になったと思います。 設定内容の詳細については、appの設定値とlogrotateの詳細を参照してください☆

php-fpmはgraceful restartしません(回避策あり)

php-fpmはgraceful restart. そう思っていた頃が私にもありました

以下の公式ドキュメントに「緩やかな (graceful) 停止/起動 機能を含む高度なプロセス管理」と記載があるので、 何の疑いもなくservice php-fpm reloadを叩いたらプロセスが落ちました。。

PHP: FastCGI Process Manager (FPM) - Manual

reloadもrestartも終了処理は同じ

もちろんこれはreloadだからというわけではありません。 reloadもrestartも、実行するkillコマンドにUSR2オプションは付いています。

付いているのですが、これが期待する動作(プロセスの処理が終了したらkill)になりません。

ググるとすぐ出てくるのですが

以下のバグとして上がっていますが、ずっと放置されているようです。

PHP :: Bug #60961 :: Graceful Restart (USR2) isn't very graceful

対策

php-fpmのprocess_control_timeoutを、デフォルトの0からコネクションタイムアウトの設定値と同程度の値に変えると、 プロセスの終了を待って再起動するようになります。(reloadも同様)

おそらくこうすることで、親プロセスが子プロセスの状態を知ることができるようになるからだとは思いますが・・・推測です。 性能影響も図れていないので、これが正しい対策なのかはなんとも言えません。 ただこうするとgracefulにはなったので、課金のような途中で殺すとまずいAPIなどは、設定すると幸せになれるかもしれません。

後は、世のPHPマスターに期待するだけの人生を送ろうと思います。

【duolingo】最近の英語学習方法

duolingoを使って英語の勉強をしています。

www.duolingo.com

どういうものか?

ざっくり言うと、文法、用途でジャンル分けされた内容の小テストをひたすら消化していくものになります。

f:id:seri_wb:20160328210001p:plain

出題される問題は、英文を音読するだけのもあれば、翻訳(日英、英日)を文字入力で回答するものもあります。 さらに、翻訳の日英は発声で答える場合もありますし、選択肢で答える場合もあります。

このように回答方法が多岐にわたるので、ジャンルで似たような英文問題が続いても、丸暗記になりづらい学習ができている気がします。 1回の学習時間が3分位で終わるのも、気が向いたときにやりやすくていい感じです。

無料で利用することができるので、試してみてもらったほうがわかりやすいかもしれませんね。

ただ、英語の音声認識の方は、結構発音を正しくしないと認識しなかったり、間違ったことを言っても正解と認識したりと、 まだ改善の余地はありそうです。なので気になるようなら、発声テストは無効にして学習するのもありかと思います(オプションで選択可能)。

あえて問題を上げるとしたら、開くたびにちょいちょい私に友達がいないことを煽ってくるところですかね!

f:id:seri_wb:20160328210004p:plain

Phoenix Frameworkのドキュメント翻訳始めました

いつも英語が話せるようになりたいなと漠然と思っていたので始めた英語学習ですが、 今は特に英語を使う機会がないので、Phoenix Frameworkのドキュメント翻訳をすることでモチベーションを保とうかと考えています。

これからも折を見て残りを訳していこうと思います。

しかし、日本語に直すっていうのは別スキルかなと翻訳作業しながら思いました。

【Linux】メモリがカツカツなサーバのメモリを復活させる

メモリ枯渇の背景

仕事で、PHPのPhalcon FWで作ったAPIアプリケーションが乗ったphp-fpmサーバを運用しているのですが、 こやつで大量のリクエストをさばけるよう、負荷試験を行ってチューニングした結果、 現在php-fpmプロセスは、staticでリクエストを待つようになっています。

そのせいなのか、リクエストが少ないとプロセスのリフレッシュまで時間がかかり、 結果、APIサーバのメモリを食い潰すという事態にちょいちょいなります。

これは負荷試験で大量リクエストを投げているときは出てこない事象なので、完全に盲点でした。

問題発覚後は、設定値チューニングしたり、php-fpmをreloadしたりして適時対応してきたのですが、 本日ふと、サーバ上のメモリのほとんどが、reloadでも開放されていないことに気付きました。

・解放前
$ free -m
             total       used       free     shared    buffers     cached
Mem:          7871       7592        279          1        167        308
-/+ buffers/cache:       7116        755
Swap:         1023          0       1023

・reloadで解放
$ sudo service php-fpm reload
Reload service php-fpm  done

・解放後
$ free -m
             total       used       free     shared    buffers     cached
Mem:          7871       5080       2791          1        167        308
-/+ buffers/cache:       4603       3267
Swap:         1023          0       1023

そういえば、php-fpmのrestart/reloadは公式ドキュメントにGracefull restartと書かれていますが、 実際には期待する動作をしませんでした。この件の対応法についてはまた別途記事にしようと思います。

メモリ使用の詳細を確認する

以下のコマンドでメモリ情報を確認したところ、Slabという領域が4Gほど確保していることに気付きました。

$ view /proc/meminfo

Slabとは?

わからなかったので調べました。
以下のサイトにお世話になった結果、どうもKernelキャッシュの一種のようですね。

詳細はリンク先で☆

Slabキャッシュをクリアした話 – CLARA ONLINE techblog

Slabキャッシュの確認

slabtopコマンドで上位2つの消費が多いものを見たところ、 参考サイトと同様にdentryのキャッシュが肥大化しているようでしたので、 このキャッシュをクリアすることにしました。

Slabキャッシュのクリア

以下が各フェーズの実行結果です。

・slabtopの結果(reload後)
  OBJS ACTIVE      USE OBJ SIZE   SLABS OBJ/SLAB CACHE SIZE NAME
20941060 20940019  99%    0.19K 1047053       20   4188212K dentry
  302198   301745  99%    0.06K    5122       59     20488K size-64

・Slabキャッシュクリアとその後のfree
# sync
# echo 2 > /proc/sys/vm/drop_caches
# free -m
             total       used       free     shared    buffers     cached
Mem:          7871        791       7080          1        167         56
-/+ buffers/cache:        567       7304
Swap:         1023          0       1023

・slabtopの結果(Slabキャッシュクリア後)
  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME
110580 110572  99%    0.19K   5529       20     22116K dentry
 83068  82608  99%    0.20K   4372       19     17488K vm_area_struct

drop_cachesを変更するにはrootになって実行する必要がありました。

Slabキャッシュクリアの結果

freeコマンドの結果だけからもわかるように、3Gなかったメモリの空き量が、 一気に7Gまで上昇しました。これはすごい!

そしてその後の経過を1日Zabbixで見守っていたのですが、 クリアしたSlabキャッシュをすぐに同じレベルまで確保することはなさそうでしたし、 アプリケーションにも不具合が出てなかったので、この対応で一旦メモリ枯渇の心配は(しばらく)なくなりました。

結論

アクセスが少ないうちは、php-fpmのプロセス管理をdynamicにしましょう。