如何使用Spring Integration中的LoggingHandler格式化日志并添加已用时间

时间:2016-04-09 00:31:15

标签: java spring spring-integration

我正在使用Spring Integration DSL与Java 1.7和AMQP,我正在尝试使用LoggingHandler通过logback记录我的事件,这是我的配置代码片段。

@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());
}

现在,我有两个主要问题:

  1. 此loggingHandler正在记录从请求和响应到回溯的标头,这是我目前拥有的标头的响应日志条目示例,如下所示:

    {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"}}
    
  2. 所以,这里的问题是,有没有办法使用表达式将此输出格式化为CSV格式?这让我觉得也许这可以用一个logback布局来解决。

    1. 这个日志事件发生在两个不同的时间,有请求和响应,有没有办法记录请求和响应之间的经过时间?我正在使用Splunk处理两个日志条目并计算已用时间,但我希望在一个日志行中使用它并避免使用Splunk,因为许可证成本。
    2. 感谢您的帮助。

      更新:

      最后,我使用了Artem Bilan对enrichHeaders()提出的建议,我在请求中添加了时间戳,并且当响应将返回时计算已用时间。

      另外我不得不说,关于以CSV格式登录的这一要求不仅仅是记录,因此决定以不同的方式处理这一问题,使用AMQP跟踪每个事务并以所需的格式进行处理。

1 个答案:

答案 0 :(得分:0)

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

  2. LoggingHandler并非打算这样做。它的责任只是记录来自渠道的信息。这是一个主要的消息原则 - 松散耦合。有几种技术可以帮助您确定正确的解决方案。

  3. 2.1由于您要经过请求和响应之间的时间(看起来您已经可以使用Splunk执行此操作),因此,您可以使用{{1}以类似的方式聚合它们来自Spring Integration。只有在此之后才会将带有所需时间字段的单个消息发送给记录器。

    2.2另一种方式(我发现它更好)。只需在将请求消息发送到流程通道之前计算它。例如。 .aggregate()可以帮助您。并在响应准备好返回时使用该标头来计算经过的时间。只有从这里发送单个消息到记录器。