はじめに.

簡単に自己紹介をしたいと思います。2018年4月に入社致しました、西岡と申します。趣味でPHPを個人的に学習していましたが、そのなかでDrupalというCMSに出会い、本格的に学んでみたいと思い、ご縁があってstudio umiにお世話になることになりました。

ですので、プログラミングやDrupalに関しても学び始めたばかりなので、これからこのようなblogを通して自分の学んだことを発信していきたいと考えています。

では、本題に移っていきたいと思います。

今回ご紹介するのはDrupal8で、ログメッセージを残す方法です。

Drupal7ではwatchdog()を使用して、ログメッセージを残していましたが、Drupal8になってからはその関数は使用できなくなり、代わりにLogging APIを用いてログメッセージを残すようになりました。

今回はLogging APIの中でも手続き型と呼ばれる方法を用いて紹介していきたいと思います。

ログメッセージが表示される場所

まず、ログメッセージが表示される場所はご存知かもしれませんが、説明しておきます。

管理画面からレポートという箇所から、最近のログメッセージがログメッセージが表示される場所になります。 管理画面の開き方がわからない方はDrupal8 入門 : 管理画面編を参考にしてみてください。

開発などでエラーが出て行き詰まったりなどしたときは、このログメッセージを見ると、どこにどのようなエラーが出ているのかなどが把握できます。自分も当初からエラーばかりでログメッセージとにらめっこしています笑

カスタムモジュールの実装

今回は、コンテンツが更新されたらコンテンツのタイトルが誰によって更新されたのかというログメッセージを残すカスタムモジュールを作成していきます。(今回の例では、title: test、user: adminとしています。)

実装内容の紹介.

まずモジュールのファイル構造は以下の通りです

モジュール構造

modules
 └─ log_message
        ├── log_message.info.yml
        └── log_message.module

log_message.info.ymlの設定は以下の通りです。

name: 'Log message'
type: 'module'
description: 'コンテンツが更新されればログメッセージを残す'
core: '8.x'

ここはカスタムモジュールの名前やカスタムモジュールのがどのような機能なのかを説明している ファイルです。

次にlog_message.moduleの中身を作成していきますが、以下のようになります。

<?php
/**
 * @file
 * コンテンツが更新されれば、そのタイトルと更新したユーザー名をログメッセージに残す.
 */

/**
 * Implements hook_ENTITY_TYPE_update().
 */
function logmessage_node_update(Drupal\Core\Entity\EntityInterface $entity) {

  // 更新されたコンテンツのタイトルを取得.
  $title = $entity->getTitle();

  // コンテンツを更新したユーザー名を取得.
  $user_name = \Drupal::currentUser()->getDisplayName();

  // タイトルまたはユーザー名が取得できなければ処理を行わない.
  if (!$title || !$user_name) {
    return;
  }

  // ログメッセージを出力.
  \Drupal::logger('log_message')->notice('@titleは@userによって更新されました。', [
    '@title' => $title,
    '@user' => $user_name,
  ]);

}

では1つずつ説明していきたいと思います。

今回ご紹介する内容はコンテンツが更新されればということなので、hook_ENTITY_TYPE_update()を使用します。 これの説明に関しては、今回の趣旨から脱線してしまうため割愛させていただきます。

それぞれのコードの処理の内容についてはコメントをご参照ください。

タイトルとユーザー名が取得するコードが実装できれば、いよいよログメッセージを残すコードを実装していきます。 今回はLogging APIの中で手続き型を使用したのを紹介します。

\Drupal::

Drupalクラスにあるプロパティやメソッドを使用するための準備です。今回使用するlogger()はこのDrupalクラスにあります。 ::(コロン)はDrupalクラスをインスタンス化せずにプロパティやメソッドにアクセスするという意味です。

logger()

これはDrupalクラスにある静的メソッドです。

パラメーター string $channel:チャネルの名前になります。チャネルとはこのメッセージが属するカテゴリのことです。任意の文字列を使用できますが、一般的にはこれを呼び出すサブシステムの名前を使用します。つまり、基本的にはモジュールの名前を使用すること多いです。下記の画像にlog_messageというカテゴリが追加されているのが分かると思います。

ログメッセージのタイプ画面

返り値:ロガーオブジェクトを返します。

notice()

返ってきたロガーオブジェクトは9つのメソッドがあり、log()も9つ目のメソッドとして数えられていますが、log()は任意のログレベルを受け取るメソッドのため、ログレベルを表すメソッドは全部で8つとなります。

これらはログメッセージの重大度を表しており、 \PSR\Log\LoggerInterfaceの DRUPALROOT/vendor/psr/log/Psr/Log/LoggerInterface.phpファイルの中に記述されています。

また、以下の関連リンクのinterface LoggerInterfaceにも詳細が載っていますので、目を通してみてください。

ログメッセージを残したいものに応じて、記述するメソッドを変更することでログメッセージの重大度を把握することができるようになります。

ログメッセージのログレベル画面

notice()の()中身はログメッセージの内容になります。

これは引用符で囲まれたPHPの文字列、またはプレースホルダーを使用する文字列にすることができます。今回の例では、後者を選択しております。

ここまで実装できたらカスタムモジュールをインストールして有効化しましょう。

有効化できたら実際にコンテンツを作成し、編集してみてください。 今回はコンテンツが更新されたらということなので、新規に作成した場合、作成しただけではメッセージは表示されないので気をつけてください。

コンテンツを更新し、更新されましたという文字が出たら上記で示したログメッセージが表示される箇所へ移動してください。 コンテンツのタイトルとユーザー名が表示されたログメッセージがありますでしょうか???

そのログメッセージが以下のように(title: test、user: admin)表示されていれば成功となります。

ログメッセージ画面

まとめ

いかがでしたでしょうか。 今回は簡単な方法の紹介でしたが、独自のloggerを作成し、ログメッセージの出力先をカスタマイズすることも可能なため、機会があればそちらもご紹介できるようになれればと考えています。

以上、目を通していただきありがとうございました。