2015-11-24 41 views
0

我正在编写一个Web应用程序,其中用户(包括许多其他内容)可以构建和运行自己的脚本。这些脚本运行在后端,它们可能会或可能不会生成错误 - 此类错误现在写入系统日志。以编程方式从log4j获取日志事件

如果用户通过web应用程序本身查看这些类型的日志事件将会有所帮助,所以我想管道&以某种方式从log4j过滤它们(在事件发生之前),这样我就可以编程访问他们。 Elasticsearch有类似的东西 - 当没有找到结果时,它会显示在给定的时间范围内发生的错误。

我想我可以只抽象记录,并确保所有的事件都发送到log4j和客户端,但我希望有一个更好的方法,而不必触摸记录器调用(或必须从日志文件中读取)。

看着log4j2网站,但没有找到任何有用的东西 - 任何想法如何实现这样的东西?

回答

2

要拦截日志事件,你可以在三个点插入你的一部分:

  • 的log4j后:我们的Log4j日志的东西,你可以很容易地“查询“在你的应用程序中。有各种各样的Appender可用于此。记录到数据库是一种选择,您可以登录到标准输出并将其重定向到您的应用程序,因此您可以获得某种流

  • 使用appender:您可以实现自己的appender,使用log4j进行配置并执行无论你想在那里。

  • 在log4j之前:将每次调用Log4j Logger包装为您自己的实现,并在实际记录您的事件之前或之后在其中执行您的逻辑。

的附加器的方法似乎是最优雅:它允许使用log4j的配置选项来控制您的前端显示的内容,并没有什么,并且由于附加目的地在同一文件中配置使得它不太由于没有意识到对用户来说很重要,有可能有人会禁用日志记录。但它需要关于log4j内部的大部分知识。

+0

同意appender方法是最优雅的。我做了一些试验,似乎工作得很好。 – sfThomas

0

因为你不想分析日志,所以我会去记录数据库。一个建议可能是log4j_logging_database。

这当然意味着你编写查询和格式化日志记录以使其可以从sql进行分析,并且还可以构建一种向客户端展示这些查询的方法。

你可以找到一个教程here。有一个日志记录级别,所以你可以根据你的配置过滤错误和重要的工作人员。不要忘记将索引添加到感兴趣的表列中,因为一段时间后日志记录会变得很大。

此致

萨诺斯

1

一种可能的解决方案可能是使用一个管道输入流。

// pipes output in the output stream to the input stream 
PipedInputStream in = new PipedInputStream(); 
PipedOutputStream out = new PipedOutputStream(in); 

// create custom l4j appender 
Appender customAppender = new WriterAppender(
            new PatternLayout("%-5p %d [%t][%F:%L] : %m%n"), out); 

//use any logger: 
logger.addAppender(customAppender); 
//or the root logger: Logger.getRootLogger().addAppender(customAppender); 

// write a test message to log 
logger.error("test"); 

// printing entries in piped input stream 
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in)); 
String line; 
while (bufferedReader.ready() && (line = bufferedReader.readLine()) != null) { 
    System.out.println("log entry: " + line); 
} 

结果输出:

log entry: ERROR 2015-11-24 11:58:18,366 [main][Main.java:52] : test 

原因,你可以使用过滤器的附加器(或定义自己的过滤器)。 例如过滤日志级别范围:

LevelRangeFilter levelRangeFilter = new LevelRangeFilter(); 
levelRangeFilter.setLevelMin(Level.INFO); 
levelRangeFilter.setLevelMax(Level.ERROR); 
customAppender.addFilter(levelRangeFilter); 
相关问题