elk

轉載,供日后回查

ELK6.2.2(elasticsearch+logstash+kibana)開源日志分析平臺搭建(零):源起

子豪

1現狀:

我司目前日志情況是,在各個IDC部署四個大業務線程序。日志統一打印到各自IDC的/logdata目錄。此目錄為百T級別的gluster。在其中,日志按照機器名稱=》程序名稱的目錄結構存放。在同一目錄下,分別為同一程序的運行日志(process.log),錯誤日志(error.log),下行日志(submit.log),上行日志(recv.log)等類別的日志,并按照日期切分。

[superuser@ft3q-app47 logs]$ df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/VolGroup-LogVol01
                      1.1T  106G  920G  11% /
/dev/sda1             190M   41M  140M  23% /boot
tmpfs                  24G     0   24G   0% /dev/shm
192.168.193.201:/logdata
                      110T   45T   65T  41% /logdata
192.168.173.201:/logdata
                       37T   11T   27T  28% /logdata-1
  • 2出現的問題:

2.1運維同事目前還是用傳統的查詢文件方式查看日志。cat?error.log_yyyy_mm_dd|grep “keyword”。在分布式、微服務的環境下, 比較繁瑣,而且還容易遺漏,最重要的是效率低。

2.2詢問一條消息的消息軌跡時無從下手,分別經過的服務端、邏輯和網關模塊因為分布式太多了。

  • 3痛點:

3.1從海量分散文件中,迅速、準確地找到包含某關鍵詞的日志。

3.2完整找出某關鍵詞在某一時間段內出現在的每個日志中,即消息軌跡。

  • 4解決方案:

構建我司自己的日志分析系統。

  • 5方案一

5.1splunk

Splunk是大數據領域第一家在納斯達克上市公司,Splunk提供一個機器數據的引擎。使用 Splunk可收集、索引和利用所有應用程序、服務器和設備(物理、虛擬和云中)生成的快速移動型計算機數據 。從一個位置搜索并分析所有實時和歷史數據。 使用 Splunk 處理計算機數據,可讓您在幾分鐘內(而不是幾個小時或幾天)解決問題和調查安全事件。監視您的端對端基礎結構,避免服務性能降低或中斷。以較低成本滿足合規性要求。關聯并分析跨越多個系統的復雜事件。獲取新層次的運營可見性以及 IT 和業務智能。

elk

但因為其要求每日數據量小于500M,否則收費,每月225美元,并且其可拓展性差。我司每日某一業務線日志量就可達300G。所以我們不用。(還不是因為要錢嘛)

elk

5.2ELK stack

elk

 

ELK 是elastic公司提供的一套完整的日志收集、展示解決方案,是三個產品的首字母縮寫,分別是ElasticSearch、Logstash 和 Kibana
ElasticSearch簡稱ES,它是一個實時的分布式搜索和分析引擎,它可以用于全文搜索,結構化搜索以及分析。它是一個建立在全文搜索引擎 Apache Lucene 基礎上的搜索引擎,使用 Java 語言編寫。ELK 是elastic公司提供的一套完整的日志收集、展示解決方案,是三個產品的首字母縮寫,分別是ElasticSearch、Logstash 和 Kibana。

Logstash是一個具有實時傳輸能力的數據收集引擎,用來進行數據收集(如:讀取文本文件)、解析,并將數據發送給ES。

Kibana為 Elasticsearch 提供了分析和可視化的 Web 平臺。它可以在Elasticsearch 的索引中查找,交互數據,并生成各種維度表格、圖形。

其特點是代碼開源,并且是JAVA寫的,有完善的REST API,我們可以拓展程序。所以選擇ELK進行日志分析。

elk

  • 6規劃一:ELK讀取分散文件

方案設計:

在不改動現有平臺的情況下,增加一套ELK讀取分散的文件。通過logstash組件讀取每個文件建立索引入es,運維人員可通過kibana方便查詢。架構如下:

elk

優點:現有程序完全沒有改動。

缺點:

1日志還是零散分部,cluster有報出文件性能差問題。

2日志占用空間,導入ES后索引占用空間,即數據冗余。

3 Logstash Agent的維護不是很理想,Logstash是基于Ruby的,啟動它就要有幾十兆內存被jvm吃掉,我們想避免在每個機器上都要起一個Logstash。并且在我們使用過程中Logstash非常不穩定,莫名其妙就死掉了,還需要一個守護進程守護它。

4log標準化。現階段各程序日志還是不標準。

  • 6規劃二:增加KAFKA

日志直接寫入KAFKA,logstash抽取KAFKA數據入ES,運維人員可通過kibana方便查詢。架構如下:

elk

此架構避免了單個logstash讀取多文件會卡的問題。使用kafak,可以讓統一模塊如cmpp服務端寫入同一kafka話題(topic),使得負載均衡的模塊可以完整地錄入。Logstash通過讀取一個topic賦予一個確定的索引如 logstash-server-cmpp,在以后查詢中就可以批量查詢同一功能的日志了。

優點:

1去除日志gluster。

2日志規范化后,可以精細查詢每條日志。并且可以分詞檢索。

3完整,精確。消息軌跡可以查詢出來。

4建立相應索引后,可以快速檢索。

缺點:

1需要對現有程序進行改動,1建立標準化日志打印公共包2引入kafka包3修改log4j配置文件

2申請資源,每個IDC需要搭建至少一套kafka、ELK。

對現有平臺的影響:

1、程序改動。程序必須改動,可以分批次地灰度上線。

2、容錯機制。kafka使用集群部署,一般不會掛掉。如果kafka掛掉,程序可以運行。

3、性能。底層使用apach自己的kafka-clients,性能應該能保證。經測試,單個log入單個topic速度在700/s。

4、運維人員查詢機制。由以往登入跳板機,grep各模塊文件,轉換到查詢模塊索引,指定某字段為某值,web頁面查詢。

5、報警機制改變。以往基于error日志文件。現在可以使用ES自帶的查詢API監控某一個TOPIC,出現關鍵字報警。

6、配套程序開發。定時刪除kafka數據,定時刪除es索引,監控程序等。

  • 7規劃三:每個IDC分業務搭建多套ELK

日志量大以后,每個IDC內部根據業務進行細分,分出多套日志系統。架構如下:

elk

根據LinkedIn(領英)的使用情況來看,有20多個針對不同業務模塊的ELK集群,1000+服務器,主要都是Elasticsearch。1分鐘之內生產系統發生的log這邊就可以搜索,所有的log保留7到14天。現在大概有500億的索引文檔,500到800T,之前測試時推到1500到2000T都是可以工作的。

  • 8目前測試情況:

ft3q IDC的tapp21-tapp23部署3臺kafka集群。tapp25部署ELK。測試程序分別模擬服務端、邏輯、網關發送至3個topic,logstash消費信息并且賦予3種索引。其中submit明細我做了分詞,將手機號、內容、redis隊列名解析出來。

elk

ELK6.2.2(elasticsearch+logstash+kibana)開源日志分析平臺搭建(一):es簡單搭建

1物理環境

物理機配置

IP CPU 內存 硬盤
192.168.193.47 E5-2650v2 48G 1TB
192.168.193.147 E5-2650v2 48G 1TB
192.168.193.48 E5-2640v3 64G 1TB
192.168.193.148 E5-2640v3 64G 1TB

因為強調elk比較吃機器,所以網絡部門同事給了不錯的機器。應該可以運行elk。

[superuser@ft3q-app47 elk]$ top
top - 16:59:37 up 87 days, 22:55,  1 user,  load average: 27.89, 24.80, 24.19
Tasks: 622 total,   2 running, 620 sleeping,   0 stopped,   0 zombie
Cpu(s):  3.5%us,  3.0%sy,  0.0%ni, 92.7%id,  0.8%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  49397260k total, 48563720k used,   833540k free,   253412k buffers
Swap: 16777212k total,  3753420k used, 13023792k free, 15169808k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                                   
30512 superuse  20   0 86.3g  20g 460m S 176.5 44.3   9889:16 java                                                                                                                                      
 1086 root      20   0     0    0    0 S  2.6  0.0 271:20.94 jbd2/dm-1-8                                                                                                                                
 2707 root      20   0     0    0    0 S  2.0  0.0  28:19.76 kondemand/2                                                                                                                                
 2713 root      20   0     0    0    0 S  2.0  0.0  37:24.09 kondemand/8

規劃一下,在前3臺安裝ES集群。最后一臺安裝filebeat,packagebeat等小東西。

2安裝java

因為是java寫的,所以首先需要安裝java。安裝方法我就不寫了。

[superuser@ft3q-app47 logs]$ java -version
java version "1.8.0_91"
Java(TM) SE Runtime Environment (build 1.8.0_91-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.91-b14, mixed mode)

3官網找到最新版下載地址,下載。目前是6.2.2

[superuser@ft3q-app47 elk]$ pwd
/home/superuser/elk
[superuser@ft3q-app47 elk]$ ll
總用量 28
drwxr-xr-x  6 superuser superuser 4096 3月  22 13:25 cerebro-0.7.2
drwxr-xr-x  9 superuser superuser 4096 3月  14 16:01 es
drwxr-xr-x  5 superuser superuser 4096 3月  20 10:11 filebeat
drwxrwxr-x 12 superuser superuser 4096 3月  14 17:22 kibana
drwxrwxr-x 11 superuser superuser 4096 3月  22 10:18 logstash
drwxrwxr-x 14 superuser superuser 4096 3月  22 17:10 logstash_bank
drwxr-xr-x  4 superuser superuser 4096 3月  19 14:26 packetbeat
[superuser@ft3q-app47 elk]$ wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.2.2.tar.gz

4解壓并改名

[superuser@ft3q-app47 elk]$ tar -zxvf elasticsearch-6.2.2.tar.gz
[superuser@ft3q-app47 elk]$ mv elasticsearch-6.2.2 es

5修改config/elasticsearch.yml配置文件

[superuser@ft3q-app47 es]$ vim config/elasticsearch.yml
#集群名稱
cluster.name: ft3q
#節點名稱
node.name: node-47
#如果是master節點設置成true 如果是
node.master: true
#如果是data節點設置成true
node.data: true
#數據儲存路徑
path.data: /home/superuser/elk/es/data
#日志儲存路徑
path.logs: /home/superuser/elk/es/logs
#監聽地址
network.host: 192.168.193.47
#交互端口
http.port: 9200
#集群的三個節點
discovery.zen.ping.unicast.hosts: ["192.168.193.47", "192.168.193.147","192.168.193.48"]
#至少要發現集群可做master的節點數
discovery.zen.minimum_master_nodes: 2
#不鎖內存
bootstrap.memory_lock: false
#Centos6不支持SecComp
bootstrap.system_call_filter: false
#如果啟用了 HTTP 端口,那么此屬性會指定是否允許跨源 REST 請求。
http.cors.enabled: true
#如果 http.cors.enabled 的值為 true,那么該屬性會指定允許 REST 請求來自何處。
http.cors.allow-origin: "*"
#增大bulk隊列大小
thread_pool.bulk.queue_size: 20000
#設置恢復時的吞吐量(例如:100mb,默認為0無限制.如果機器還有其他業務在跑的話還是限制一下的好) 
indices.recovery.max_bytes_per_sec: 100mb
#可以使用值:eg:50mb 或者 30%(節點 node heap內存量),默認是:unbounded
indices.fielddata.cache.size: 50mb
#集群發現超時時間
discovery.zen.ping_timeout: 200s
#集群ping間隔
discovery.zen.fd.ping_interval: 30s
#超時
discovery.zen.fd.ping_timeout: 200s

6修改config/jvm.options配置文件

-Xms20g
-Xmx20g

主要就是這兩個值,根據自己的機器來配置。

7修改系統參數

如果現在啟動es,仍然會報一些錯,根據錯誤信息,修改系統參數。切換到root。

7.1max file descriptors [65535] for elasticsearch process is too low, increase to at least [65536]

方案:vi /etc/sysctl.conf

fs.file-max=655350

保存之后sysctl -p使設置生效

vi /etc/security/limits.conf 新增

* soft nofile 655350

* hard nofile 655350

保存之后sysctl -p使設置生效

7.2max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]

方案:vi /etc/sysctl.conf

vm.max_map_count=655360

保存之后sysctl -p使設置生效

可能還會遇到max number of threads [1024] for user [huang] is too low, increase to at least [4096]

需要修改用戶的最大可用線程數,vim /etc/security/limits.d/90-nproc.conf

可能還會遇到system call filters failed to install; check the logs and fix your configuration or disable system call filters at your own risk

Centos6不支持SecComp,而ES5.2.0以后默認bootstrap.system_call_filter為true

禁用:在elasticsearch.yml中配置bootstrap.system_call_filter為false,注意要在Memory下面:?
bootstrap.memory_lock: false?
bootstrap.system_call_filter: false

8終于可以啟動

以后臺方式啟動

[superuser@ft3q-app47 es]$ ./bin/elasticsearch -d

9驗證一下

[superuser@ft3q-app47 es]$ curl 192.168.193.47:9200
{
  "name" : "node-47",
  "cluster_name" : "ft3q",
  "cluster_uuid" : "vAUZvtDIQoWGReAgGu19Vw",
  "version" : {
    "number" : "6.2.2",
    "build_hash" : "10b1edd",
    "build_date" : "2018-02-16T19:01:30.685723Z",
    "build_snapshot" : false,
    "lucene_version" : "7.2.1",
    "minimum_wire_compatibility_version" : "5.6.0",
    "minimum_index_compatibility_version" : "5.0.0"
  },
  "tagline" : "You Know, for Search"
}

10其他兩臺也照此安裝,最后可以看到,這三臺組成集群,5分片*2副本,顯示綠色。

elk

ELK6.2.2(elasticsearch+logstash+kibana)開源日志分析平臺搭建(二):kibana簡單搭建

1下載,解壓,重命名

[superuser@ft3q-app48 es]$ wget https://artifacts.elastic.co/downloads/kibana/kibana-6.2.2-linux-x86_64.tar.gz
[superuser@ft3q-app48 es]$ tar -zxvf kibana-6.2.2-linux-x86_64.tar.gz
[superuser@ft3q-app48 es]$ mv kibana-6.2.2-linux-x86_64 kibana

2配置

[superuser@ft3q-app47 kibana]$ vim config/kibana.yml
#端口
server.port: 5601
#監聽地址 本機
server.host: "0.0.0.0"
#命名
server.name: "kibanaServer47"
#es集群地址
elasticsearch.url: "http://192.168.193.47:9200"
#kibana入es的索引
kibana.index: ".kibana"
#x-pack插件安裝后的用戶名,密碼
elasticsearch.username: "kibana"
elasticsearch.password: "kibana"

3啟動,后臺運行

[superuser@ft3q-app47 kibana]$ nohup ./bin/kibana &

4查看運行情況

瀏覽器查看 http://192.168.193.47:5601

elk

完美!

ELK(elasticsearch+logstash+kibana)開源日志分析平臺搭建(四):logstash解析日志

前文已經簡單搭建好了elk,現在就入數據這一方面,我們簡單分析。

1現狀:我司java程序全部使用log4j2經行日志寫文件。其基本例子如下:

<?xml version="1.0" encoding="UTF-8"?>
<!-- status:log4j自身日志,monitorInterval:自動檢測配置文件是否改變,單位:s -->
<configuration status="info" monitorInterval="5" shutdownHook="disable">
    <Properties>
        <!-- 配置日志文件輸出目錄 -->
        <Property name="LOG_HOME">/logdata-local/path/to/log/</Property>
    </Properties>
    <appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout charset="UTF-8" pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} - %msg%n"/>
            <!--控制臺只輸出level及以上級別的信息(onMatch),其他的直接拒絕(onMismatch) -->
            <ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"/>
        </Console>

        <!-- 服務端主日志 -->
        <RollingFile name="asyncservice" fileName="${LOG_HOME}/service.log"
                     filePattern="${LOG_HOME}/service_%d{yyyy-MM-dd}_%i.log">
            <Filters>
                <!-- 打印除error日志所有日志 -->
                <ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/>
                <ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
            <PatternLayout charset="UTF-8"
                           pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} [%L]  - %msg%n"/>
            <Policies>
                <!-- 更新時間 -->
                <TimeBasedTriggeringPolicy modulate="true" interval="1"/>
                <SizeBasedTriggeringPolicy size="500MB"/>
            </Policies>
            <!-- 最多8個日志 -->
            <DefaultRolloverStrategy max="10"/>
        </RollingFile>

        <!-- 服務端錯誤日志 -->
        <RollingFile name="asyncerror" fileName="${LOG_HOME}/error.log"
                     filePattern="${LOG_HOME}/error_%d{yyyy-MM-dd}_%i.log">
            <Filters>
                <!-- 打印error日志 -->
                <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
                <ThresholdFilter level="error" onMatch="DENY" onMismatch="ACCEPT"/>
            </Filters>
            <PatternLayout charset="UTF-8"
                           pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} [%L] - %msg%n"/>
            <Policies>
                <!-- 更新時間 -->
                <TimeBasedTriggeringPolicy modulate="true"
                                           interval="1"/>
                <SizeBasedTriggeringPolicy size="500MB"/>
            </Policies>
            <!-- 最多8個日志 -->
            <DefaultRolloverStrategy max="8"/>
        </RollingFile>

        <RollingFile name="asyncmonitor" fileName="${LOG_HOME}/monitor.log"
                     filePattern="${LOG_HOME}/report_%d{yyyy-MM-dd}_%i.log">
            <PatternLayout charset="UTF-8" pattern="%d{HH:mm:ss.SSS} - %msg%n"/>
            <Policies>
                <!-- 更新時間 -->
                <TimeBasedTriggeringPolicy modulate="true" interval="1"/>
                <SizeBasedTriggeringPolicy size="500MB"/>
            </Policies>
            <!-- 最多8個日志 -->
            <DefaultRolloverStrategy max="8"/>
        </RollingFile>

        <Async name="service" bufferSize="102400">
            <AppenderRef ref="asyncservice"/>
        </Async>
        <Async name="error" bufferSize="102400">
            <AppenderRef ref="asyncerror"/>
        </Async>
        <Async name="monitor" bufferSize="102400">
            <AppenderRef ref="asyncmonitor"/>
        </Async>
    </appenders>


    <loggers>
        <Logger name="monitor" level="info" additivity="false">
            <AppenderRef ref="monitor"/>
        </Logger>
        <root level="info">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="service"/>
            <AppenderRef ref="error"/>
        </root>
    </loggers>

</configuration>

其中主要使用了log4j2的異步緩沖池,5秒刷新配置,自動分日期打包文件等特性。

2目標

我們主要關注

pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} [%L]  - %msg%n"

打出來的日志基本是這樣:

2018-03-27 21:22:19.048 [pool-4-thread-1] INFO  com.common.monitor.MonitorService []  - 監控redis連接#執行結果:OK,監控狀態:redis狀態:true(0,0)

我決定使用logstash的grok插件,過濾信息

3成果

input{
    file {
        path => ["/logdata-local/*/*.log"]
        exclude => "*_*.log"
        max_open_files => "18600"
        codec => multiline {
                pattern => "^\s"
                what => "previous"
                }
        }
}
filter{
        grok {
             match =>{
                "message" =>"%{TIMESTAMP_ISO8601:logtime}\s\[%{DATA:logthread}\]\s%{LOGLEVEL:loglevel}\s\s%{DATA:logclass}\s\[\].{4}%{GREEDYDATA:logcontent}"
                }
                remove_field => ["message"]
            }
        date {
                match => ["logtime", "yyyy-MM-dd HH:mm:ss.SSS"]
                target => "@timestamp"
                }
        mutate {
            add_field => { "filepath" => "%{path}" }
              }
        mutate{
        split => ["filepath","/"]
            add_field =>   {
                "idx" => "%{[filepath][1]}-%{[filepath][2]}-%{[filepath][3]}"
            }
            add_field =>   {
                "filename" => "%{[filepath][3]}"
            }
        }
        mutate{
                lowercase => [ "idx" ]
        }
}
output {
        elasticsearch {
                hosts => ["192.168.193.47:9200","192.168.193.47:9200","192.168.193.47:9200"]
                index => "logstash-bank-%{idx}-%{+YYYY.MM.dd}"
                user => elastic
                password => elastic
         }
}

過濾器意思將其自動生成的message信息解析,然后移除。將文件路徑的“/”轉化為“-”建立索引。索引不能有大寫,最后都小寫化。

解析出的日志時間,覆蓋原始的@timestamp字段。

其基本將每條日志的時間、線程、日志級別、類和內容字段分析了出來,以后看運維同事有什么查詢需求,將規范化內容再細化解析。

4kibana呈現

elk

這樣日志就像數據庫一樣,可以按照字段查詢了。

本文來自投稿,不代表Linux運維部落立場,如若轉載,請注明出處:http://www.www58058.com/104259

(5)
生而為人生而為人
上一篇 2018-07-30
下一篇 2018-07-31

相關推薦

  • Linux筆記 – RPM及YUM軟件包的管理與使用 2(YUM工具的使用方法)

    ◆ 軟件包的管理- YUMYUM(Yellowdog Updater Modified)工具與APT(debain ubuntu等)工具一樣,在解決軟件依賴關系的同時可以下載、安裝、升級、卸載等功能的重要工具。YUM的相關設定在 /etc/yum.conf?文件中有詳細的描述。為了設置軟件包的軟件源信息,需要修改/etc/yum.conf 文件或在?/etc…

    2018-05-08
  • 第一周作業

    1、描述計算機的組成及其功能。 計算機由運算器,控制器,存儲器,輸入設備和輸出設備五大部分組成。 (1)運算器的功能是用于完成算術運算、邏輯運算。負責計算機執行的所有數學與邏輯功能。 (2)控制器的功能是主要負責對程序所執行的指令進行分析,并協調計算機各部件進行工作計算機的所有 其他部件。 (3)存儲器的功能是用于儲存信息的設備,通常是將信息數字化后再利用電…

    Linux筆記 2018-05-11
  • ansible_playbook

    —– hosts: allremote_user: root vars:ports:-81-82-83 vars:ports:– listen_port: 81– listen_port: 82– listen_port: 83 vars:ports:– web1:port: 81#na…

    Linux筆記 2018-07-30
  • Docker容器技術之Dockerfile

    什么是dockerfile?
    dockerfile可以理解為構建docker images的源碼(原料),docker可以通過讀取一個dockerfile來自動構建docker鏡像

    2018-08-06
  • 第十周博客作業

    1、Centos系統下實現httpd-2.2的安裝,并分別實現prefork、worker、event等幾種工作方式
    2、簡述request報文請求方法和狀態響應碼
    3、詳細描述httpd虛擬主機、站點訪問控制、基于用戶的訪問控制、持久鏈接等應用配置實例

    2018-05-26
欧美性久久久久