2017-12-27 7 views
0

Tomcat 액세스 로그를 kafka 항목으로 보내려합니다. 나는 Tomcat 로깅 문서를 읽었고, 나는 Tomcat이 apache juli를 사용한다는 것을 발견했다.kafka에 tomcat 액세스 로그를 보내는 방법

기본 로깅을 제거하고 모든 액세스 로그를 kafka에 보내려고합니다.

가 나는

<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" 
       prefix="localhost_access_log" suffix=".txt" 
       pattern="%h %l %u %t &quot;%r&quot; %s %b" /> 

지금 내가이 설정하지만 방법을 변경해야 server.xml에 발견?

답변

1

당신은 바람둥이의 소스 코드를 통과 할 수 있으며,이 키를 찾을 수는 AccessLogValve.java에 존재 :

톰캣 8의 경우 :

public void log(CharArrayWriter message) { 
    this.rotate(); 
    if (this.checkExists) { 
     synchronized(this) { 
      if (this.currentLogFile != null && !this.currentLogFile.exists()) { 
       try { 
        this.close(false); 
       } catch (Throwable var8) { 
        ExceptionUtils.handleThrowable(var8); 
        log.info(sm.getString("accessLogValve.closeFail"), var8); 
       } 

       this.dateStamp = this.fileDateFormatter.format(new Date(System.currentTimeMillis())); 
       this.open(); 
      } 
     } 
    } 

    try { 
     synchronized(this) { 
      if (this.writer != null) { 
       message.writeTo(this.writer); 
       this.writer.println(""); 
       if (!this.buffered) { 
        this.writer.flush(); 
       } 
      } 
     } 
    } catch (IOException var7) { 
     log.warn(sm.getString("accessLogValve.writeFail", new Object[]{message.toString()}), var7); 
    } 

} 

당신은 당신에게 그에서 로그를해야 구성 방법을 알게 될 것입니다. 잘

<Valve className='com.xxx.lekafkavalve.LeKafkaAccesslogValve'   enabled='true' topic='info' pattern='%{yyyy-MM-dd  HH:mm:ss}t||info||AccessValve||Tomcat||%A||%a||%r||%s||%D' bootstrapServers='kafkaaddress' producerSize='5' properties='acks=0||producer.size=3'/> 
+0

감사합니다. 장, 감사합니다. –

1

: 그럼 당신은 같이 server.xml에에 자신의 설정을 추가해야

public class LeKafkaAccesslogValve extends ValveBase implements AccessLog { 
    private String topic; 
    private String bootstrapServers; 

    // If set to zero then the producer will not wait for any acknowledgment from the server at all. 
    private String acks; 

    private String producerSize ; 

    private String properties; 

    private List<Producer<byte[], byte[]>> producerList; 
    private AtomicInteger producerIndex = new AtomicInteger(0); 
    private int timeoutMillis; 
    private boolean enabled = true; 

    private String pattern; 
    private AccessLogElement accessLogElement; 
    private String localeName; 
    private Locale locale = Locale.getDefault(); 


    @Override 
    public void log(Request request, Response response, long l) { 
     if (producerList != null && getEnabled() && getState().isAvailable() && null != this.accessLogElement) { 
      try { 
       getNextProducer().send(new ProducerRecord<byte[], byte[]>(topic, this.accessLogElement.buildLog(request,response,time,this).getBytes(StandardCharsets.UTF_8))).get(timeoutMillis, TimeUnit.MILLISECONDS); 
      } catch (InterruptedException | ExecutionException | TimeoutException e) { 
       log.error('accesslog in kafka exception', e); 
      } 
     } 
    } 

    @Override 
    public void setRequestAttributesEnabled(boolean b) { 
     //some other code if you would like 
    } 

    @Override 
    public boolean getRequestAttributesEnabled() { 
     //some other code if you would like 
     return false; 
    } 

    @Override 
    public void invoke(Request request, Response response) throws IOException, ServletException { 
     //some other code if you would like 
    } 
} 

:

그럼 당신은 클래스를 만들어야합니다, 시작하자 ValveBase 같은 AccessLog를 구현 확장합니다. 또한 로그 프레임 워크를 log4j2로 전환하면 효율성을 높일 수 있으므로 kafka에 메시지를 보내면 주된 속도가 저하되지 않습니다.

관련 문제