gpt4 book ai didi

java - 如何在以下上下文中获得正确的记录器行号

转载 作者:太空宇宙 更新时间:2023-11-04 14:22:25 25 4
gpt4 key购买 nike

我花了一些时间找出一种可持续的方法来过滤 ERROR我的应用程序实时记录 JBoss服务器。与Log4j我可以轻松使用SocketAppender我按照它通知 ERROR 的方式配置了它实时登录。不幸的是我不能用 JBoss AS 7 来做到这一点。我找不到 SocketAppender除了 SMTPAppender 之外的其他实现方式。所以我想出了一个办法来解决这个问题。请看看我到目前为止做了什么。

我为 Logger 编写了一种包装器.

我的应用程序的示例类

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyClass {
private Logger logger= LoggerFactory.getLogger(MyClass.class);

public void updateData(String data){
logger.info("updating data with {} ",data);
try {
// do somthing
}catch (Exception e){
//something went wrong
logger.error("update fail ",e);// I want to get this message real time
}
}
}

现在我想到了一个方法来获取 ERROR日志。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyLogger {
private Logger logger = null;

private MyLogger() {
}

public static MyLogger getLogger(Class clazz) {
MyLogger logger = new MyLogger();
logger.logger = LoggerFactory.getLogger(clazz);
return logger;
}

public void info(String format, Object... arguments) {
logger.info(format,arguments);
}

public void error(String format, Object... arguments) {
// now i can send this message real time,
// i am calling web service with error log by a new Thread
logger.error(format,arguments); // say line number 10
}
}

MyLogger使用方法如下

public class MyClass {
private static MyLogger logger= MyLogger.getLogger(MyClass.class);

public void updateData(String data){
logger.info("updating data with {} ",data);
try {
// do somthing
}catch (Exception e){
//something went wrong
logger.error("update fail ",e); // say line number 14
}
}
}

此时我的要求符合,但这会产生一个新问题。

以下是JBoss的记录器格式配置

<pattern-formatter pattern="%K{level}%d{HH:mm:ss,SSS} %-5p (%F:%L) (%t) %s%E%n"/>

现在%F -文件名将变为MyLogger类(class)。和%L - 行号将成为MyLogger的行号这会导致日志不准确。

部分示例日志

(MyLogger.java : 10) // but this should be (MyClass.java : 14)

现在我已将此模式更改为

<pattern-formatter pattern="%K{level}%d{HH:mm:ss,SSS} %-5p [%c:%L] (%t) %s%E%n"/>

这几乎可以工作,但是 %c -class name 给出了预期的正确类。但无法获取行号(正确的行号)。

更改记录器 paten 后我得到了什么

(com.my.test.MyClass : 10) // but this should be (com.my.test.MyClass : 14)    

这是我的问题。

  1. 是否有任何日志附加程序( SocketAppenderJMSAppender )与 JBoss AS7 一起使用?(在 Jboss AS 7 上没有找到有效的解决方案)
  2. 还有比这更好的方法吗?
  3. 有没有办法使用这种方法获得正确的行号?

我已经在 JBossDeveloper 中提出了问题。但至少目前还没有任何评论。

https://developer.jboss.org/thread/249729

任何帮助都非常感谢。

最佳答案

如果您使用的是 JBoss 7.2 (EAP 6.1) 或更高版本,则可以使用 Log4j 附加程序 作为自定义处理程序 ( check this issue )。

例如

<custom-handler name="server" class="org.apache.log4j.net.SocketAppender" module="org.apache.log4j">
<level name="INFO"/>
<formatter>
<pattern-formatter pattern="%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/>
</formatter>
<properties>
<property name="RemoteHost" value="10.10.10.10"/>
<property name="Port" value="1234"/>
<property name="LocationInfo" value="true"/>
<property name="ReconnectionDelay" value="10000"/>
</properties>
</custom-handler>

在其他情况下,使其在 JBoss AS 7 中工作的唯一方法是为 SocketAppender 开发自定义 java.util.logging.Handler

查看Creating a custom logging handler in JBOSS as 7.1.0 FinalCustom log handlers on 7.0.1创建自定义日志处理程序,然后将它们委托(delegate)给 Log4jAppenderHandler

例如(示例代码):

import java.util.Collections;
import java.util.logging.Filter;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.LogRecord;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.net.SocketAppender;
import org.apache.log4j.net.SyslogAppender;
import org.apache.log4j.spi.LocationInfo;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.ThrowableInformation;
import org.jboss.logmanager.ExtLogRecord;
import org.jboss.logmanager.log4j.handlers.Log4jAppenderHandler;


public class SocketHandler extends Handler {

private final Log4jAppenderHandler log4j = new Log4jAppenderHandler(new SocketAppender());

@Override
public void publish(LogRecord record) {
if (record == null) {
return;
}
ExtLogRecord extRecord;
if (record instanceof ExtLogRecord) {
extRecord = (ExtLogRecord) record;
} else {
extRecord = ExtLogRecord.wrap(record);
}
if (isLoggable(record)) {
LoggingEvent event = new LoggingEvent(extRecord.getLoggerClassName(),
Logger.getLogger(extRecord.getLoggerClassName()), extRecord.getMillis(),
Level.toLevel(extRecord.getLevel().toString()), extRecord.getFormattedMessage(),
extRecord.getThreadName(), extRecord.getThrown() == null ? null
: new ThrowableInformation(extRecord.getThrown()), extRecord.getNdc(),
new LocationInfo(new Throwable(), extRecord.getLoggerClassName()),
Collections.singletonMap("org.jboss.logmanager.record", extRecord));
((SyslogAppender) log4j.getAppender()).doAppend(event);
flush();
}
}

@Override
public void flush() {
log4j.flush();
}

@Override
public void close() throws SecurityException {
log4j.close();
}

@Override
public void setFilter(Filter filter) {
log4j.setFilter(filter);
}

@Override
public void setFormatter(Formatter formatter) {
log4j.setFormatter(formatter);
}

public void setThreshold(String threshold) {
((SocketAppender) log4j.getAppender()).setThreshold(Level.toLevel(threshold));
}

public void setRemoteHost(String remoteHost) {
((SocketAppender) log4j.getAppender()).setRemoteHost(remoteHost);
}

public void setPort(String port) {
try {
((SocketAppender) log4j.getAppender()).setPort(Integer.parseInt(port));
} catch (Exception e) {}
}

public void setReconnectionDelay(String reconnectionDelay) {
try {
((SocketAppender) log4j.getAppender()).setReconnectionDelay(Integer.parseInt(reconnectionDelay));
} catch (Exception e) {}
}

public void setLocationInfo(String locationInfo) {
try {
((SocketAppender) log4j.getAppender()).setLocationInfo(Boolean.parseBoolean(locationInfo));
} catch (Exception e) {}
}

}

我认为最好的方法是这样,这样您就不会在应用程序中实现日志记录。

另请参阅:Logging Configuration

我希望这会有所帮助。

关于java - 如何在以下上下文中获得正确的记录器行号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27039249/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com