はじめに
node/expressのログは一般的にはローカルのストレージに出力・保存しますが、サーバー台数が増えた場合は1サーバーに集約したい場合があります。
方法としてはrsyslogで集約する、fluentdで集約するなどの方法が有名ですが、私はアプリ側で実装してしまうことにしました。
UDPのsyslogで飛ばしてしまえばrsyslog用にファイルを出力する必要もありませんし、fluentdで解析させる負荷もかからなくなるためです。
方法
log4js + log4js-syslog-appender
log4jsを使用しているので第一候補だったのですが動作せず。
アプリ側からパケットが出ていませんでした。
メンテナンスもされていないので廃案
log4js + log4js-fluent-appender
パケットは出ていたのですがgraylogの方での受信方法が分からず廃案
posix
使用しているとの記事があったのですがスマートじゃないなと思い廃案
winston + winston-graylog2
送信系はwinstonを使用することにしました
このパターンはgraylog形式(GELF)で送信する方式です
しかし、送信されるパラメーターが少なくカスタマイズの方法が分からなかったので廃止
winston + winston-syslog
これを採用
winstonでsyslogw送信する方式です。
フルでログが送信されたためこれを採用しました。
コード
最終的には次のようになりました。
なお、ファイルログはlog4jsを継続しています。
var winston = require('winston')
var expressWinston = require('express-winston');
require('winston-syslog').Syslog;
app.use(expressWinston.logger({
transports: [
//new winston.transports.Console(),
new winston.transports.Syslog({
host: "xxx.xxx.xxx.xxx",
port: "3514",
}),
],
format: winston.format.combine(
winston.format.json()
),
meta: true,
msg: "HTTP {{req.method}} {{req.url}}",
expressFormat: true,
ignoreRoute: function (req, res) { return false; }
}));
graylog側の設定
・System -> Inputs から Syslog UDP を追加
・Manage Extoractor にて、[Split & index] を選択。Split by に「]:」を設定
※ プロセス名などが出力されるため分割します。winston-syslog の仕様?
・Manage Extoractor にて[JSON] を選択。Sorce に「json」を設定
前回spliteしたものをjson解析します。
ひとこと
今回初めてgraylogの設定をやってみたのですが、想像以上にopensearch(elasticsearch)が重いです。
サーバー6台でこれ。
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
240712 opensea+ 20 0 4964028 256492 9256 S 26.0 14.6 26:07.49 java
まだ大丈夫なんですが、そのうち変えないといけないかもしれません。
同様のことをやっている方の時期がほとんど見つからなかったので書いてみました。
ご参考まで。
コメント