2016-11-08 6 views
1

스택 추적을 Logstash에 기록하려고합니다.syslog를 통해 log4j2 스택 추적 보내기

로깅 스택은 ELK (ElasticSearch, Logstash, Kibana)입니다.

로그를 생성하는 응용 프로그램은 로깅 인터페이스로 slf4j을 사용하고 로깅 구현으로는 log4j2을 사용하는 Java 응용 프로그램입니다.

log4j2.xmlRFC5424 형식이 syslog이 appender를 선언

<Appenders> 
    <Syslog name="RFC5424" format="RFC5424" host="localhost" port="8514" 
      protocol="TCP" appName="MyApp" includeMDC="true" mdcId="mdc" 
      facility="LOCAL0" enterpriseNumber="18060" newLine="true" 
      messageId="Audit" id="App"> 
    <LoggerFields> 
     <KeyValuePair key="thread" value="%t"/> 
     <KeyValuePair key="priority" value="%p"/> 
     <KeyValuePair key="category" value="%c"/> 
     <KeyValuePair key="exception" value="%ex{full}"/> 
    </LoggerFields> 
    </Syslog> 
</Appenders> 

나는과 같이 자바 응용 프로그램에서의 Throwable 로그 :

예외가 기록됩니다

org.slf4j.LoggerFactory.getLogger("exception_test").error("Testing errors", new RuntimeException("Exception message")); 
, Logstash는 다음과 같이 추적하여 지속되는 것을 보여줍니다.

{ 
    "@timestamp":"2016-11-08T11:08:10.387Z", 
    "port":60397, 
    "@version":"1", 
    "host":"127.0.0.1", 
    "message":"<131>1 2016-11-08T11:08:10.386Z MyComputer.local MyApp - Audit [[email protected] category=\"exception_test\" exception=\"java.lang.RuntimeException: Exception message", 
    "type":"syslog", 
    "tags":[ 
     "_grokparsefailure" 
    ] 
} 

그리고 Kibana가 로그 항목 중 하나의 _source 필드 내에 정확하게 동일한 JSON을 표시하는지 확인합니다.

여기에 문제가 있습니다. 스택 추적이 저장되지 않습니다. 그리고 "오류 테스트 중"이라는 메시지가 사라집니다.

"tags":["_grokparsefailure"]은 불행하지만 은이 질문과 관련이 없습니다..

<Syslog name="RFC5424" format="RFC5424" host="localhost" port="8514" 
     protocol="TCP" appName="MyApp" includeMDC="true" mdcId="mdc" 
     facility="LOCAL0" enterpriseNumber="18060" newLine="true" 
     messageId="Audit" id="App"> 
    <LoggerFields> 
    <KeyValuePair key="thread" value="%t"/> 
    <KeyValuePair key="priority" value="%p"/> 
    <KeyValuePair key="category" value="%c"/> 
    <KeyValuePair key="exception" value="%ex{full}"/> 
    </LoggerFields> 
    <ExceptionPattern>%ex{full}</ExceptionPattern> 
</Syslog> 

<ExceptionPattern/> 로그 메시지를 대체하고, 은 (슬프게도) 모든 loggerFields를 생략 : 그것은 아무것도 변경한다면


내가 볼 <ExceptionPattern/>를 추가했습니다. 하지만 클래스 이름과 줄 번호를 알려줍니다.

{ 
    "@timestamp":"2016-11-08T11:54:03.835Z", 
    "port":60397, 
    "@version":"1", 
    "host":"127.0.0.1", 
    "message":"at com.stackoverflow.LogTest.throw(LogTest.java:149)", 
    "type":"syslog", 
    "tags":[ 
     "_grokparsefailure" 
    ] 
} 

다시 : 스택 추적이 없습니다. 그리고 다시 : "테스트 오류"라는 메시지가 사라집니다.


어떻게 log4j2을 사용하여 스택 추적을 Logstash에 기록 할 수 있습니까? 필자는 반드시 첨부 파일 syslog을 사용할 필요는 없습니다.

는 기본적으로 제약 조건은 다음과 같습니다

단일 로그되는 것으로 이해 될 필요가
  • 멀티 라인 스택 추적 (I에서 syslog를 사용하는 이유는) 특정 로깅 인프라에 잠글 수 없습니다
    • 등록. "스택 추적의 각 줄"이 "별도의 로그 메시지"가되는 것은 바람직하지 않습니다.
    • 스택 추적은 필터를 거쳐야합니다. 일반적인 예외는 페이지 길이의 스택 추적을 가질 수 있습니다. Spring과 같은 프레임을 걸러 내고 싶습니다.
  • 답변

    1

    Log4j 2.5의 SyslogAppender는 만 UDP를 통해 스택 추적을 전송할 수 있습니다.. UDP와

    <Syslog name="RFC5424" format="RFC5424" host="localhost" port="8514" 
         protocol="UDP" appName="MyApp" includeMDC="true" mdcId="mdc" 
         facility="LOCAL0" enterpriseNumber="18060" newLine="true" 
         messageId="LogTest" id="App"> 
        <LoggerFields> 
        <KeyValuePair key="thread" value="%t"/> 
        <KeyValuePair key="priority" value="%p"/> 
        <KeyValuePair key="category" value="%c"/> 
        <KeyValuePair key="exception" value="%ex{full}"/> 
        </LoggerFields> 
        <ExceptionPattern>%ex{full}</ExceptionPattern> 
    </Syslog> 
    

    : 모두 ExceptionPatternLoggerFields.KeyValuePair["exception"] 시작은 여러 스택 추적을위한 솔루션으로 작동합니다.

    이 내가 syslog를 통해 UDP을 통해 예외를 보내 logstash 인쇄 것입니다 : [[email protected] exception=\"…\"] 내부

    { 
        "@timestamp" => 2016-11-14T13:23:38.304Z, 
         "@version" => "1", 
          "host" => "127.0.0.1", 
         "message" => "<131>1 2016-11-14T13:23:38.302Z BirchBox.local MyApp - LogTest [[email protected] category=\"com.stackoverflow.Deeply\" exception=\"java.lang.RuntimeException: Exception message\n\tat com.stackoverflow.Deeply.complain(Deeply.java:10)\n\tat com.stackoverflow.Nested.complain(Nested.java:8)\n\tat com.stackoverflow.Main.main(Main.java:20)\n\" priority=\"ERROR\" thread=\"main\"] Example error\njava.lang.RuntimeException: Exception message\n\tat com.stackoverflow.Deeply.complain(Deeply.java:10)\n\tat com.stackoverflow.Nested.complain(Nested.java:8)\n\tat com.stackoverflow.Main.main(Main.java:20)", 
          "type" => "syslog", 
          "tags" => [ 
         [0] "_grokparsefailure" 
        ] 
    } 
    

    우리가 LoggerFields.KeyValuePair["exception"] 스택 트레이스를 얻을.

    이 외에도 : 스택 추적 ExceptionPattern에 기록 된 메시지 자체로 확실히 삽입된다.

    참고로

    :이은 (대신에 protocol="TCP" 전술 한 바와 같이, 즉 같은 SyslogAppender을하지만) 나는 syslog를 통해 TCP를 통해 예외를 보낼 때 무엇을 logstash 인쇄입니다 :

    { 
        "@timestamp" => 2016-11-14T19:56:30.293Z, 
          "port" => 63179, 
         "@version" => "1", 
          "host" => "127.0.0.1", 
         "message" => "<131>1 2016-11-14T19:56:30.277Z BirchBox.local MyApp - Audit [[email protected] category=\"com.stackoverflow.Deeply\" exception=\"java.lang.RuntimeException: Exception message", 
          "type" => "syslog", 
          "tags" => [ 
         [0] "_grokparsefailure" 
        ] 
    } 
    { 
        "@timestamp" => 2016-11-14T19:56:30.296Z, 
          "port" => 63179, 
         "@version" => "1", 
          "host" => "127.0.0.1", 
         "message" => "at com.stackoverflow.Deeply.complain(Deeply.java:10)", 
          "type" => "syslog", 
          "tags" => [ 
         [0] "_grokparsefailure" 
        ] 
    } 
    { 
        "@timestamp" => 2016-11-14T19:56:30.296Z, 
          "port" => 63179, 
         "@version" => "1", 
          "host" => "127.0.0.1", 
         "message" => "at com.stackoverflow.Nested.complain(Nested.java:8)", 
          "type" => "syslog", 
          "tags" => [ 
         [0] "_grokparsefailure" 
        ] 
    } 
    { 
        "@timestamp" => 2016-11-14T19:56:30.296Z, 
          "port" => 63179, 
         "@version" => "1", 
          "host" => "127.0.0.1", 
         "message" => "at com.stackoverflow.Main.main(Main.java:20)", 
          "type" => "syslog", 
          "tags" => [ 
         [0] "_grokparsefailure" 
        ] 
    } 
    { 
        "@timestamp" => 2016-11-14T19:56:30.296Z, 
          "port" => 63179, 
         "@version" => "1", 
          "host" => "127.0.0.1", 
         "message" => "\" priority=\"ERROR\" thread=\"main\"] Example error", 
          "type" => "syslog", 
          "tags" => [ 
         [0] "_grokparsefailure" 
        ] 
    } 
    { 
        "@timestamp" => 2016-11-14T19:56:30.296Z, 
          "port" => 63179, 
         "@version" => "1", 
          "host" => "127.0.0.1", 
         "message" => "java.lang.RuntimeException: Exception message", 
          "type" => "syslog", 
          "tags" => [ 
         [0] "_grokparsefailure" 
        ] 
    } 
    { 
        "@timestamp" => 2016-11-14T19:56:30.297Z, 
          "port" => 63179, 
         "@version" => "1", 
          "host" => "127.0.0.1", 
         "message" => "at com.stackoverflow.Deeply.complain(Deeply.java:10)", 
          "type" => "syslog", 
          "tags" => [ 
         [0] "_grokparsefailure" 
        ] 
    } 
    { 
        "@timestamp" => 2016-11-14T19:56:30.298Z, 
          "port" => 63179, 
         "@version" => "1", 
          "host" => "127.0.0.1", 
         "message" => "at com.stackoverflow.Nested.complain(Nested.java:8)", 
          "type" => "syslog", 
          "tags" => [ 
         [0] "_grokparsefailure" 
        ] 
    } 
    { 
        "@timestamp" => 2016-11-14T19:56:30.298Z, 
          "port" => 63179, 
         "@version" => "1", 
          "host" => "127.0.0.1", 
         "message" => "at com.stackoverflow.Main.main(Main.java:20)", 
          "type" => "syslog", 
          "tags" => [ 
         [0] "_grokparsefailure" 
        ] 
    } 
    { 
        "@timestamp" => 2016-11-14T19:56:30.299Z, 
          "port" => 63179, 
         "@version" => "1", 
          "host" => "127.0.0.1", 
         "message" => "", 
          "type" => "syslog", 
          "tags" => [ 
         [0] "_grokparsefailure" 
        ] 
    } 
    

    그것은 보인다 TCP처럼 실제로 작동하지만, 하나의 로그 메시지를 많은 syslog 메시지 (예 : \n)로 나눕니다.