13

Webアプリでユーザーアクティビティをログに記録できるようにしたいと思います。現在、ログエラーなどに適したlog4jを使用していますが、ユーザー、実行されたサーブレットメソッド、およびメソッドパラメータをログに記録するのが最善の方法かわかりません。認証にスプリングセキュリティを使用しています。

典型的なサーブレットは次のようになります。

public class BankAccountServlet {
    @RequestMapping("/deposit")
    public void deposit(double amount) {
        ...
    }

    @RequestMapping("/checkBalance")
    public double checkBalance() {
        ...
    }
}

fooとbarの2人のユーザーがいる場合、fooは残高を確認し、barは現金10.00と5.00の2つの合計を入金します。ログを次のように表示したいのですが。

01/01/1970 23:59:59 - foo - checkBalance
02/01/1970 23:59:59 - bar - deposit - 10.00
02/01/1970 23:59:59 - bar - deposit - 5.00

誰かがアドバイスを提供できれば、私は本当に彼らの助けに感謝します。

4

3 に答える 3

34

Log4Jに組み込まれているMDC/NDC機能を使用して実現するのは実際には非常に簡単です(SLF4JとLogbackはMDCのみをサポートします)。

MDCフィルターの実装

まず、ユーザー名をMDC/NDCに追加するサーブレットフィルターを実装します。Logbackは便利なMDCInsertingServletFilterを提供し、SpringフレームワークはLog4jNestedDiagnosticContextFilterもストアに追加します。それらを見てください、しかしあなたはこのようなカスタムのものを必要とするでしょう:

public class UserToMdcFilter implements javax.servlet.Filter
{
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        MDC.put("user", SecurityContextHolder.getContext().getAuthentication().getPrincipal());
        try {
            chain.doFilter(request, response);
        } finally {
            MDC.remove("user");
        }
    }

    //...
}

ロギングパターンにMDC値を追加する

web.xmlこのフィルターがSpringセキュリティフィルターの後に適用されていることを確認してください。MDC機能は非常に優れています。要求された場合、MDCスレッドローカルマップに保存されているすべての値がすべてのロギングステートメントに追加されます。あなたの場合、これを追加するだけです:

%X{user}

ロギングパターンに。

目立たないロギングメソッドのパラメータ/値

ロギングメソッド名、パラメーター、および戻り値はユーザー次第です(ユーザー名は自動的に追加されます)が、定型的なロギングコードを完全に削除するための洗練された方法がいくつかあります。このSpringの組み込みアスペクトを試してください。

<bean id="customizableTraceInterceptor" class="org.springframework.aop.interceptor.CustomizableTraceInterceptor">
    <property name="enterMessage" value="Entering $[methodName]($[arguments])"/>
    <property name="exitMessage" value="Leaving $[methodName](): $[returnValue]"/>
</bean>
<aop:config>
    <aop:advisor advice-ref="customizableTraceInterceptor" pointcut="execution(public * BankAccountServlet.*(..))"/>
</aop:config>

最終的な考え

于 2011-05-24T20:23:56.157 に答える
0

私は過去にlog4jを使用して、単なるエラー以上のものをログに記録しました。コード全体にINFOタグを追加し、ログレベルを変更しました。そうすれば、これらのアクティビティをログに記録する必要がなくなった場合は、ログレベルを変更するだけで完了です。それがお役に立てば幸いです。

于 2011-05-24T20:03:07.347 に答える
0

サーバーログにログインする場合は、コンテナログメカニズムを使用してコンテナログにログインするServletContext.log()メソッドを使用します。

于 2011-05-25T05:54:28.023 に答える