EAGLEYE監控預警平臺

概述

監控預警平臺, eagle + eye (鷹眼)的合體詞, 寓意可以快速發現問題, 并及時作出響應,Eagleye整個分為:

  • eagleye-java-client: 針對java程序進行日志收集
  • eagleye-alerter: 根據控制臺設置的預警規則, 對匹配日志進行實時預警.
  • eagleye-admin: eagleye管理界面,可以看到各個app的接入情況,設置預警規則,進行日志檢索等.
  • eagleye-collector: eagleye日志收集器, 該收集器主要是從kafka中收集日志病存儲到Elasticsearch中, 也可以用logstash替代.
  • eagleye-task: eagleye的定時監聽組建, 如果下游其他系統需要某個app日志,可以直接通過該組建發送.

核心功能說明

首頁客戶端感知

首頁

所有接入eagleye-java-client的應用每分鐘都會通過redis發送心跳數據, 這里面包括應用所在機器的IP, PID, 每分鐘日志的生產力, 應用最近一次啟動到現在日志總量.如果應用進程被kill,則首頁上相應的節點會消失.

應用管理

應用管理

在這里進行app管理, 應用在發送日志之前, 需要在log4j配置文件中配置應用的名稱, eagleye最終會根據這個配置名稱來匹配預警規則. 所以這里的名稱需要在應用程序中的log4j配置中的名稱一致.

規則管理

規則管理

我們可以通過預警管理設置具體的預警規則, 可以通過正則表達式來匹配日志中的內容, 提示中給出來比較常規的預警規則設置.

預警設置

預警設置
  1. 針對某一個應用里面的某一個預警規則,我們可以設置給誰發送短信預警, 給誰發送郵件預警.

  2. 我們通過預警設置的管理將具體的應用和預警規則進行掛鉤.

Zookeeper監控

ZK監控

這里我們借鑒了阿里巴巴的Taokeeper監控軟件, 開發了部署更加方便的zookeeper監控, 可以針對每一個集群中的每一個zk實例進行每分鐘自檢, 如果超出我們設定的預警閾值, 則會進行實時報警.

日志概覽

日志概覽

我們前期通過Kibana的簡單統計頁面可以了解各個應用日志的大致情況. 只需要簡單的配置即可實現.

日志檢索

日志檢索

全量日志收集進來之后, 我們需要對它們進行精確檢索. 這里我們提供了針對時間區間, IP, PID,線程ID, 應用名稱, 日志關鍵字等的聯合檢索功能

日志上下文

日志上下文

有些時候我們只檢索出滿足條件的日志還不能幫助我們快速定位問題, 我們還需要查看日志的上下文, 那么我們可以雙擊某一條日志, 則可以查看該條日志的前200條和后200條日志.

ES監控

HEAD

可以查看ES集群中詳細的Sharding信息.

BIGDESK

可以查看某一個ES實例所在機器的JVM, CPU, 內存等詳情.

Zipkin監控

ZIPKIN

可以根據服務名稱查看具體的RPC調用鏈詳情.

詳細設計

Eagleye整體架構圖

eagleye,整體架構圖

eagleye作為所有服務的日志監控預警平臺, 需要收集所有后臺服務的全量日志,主要分成如下幾個部分:

  • 各個java服務需要接入的基于log4j appender的日志收集客戶端(eagleye-java-client).
  • 我們統一通過Kafka作為日志傳輸通道, 因為要收集的是所有服務的全量日志,日志量龐大,Kafka非常適合這種分布式收集的場景, 并且可以很容易的進行水平拓展.
  • 我們通過eagleye-alert 從kafka中獲取日志, 并根據eagleye-admin中設置的預警規則進行實時預警, eagleye-alert支持水平拓展,并可以做到高可用.
  • 通過logstash進行全量日志的收集并存儲到elasticsearch中進行存儲, 最終用kibana進行快速的檢索和統計.
  • eagleye-admin是eagleye架構的管理控制臺, 從這可以進行各種預警規則的配置, 監控各個client, alerter的心跳, es的存儲狀態, 提供日志檢索,統計界面.eagleye-admin作為一個管理控制臺,并不需要高可用,所以只需要部署一個實例, 即使admin不可用也不會影響所有日志的收集預警功能.
  • 所有服務器的心跳, 預警規則, 都是通過redis進行通信.

日志收集,存儲架構圖

日志收集,存儲架構圖

日志可靠性說明

因為將來會涉及到交易流程的日志跟蹤, 所以日志的可靠性需要保證.鑒于之前推動zookeeper的dns設置過程(運維人員需要每臺服務器去修改,推動時,不是這臺服務器沒有設置,就是那臺服務器沒有設置), 日志收集任務前期在服務端進行日志采集的過程, 并沒有引入第三方的收集工具(鑒于logstash的部署問題,我們在后期引入了自己寫的eagleye-collector來進行日志中繼).在服務端進行日志采集方式, 采用自定義log4j的appdender方式接入采集點.通過kafka作為日志傳輸通道.當然, 采用這種方式有一個風險點是,假如kafka不可用時,日志將采集不到. 但是會記錄到本地log日志中,并不會丟失. 服務端進行日志采集,也有高可用方案,可以每臺部署服務的機器都部署logstash進行收集,即使logstash不可用,日志也不會丟失,并且,logstash啟動時會將丟失收集的日志重新采集.但是logstash部署在服務端所在的機器,對前期日志采集工作量比較大,并不適合我們前期小步迭代推動eagleye項目.所以我們前期約定,在極端情況下,我們允許小概率收集日志失敗的可能.因為采用的是Kafka的隊列方式進行傳輸,所以并不影響我們將來更替高可用的日志采集方案.

日志中繼說明

日志中繼器的存在,有利于我們水平拓展日志收集,并靈活指定存儲媒介.Logstash可以靈活的接入es, hdfs, mysql, cvs, local file 等存儲媒介, 并可以靈活的對日志內容進行過濾.Logstash相比flume會更輕量一些,并且是elasticsearch的同源產品.
如果覺得logstash部署麻煩, 可以直接采用后續開發的eagleye-collector進行日志中繼.

日志存儲

我們選擇Elasticsearch進行存儲, 當然也可以隨時切換成hdfs進行存儲, elasticsearch提供了豐富的RESTFul風格的api,和語言無關.ES的集群搭建成本非常低,每一個ES服務會自動發現集群并加入進去.

日志檢索, 統計

因為有Kibana的存在, 我們可以很輕易并且快速的從es中檢索出我們想要的日志. 可以從多維度進行日志的統計.關鍵是這些功能的提供, 我們不需要寫任何一行代碼,后續我們又開發了自定義檢索,可以查看某一條日志的上下文.

備注

上圖中的channel, relayer, es 可以部署在相同的機器中,也可以進行拆分. 每一層都可以選用其他方案進行替代,并不影響整個系統的運轉.

測試

功能測試

性能測試

  • logstash 性能測試:
    單臺服務器的單個logstash實例
    內存:500m
    input consumers : 1
    output workers : 2
    機器內存: 4G, 其中2個G被es消耗, 1個多G被日志mock程序占用
    機器8核,普通pc機

    在output配置中
    workers => 2 # 如果這個配置開太大容易內存溢出, 需要根據機器配置進行調整, 在測試環境logstash 內存500m時,2個線程效率最高
    flush_size => 1000 #該配置配合workers進行調整, 如果太大, 也容易內存溢出, 或者增加gc次數.目前這個配置可以達到單臺logstash可以20000/s的日志寫入

    gc觀察
    在bin/logstash.lib.sh 文件中 logstash 采用了 如下gc方式

    JAVA_OPTS="$JAVA_OPTS -XX:+UseParNewGC"
    JAVA_OPTS="$JAVA_OPTS -XX:+UseConcMarkSweepGC"
    

    觀察曲線如下圖:

    logstash采用自己默認gc

    老年代gc會比較頻繁,增加了stop the world的時間,會影響性能.

    注釋掉之后的曲線老年代很少出現回收現象, 不會造成stop the world 現象

    logstash采用jvm默認gc

    但是采用jvm默認gc方式后運行了1個小時之后出現了頻繁的老年代gc, 如下圖:


    logstash采用jvm默認gc

    簡單的測試觀察之后, 還是建議使用logstash默認的gc

    JAVA_OPTS="$JAVA_OPTS -XX:+UseParNewGC"
    JAVA_OPTS="$JAVA_OPTS -XX:+UseConcMarkSweepGC"
    
  • eagleye-java-client 性能測試

    client往kafka中發送日志可以80000/s, 這取決與網絡速度和硬盤速度

    運行時通過jmx觀察內存,如下圖: 沒有一次老年代回收


    eagleye-java-client gc圖
  • eagleye-alert 性能測試

    • 單服務, 單機器(244)壓力測試:
      cpu使用如下圖:


      cpu
      cpu

      內存使用如下圖:


      內存
      內存

      吞吐量:3.15w條message/s


      吞吐量
      吞吐量
    • 雙服務, 雙機器(244, 177)壓力測試:
      177的cpu使用如下圖:


      cpu
      cpu
    • 177內存使用如下圖:


      內存
      內存
    • 177吞吐量:2.32w條message/s

    • 244的cpu使用如下圖:


      cpu
      cpu
    • 244內存使用如下圖:


      內存
      內存
    • 244吞吐量:3.22w條message/s
      發現單機處理時最大吞吐量 與雙機處理時最大吞吐量相同 , 但是通過下面單機雙實例測試可以確認服務器網絡io不是瓶頸 ,
      初步認為是單個kafka topic 分區的生產力是有限的 , 雙機處理時吞吐量的差距是由于kafka topic 分區分配不均衡導致(244得到3個分區 , 177得到兩個)
      修改kafka分區數到10個后, 發現單個程序實例即使分配到更多(5個或10個)分區, 吞吐量上限仍然是3w/s ,
      進一步測試得到的結果是程序的性能瓶頸在kafka消費者迭代獲取數據部分, 且一個程序中運行多個針對單個topic的ConsumerConnector并不會提高程序吞吐量

    • 單機(244)雙實例
      程序1(吞吐量 1.68w條message/s , 分配到2個分區)
      程序2(吞吐量 2.9w條message/s , 分配到3個分區)

    • 總結:
      alerter程序啟動時可以通過配置文件loomContext.xml配置alerterConsumerThreadNum(alerter程序kafka消費者線程數).一個kafka消費者線程可以消費多個到0個分區, 但一個分區最多只能被一個消費者線程消費,新的消費程序加入或舊的消費程序失去連接會引發所有分片和所有消費者線程間的再平衡, 但是如果已經是每個分片都被不同的線程消費, 即分片和消費線程為1對1的關系時, 再加入消費程序, 該消費程序將會分配不到分區 導致該消費程序吞吐量為0.單個程序實例的吞吐量在3w/s, 可以通過部署多個實例的方式實現水平擴容, 但需要確保新部署的實例會得到topic分區,如線上服務topic有24個分區, 最多可部署alerter程序實例數為 24/alerterConsumerThreadNum, 即如alerterConsumerThreadNum配置為3, 最多可以部署24/3=8個alerter程序實例.

部署

kafka topic創建

./kafka-topics.sh -create --topic 'EAGLEYE_LOG_CHANNEL' --zookeeper 'spark:2181,witgo:2181' --partitions 10 --replication-factor 1
./kafka-topics.sh -create --topic 'EAGLEYE_ALERT_MAIL' --zookeeper 'spark:2181,witgo:2181' --partitions 10 --replication-factor 1
./kafka-topics.sh -create --topic 'EAGLEYE_ALERT_SMS' --zookeeper 'spark:2181,witgo:2181' --partitions 10 --replication-factor 1

logstash 部署步驟

  • 通過rbenv 對ruby環境安裝(logstash 需要有jruby1.7.11 版本支持):

    git clone git://github.com/sstephenson/rbenv.git ~/.rbenv
    
  • 用來編譯安裝 ruby

    git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
    
  • 用來管理 gemset, 可選, 因為有 bundler 也沒什么必要

    git clone git://github.com/jamis/rbenv-gemset.git  ~/.rbenv/plugins/rbenv-gemset
    
  • 通過 gem 命令安裝完 gem 后無需手動輸入 rbenv rehash 命令, 推薦

    git clone git://github.com/sstephenson/rbenv-gem-rehash.git ~/.rbenv/plugins/rbenv-gem-rehash
    
  • 通過 rbenv update 命令來更新 rbenv 以及所有插件, 推薦

    git clone https://github.com/rkh/rbenv-update.git ~/.rbenv/plugins/rbenv-update
    
  • 然后把下面的代碼放到 ~/.bash_profile 里

    export PATH="$HOME/.rbenv/bin:$PATH"
    
  • 然后重開一個終端就可以執行 rbenv 了.

    rbenv install 1.9.3-p551 # 安裝 1.9.3-p551
    rbenv install jruby-1.7.11 # 安裝 jruby-1.7.11  
    rbenv global jruby-1.7.3 # 默認使用 jruby-1.7.3
    
  • 下面從咱們的gitlab上獲取已經安裝好插件的logstash-1.4.2

    git clone git@git.xxx.com:trade_architect/logstash.git
    
  • 因為logstash需要使用kafka, 所以需要在本機配置, 生產環境的kafka的hosts表

    192.168.1.43 xx-xx-1
    192.168.1.46 xx-xx-2
    192.168.1.60 xx-xx-3
    192.168.1.67 xx-xx-4
    192.168.1.73 xx-xx-5
    
  • 按照logstash進行負載均衡存儲的es實例

    (1). git clone git@git.xxx.com:trade_architect/elasticsearch.git

    (2). 在elasticsearch-1.4.4/config/elasticsearch.yml 中設置將需要輸出的數據, 日志路徑.

     node.name: "eagleye_es_logstash_XXX"   #其中XXX可以標識出該機器
    
     path.data: /home/zhejava/esdata/data   #因為該實例不存儲數據使用, 只是用來進行檢索和存儲時當做集群負載均衡器使用,
     path.work: /home/zhejava/esdata/work  #存放臨時文件的位置
     path.logs: /home/zhejava/esdata/logs  #存放日志的位置
    
     transport.tcp.port: 9300  #配置開啟, 并修改為9301
    
     http.port: 9200 #配置開啟 , 并修改為9201
    
     node.master: false  #開啟配置
     node.data: false     #開啟配置
    

    (3). 在 elasticsearch-1.4.4/bin/elasticsearch 文件中的 ES_HEAP_SIZE=32768m 修改為 8192m 即可

    (4). 執行

     elasticsearch-1.4.4/bin/elasticsearch -d
    
  • 進入到 logstash-1.4.2 中執行

    sh start.sh 
    

    即可, 在該文件中可以配置logstash具體的日志輸出路徑.

  • 手動搭建logstash服務
    如果不想使用已經安裝好插件的logstash請參照下面的方式安裝.如果按照官方文檔的部署可以git clone 最新版的logstash-kafka, 并且在該目錄下執行 make tarball, 然后生成 logstash-1.4.2.tar.gz,但是這需要有一個暢通的網絡, 因為有一個無形的墻,阻擋我們完成這件事, 我個人嘗試vpn出去, 也出現了失敗, 網絡并不穩定.所以我還是闡述一下通過手動搭建一個logstash 服務, 并可以從kafka中消費隊列, 并存儲消息到elasticsearch中.

    (1) 下載官方logstash-1.4.2 版本, 這是最新的release版本.

    wget https://download.elasticsearch.org/logstash/logstash/logstash-1.4.2.tar.gz
    

    (2) 下載 logstash 針對kafka的插件 logstash-kafka v0.6.2 (或者可以通過git clone獲取最新的版本)

    wget https://github.com/joekiller/logstash-kafka/archive/v0.6.2.tar.gz  
    

    (3) 因為logstash-kafka是ruby項目, 所以需要依賴ruby環境(具體見本文上半部分)

    (4) 解壓logstash包,得到 $logstash_home, 并創建 $logstash_home/vendor/jar/kafka_2.9.2-0.8.1.1/libs/

    (5) 下載kafka程序包(如果沒有, 請去官網下最新0.8.1.1版本.

    wget https://www.apache.org/dyn/closer.cgi?path=/kafka/0.8.1.1/kafka_2.9.2-0.8.1.1.tgz)
    

    (6) 從$kafka_home/lib 目錄復制所有jar文件到$logstash_home/vendor/jar/kafka_2.9.2-0.8.1.1/libs/下

    (7) 復制logstash-kafka/lib/logstash里的 inputs 和 outputs 下的 kafka.rb,拷貝到對應的 $logstash_home/lib/logstash 里的 inputs 和 outputs 對應目錄下

    (8) 安裝logstash-input-kafka

    git clone https://github.com/logstash-plugins/logstash-input-kafka.git
    

    然后進入該目錄下運行bundle install, 這時會下載logstash運行時依賴的各種gem (這又是一個大坑, 之前忽略了這一步)

    (9) 在$logstash_home目錄下運行:

    GEM_HOME=vendor/bundle/jruby/1.9 GEM_PATH= java -jar vendor/jar/jruby-complete-1.7.11.jar --1.9 ../logstash-kafka/gembag.rb ../logstash-kafka/logstash-kafka.gemspec
    

    (10) 在$logstash_home目錄下創建 logstash.yml 配置文件,文件內容為如下:

    input {
        kafka {
            zk_connect => "xxx1:2181,xxx2:2181"
            group_id => "eagleye_logstash"
            topic_id => "EAGLEYE_LOG_CHANNEL"
            consumer_threads => 5  
        }
    }
    
    output {
      elasticsearch {
        cluster => "eagleye_es"
        # 我們可以版本搭建一個es服務, 該服務不存儲數據和檢索, 只是發現es集群,并轉發操作請求
        host => "localhost"
        port => "9301"
        protocol => "transport"
        index => "eagleye-log-%{+YYYY.MM.dd}"
        index_type => "log"
        workers => 2 # 如果這個配置開太大容易內存溢出, 需要根據機器配置進行調整, 在測試環境logstash 內存500m時,2個線程效率最高
        flush_size => 1000 #該配置配合workers進行調整, 如果太大, 也容易內存溢出, 或者增加gc次數.目前這個配置可以達到單臺logstash可以20000/s的日志寫入
        template_overwrite => true
      }
    }
    

    (11) 啟動logstash(進入bin目錄)

    nohub logstash agent -f logstash.yml > /home/zhejava/logstash_log/logstash.log &
    

    (12) logstash-1.4.2 默認的elasticsearch-logstash.json 模板并沒有生效, 里面只是一個通用的樣板,我將 logstash-1.4.2/lib/logstash/outputs/elasticsearch/elasticsearch-template.json 修改為如下內容:

    {
      "template" : "eagleye-*", //這個需要和要操作的index名稱匹配,很重要,默認是logstash*,而我們的是eagleye*,所以該模板一直不好使,沒注意,大坑啊.
      "settings" : {
        "index.refresh_interval" : "5s"
      },
      "mappings" : {
         "log" : {
                "properties" : {
                    "@timestamp" : {
                        "type" : "date",
                        "format" : "dateOptionalTime"
                    },
                    "timestamp" : {
                        "type" : "date", //日期類型, 在生成json的對象中需要是date類型
                        "format" : "dateOptionalTime" 
                    },
                    "head" : {//涉及到map嵌套,可以這樣寫
                        "properties" : {
                            "app" : {
                                "type" : "string",
                                "index" : "not_analyzed" //該字段不需要分詞索引,統計時不會因為"-"而將一個分開統計
                            }
                        }
                    }
                }
            }
      }
    }
    

    (13) logstash時差8小時問題
    logstash在按每天輸出到elasticsearch時,因為時區使用utc,造成每天8:00才創建當天索引,而8:00以前數據則輸出到昨天的索引
    修改logstash/lib/logstash/event.rb 可以解決這個問題
    第226行

    .withZone(org.joda.time.DateTimeZone::UTC)
    

    修改為

    .withZone(org.joda.time.DateTimeZone.getDefault())
    

    (14) 碰到的坑
    logstash到此已經部署完畢, 這里碰到一個坑: 是logstash從kafka中消費消息是始終不能轉換DefaultDecoder對象為json, 最后發現 v0.6.2版本的logstash-kafka中的inputs插件有問題,這時, 你需要去github中獲取logstash-kafka 項目下的logstash-kafka/lib/logstash/inputs/kafka.rb 作為最新的input插件覆蓋之前的.

elasticsearch 部署

  • 依賴 jdk 1.7

  • 獲取Elasticsearch項目

    git clone git@git.xxx.com:trade_architect/elasticsearch.git
    
  • 在elasticsearch-1.4.4/config/elasticsearch.yml 中設置將需要輸出的數據, 日志路徑.

    node.name: "eagleye_es_XXX"   #其中XXX可以標識出該機器
    
    path.data: /home/zhejava/esdata/data   #es數據存儲位置, 需要是獨立的磁盤, 空間越大越好, 到時,公司的全量日志可能會存儲在這, 會是高IO操作
    path.work: /home/zhejava/esdata/work  #存放臨時文件的位置, 建議有獨立的磁盤
    path.logs: /home/zhejava/esdata/logs  #存放日志的位置, 建議獨立的磁盤
    
  • 執行 elasticsearch-1.4.4/bin/elasticsearch -d

eagleye-java-client 部署

因為我們的日志收集是對kafka強依賴, 所以需要有一些配置來進行相關的配置才能接入, 具體的配置主要集中在log4j.xml 和spring配置文件中.

  • pom.xml中添加如下內容:

    <!--基于scala-2.9.2-->
    <dependency>
        <groupId>com.xxx</groupId>
        <artifactId>eagleye-java-client</artifactId>
        <version>1.1.0-SNAPSHOT</version>
    </dependency>
    
  • log4j.xml中需要添加一個自定義的appender節點, 具體如下:

    <appender name="eagleye" class="com.xxx.eagleye.client.log4jappender.EagleyeAppender">
        <param name="app" value="eagleye-test" /> <!-- 這里的名稱就是eagleye-admin中提到的app , eagleye會按照這個進行約定預警規則的綁定,可以和application name(loom中的)一致 -->
        <layout class="org.apache.log4j.PatternLayout" />
    </appender>
    
    <root>
        <level value="INFO"/>
        <appender-ref ref="console"/>
        <!-- 不要忘記在這里將自定義的eagleye appender 添加到root節點下 -->
        <appender-ref ref="eagleye"/> 
    </root>
    

    如果你用的是log4j.properties文件, 如下配置:

    log4j.appender.eagleye=com.xxx.eagleye.client.log4jappender.EagleyeAppender
    # 這里的名稱就是eagleye-admin中提到的app , eagleye會按照這個進行約定預警規則的綁定,可以和application name(loom中的)一致
    log4j.appender.eagleye.app=eagleye-test 
    log4j.appender.eagleye.layout=org.apache.log4j.PatternLayout
    
    #不用忘記在rootLogger中添加eagleye的appender
    log4j.rootLogger=INFO,console,file,eagleye
    
  • 在spring配置文件中進行如下配置:

    <!-- 以下配置可以引入imago進行集中配置管理 需要顯式設置lazy-init="false" 因為整個程序沒有通過spring去獲取eagleyeChannel對象 -->
    <bean id="eagleyeChannel" class="com.xxx.eagleye.client.Configuration" lazy-init="false">
        <!-- 該redis地址主要是記錄client的心跳, 日志生產力,日志總量 -->
        <constructor-arg name="redisIp" value="#{configManager.getRedisConfig('trade_public_redis','14.1').ip}"/> 
        <constructor-arg name="redisPort" value="#{configManager.getRedisConfig('trade_public_redis','14.1').port}"/>
        <constructor-arg name="redisPwd" value="#{configManager.getRedisConfig('trade_public_redis','14.1').pwd}"/>
        <constructor-arg name="kafkaBroker" value="#{configManager.getKafkaConfig('trade_public_kafka','1.1').broker}"/> <!-- 需要用到進行日志收集的kafka配置 -->
        <!--<constructor-arg name="kafkaTopic" value="EAGLEYE_LOG_CHANNEL" />--> <!-- 收集日志的topic名稱, 該配置默認不需要配置 -->
        <!--<constructor-arg name="sendFreq" value="3000" />--> <!-- 批量操作時間間隔, 單位 ms, 這些時間間隔往kafka批量推送一次 -->
    </bean>
    
  • 因為使用的kafka需要用到域名, 需要配置以下kafka的host表,類似如下:

    192.168.1.158 xxx1
    192.168.1.159 xxx2
    
  • 如果要發送監控數據, 在代碼中可以這樣寫:

    logger.info(MonitorLog.build().type(LogType.EAGLEYE_MONITOR_LOG_REFUND_SHMJCSWGBSL).value(105D));
    

    注: 如果你想看到client發送的具體日志內容, 請在log4j.xml配置做如下配置:

    <logger name="com.xxx.eagleye.client.log4jappender.EagleyeAppender">
        <level value="debug"/>
    </logger>
    

kibana部署和配置

概述:Kibana 是為 Elasticsearch 設計的開源分析和可視化平臺。你可以使用 Kibana 來搜索,查看存儲在 Elasticsearch 索引中的數據并與之交互。你可以很容易實現高級的數據分析和可視化,以圖標的形式展現出來。

部署:

  • 部署一個用于做負載的Elasticsearch,Elasticsearch的部署詳見(elasticsearch 部署),部署完成后修改

  • 下載Kibana 4

  • 解壓 .zip 或 tar.gz 壓縮文件

  • 配置Elasticsearch地址,在config/kibana.yml文件,配置第一步安裝的elasticsearch地址.

    elasticsearch_url: "http://localhost:9200"
    
  • bin/kibana,啟動kibana

  • 訪問5601端口.

配置

  • 配置索引(相當于數據庫名),es存入數據是每天創建一個索引,所以kibana要讀取數據必須先配置索引,索引可以按天模糊匹配.配置方法如下圖.
    配置完索引后,選擇時間戳,要選擇帶"@"符號的timestamp用日志進入es的時間字段.


    kibana
  • 配置discover:配置各種查詢數據,進行條件篩選

    kibana

    kibana

    (1). 點擊discover菜單,點擊搜索口后面的添加按鈕(加號),在左側Field項下會列出所有的字段信息,鼠標移到字段上面,會出現add按鈕,點擊添加,該字段會出現在上方的select field項下.
    (2). 配置完成后,右邊會出現選擇的列和數據.
    (3). 點擊apply應用所選的配值
    (4). 點擊保存,在頁面的右上方,有個保存的圖標.填寫保存的名字

  • 配置visualize:visualize是對discover數據表的各種匯總信息,并以各種個圖表顯示.

    kibana

    kibana

    (1). 點擊visualize菜單,點擊搜索口后面的添加按鈕(加號).
    (2). 選擇樣式
    (3). 選擇基礎數據(discover保存的基礎數據)
    (4). 在左側選擇自己需要的統計數據,Metric選項卡中選擇統計結果如(count,avg,sum等).buckets下面的選項可以選擇如何分組,相當于group by 后面的字段
    (5). 點擊apply應用所選的配值,點擊右上角保存按鈕,然后輸入名字保存.

  • 配置dashboard:將discover和visualize保存的各種表格和報表集中在一起顯示

    kibana

    kibana

    (1). 點擊上圖添加按鈕,跳轉到選擇discover和visualize頁面.
    (2). 選擇需要的discover和visualize頁面.此時會在下放顯示.
    (3). 拖動改變位置和大小.
    (4). 保存設置好的面板.

  • 搜索框簡易使用說明
    (1). 在特定的字段里搜索,例如:line_id:86169
    (2). 可以用 AND/OR 來組合復雜的搜索,AND/OR必須大寫,例如:food AND love
    (3). 括號的使用:("played upon" OR "every man") AND stage
    (4). 數值類型的數據可以直接搜索范圍:line_id:[30000 TO 80000] AND havoc
    (5). 搜索所有:*
    (6). 如果輸入 where1 where2 兩個單詞,實際搜索的是where1 OR where2 如果要搜索where1 where2,請用雙引號引起來"where1 where2"

alerter 部署和配置

  • 部署:
    (1). 獲取代碼

    git clone git@git.xxx.com:trade_architect/eagleye.git
    

    (2). 進入在eagleye-alerter程序根目錄

    cd eagleye/eagleye-alerter 
    

    (3). 在eagleye-alerter程序根目錄執行

    git -pull && mvn clean package -Dmaven.test.skip=true -U 
    

    完成后進入文件夾得到 項目壓縮包 eagleye-alerter-1.0.0-all.tar.gz

    (4). 解壓項目包

    (5). 執行啟動

    nohup ./start.sh  > /data/applogs/eagleye/service.log  2>&1  &
    
  • 關閉:
    需要手動kill掉程序進程,可以執行以下命令:

    ps -ef | grep 'com.xxx.eagleye.alerter.App' | grep -v 'grep' |  awk '{print $2}' | xargs  kill
    
  • 配置說明:
    由于alerter程序會和kafka,zookeeper集群進行通信, 所以程序運行前需要配置相關host, 配置如下:

    #kakfa cluster
    192.168.1.43 xx-xx-1
    192.168.1.46 xx-xx-2
    192.168.1.60 xx-xx-3
    192.168.1.67 xx-xx-4
    192.168.1.73 xx-xx-5
    

    loomContext.xml 中可以配置日志toipc kafka消費者的消費線程數(alerterConsumerThreadNum),alerter程序可以部署的最大實例數為 kafka日志topic分區數/alerterConsumerThreadNum.如果部署的程序實例數超過了最大實例數, 新的程序實例將會得消費不到得到topic分區, 不產生吞吐量.

  • 需要注意:

    (1). 需要替換conf/log4j.xml 中的日志文件目錄 , 和命令輸出日志目錄

    (2). 需要修改run.sh 中的變量IP 為服務器IP , HEAP_DUMP_PATH 為日志目錄的文件

    (3). 由于alerter即是kafka消費者, 又是kafka生產者, 為了避免死循環, 程序在打印描述性日志前都都加了'~', 創建alerter程序的預警規則時, 應當在規則中過濾日志內容第一個字符為'~'的情況

eagleye-admin部署

  • 執行附件腳本,初始化表.

  • 獲取代碼

    git clone git@git.xxx.com:trade_architect/eagleye.git
    
  • cd eagleye/

  • 編譯

    mvn clean; mvn -DskipTests package
    
  • 在tomcat中部署eagleye-admin/target/eagleye-admin.war包。

  • 初始用戶名密碼:admin/test

非java項目對接

如果非java服務想對接到該預警平臺, 請按照如下json格式:

   {
       "body": "日志內容",
       "head": {
           "app": "eagleye-test",
           "ip": "192.168.1.100",
           "level": "WARN",
           "pid": "3817"
       },
       "timestamp": 1426216784971
   }
   發送到kafka的 名為:EAGLEYE_LOG_CHANNEL 的topic中
   
   如果是直接接入其他非java的日志, 并且還不想格式化上述json,可以直接開啟一個logstash實例, 配置文件如下:
   input {
     file {
        path => ["/home/zhejava/logstash/logstash-1.4.2/temp/*.log"]
       # type => "system"
       # start_position => "beginning"
     }
   }
   
   
   filter {
     grok {
       match => { "message" => "" }
       add_field => {
           "head.app" => "logstash-test"
           "head.ip" => "192.168.5.177"
           "head.level" => "WARN"
           #"timestamp" => 1426237376377
           #"head" => "{'app' : 'eagleye-test-b','ip' : '192.168.5.244','level' : 'ERROR','pid' : '9744'}"
       }
   
       remove_field => [ "message" ]
     }
   }
   
   
   # 如果是入kafka請這么寫
   output {
     #stdout {
     #   codec => rubydebug
     #   #codec => plain
     #}
   
     kafka {
        #codec => plain {
        #   format => "%{body}"
        #}
        broker_list => "witgo:9092,spark:9092"
        topic_id => "EAGLEYE_LOG_CHANNEL"
   
     }
   }
   
   
   # 如果是入es 請這么寫,不推薦直接入es, 這樣就不能設置實時預警了
   output {
         elasticsearch {
         cluster => "eagleye_es"
         host => "localhost"
         port => "9301"
         protocol => "transport"
         index => "eagleye-log-%{+YYYY.MM.dd}"
         index_type => "log"
         workers => 2
         flush_size => 1000
         template_overwrite => true
         }
   }

其他

ES自定義檢索功能說明

  • elastic search建立索引時, 會使用現有詞典進行分詞, 如果用戶輸入的關鍵詞不在當前詞庫中, 將不會搜索到結果, 遇到這種情況, 建議用戶縮小關鍵詞粒度, 并使用多個關鍵詞進行查詢
  • 多個關鍵詞可以用空格分開

ES index template功能簡介

elasticsearch template 官方文檔

  • ES可用通過預先設置的template來指定即將創建索引的setting 和 mapping 設置
  • 使用方式:
    (1). 使用命令添加
    (2). 將 template模板 添加到 config/templates/ 目錄
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,622評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,716評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,746評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,991評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,706評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,036評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,029評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,203評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,725評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,451評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,677評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,161評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,857評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,266評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,606評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,407評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,643評論 2 380

推薦閱讀更多精彩內容