2015-01-29 12 views
3

Я пытаюсь разобрать файл log4net в json.Q: логический файл log4net с Regex + NXLog

Вот мой пример log4net:

2015-01-27 01:06:18,859 [7] ERROR Web.Cms.Content.Base.Taxonomy.TaxonomyDetectionProvider [(null)] - Get taxonomy Type Failed for Tools 
2015-01-27 06:34:31,051 [26] ERROR www.Status404 [(null)] - ErrorId: 20150127_102b01c6-3208-48c5-8c8b-ae4f92cf2b20 
    UserAgent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.99 Safari/537.36 
    HostAddress: 192.168.10.2 
    RequestUrl: /ErrorPages/404.aspx 
    MachineName: QA01 
    Raw Url:/undefined/ 
    Referrer: http://qa1.www.something.com/toolset.aspx 

2015-01-27 06:34:33,270 [26] DEBUG Web.Caching.Core.CacheManagerBase [(null)] - Custom CacheProvider:Web.Caching.Core.AppFabricCacheManager,Web.Caching.Core Disabled 

С этим я использую xm_multiline, чтобы захватить каждый записей журнала.

<Extension multiline> 
    Module  xm_multiline 
    HeaderLine /^\d{4}\-\d{2}\-\d{2} \d{2}\:\d{2}\:\d{2},\d{3}/ 
    EndLine  /\r?\n\r?\n^\d{4}\-\d{2}\-\d{2} \d{2}\:\d{2}\:\d{2},\d{3}/ 
</Extension> 

Я использую регулярное выражение, чтобы захватить метку времени в качестве заголовка, то я использую регулярное выражение, чтобы захватить два раза новой строки, то следующий временной метки в качестве лицевой линии. Однако он по-прежнему обрабатывает вторую и последнюю записи как одну запись в журнале.

Вот результат:

{ 
    "EventReceivedTime":"2015-01-27 01:06:35", 
    "SourceModuleName":"log4net", 
    "SourceModuleType":"im_file", 
    "time":"2015-01-27 01:06:18,859", 
    "thread":"7", 
    "level":"ERROR", 
    "logger":"Web.Cms.Content.Base.Taxonomy.TaxonomyDetectionProvider", 
    "ndc":"(null)", 
    "message":"Get taxonomy Type Failed for Tools" 
}{ 
    "EventReceivedTime":"2015-01-27 06:34:35", 
    "SourceModuleName":"log4net", 
    "SourceModuleType":"im_file", 
    "time":"2015-01-27 06:34:31,051", 
    "thread":"26", 
    "level":"ERROR", 
    "logger":"www.Status404", 
    "ndc":"(null)", 
    "message":" ErrorId: 20150127_102b01c6-3208-48c5-8c8b-ae4f92cf2b20\r\n UserAgent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.99 Safari/537.36\r\n HostAddress: 192.168.10.2\r\n RequestUrl: /ErrorPages/404.aspx\r\n MachineName: QA01\r\n Raw Url:/undefined/\r\n Referrer: http://qa1.www.something.com/toolset.aspx\r\n\r\n2015-01-27 06:34:33,270 [26] DEBUG Web.Caching.Core.CacheManagerBase [(null)] - Custom CacheProvider:Web.Caching.Core.AppFabricCacheManager,Web.Caching.Core Disabled" 
} 

Я использовал это для производства этой продукции:

Exec if $raw_event =~ /^(\d{4}\-\d{2}\-\d{2} \d{2}\:\d{2}\:\d{2},\d{3}) \[(\S+)\] (\S+) (\S+) \[(\S+)\] \- (.*)/s \ 
     { \ 
      $time = $1; \ 
      $thread = $2; \ 
      $level = $3; \ 
      $logger = $4; \ 
      $ndc = $5; \ 
      $message = $6; \ 
      to_json(); \ 
     } \ 
     else \ 
     { \ 
      drop(); \ 
     } 

Я также пытался настроить его с помощью этого избежать, сочетающих последние две записей как один. Однако я больше не могу получить последнюю запись.

Exec if $raw_event =~ /^(\d{4}\-\d{2}\-\d{2} \d{2}\:\d{2}\:\d{2},\d{3}) \[(\S+)\] (\S+) (\S+) \[(\S+)\] \- ([\s\S]*?)(\r?\n\r?\n|$)/ \ 
     { \ 
      $time = $1; \ 
      $thread = $2; \ 
      $level = $3; \ 
      $logger = $4; \ 
      $ndc = $5; \ 
      $message = $6; \ 
      to_json(); \ 
     } \ 
     else \ 
     { \ 
      drop(); \ 
     } 

ответ

0

Я бы не стал пытаться проанализировать ваш журнал в JSON. Скорее вы должны напрямую создавать JSON. Есть некоторые appenders, которые можно использовать непосредственно, чтобы сделать это, например, log4net.ext.json:

Продлить log4net объекта с простыми опциями конфигурации для создания записей журнала в формате JSON. Это особенно удобно для передачи семантической информации другим утилитам, таким как nxlog, LogStash, GrayLogs2 и .

(курсив мой)

Если вам нужна удобочитаемая версия журнала Вы можете создать два лесорубов, которые каждый выход один формат, но я предполагаю, что вы будете использовать nxlog для этого в любом случае.

На мой взгляд, регулярное выражение не очень хороший способ отбросить из журнала произвольной формы в структурированный журнал, чтобы вы могли его структурировать напрямую.

+0

Большое спасибо за ваш ответ. Я рассмотрел этот путь в первую очередь. Тем не менее, я думаю, что в максимально возможной степени я не буду изменять конфигурацию log4net и оставаться там, где был установлен. – Nataraki

+0

Вам удалось сохранить конфигурацию log4net и проанализировать вывод? – samy

+0

К сожалению, я пока не получил никакого прогресса. – Nataraki

1

Я работаю над аналогичной проблемой. Я думаю, что вам нужно удалить параметр в лицевой линии:

<Extension multiline> 
    Module  xm_multiline 
    HeaderLine /^\d{4}\-\d{2}\-\d{2} \d{2}\:\d{2}\:\d{2},\d{3}/ 
</Extension> 

Поскольку лицевая линия является частью сообщения. Это то, что я понимаю чтение документа здесь: http://nxlog-ce.sourceforge.net/nxlog-docs/en/nxlog-reference-manual.html#xm_multiline

лицевой линии

Это аналогично директиве HeaderLine. Эта необязательная директива также берет строку или литерал регулярных выражений для соответствия каждой строке. При успешном совпадении сообщение считается завершенным и испускается.

Первое сообщение хорошо интерпретируется, потому что парсер снова нашел HeaderLine, поэтому он закрывает первое сообщение.

Как вы можете прочитать в том же документе:

До тех пор, пока новый заголовок прочитал, предыдущее сообщение сохраняется в буфере, потому что модуль не знает, где заканчивается сообщение. Модуль im_file принудительно очищает этот буфер после настроенного тайм-аута PollInterval. Если это поведение неприемлемо, подумайте о том, чтобы использовать какой-либо метод инкапсуляции (JSON, XML, RFC5425 и т. Д.) Или использовать маркер использования и конца с помощью EndLine, если это возможно.

В вашем случае, если каждый из многострочного журнала заканчивается 2 новой строкой, вы должны попробовать

EndLine /\r?\n\r?\n/ 

Надежда эта помощь.