Регистрация активности пользователя в веб-приложении

#java #servlets #logging #spring-security #dwr

#java #сервлеты #протоколирование #spring-безопасность #dwr

Вопрос:

Я хотел бы иметь возможность регистрировать действия пользователя в веб-приложении. В настоящее время я использую log4j, который хорошо работает для регистрации ошибок и т.д., Но я не уверен, какой наилучший подход заключается в регистрации пользователя, выполняемого метода сервлета и параметров метода. Я использую spring security для аутентификации.

Типичный сервлет может выглядеть следующим образом:

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

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

Если есть два пользователя, foo и bar, где foo проверяет свой баланс, а bar вносит две суммы наличных 10,00 и 5,00. Я бы хотел, чтобы журналы выглядели как:

 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
  

Если кто-нибудь может дать какой-нибудь совет, я был бы очень признателен за их помощь.

Комментарии:

1. Это может быть вырвано из контекста, но если это реальное банковское приложение, я бы воздержался от регистрации таких данных, не обеспечив достаточной защиты журналов.

Ответ №1:

На самом деле этого довольно просто достичь, используя функциональность MDC / NDC, встроенную в Log4J (SLF4J и Logback поддерживают только MDC).

Реализация фильтра MDC

Сначала реализуйте фильтр сервлетов, который добавит имя пользователя в MDC / NDC. Logback предоставляет удобный MDCInsertingServletFilter, Spring Framework также добавляет 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 security filter. Функция MDC действительно проста — она добавит все значения, сохраненные в MDC thread-local map, к каждому оператору ведения журнала, если потребуется. В вашем случае просто добавьте это:

 %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>
  

Заключительные мысли

Комментарии:

1. Есть ли какие-либо подобные примеры для Log4J2?

Ответ №2:

В прошлом я использовал log4j для регистрации большего, чем просто ошибок. Я добавил ИНФОРМАЦИОННЫЕ теги по всему своему коду и изменил уровень ведения журнала. Таким образом, если вы решите, что вам больше не нужно регистрировать эти действия, вы можете просто изменить уровень ведения журнала, и все готово. Я надеюсь, что это поможет.

Ответ №3:

Если вы хотите войти в разделенные журналы, используйте метод ServletContext.log(), который использует механизм ведения журнала контейнера и регистрируется в журналах контейнера..