2014-03-27 57 views
2

此問題類似於未答覆的rsyslog specific question on Server Fault。我不清楚最好的解決方案是通過已有的軟件,如rsyslog或logstash,或者我必須自己構建一些東西。這就是我在這裏問的原因。如何將消息記錄到通用(更改)文件

問題

我有並行運行幾個蟒進程(通過多處理來處理)。他們構建需要寫入該組的相同日誌文件的組。從多個進程登錄到同一個文件必須經過某種序列化才能避免文件損壞,所以記住rsyslog或logstash。

我無法找到的(rsyslog和logstash都不知道)是如何過濾包含我無法知道的文件名的字段(或標記或可能在該系統中調用的任何內容) (包含我不控制的版本號),並將這些消息寫入通訊文件。

所以,我知道它是如何完成靜態輸入過濾器與動態輸出。但我不知道它是如何完成動態輸入和動態輸出的。

我最喜歡幻想的解決方案

在Python應用程序:

  • 創建自定義格式,其添加包含目標日誌文件的名稱的字段(如syslogtag爲rsyslog現在)

  • 添加一個SyslogHandler或類似於我的記錄器。

在rsyslog現在或logstash配置添加規則像

<config of some logging system> 
[filterfor] <field> -> write messages containing <value of field> to logfile /path/to/logs/<value of field>.log 

完成。

問題

這是可能的開箱或(在logstash)與(尚未被寫入)插件?

編輯:也許一個例子將闡明我在找什麼。在括號內的目標作爲exapmle

實施例的日誌信息:然後基於匹配的名稱

<group_a> Message that will end up only in "group_a.log" 
<group_a> Another Message for "group_a.log" 
<group_b> Some interesting message for "group_b.log" 
<group_c> Message for "group_c.log" 

這些消息將在相應的日誌文件結束。對於上面的例子,它們的內容的日誌文件將是:

/var/log/group_logs/group_a.log 
    <group_a> Message that will end up only in "group_a.log" 
    <group_a> Another Message for "group_a.log" 

/var/log/group_logs/group_b.log 
<group_b> Some interesting message for "group_b.log" 

/var/log/group_logs/group_c.log 
    <group_c> Message for "group_c.log" 

所以它的工作就像是一組保存一致的姓名,並用它作爲文件名的正則表達式。

+1

你有沒有讀過這個http://docs.python.org/dev/howto/logging-cookbook.html#logging-to-a-single-file-from-multiple-processes – msvalkon

+0

是的,但在我建立東西之前我自己,我想確保這是不可能的標準工具(我寧願站在巨人的肩膀上;))。 –

回答

1

的rsyslog現在A工作液的工作原理如下:

  1. 所有日誌信息包含由(任意)開始和結束的分隔符分隔的目標文件名的名稱。他們必須只出現包文件名(在這種情況下,我們使用[開始和]作爲結束分隔符)
  2. 消息被髮送到local0工具日誌將它們從其它信息中分離出來。

在rsyslog現在配置的顯著部分是:

$template debugFile,"/var/log/%msg:R,ERE,1,DFLT:\[\[(.*)\]\]--end%.log" 

通過正則表達式生成的消息的日誌文件的絕對路徑 - 由rsyslog現在團隊提供的Regular Expression Checker/Generator在這兒可以幫忙。

$template rawFormat,"%msg%\n" 

輸出模板只包含原始日誌消息(主要是裝飾性的)。

local0.* ?debugFile;rawFormat 

使用此模板和格式將所有日誌發送到local0設施。

1

以下解決方案適用於logstash(不需要插件)。

我會使每個進程輸出到一個單獨的文件,比如/path/logs/process-<unique-process-specific-id>.log。該文件將包含線,如:

<group> <rest of line> 

然後,你可以使用此配置:

input { 
    file { 
    path => "/path/logs/process-*.log" 
    start_position => beginning 
    } 
} 

filter { 
    grok { 
    match => { "message" => "\A(?<group>[^ ]++) (?<rest>.*+)\z" } 
    } 
} 

output { 
    file { 
    path => "/path/logs/group-%{group}.log" 
    message_format => "%{rest}" 
    } 
} 

所以,如果一個進程正在寫一本線/path/logs/process-foobar.log看起來像:

groupA Hello world! 

..那麼這將進而產生一個日誌文件/path/logs/group-groupA.log與內容

Hello world! 
+0

看起來這個解決方案適用於logstash?你能澄清一下嗎? –

+0

是的,這是針對logstash的,不需要任何插件。 –

+0

該組名稱應該不包含空格,並且該行的其餘部分由一個空格分隔。 –

相關問題