使用数据源记录查询的最佳方法

时间:2016-04-14 15:29:40

标签: java mysql jpa wildfly audit

我要求将记录用户的查询(选择,更新,插入,删除)记录或写入数据库。我在互联网上看过教程,但他们没有涉及这个案例。我需要将查询记录到数据源,但还要在记录到应用程序(JSF)的会话中附加用户的名称。我该怎么办?

我正在使用EntityManager而不是Hibernate会话。

2 个答案:

答案 0 :(得分:0)

自定义JPA-Provider LoggingClass

如果您想记录任何sql-queries:

只需按照所选JPA-Provider的说明执行自定义日志记录即可。这样您就可以将用户添加到您的logentry - > EclipseLink

PS:不要忘记在persistence.xml中将Logging-Level设置为FINE,这样可以为任何查询启用SQL-Logging。

的logback

如果您只想记录您的EJB-Logic:

我之前在LOGBack的项目中完成了这项工作,该项目是从log4j构建的。它很容易设置。只需按照instructions

神奇的LOGBack正在做的事情可以在logback.xml

中定义
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
   <layout class="de.package.LoggingPattern">
      <Pattern>[%date{dd.MM.yyyy - HH:mm:ss.SSS}] [%thread] %-5level %logger [%user] --- %msg%n</Pattern>
   </layout>
</encoder>

为了记录用户正在执行的每个查询,您必须将user-id解析为日志记录模式。这可以使用自定义ch.qos.logback.classic.PatternLayout和自定义ch.qos.logback.classic.pattern.ClassicConverter来完成。使用它们,您可以为日志记录模式定义新参数。在这种情况下,它是%user

PatternClass:

public class LoggingPattern extends PatternLayout {
    static {
        PatternLayout.defaultConverterMap.put(
                "user", UserConverter.class.getName());
    }
}

ConverterClass:

public class UserConverter extends ClassicConverter {

    @Override
    public String convert(ILoggingEvent event) {
        //somehow get your logged in user from the current session:
        UserAccount currentUser = Util.getUserAccount();
        if (currentUser != null) {
            return currentUser.getLogin();
        }
        return "NO_USER";
    }
}

最后,您只需记录EJB类中的每个EJB-Transaction:

public class SomeEJB {

    @PersistenceContext(
       unitName = "SOME_UNITNAME",
       type = PersistenceContextType.TRANSACTION
    )
    protected EntityManager em;
    protected Logger log;

    @PostConstruct
    private void init() {
        log = LoggerFactory.getLogger(this.getClass());
    }

    public <T> T update(T o) {
        log.info("update: " + o.toString());
        return em.merge(o);
    }

    .
    .
    .
}

快乐的伐木!

答案 1 :(得分:0)

一种解决方案是使用Proxy over JDBC Driver并从ThreadLocal上下文中获取用户名。