先行レビュー
我々は以前、ログ監視、ログ収集、ホット更新の構成、コルーチンダイナミックの起動とシャットダウンを含むログ収集システムの基本的な機能を、完了、およびetcd管理ファイルパスのサポートを拡大しました。
このセクションターゲット
この新しいセクションログクエリと検索機能を提供します。基本的な考え方はelasticsearchは、分散型マルチユーザー機能で、情報がカフカ、その後入れelasticsearchから読み込まれますログインすることで
、それは私たちが提供し、指定されたデータを照会することができるアクセスへのフルテキスト検索エンジン、Webインターフェイスの。さらに、容易に検索および照会する弾性kibana視覚で利用することができる
クエリ。KibanaはElasticsearch設計のためのオープンソースの解析と可視化プラットフォームです。
ソースコードの実装
カフカログからの読み取りと弾性機能のこの部分を解析するために書かれた、私たちは別のプロセスにそれを洗練し、独立したプロセスは、データの監視を開始カフカ。
メインパッケージ インポート( "FMT" kafconsumer "をgolang- / logcatchsys / kafconsumer" "golang- / logcatchsys / logconfig" ) 、 メイン(){FUNC V:= logconfig.InitVipper() もしV ==ゼロ{ fmt.Println(「VIPPER initは失敗した!」) のリターン } kafconsumer.GetMsgFromKafka() }
主な機能は、GetMsgFromKafka私がメッセージを読む機能がkafconsumerパッケージをカプセル化呼び出します。
GetMsgFromKafka FUNC(){ fmt.Println( "カフカ消費始まる...") 設定:= sarama.NewConfig() config.Consumer.Return.Errors =真 のvar kafkaddr = "localhostを:9092" kafkaconf、_:= logconfig。 ReadConfig(logconfig.InitVipper()、 "kafkaconfig.kafkaaddr") であればkafkaconf =ゼロ{! kafkaddr = kafkaconf(列)。 } //创建消费者 消費者、ERR = sarama.NewConsumer([]の文字列{kafkaddr}、コンフィグ) !場合ERR =ゼロ{ fmt.Println( "消費者は作成できませんでした、エラーがある"、err.Error()) リターン } 延期FUNC(消費者sarama.Consumer){ ERR場合:=回復()。ERR!= nilの{ fmt.Println( "消費者のパニックエラー"、 consumer.Close() のTopicSet =ゼロ //回收所有协程 のため_、ヴァル=レンジtopicMap { _ため、VALT:=レンジヴァル{ valt.Cancel() } } topicMap =ゼロ }(消費者) topicSetTmp:= ConstructTopicSet () もしtopicSetTmp ==ゼロ{ fmt.Println( "コンストラクトトピック・セット・エラー") リターン } のTopicSet = topicSetTmp ConsumeTopic(消費者) }
GetMsgFromKafkaはカフカの消費者で作成し、その後、ConstructTopicSetは、構成に応じてトピックのコレクションを構築し、コールのTopicSetコレクションは、実際にマップされ
話題を集めたが繰り返されていないことを確認します。そして、カフカConsumeTopicトピックからデータを取得するための関数を呼び出します。
FUNC ConstructTopicSet()マップ[ストリング] BOOL { topicSetTmp:=メイク(地図[ストリング] BOOL) configtopics、_:= logconfig.ReadConfig(logconfig.InitVipper() "は、collectlogs") 場合configtopics ==ゼロ{ CONFTOPIC後藤 } ため_、configtopic:([]インターフェイス{}){=レンジconfigtopics = configtopic(マップ[インターフェイス{}]インターフェイス{})。confmap キー、ヴァルのために:=レンジconfmap { キーIF(列)== " logtopic」{ topicSetTmp [ヴァル(文字列)] = TRUE } } } CONFTOPIC: リターンtopicSetTmp }
ConstructTopicSetは、構成トピックのリストを読み、[トピックにマップを返します。
FUNC ConsumeTopic(消費者sarama.Consumer){ キーについては、_:=範囲のTopicSet { partitionList、ERR:= consumer.Partitions(キー) ERRの場合= nilの{! fmt.Println( "消費者のパーティションに障害が発生し得る") fmt.Println( "エラーがある"、err.Error()) 続ける } パーティションに:=範囲partitionList { PC、ERR = consumer.ConsumePartition(キー、INT32(パーティション)、sarama.OffsetNewest) ERR =ゼロ{なら! fmt.Println( "消費パーティションエラーがある"、err.Error())が 継続 } 延期pc.AsyncClose() :=新しい(TopicData)topicData )topicData.Ctx、topicData.Cancel = context.WithCancel(context.Background() topicData.KafConsumer =パソコン topicData.TPartition =新しい(TopicPart) topicData.TPartition.Partition = INT32(パーティション) topicData.TPartition.Topic =鍵 _、OKM = topicMap [キー] !場合OKM { topicMap [キー] =メイク(地図[INT32] * TopicData) } topicMap [キー] [ INT32(パーティション)] = topicData 外出ReadFromEtcd(topicData) } } {用 {選択 = <-topicChan:ケースtopicpart fmt.Printfを( "ゴルーチンが終了受信トピックパーティションが%D \ nは、%sである" topicpart。トピック、topicpart.Partition) //重启消费者读取数据的协程 ヴァル、[OK]:= topicMap [topicpart.Topic] であれば、{OK! 続ける } TP、[OK]:= valの[topicpart.Partition] であればOK {! 引き続き } tp.Ctx、tp.Cancel = context.WithCancel(context.Background()) 行きReadFromEtcd(TP) } } }
ConsumeTopic実際のトピックは、マップトラバーサル話題に設定してから、メッセージを読むためにコルーチンReadFromEtcd通話機能を開始しています。
ReadFromEtcd(topicData * TopicData)funcを{ fmt.Printfは(topicData.TPartition.Topic、 "カフカ消費者がメッセージを読んで始め、トピックは%sで、一部は%D \ nが" topicData.TPartition.Partition) ロガー:=ログ。新(os.Stdout、 "LOGCAT"、log.LstdFlags | log.Lshortfile) elastiaddr、_:= logconfig.ReadConfig(logconfig.InitVipper()、 "elasticconfig.elasticaddr") であればelastiaddr == nilの{ elastiaddr =「localhostを: 9200" } esClient、ERR:= elastic.NewClient(elastic.SetURL( "のhttp://" + elastiaddr(文字列))、 elastic.SetErrorLog(ロガー))! 誤る場合= nilの{ //エラー処理の logger.Println ( "elesticクライアントエラーを作成する"、err.Error()) リターン } 情報、コード、ERR:= esClient.Ping( "のhttp://"。+ elastiaddr(文字列))。ド(context.Background()) !もしERR = nilの{ logger.Println( "elestic検索のpingエラー、" 、err.Error()) esClient.Stop() esClient =ゼロ 復帰 } fmt.Printf(コード、info.Version.Number) "Elasticsearchはコード%dとバージョン%S \ Nで返さ" esversion、ERR = esClient .ElasticsearchVersion( "のhttp://"。+ elastiaddr(文字列)) !もしERR = nilの{ fmt.Println( "elestic検索バージョンが失敗します"、err.Error()) esClient.Stop() esClient = nilの リターン } fmt.Printf( "Elasticsearchバージョン%S \ n"は、esversion) 延期FUNC(弾性esClient *。クライアント){ ERR場合:=(回復)。ERR! fmt.Printf( "消費者メッセージパニック%S、トピックは%sで、一部は%D \ n"は、ERR、 topicData.TPartition.Topic、topicData.TPartition.Partition) topicChan < - topicData.TPartition } }(esClient) VAR typestr = "catlog" typeconf、_:= logconfig.ReadConfig(logconfig.InitVipper()、 "elasticconfig.typestr") であればtypeconf =ゼロ{! typestr = typeconf(列)。 } {ための 選択{ ケースMSG、OK:= <-topicData.KafConsumer.Messages(): !もしOK { fmt.Println( "etcdメッセージちゃん閉") リターン } fmt.Printf(" %sの---パーティションた:%d、オフセット:% D、キー:%sの、 msg.Topic、msg.Partition、msg.Offset、ストリング(msg.Key)、ストリング(msg.Value)) idstr = strconv.FormatInt(Int64型(msg.Partition)、10)+ strconv.FormatInt(msg.Offset 、10) LOGDATA:=&LOGDATA {トピック:msg.Topic、ログ:列(msg.Value)、イド:idstr} CREATEINDEX、ERR:= esClient.Index()インデックス(msg.Topic).TYPE(typestr)。 ID(idstr).BodyJson(LOGDATA).doという(context.Background()) ERRなら!=ゼロ{ logger.Println( "インデックスを作成できませんでした"、err.Error()) 続ける } fmt.Println(「インデックスを作成成功、」、CREATEINDEX) ケース<-topicData.Ctx.Done(): fmt.Println( "!親ゴルーチンから出た受信") のリターン } } }
コルーチン衝突通知が親コルーチンに送信される場合、コルーチンを再開しながら、ReadFromEtcd機能は、弾性カフカに読み出したデータを書き込みます。
結果は
我々はプログラムを監視し、ログを起動し、情報処理プログラムは、現在設計されて開始する前に。
あなたが見ることができる場合は常にログはプログラムチェンジ情報の書き込みカフカを監視し、ログに書き込まれています。
一方、情報処理プログラムは、連続弾性カフカライトからデータを読み出します。私たちは、データを照会kibana
ソースのダウンロード
https://github.com/secondtonone1/golang-/tree/master/logcatchsysは
私の社会的関心号に感謝します