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

Я хотел бы иметь возможность регистрировать действия пользователей в веб-приложении. В настоящее время я использую 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

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


person James    schedule 24.05.2011    source источник
comment
Это может быть вырвано из контекста, но если это настоящее банковское приложение, я бы воздержался от регистрации таких данных, не обеспечив достаточную защиту журналов.   -  person Vineet Reynolds    schedule 25.05.2011


Ответы (3)


На самом деле этого довольно просто добиться с помощью функций MDC/NDC, встроенных в Log4J (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>

Последние мысли

person Tomasz Nurkiewicz    schedule 24.05.2011
comment
Есть ли подобные примеры для Log4J2? - person zygimantus; 30.10.2015

Я использовал log4j в прошлом, чтобы регистрировать больше, чем просто ошибки. Я добавил теги INFO в свой код и изменил уровень ведения журнала. Таким образом, если вы решите, что вам больше не нужно регистрировать эти действия, вы можете просто изменить уровень ведения журнала, и все готово. Надеюсь, это поможет.

person DouglasHeitner    schedule 24.05.2011

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

person Ramesh PVK    schedule 25.05.2011