应该在分布式系统中使用哪些Appender?如何配置?

时间:2012-08-08 11:09:56

标签: java logging log4j apache-chainsaw

我正在尝试将日志记录组件添加到分布式系统。它是用AspectJ编写的,以避免链接当前的源代码。我使用socket appender发送日志,但我想尝试一些更有效的方法。

我听说我应该使用JMSAppenderAsyncAppender,但我没有配置它。我应该创建收集日志的Receiver并将它们传递给数据库和GUI(我使用ChainSaw)吗?

我尝试关注turorial1tutorial2,但他们还不够明确。

enter image description here

修改

在我准备的一个小型演示中,我发送了6个日志来请求(模拟3个组件)

[2012-08-08 15:40:28,957] [request1344433228957] [Component_A] [start]
[2012-08-08 15:40:32,050] [request1344433228957] [Component_B] [start]
[2012-08-08 15:40:32,113] [request1344433228957] [Component_C] [start]
[2012-08-08 15:40:32,113] [request1344433228957] [Component_C] [end - throwing]
[2012-08-08 15:40:32,144] [request1344433228957] [Component_B] [end]
[2012-08-08 15:40:32,175] [request1344433228957] [Component_A] [end]

使用套接字Appender。所以我的log4j.properties是:

log4j.rootLogger=DEBUG, server

log4j.appender.server=org.apache.log4j.net.SocketAppender
log4j.appender.server.Port=4712
log4j.appender.server.RemoteHost=localhost
log4j.appender.server.ReconnectionDelay=1000

所以我跑

>java -classpath log4j-1.2.17.jar org.apache.log4j.net.SimpleSocketServer 4712 log4j-server.properties

配置

log4j.rootLogger=DEBUG, CA, FA

#
log4j.appender.CA=org.apache.log4j.ConsoleAppender
log4j.appender.CA.layout=org.apache.log4j.PatternLayout
log4j.appender.CA.layout.ConversionPattern=[%d] [%t] [%c] [%m]%n

#
log4j.appender.FA=org.apache.log4j.FileAppender
log4j.appender.FA.File=report.log
log4j.appender.FA.layout=org.apache.log4j.PatternLayout
log4j.appender.FA.layout.ConversionPattern=[%d] [%t] [%c] [%m]%n

然后我将我的日志从文件发送到Chainsaw:

enter image description here

这绝对是基本的,但我想学习如何做得更好。首先,我想异步发送日志。然后创建非常简单的Receiver,例如可以将日志传递给文件。

我尝试按照上面列出的教程,但我失败了。所以问题是:你能提供一些示例配置吗? Receiver.javalog4.properties个文件的示例?

4 个答案:

答案 0 :(得分:2)

我会使用NFS或CDFS并在所有计算机上安装驱动器。让每个应用程序实例写入不同的文件。无论您使用多少台计算机,您都可以在一个目录(或驱动器)中找到所有日志。

我不会在具有高延迟的全球WAN上使用NFS或CDFS,例如>往返50毫秒。在这个原因我使用了JMS(但我没有使用log4j)

答案 1 :(得分:2)

我的两分钱..无论你做什么,请确保使用异步机制将日志传递给接收者,否则最终会拖延你的应用程序。另一点,为了可靠地提供日志,你应该考虑在appender本身内置的故障转移机制 - 接收器可能短时间或长时间离线,如果你关心日志,肯定需要故障转移。我们已经构建了similar system您描述的内容(对于添加内容感到抱歉),但如果您愿意,可以使用我们的appender(查看downloads),它是免费的并且有来源。还有一个视频教程。它具有故障转移和灵活的异步机制以及备份回退。

您应该使用多少个appender?每个jvm一个appender会做得很好。配置文件可能应该是每个jvm,不知道你打算如何实现接收器,在任何情况下,appender需要找到你的接收器,通常至少是主机端口对。关于数据库,我的经验非常糟糕的是RDBMS(我们正在转向nosql),但如果你没有超过几亿条记录,那么大多数商业数据库都会付出一些努力。我必须说,这不是一项简单的任务,花了我们几年的时间来建立你刚刚用几个瘦小的矩形绘制的商业质量系统:)

答案 2 :(得分:2)

最后我发现了如何配置它。我把2个文件放到src文件夹中。

jndi.properties

topic.logTopic=logTopic

和log4j-jms.properties

log4j.rootLogger=INFO, stdout, jms

## Be sure that ActiveMQ messages are not logged to 'jms' appender
log4j.logger.org.apache.activemq=INFO, stdout

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern= 

## Configure 'jms' appender. You'll also need jndi.properties file in order to make it work
log4j.appender.jms=org.apache.log4j.net.JMSAppender
log4j.appender.jms.InitialContextFactoryName=org.apache.activemq.jndi.ActiveMQInitialContextFactory
log4j.appender.jms.ProviderURL=tcp://localhost:61616
log4j.appender.jms.TopicBindingName=logTopic
log4j.appender.jms.TopicConnectionFactoryBindingName=ConnectionFactory

然后我用VM参数

运行我的程序
-Dlog4j.configuration=log4j-jms.properties

并接收课程Receiver.java

中的日志
public class Receiver implements MessageListener {

    PrintWriter pw = new PrintWriter("result.log");
    Connection conn;
    Session sess;
    MessageConsumer consumer;

    public Receiver() throws Exception {


        ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");
        Connection conn = factory.createConnection();
        Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
        conn.start();
        MessageConsumer consumer = sess.createConsumer(sess.createTopic("logTopic"));
        consumer.setMessageListener(this);
    }

    public static void main(String[] args) throws Exception {
        new Receiver();

    }

    public void onMessage(Message message) {
        try {
            LoggingEvent event = (LoggingEvent) ((ActiveMQObjectMessage) message).getObject();

            DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS"); 
            String nowAsString = df.format(new Date(event.getTimeStamp())); 

            pw.println("["+ nowAsString + "]" + 
                    " [" + event.getThreadName()+"]" +
                    " ["+ event.getLoggerName() + "]" +
                    " ["+ event.getMessage()+"]");
            pw.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

答案 3 :(得分:2)

我建议使用syslog和内置的syslog appender。使用TCP进行可靠的日志记录(可能是+ Asyc appender)或使用UDP进行“即发即弃”日志记录。 如果需要,我有一个rsyslog配置。