2016-04-22 108 views
2

我有我的NGINX日誌格式化爲JSON:

log_format le_json '{ "@timestamp": "$time_iso8601", ' 
        '"remote_addr": "$remote_addr", ' 
        '"remote_user": "$remote_user", ' 
        '"body_bytes_sent": "$body_bytes_sent", ' 
        '"status": $status, ' 
        '"request": "$request", ' 
        '"request_method": "$request_method", ' 
        '"response_time": $upstream_response_time, ' 
        '"http_referrer": "$http_referer", ' 
        '"http_user_agent": "$http_user_agent" }'; 

我的日誌得到由filebeat撿到並送到Logstash具有以下配置:

input { 
    beats { 
    port => 5044 
    codec => "json" 
    } 
} 
filter { 
    geoip { 
     database => "C:/GeoLiteCity.dat" 
     source => "[remote_addr]" 
      } 
} 
output { 
    elasticsearch { 
    template => "C:/ELK/logstash-2.2.2/templates/elasticsearch-template.json" 
    template_overwrite => true 
    hosts => ["127.0.0.1"] 
    index => "%{[@metadata][beat]}-%{+YYYY.MM.dd}" 
    document_type => "%{[@metadata][type]}" 
    } 
} 

我遇到的問題是$ upstream_response_time。如果沒有響應時間,NGINX會在這篇文章中加上' - '。正如你所看到的,我不會在$ upstream_response_time附近放置「」,因爲我希望它是一個數字,所以我可以在Kibana中執行計算並顯示。當發送' - '時,我在Logstash中得到一個jsonparsefailure,因爲它不是一個數字。

我想將所有的' - '設置爲0.最好的方法是什麼? 我試圖在nginx-config中對它進行過濾並沒有成功。我認爲這需要在發送到Logstash之前完成,因爲這是發生分析失敗的地方。

任何想法?

+0

作爲一種解決方法,你可以在它之後放置一個零。所以它變成了'0.1230'或'-0',都是完全有效的數字:) –

+0

或者使用'map'指令 –

+0

你不需要在正則表達式中使用斜槓,甚至根本不需要正則表達式。 –

回答

3

試試這個:

map $upstream_response_time $temprt { 
    default $upstream_response_time; 
    ""  0; 
} 

$upstream_response_time一個數字或取消。 Nginx將未設置的變量記錄爲破折號(-),但map將它們視爲空字符串。

+0

謝謝! This worked: 'map $ upstream_response_time $ temprt { \t \t default $ upstream_response_time; \t \t「」0; \t}' 似乎它是空的,在幕後的某個地方它被設置爲「 - 」,如果是這種情況。 –

+0

謝謝,修復答案 –

+0

@JesperPersson nginx用日誌模塊中的破折號代替未設置的變量https://github.com/nginx/nginx/blob/master/src/http/modules/ngx_http_log_module.c#L957-L960 –