Java Logging API,用于详细(和多行)日志 [英] Java Logging API for Detailed (and multiline) Logs

查看:108
本文介绍了Java Logging API,用于详细(和多行)日志的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想找到一个API,该API可让我在应用程序的所有关键日志点中提供特定的规范集信息.更具体地说,这将是一条多行消息,其中包含以下信息(除了基本信息):

I'd like find an API that will allow me to provide a specific canonical set of information in all of my critical log points of my application. More specifically, it would be a multi-line message with the following information (in addition to the basics):

  1. 记录类别
  2. 简短描述标题
  3. 说明
  4. 我的应用将采取的响应措施(损害控制)
  5. 详细信息(异常信息等)

例如,使用一个多行日志,如下所示:

With a single multi-line log looking, for example, like so:

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>....

这是一条冗长的语句,它将对发生的确切信息,发生的位置以及应用程序为响应异常事件所做的工作提供非常有益的信息.

This is a verbose statement that would be very informative about exactly what occurred, where it occurred, and what the application is doing in response to the event of the exception.

我能找到的最接近的是JBoss日志记录API,以及在

The closest I could find was the JBoss logging API and an example of some code I found in the ActiveMQ Artemis source. The message format declaration can be defined in a single file like so:

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

然后将记录一个

And one would log a line with this message in their code by writing:

ActiveMQUtilLogger.LOGGER.failedToParseAddressList(e, addressList);

这是我所寻找的最接近的东西.很酷.但是,我没有使用JBoss(也不想锁定该API).

That's the closest I could find to what I was looking for. Very cool. However, I'm not using JBoss (and also don't want to lock into that API).

我可以使用LOG4J,它具有 StructuredDataMessage和结构化可以在布局中使用的数据查找,默认情况下,我将最终使用它.我的代码可以委托一些StructuredDataMessage工厂来解决此问题.但是,这比使用类似JBoss API的东西要大一些.

I can use LOG4J, which has a StructuredDataMessage and Structured Data Lookup which can be used in a Layout, and I'll by default end up using that; my code could delegate to some StructuredDataMessage factory to solve this. However, it's a little bit bulkier than using something like this JBoss API.

是否有人对此问题有任何建议-是其他API,代码模式还是一个巧妙的技巧?

推荐答案

您还没有说明为什么不使用log4j2的任何特定原因,因此建议您采用这种方式.如您所指出的,它提供了StructuredDataMessage,您可以使用它来满足您的需求.尽管在这种情况下,我建议使用MapMessage,因为您的示例未包含idtype之类的东西,这些东西已内置在StructuredDataMessage类中.

You haven't stated any specific reasons why you wouldn't use log4j2 so I'd suggest going that route. As you point out it provides the StructuredDataMessage which you can use to fit your needs. Although in this case I would suggest using MapMessage since your example didn't include things like id and type which are built into the StructuredDataMessage class.

这里有一些简单的示例代码:

Here's some quick sample code:

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配置文件以及相应的文件:

and a log4j2.xml configuration file to go along with it:

<?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工厂来解决此问题

my code could delegate to some StructuredDataMessage factory to solve this

我同意,这里的工厂模式将是一个不错的选择.正如我在示例代码中评论的那样,您可以将buildMsg方法移至工厂类.

I agree, the factory pattern would be a good choice here. As I commented in the sample code you could move the buildMsg method to a factory class.

但是,它比使用类似JBoss API的东西要大一些.

However, it's a little bit bulkier than using something like this JBoss API.

我真的不知道它有多大.如果您发现大多数时候MapMessage中的一项或两项都在更改,则可以轻松地编写非常具体的方法,类似于您提到的API.要添加到上面的示例中:

I don't really see how it's any bulkier. If you find that most of the time only one or two of the items in the MapMessage are changing you could easily write very specific methods similar to the API you mentioned. To add to the above example:

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

您可能希望将常量分配给此方法中使用的字符串,但是正如我所说的,这只是一个简单的示例.

You would probably want to assign constants to the strings being used in this method, but as I said this is just a quick example.

这篇关于Java Logging API,用于详细(和多行)日志的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆