8
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

MonologのSlackHandlerに、サーバー情報および実行時の環境情報($_SERVERの各情報)を出力させるには

Last updated at Posted at 2014-12-06

はじめに

MonologのSlackHandlerの使い方については、MonologのSlackHandlerでSlackに通知するを参照いただくとして、Slackに通知される情報が十分でないと感じるようになってきました。

monolog_slack_ss_01.png

上記の例は、/aaa という存在しないページにアクセスしようとして、NotFoundExceptionが発生したログですが、この内容では、下記のようにいろいろ不満があります。

  • Webサーバーが複数あった場合、どのサーバーで発生したか分からない
  • リクエストがあったURLが特定できないケースがある
  • アクセス元がまったく分からない

そこで、MonologのREADMEなどをあらためて確認したところ、Monologには、あらかじめ、Processorがいくつか用意されていて、WebProcessorを追加すれば、不満が解消しそうです。

WebProcessorの追加

WebProcessorを追加するには、以下のようにします。
(Silexの場合)

$processor = new Monolog\Processor\WebProcessor();
$app['monolog']->pushProcessor($processor);

初期状態では、下記の情報が出力されるようになります。

// Monolog/Processor/WebProcessor.php
/**
 * @var array
 */
protected $extraFields = array(
    'url'         => 'REQUEST_URI',
    'ip'          => 'REMOTE_ADDR',
    'http_method' => 'REQUEST_METHOD',
    'server'      => 'SERVER_NAME',
    'referrer'    => 'HTTP_REFERER',
);

$_SERVER['SERVER_ADDR']と$_SERVER['HTTP_USER_AGENT']も出力したいので、addExtraFieldにて追加します。

$processor->addExtraField('server_ip', 'SERVER_ADDR');
$processor->addExtraField('user_agent', 'HTTP_USER_AGENT');

しかし、WebProcessorで追加したはずの情報が何も出力されない

結論から言うと、1.11.0時点では、Processorを追加してもSlackに通知することはできません。
WebProcessorはログレコードの'extra'フィールドに情報を付加するんですが、SlackHandlerが'extra'フィールドを全く出力しません。

// Monolog/Logger.php
$record = array(
    'message' => (string) $message,
    'context' => $context,
    'level' => $level,
    'level_name' => $levelName,
    'channel' => $this->name,
    'datetime' => \DateTime::createFromFormat('U.u', sprintf('%.6F', microtime(true)), static::$timezone)->setTimezone(static::$timezone),
    'extra' => array(),
);

// Monolog/Handler/SlackHandler.php
$dataArray['attachments'] = json_encode(
    array(
        array(
            'fallback' => $record['message'],
            'color' => $this->getAttachmentColor($record['level']),
            'fields' => array(
                array(
                    'title' => 'Message',
                    'value' => $record['message'],
                    'short' => false
                ),
                array(
                    'title' => 'Level',
                    'value' => $record['level_name'],
                    'short' => true
                )
            )
        )
    )
);

強引に継承クラスを作って対応

もう、かなり強引ですが、SlackHandlerを継承したサブクラスを自作して、処理を書き換えるしかないです。
SlackHandlerはおそらく継承されることを想定していないので、肝心な部分がprivate変数、private関数なので、泣く泣く本家からコードをコピペしてます。
早く捨てたい。。

Gistにコードをあげたので、詳しくはこちらを参照ください。

'extra'フィールドを追加している部分だけ抜粋します。

$fields = array(
                array(
                    'title' => 'Message',
                    'value' => $record['message'],
                    'short' => false
                ),
                array(
                    'title' => 'Level',
                    'value' => $record['level_name'],
                    'short' => true
                )
            );

if ((isset($record['extra'])) && (is_array($record['extra']))) {
    foreach ($record['extra'] as $title => $value) {
        $fields[] = array(
            'title' => $title,
            'value' => $value,
            'short' => true
        );
    }
}

$dataArray['attachments'] = json_encode(
    array(
        array(
            'fallback' => $record['message'],
            'color' => $this->getAttachmentColor($record['level']),
            'fields' => $fields,
        )
    )
);

PR出そうかと思いましたが、既出のものがありましたので、それがMergeされることを願うばかりです。
https://github.com/Seldaek/monolog/pull/435

ついに本家が対応、しかし(1/18追記)

ついに、v1.12.0 (2014-12-29)にて、上記PRがMergeされました。
Added $useShortAttachment to SlackHandler to minify attachment size and $includeExtra to append extra data

早速試してみました。しかし...
monolog_slack_v1.12.0.png

Extraというタイトルで、「 | 」区切りでごちゃっとまとめられてます。
正直、これは嬉しくない。
Extra Fieldであることを利用する側は意識する必要ないし、「 | 」にするために、Line Formatterをわざわざ使うのもちょっと理解できない。

あまりにも酷いので、PR出しました(1/18追記)

ということで、PR出しました。
Improve a view of extra fields in SlackHandler.
正直、元々のPR#435が許されるのなら、これも許されるはずと思ってます。

PRは却下、しかし、v1.13.0 (2015-03-05) がリリース(3/22追記)

先日、v1.13.0がリリースされ、結果、私のPR(#496)は却下されたのですが、かわりに別のPR(#507)がMergeされました。

結果、Call Stackが出力されるように!

試してみたところ、下記のように通知されるようになってました。
monolog_slack_v1.13.0.png

なお、コンストラクタの設定は
$bubble: true, $useShortAttachment: false, $includeContextAndExtra: true
にしました。

// vendor/monolog/monolog/src/Monolog/Handler/SlackHandler.php
/** 
 * __construct
 * (中略)...
 * @param bool $bubble Whether the messages that are handled can bubble up the stack or not
 * @param bool $useShortAttachment Whether the the context/extra messages added to Slack as attachments are in a short style
 * @param bool $includeContextAndExtra Whether the attachment should include context and extra data
 */

分かりにくいですが、Call Stack が出力されています。
これは、'extra'フィールドと同様に、'context'フィールドも出力するようにしているためです。
('context'フィールドにCall Stackが含まれていることは正直知りませんでした。)
詳しくは、下記コードを参照ください。

参考)
https://github.com/Seldaek/monolog/blob/6f0e7f666e39b6e606d9837b146404312bec1a03/src/Monolog/Handler/SlackHandler.php#L182-L202

ちなみに、$useShortAttachment: trueにすると、下記のようになります。
(うーん、やっぱり見づらい)

monolog_slack_v1.13.0_short.png

さいごに(3/22更新)

これで、ようやく独自のSlackHandlerは捨てることができます。
MonologのProcessorやHandler、'extra'および'context'フィールドなど理解が深まったですし、PRも無駄ではなかったな〜と。
個人的にはいい経験ができました。

8
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?