用于详细(和多行)日志的Java日志API

问题描述:

我想找到一个API,它允许我在我的应用程序的所有关键日志点中提供特定的规范集信息。更具体地,这将是具有以下信息(除了基本的)多行消息:用于详细(和多行)日志的Java日志API

  1. 日志类别
  2. 简要说明标题
  3. 说明
  4. 响应操作(损伤控制)我的应用程序将采取
  5. 详细信息(异常信息等)

有了一个单一的多行日志看,为电子商务xample,像这样:

2017-11-10 14:26:59,156 [main] WARN o.s.t.c.s.ExampleClass: 
    Caption: Unconformable data 
    Description: The data provided from the X datasource in order to perform Y operation could not be translated 
    Response Action: Application will discard unusable data into this component's DLQ 
    Details: The data string "x" was not of expected Integer type 
     <Some stacktrace>.... 

这是一个冗长的声明,这将是对什么发生,它发生了,什么应用程序响应异常的情况下,这样做非常丰富。

我能找到的最接近的是JBoss日志API和我在ActiveMQ Artemis source中找到的一些代码示例。 消息格式声明可以在一个单一的文件中定义,像这样:

@LogMessage(level = Logger.Level.WARN) 
    @Message(id = 202008, value = "Failed to check Address list {0}.", 
     format = Message.Format.MESSAGE_FORMAT) 
    void failedToParseAddressList(@Cause Exception e, String addressList); 

而且人会通过书面形式记录在他们的代码line with this message

ActiveMQUtilLogger.LOGGER.failedToParseAddressList(e, addressList); 

这是我能找到的最接近的是我正在寻找。很酷。但是,我没有使用JBoss(也不想锁定该API)。

我可以使用LOG4J,它有一个StructuredDataMessage and Structured Data Lookup它可以在一个布局中使用,我会默认最终使用它;我的代码可以委托一些StructuredDataMessage工厂来解决这个问题。然而,这比使用这个JBoss API更笨重一点。

有没有人对此问题有任何建议 - 无论是另一种API,代码模式还是漂亮的技巧?

+0

你在某种容器中运行吗?你可能会用一种模式来做,但它可能取决于你使用的日志管理器。 –

你没有说明你为什么不使用log4j2的任何具体原因,所以我建议去那条路线。正如您指出的那样,它提供了StructuredDataMessage,您可以使用它来满足您的需求。虽然在这种情况下,我会建议使用MapMessage,因为您的示例不包括内置于StructuredDataMessage类中的内容,如idtype

下面是一些快速的示例代码:

import org.apache.logging.log4j.LogManager; 
import org.apache.logging.log4j.Logger; 
import org.apache.logging.log4j.message.MapMessage; 

public class MapMessageExample { 

    private static final Logger log = LogManager.getLogger(); 

    public static void main(String[] args){ 
     log.info(buildMsg("My title", "This is the description", 
       "No response needed", "Some details here"));   
    } 

    // This could be moved into a factory class 
    public static MapMessage buildMsg(String title, String description, 
      String responseAction, String details) 
    { 
     MapMessage mapMsg = new MapMessage(); 
     mapMsg.put("title", title); 
     mapMsg.put("desc", description); 
     mapMsg.put("response", responseAction); 
     mapMsg.put("details", details); 
     return mapMsg; 
    } 
} 

和log4j2。xml配置文件与它一起去:

<?xml version="1.0" encoding="UTF-8"?> 
<Configuration status="WARN"> 
    <Appenders> 
     <Console name="Console" target="SYSTEM_OUT"> 
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%M] %-5level %logger{36}%n\tCaption: ${map:title}%n\tDescription: ${map:desc}%n\tResponse Action: ${map:response}%n\tDetails: ${map:details}%n" /> 
     </Console> 
    </Appenders> 

    <Loggers> 
     <Root level="debug"> 
      <AppenderRef ref="Console" /> 
     </Root> 
    </Loggers> 
</Configuration> 

下面是一些示例输出:

00:40:45.810 [main] INFO example.MapMessageExample 
    Caption: My title 
    Description: This is the description 
    Response Action: No response needed 
    Details: Some details here 

最后的一些想法:

我的代码可以委托一些StructuredDataMessage工厂来解决这个

我同意,工厂模式将是一个好的町冰在这里。正如我在示例代码中所评论的那样,您可以将buildMsg方法移至工厂类。

但是,它比使用像这个JBoss API这样的东西有点笨重。

我真的不知道它有多大。如果您发现大多数时间里只有MapMessage中的一两个项目发生变化,您可以轻松编写类似于您所提及的API的非常具体的方法。要添加到上面的例子:

public static MapMessage reallySpecificLogMessage(String details){ 
    return buildMsg("My specific message title", "My specific description", 
      "My specific response action", details); 
} 

你可能要分配在该方法中使用常量字符串,但正如我所说,这只是一个简单的例子。

+0

是的,我想我会像这样使用它,但想看看有没有其他的东西/其他想法。谢谢 – Dovmo