2012-08-08 2 views
5

로깅 구성 요소를 분산 시스템에 추가하려고합니다. 현재 소스 코드의 연결을 피하기 위해 AspectJ으로 작성되었습니다. 소켓 appender를 사용하여 로그를 보내지 만 더 효과적인 것을 시도하고 싶습니다.분산 시스템에서 어떤 Appender를 사용해야합니까? 어떻게 구성합니까?

JMSAppenderAsyncAppender을 사용해야한다고 들었지만 구성에 실패했습니다. 로그를 수집하여 데이터베이스와 GUI에 전달하는 Receiver을 생성해야합니까 (ChainSaw을 사용합니까)?

나는 turorial1tutorial2을 따르려고했지만 충분히 명확하지 않습니다.

enter image description here

편집 : 작은 데모에서

나는 내가 소켓이 appender를 사용하여 요청 (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] 

6 로그를 보낼 준비했습니다. 그래서 내 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 

은 그 때 나는 전기 톱에 파일에서 내 로그를 보내

enter image description here

그것은 절대적으로 기본이지만, 더 잘하는 법을 배우고 싶습니다. 우선, 로그를 비동기 적으로 보내고 싶습니다. 그런 다음 매우 간단한 수신기를 만드십시오. 로그를 파일에 전달할 수 있습니다.

나는 위에 나열된 자습서를 따르려고했지만 실패했습니다. 질문은 다음과 같습니다. 예제 구성을 제공 할 수 있습니까? Receiver.javalog4.properties 파일의 예는 무엇입니까?

답변

2

마지막으로 구성 방법을 찾았습니다. src 폴더에 2 개의 파일을 넣었습니다.

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(); 
     } 
    } 
} 
2

NFS 또는 CDFS를 사용하고 모든 시스템에 드라이브를 마운트합니다. 각 응용 프로그램 인스턴스를 다른 파일에 기록하십시오. 얼마나 많은 기계를 사용하든 하나의 디렉토리 (또는 드라이브)에 모든 로그를 찾을 수 있습니다.

대기 시간이 긴 글로벌 WAN에서 NFS 나 CDFS를 사용하지 않을 것입니다. > 50ms 왕복. 이 이유로 나는 JMS를 사용했다. (log4j를 사용하지 않았다.)

+0

시스템 이름이 아닌 요청 유형별로 로그를 다른 파일로 분할해야합니다. 가능한가? – alicjasalamon

+0

거의 실시간으로 처리해야합니까, 아니면 밤에 처리 할 수 ​​있습니까? 요청 당 파일은 매우 비효율적 일 수 있습니다. 시간에 민감한 무언가를하고 있다면 log4j를 사용하지 않을 것입니다. ;) –

+0

내 아이디어는 : 메시지가 JMS appender에 의해 비동기 적으로'Receiver'로 보내집니다. 'Receiver'는 가장 긴 요청이나 50 개 그룹 중 하나의 요청을 선택한 다음 ChainSaw 및 데이터베이스로 전달합니다. 이 상황에서 log4j를 사용해야합니까? ** 쉬운 ** 해결책을 찾고 있습니다 – alicjasalamon

2

나의 두 센트. 당신이 무엇을 하든지, 비동기 메커니즘을 사용하여 로그를 리시버에 전달해야한다. 앱. 또 다른 점은 로그를 안정적으로 전달하기 위해 appender 자체에 내장 된 장애 조치 메커니즘을 고려해야합니다. 수신기가 단기간 또는 장기간 동안 오프라인 상태가 될 수 있습니다. 로그를 관리하는 경우 장애 조치가 반드시 필요합니다. 우리는 (추가를 위해 죄송합니다) similar system을 작성했습니다. 그러나 우리 appender (보기는 downloads에서 볼 수 있습니다.)가 마음에 들면 무료이며 소스가 있습니다. 비디오 자습서도 있습니다. 장애 조치 및 유연한 비동기 메커니즘과 백업 폴백 기능이 있습니다.

얼마나 많은 어펜더를 사용해야합니까? jvm 당 하나의 appender가 괜찮습니다.구성 파일은 아마도 jvm 당이어야하며, 리시버를 구현하려는 방법을 알지 못하며, 어쨌든 appender는 보통 호스트 포트 쌍인 수신기를 찾아야합니다. 데이터베이스에 관해서는 RDBMS를 사용하여 매우 만족스럽지 않지만 (nosql로 옮겨 가고 있습니다), 수억 개의 레코드를 넘지 않으면 대부분의 상용 데이터베이스가 약간의 노력을 기울일 것입니다. 제가 말해야 할 간단한 작업이 아니라, 몇 마른 직사각형으로 그려진 상용 품질 시스템을 구축하는 데 2 ​​년이 걸렸습니다.

+0

확실히 간단하지 않습니다. 확실히 2 학년 학생은 아닙니다. LogFaces는 멋져 보이고 의심없이 영감을 얻습니다. 귀하의 조언은 매우 "높은 수준"이므로 자세한 내용을 제공하기 위해 잠시 후 나의 질문을 편집하겠습니다. 나는 내가 사용하는 모든 기술에 대해 새로운 것이므로 확실히 지원이 필요하다. – alicjasalamon

2

syslog와 내장 syslog appender를 권하고 싶습니다. TCP를 사용하여 안정적인 로깅 (+ Asyc appender 어쩌면) 또는 UDP를 fire-and-forget 로깅에 사용하십시오. 필요할 경우 rsyslog 설정이 있습니다.

+0

syslog appender를 사용하지 않는다면 log4j와 함께 제공되는 많은 구조화 된 정보를 잃어 버릴 수 있습니다. 시작 지점이 log4j가 아니라면 확실히 좋은 옵션이 될 것입니다. –

+0

동의합니다. 3.5 년이 지난 지금, 우리는 더 이상 syslog를 사용하지 않습니다. (logback + logentries appender). – Jan