java - 记录时在其他层使用 session 数据的正确方法

标签 java logging design-patterns web

我想写一些包含执行者信息的信息日志。假设我有这个 SaveUser 函数:

public class UserDAO {
    Logger logger = LogManager.getLogger();

    public void SaveUser(User user, LoggerInfo info) {
        logger.info("Executor {} trying to save user {}...", "Executor name comes here", user.name);

        this.saveToFirstDB(user);
        this.saveToSecondDB(user);

        logger.info("Executor {} succesfully saved user {}.", "Executor name comes here", user.name);
    }

    private void SaveToFirstDB(User user) {
        logger.info("Executor {}, enter SaveToFirstDB.", "Executor name comes here", user.name);

        // save user to first db..

        logger.info("Executor {}, exit SaveToFirstDB.", "Executor name comes here", user.name);
    }

    private void SaveToSecondDB(User user) {
        logger.info("Executor {}, enter SaveToSecondDB.", "Executor name comes here", user.name);
        I
        // save user to second db..

        logger.info("Executor {}, exit SaveToSecondDB.", "Executor name comes here", user.name);        
    }
}

我想在Controller层调用它:

public class UserController{

    // for example - using Java Spark request and response context
    public void SaveUser(Request req, Response res) {
        User userToSave = new User(.....); // creating user object from request params

        UserDAO userDAO = new UserDAO();
        userDAO.SaveUser(userToSave);

        // I want to use this executor name:
        System.out.println(req.attribute("executor"));
    }
}

当然,我可以注入(inject)执行者名称,但我认为我不应该这样做(这只是一个简单的示例,我想注入(inject)更多详细信息,例如日期、角色等......)。

我不想注入(inject)细节,并且我不想让 DAL(例如)了解 Controller 层的上下文对象(Play、Spark..)。 那么在后端写入信息日志的正确方法是什么?

最佳答案

您可以使用 Log4j 映射诊断上下文。在这种方法中,您可以编写请求拦截器或 servlet 过滤器来设置 Log4j MDC 中的其他属性。 您的 servlet 过滤器如下所示 -

@Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        try {
            /*
             * This code puts the value "userName" to the Mapped Diagnostic
             * context. Since MDc is a static class, we can directly access it
             * with out creating a new object from it. Here, instead of hard
             * coding the user name, the value can be retrieved from a HTTP
             * Request object.
             */
            MDC.put("userName", req.attribute("executor"));
            MDC.put("date", System.currentTimeMilis());
            MDC.put("role", getRole()); 
            //Any other properties you want to set
            chain.doFilter(request, response);

        } finally {
            MDC.remove("userName");
        }
    }

然后您可以为您的 UserDao 类编写 cutomize log4j 模式。

[%d{ISO8601}] %X{userName} %X{role} %p %c - %m%n

以上语法仅供引用。

关于java - 记录时在其他层使用 session 数据的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43167975/

相关文章:

Java:打印数组元素并插入换行符

java - 如何在 Bean Validation 1.0 中构造 ConstraintViolationException?

c++ - 多渲染 API 引擎着色器文件管理

java - 如何在单元测试期间将资源文件路径交换为测试文件?

java - Gmail POP3 未获取 Java 应用程序中的所有邮件

java - 一个 (log.isDebugEnabled()) 条件每个调试语句出现

Java - 在日志中对相同的异常进行分组

java - 无法使用 SLF4J 禁用 quartz 调度程序日志记录

java - 处理所有异常

c# - 在 C# 中实现树管理父子