Day28 go-elasticsearch(二)

今日我们将要使用go-elasticsearch来搭配telegram完成讯息发送。

目标

前面章节我们有介绍过elk的警报器功能,但是由於是使用免费版本,所以就只是单纯的写入索引,来模拟实际发送警报。现在我们打算透过go-elasticsearch+telegram来实现将讯息发送到使用者。

事前准备

一、 需申请 telegram bot,详细申请步骤请参考连结
二、 使用 Kibana Alerting 建立范例要使用的索引it13-cpu

实作

接下范例是使用警报器产生的索引it13-cpu,所以资料就不用过滤,直接以时间为区间来搜寻,Query DSL语法结构如下:

{
  "query": {
    "bool": {
      "must": [
        {
          "range": {
            "@timestamp": {
              "from": "2021-10-05T03:53:08Z",
              "include_lower": true,
              "include_upper": true,
              "to": "2021-10-05T03:54:08Z"
            }
          }
        }
      ]
    }
  },
  "from": 0,
  "size": 20
}

完整范例程序

package main

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"time"

	"github.com/elastic/go-elasticsearch/v8"
	"github.com/elastic/go-elasticsearch/v8/esapi"
	tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
)

var (
	es  *elasticsearch.Client
	bot *tgbotapi.BotAPI
)

func setElkClient() {
	var err error
	cfg := elasticsearch.Config{
		Addresses: []string{"http://127.0.0.1:9200"},
	}
	es, err = elasticsearch.NewClient(cfg)
	if err != nil {
		panic(err)
	}
}

func setNewBotAPI() {
	var err error
	bot, err = tgbotapi.NewBotAPI("youToken")
	if err != nil {
		panic(err)
	}
	bot.Debug = false
}

func main() {
    //初始设定
	setElkClient()
	setNewBotAPI()
    //搜寻并发送讯息
	searchRequest()
}

func sendTelegramMsg(msg string) error {
	NewMsg := tgbotapi.NewMessage(chatID, msg) //传送讯息给使用者
	NewMsg.ParseMode = tgbotapi.ModeHTML
	_, err := bot.Send(NewMsg)
	if err != nil {
		return err
	}
	return nil
}

func searchRequest() {
	var r map[string]interface{}
	t := time.Now().UTC().Add(-1 * time.Minute).Format(time.RFC3339)
	nt := time.Now().UTC().Format(time.RFC3339)
    // 查询条件
	query := map[string]interface{}{
		"query": map[string]interface{}{
			"bool": map[string]interface{}{
				"must": []map[string]interface{}{
					{"range": map[string]interface{}{
						"@timestamp": map[string]interface{}{
							"from":          t,
							"to":            nt,
							"include_lower": true,
							"include_upper": true,
						},
					}},
				},
			},
		},
		"size": 20,
		"from": 0,
	}
	jsonBody, _ := json.Marshal(query)
	req := esapi.SearchRequest{
		Index: []string{"it13-cpu"}, // 索引名称
		Body:  bytes.NewReader(jsonBody),
	}
	res, err := req.Do(context.Background(), es)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	if err = json.NewDecoder(res.Body).Decode(&r); err != nil {
		panic(err)
	}

	for _, hit := range r["hits"].(map[string]interface{})["hits"].([]interface{}) {
		source := hit.(map[string]interface{})["_source"]
		message := source.(map[string]interface{})["message"].(string)
		if err = sendTelegramMsg(message); err != nil {
			fmt.Println("send msg error")
		}
	}
}

发送的讯息内容如下:
https://ithelp.ithome.com.tw/upload/images/20211005/20129762RO4Vxrabxs.png


<<:  Day 21 : 案例分享(6.4) 人事、差勤与薪资 - 薪资计算

>>:  总结 | ML#Day28

Android Studio 上传GitHub

GitHub 官方说明 we announced our intent to require the...

Kotlin Android 第19天,从 0 到 ML - RecyclerView 动态列表

前言: RecyclerView 可以轻松高效地显示大量数据。 RecyclerView回收这些单独...

ROS Moveit范例程序1

首先从Moveit官方的Tutorial开始。使用C++撰写机器手臂的控制。教材依据Move Gro...

Day 10 Summary 2

Introduction to embedded system Role of embedded s...

Day19 NodeJS-Express IV

前一篇说明了Express中的样板引擎与样板的使用,是比较偏向前端的部份,今天的主题是前端和後端资料...