java - 懒人登录

标签 java spring spring-mvc slf4j splunk

我有一个 spring 应用程序服务于网络请求。每个请求方法看起来像这样

@RequestMapping(value = someUri, method = RequestMethod.POST)
Response someUriProcessor (SomeRequestModelMethod request) throws Exception {

    try (JsonLogger logger = new JsonLogger(request, loggingTest1Uri)){
        // get actual result
        Response result = getSomeResultMethod(request);
        // feed result to special logging object
        logger.setResult (result);
        // return result to client
        return result;
    }
}

JsonLogger 类在 close 方法中生成 JSON 对象,并通过标准的 slf4j 日志框架记录它,并上传到日志分析工具(Splunk),它记录请求、响应、响应时间等。

在执行大量工作的 getSomeResultMethod 期间,在生产中使用标准 slf4j 和 logback 绑定(bind)生成大量有用的日志。 我希望这些日志包含在 JsonLogger 中而不触及所有底层类(它们有很多),比如使用方法 JsonLogger.appendToResultLog(String txt)。我的第一个想法是创建我自己的包装 slf4j 绑定(bind),在每次调用 logger.info、logger.error 等方法时展开堆栈跟踪,使用反射到 rest Controller 方法并在其中附加日志字符串 JsonLogger。

我有一种强烈的感觉,我正在发明一辆自行车。是否有任何或多或少的标准方法来实现所需的结果?

最佳答案

结束时没有方面和反射 - 只是自定义 logback appender。

public class JsonInnerLogsAppender extends AppenderBase<ILoggingEvent> {
    public JsonInnerLogsAppender () {
        this.setName("JSON_LOGGING_INTERNAL");
    }
    @Override
    protected void append(ILoggingEvent eventObject) {
        JsonLogger.putLogInfo(eventObject.getFormattedMessage());
    }
}

还有像这样的JsonLogger

public class JsonLogger implements AutoCloseable {

    /**
     * Contains mapping between current thread id and corresponding JsonLogger object
     */
    private static transient ConcurrentHashMap<Long, JsonLogger> loggersMap = new ConcurrentHashMap<>();

    /**
     * Should be configured with special appender pattern, like
     * <encoder>
     *     <pattern>%date{ISO8601} [%-18thread] %-5level %msg %logger{70}%n</pattern>
     * </encoder>
     */
    private transient Logger logger = LoggerFactory.getLogger(getClass());
    private transient static Gson gson = new Gson();


    /**
     * Container that would be serialized to JSON after close and added to JSON log
     */
    private final JsonLogContainer logContainer;

    public JsonLogger (Object request, HttpServletRequest servletRequest) {
        this.logContainer = new JsonLogContainer(gson.toJson(request), servletRequest.getRequestURI());
        // request is started
        loggersMap.put(Thread.currentThread().getId(), this);
    }


    /**
     * @param logString formatted log string, called from custom appender
     */
    public static void putLogInfo (String logString) {
        // find appropriate JsonLogger instance (if any) and append log to it
        JsonLogger jsonLogger = loggersMap.get(Thread.currentThread().getId());
        if ( null != jsonLogger ) {
            jsonLogger.putLogToContainer(logString);
        }
    }

    private void putLogToContainer (String logString) {
        logContainer.putLog(logString);
    }

    @Override
    public void close() throws Exception {
        String log = this.logContainer.getLog(new Date());
        // request is completed
        loggersMap.remove(Thread.currentThread().getId());
        // put record to JSON log
        logger.info(log);
    }

    public void setResult(Object result) {
        logContainer.setResponse(gson.toJson(result));
    }
}

关于java - 懒人登录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34956301/

相关文章:

java - 列表首选项默认值不起作用 Android studio

spring - 对于 Thymeleaf 中的每个运算符(operator)

javascript - 如何调用将文件上传到露天

java - 使用 Spring MVC 的 XML View

java - 禁用禁用按钮的工具提示

java - Java中典型的 "View v"调用中的 "onClick"是什么?

java - 如何在 Spring 中使用注解应用方面?

java - 如何使用 urlRewriteFilter 永久重定向带参数的 JSP?

spring-mvc - jasperreport html View 中的 nullpx

java - JDialog 中的 JList 大小