1

メッセージ自体にこの情報を明示的に追加しなくても、ログメッセージに特定の情報を含める方法を探しています。

私の夢のシナリオは、コントローラー、サービス、またはドメインクラスで発生するかどうかに関係なく、ログメッセージに定義済みの情報セット(ログインしたユーザーのユーザー名など)が含まれることです。これは、プログラマーがまったく心配することなく最適に発生します。log.debug( "some message")を実行するだけで、これが自動的に実行されます。

アイデアは、ログをJSON形式で出力することです。これにより、上記のメッセージの構造は次のようになります。

{ timestamp: "20130130T12:32", message: "some message", user: "steve", request-id: "245692"... }

これらすべてをうまくフォーマットするlog4jレイアウトを作成できますが、問題は、そもそもデータをそこに配置する方法です。

ですから、私の最初の質問は、Grailsの中に「request-id」として使用できるものはありますか?その背後にある考え方は、ユーザーが開始する「トランザクション」に対して単一の要求IDを持つことです。したがって、コントローラー内のログメッセージは、結果として呼び出されたドメインまたはサービスクラス内のログメッセージと同じrequest-idを持ちます。

2番目の質問:ユーザーが開始したトランザクション内のレイヤー(コントローラー/サービス/ドメイン)間でこのような情報を「透過的に」移動する方法はありますか?必要に応じて、コントローラーで独自のリクエストIDを生成し、そこでユーザー名を取得して、これら2つをマップに配置できます。しかし、そのマップをパラメーターとして渡すことなく、サービス/ドメインクラスとそのロガーにどのように転送しますか(コードが散らかってしまうため、これは実行したくありません)。

どんなアイデアでも大歓迎です。私はGrailsにかなり慣れていないので、優しくしてください;-)

4

1 に答える 1

1

#grailsIRCチャネルで正しい方向にプッシュしました。

Log4J(または実際にはSLF4J )には、本質的にスレッドローカルマップであるMDC(マップされた診断コンテキスト-http ://www.slf4j.org/manual.html#mdc )と呼ばれるものがあります。フィルタを作成し、必要な情報をMDCに追加することで、そのスレッドで実行されるすべてのログメッセージにこの情報を含めることができます。

「requestuuid」のようなものがあるのか​​、それともUUID.randomUUID()。toString()で生成するだけなのかという疑問はまだ残っています。

例:

フィルタを追加して、:を生成および保存しrequestIdます。

def filters = {
   all(controller:'*', action:'*') {
      before = {
         MDC.put 'requestId', UUID.randomUUID().toString()
      }
   }
}

Config%X{requestId}で、パターンを追加します

log4j = {
  appenders {
      console name:'stdout', layout:pattern(conversionPattern: '%d{DATE} %X{requestId} %5p %c{1}:%L - %m%n')
于 2013-01-30T23:19:48.187 に答える