Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/376.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在Spring集成中使用LoggingHandler格式化日志并添加运行时间_Java_Spring_Spring Integration - Fatal编程技术网

Java 如何在Spring集成中使用LoggingHandler格式化日志并添加运行时间

Java 如何在Spring集成中使用LoggingHandler格式化日志并添加运行时间,java,spring,spring-integration,Java,Spring,Spring Integration,我将Spring集成DSL与Java 1.7和AMQP结合使用,并尝试通过logback使用LoggingHandler记录我的事件,这是我的配置代码片段 @Bean public IntegrationFlow inboundFlow() { return IntegrationFlows.from(Amqp.inboundGateway(simpleMessageListenerContainer()) .mappedReplyHeaders(AMQPCons

我将Spring集成DSL与Java 1.7和AMQP结合使用,并尝试通过logback使用LoggingHandler记录我的事件,这是我的配置代码片段

@Bean
public IntegrationFlow inboundFlow() {
    return IntegrationFlows.from(Amqp.inboundGateway(simpleMessageListenerContainer())
            .mappedReplyHeaders(AMQPConstants.AMQP_CUSTOM_HEADER_FIELD_NAME_MATCH_PATTERN)
            .mappedRequestHeaders(AMQPConstants.AMQP_CUSTOM_HEADER_FIELD_NAME_MATCH_PATTERN)
            .errorChannel(gatewayErrorChannel())
            .requestChannel(gatewayRequestChannel())
            .replyChannel(gatewayResponseChannel())
        )
        .transform(getCustomFromJsonTransformer())
        .route(new HeaderValueRouter(AMQPConstants.OPERATION_ROUTING_KEY))
        .get();
}

@Bean
public MessageChannel gatewayRequestChannel() {
    return MessageChannels.publishSubscribe().get();
}

@Bean
public MessageChannel gatewayResponseChannel() {
    return MessageChannels.publishSubscribe().get();
}

@Bean
public LoggingHandler getLoggingHandler(){
    LoggingHandler loggingHandler =  new LoggingHandler(LoggingHandler.Level.INFO.name());
    loggingHandler.setLoggerName("analytics");
    loggingHandler.setExpression("headers");
    return loggingHandler;
}

private IntegrationFlow fileLoggerOutboundFlowTemplate(MessageChannel fromMessageChannel) {
    return IntegrationFlows.from(fromMessageChannel)
        .handle(getLoggingHandler())
        .get();
}

@Bean
public IntegrationFlow requestFileLoggerOutboundFlow() {
    return fileLoggerOutboundFlowTemplate(gatewayRequestChannel());
}

@Bean
public IntegrationFlow responseFileLoggerOutboundFlow() {
    return fileLoggerOutboundFlowTemplate(gatewayResponseChannel());
}
现在,我有两个主要问题:

  • 此loggingHandler将请求和响应中的头记录到logback,这是我当前拥有的带有头的响应日志条目的一个示例,如下所示:

    {errorChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@ff940b1, replyChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@ff940b1, contentType=JSON, amqp_consumerQueue=clientAdapter, userId=12345678, monitoringId=34841e03-a7f8-4f0b-8860-2f94c94e2c7a, timestamp=1454460846221, id=799de4c1-6167-6f45-de4d-1964d357d2dc, adapterRoutingKey=clientRoutingKey, messageType=RESPONSE, operationRoutingKey=login, amqp_consumerTag=amq.ctag-YMP8rrbTxLAXdYsFJ7HVjQ, result=OK, metaData={"clientVersion":"1.2.1","clientType":"WEB","ipAddress":"127.0.0.1"}}
    
  • 所以,这里的问题是,有没有一种方法可以使用表达式将输出格式化为CSV格式?这让我想,也许这可以通过一个logback布局来解决

  • 此日志事件发生在两个不同的时间(请求和响应),是否有方法记录请求和响应之间经过的时间?我使用Splunk处理两个日志条目并计算运行时间,但我希望在一个日志行中使用它,并避免Splunk,因为许可证成本太高
  • 谢谢你的帮助

    更新:

    最后,我使用了Artem Bilan提出的
    enrichHeaders()
    ,在请求中添加了时间戳,并在响应将要发回时计算经过的时间

    我还要说的是,CSV格式的日志记录要求不仅仅是日志记录,所以决定使用AMQP以不同的方式处理此问题,以跟踪每个事务,并将其设置为所需的格式

  • 不确定“使用表达式的CSV格式”是什么意思。但您确实可以使用该表达式中的任何bean并从中构建任何格式。根据您的CSV要求,我可以假设您最终会将所有日志聚合到一个文件中。因此,像
    headers.values()
    这样的东西就足够开始了。但您应该记住,并非所有地图实例都将以相同的方式排序

  • LoggingHandler
    不打算这样做。它的责任只是记录到达is频道的消息。这是一个主要的信息原则——松耦合。有几种技术可以帮助您确定正确的解决方案

  • 2.1由于您将在请求和响应之间花费一段时间(而且看起来您已经可以使用Splunk来完成这项工作),因此,您可以使用Spring Integration中的
    .aggregate()
    以类似的方式对它们进行聚合。并且仅在此之后,将带有所需时间字段的单个消息发送到记录器


    2.2另一种方法(我发现它更好)。只需计算请求消息,然后再将其发送到进程通道。例如,
    .enrichHeaders()
    可以帮助您实现这一点。并在响应准备返回时使用该标头来计算经过的时间。并且只从这里向记录器发送一条消息。

    非常感谢,我必须说,在看到您的响应后,我使用
    enrichHeaders()
    向标头添加时间戳,并计算响应准备就绪时经过的时间。