Skywalking配置告警触发

Skywalking安装好了,大致的指标也看了,告警规则也看了,剩下的就是研究下如何将告警信息发出去,不可能人工一直盯着浏览器去看,因此及时触发告警是个好办法,比如:在调用某个接口的时候出现了响应超时,超过了预期范围,那么此时就可以触发告警,及时去排查接口情况

告警触发的配置也是在alarm-settings.yml文件中,在最下面,如下:

hooks:
  webhook:
    default:
      is-default: true
      urls:
        - http://192.168.51.15:8866/alarm
#        - http://127.0.0.1/go-wechat/

其中的urls里面配置的就是告警的url,如果有多个,可以写多个,我这里写的一个,是我自己写的告警接收接口,要自定义告警接收接口,首先要知道告警后发送出来的数据是什么格式,通过程序获取,格式为JSON类型,如下:

[{  "scopeId": 6,  "scope": "ENDPOINT_RELATION",  "name": "User in User to POST:/cmb/restartContract in test_name",  "id0": "VXNlcg==".0_VXNlcg==",  "id1": "enlsY190ZXN0.1_UE9TVDovY21iL3Jlc3RhcnRDb250cmFjdA==",  "ruleName": "endpoint_relation_75_rule",  "alarmMessage": "endpoint relation percentile User in User to POST:/cmb/restartContract in zylc_test is less than 5000ms",  "tags": [],  "startTime": 1763028144347,  "hooks": ["webhook.default"]}]

    scopeId:监控范围的ID,6代表端点关系(Endpoint Relation),SkyWalking常用scopeId对照表:

    • Service(服务)
    • Service Instance(服务实例)
    • Endpoint(端点)
    • Endpoint Relation(端点关系)
    • Service Relation(服务关系)

    scope监控范围的名称,表示这是端点关系级别的监控

    name: 端点关系的描述名称

    • 格式[源端点] in [源服务] to [目标端点] in [目标服务] (这个目标服务就是agent启动的时候指定的服务名)

    id0:  经过Base64编码的端点关系标识符,表示源端点的编码标识

    id1: 经过Base64编码的端点关系标识符,表示目标端点的编码标识

    ruleName:触发告警的规则名称,也就是在alarm-settings.yml中定义的名称

    alarmMessage:告警的详细描述信息,这个才是重点

    tags:标签信息,用于附加元数据

    • 用途:可以包含自定义标签,如环境、区域等信息
    • 示例:[“env:prod”, “region:us-east”]

    startTime:告警触发的时间戳,Unix时间戳(毫秒)

    hooks:告警触发的钩子列表,定义告警要发送到的处理端点

    在本例子中,我是将告警信息发送到了自定义的脚本接口中,通过邮件实现告警,golang脚本如下:

    package main
    
    import (
    "encoding/json"
    "fmt"
    "github.com/gin-gonic/gin"
    "github.com/jordan-wright/email"
    "gopkg.in/yaml.v2"
    "io/ioutil"
    "log"
    "net/smtp"
    "time"
    )
    
    type test struct {
    	ScopeID      int
    	Scope        string
    	Name         string
    	ID0          string
    	ID1          string
    	RuleName     string
    	AlarmMessage string
    	Tags         []string
    	StartTime    int
    	Hooks        []string
    }
    type mailConfig struct {
    	Send_mail    string   //发件人
    	Recv_mail    []string //收件人,可以多个,所以用字符串切片
    	Cc_mail      []string //抄送人,也可以多个
    	Smtp_address string   //smtp服务器地址
    	Smtp_port    int      //smtp端口
    	Auth_code    string   //授权码
    }
    
    func createMail() *mailConfig {
    var mc *mailConfig
    	by, err := ioutil.ReadFile("/etc/monitor.yaml")
    if err != nil {
    		log.Fatal(err)
    	}
    	err = yaml.Unmarshal(by, &mc)
    if err != nil {
    		fmt.Println(1000)
    		log.Fatal(err)
    	}
    return mc
    }
    func sendmail(id int, scope, name, ruleName, alarmMessage, startTime, alarmStatus string) {
    	mc := createMail()
    	e := email.NewEmail()
    //设置发送方的邮箱
    	e.From = mc.Send_mail
    // 设置接收方的邮箱
    	e.To = mc.Recv_mail
    	e.Cc = mc.Cc_mail
    //设置主题
    	e.Subject = alarmStatus
    //设置文件发送的内容
    	text := fmt.Sprintf("监控范围ID:  %d\n监控范围名称:  %s\n监控端点名称:  %s\n告警规则名:  %s\n告警详细信息:  %s\n告警时间:  %s\n", id, scope, name, ruleName, alarmMessage, startTime)
    	e.Text = []byte(text)
    //设置服务器相关的配置
    	e.Send(fmt.Sprintf("%s:%d", mc.Smtp_address, mc.Smtp_port), smtp.PlainAuth("", mc.Send_mail, mc.Auth_code, mc.Smtp_address))
    
    }
    
    // 将时间戳转换为标准时间
    func timestamp(t int) string {
    	beijingTime := time.UnixMilli(int64(t)).In(time.FixedZone("CST", 8*60*60))
    return beijingTime.Format("2006年01月02日 15时04分05秒")
    }
    func main() {
    	r := gin.New()
    	r.POST("/alarm", func(c *gin.Context) {
    var t []test
    //获取原始数据,实际是一个[]uint8类型,也就是[]byte类型,可直接反序列化到结构体即可
    		by, err := c.GetRawData()
    if err != nil {
    			log.Fatal(err)
    		}
    		err = json.Unmarshal(by, &t) //反序列化到结构体中 
    if err != nil {
    			log.Fatal(err)
    		}
    		id := t[0].ScopeID
    		scope := t[0].Scope
    		name := t[0].Name
    		ruleName := t[0].RuleName
    		alarmMessage := t[0].AlarmMessage
    		startTime := timestamp(t[0].StartTime)
    		alarmStatus := "SKywalking告警触发!!!!!!!"
    		sendmail(id, scope, name, ruleName, alarmMessage, startTime, alarmStatus)
    	})
    	r.Run(":8866")
    }

    注:实际告警信息中并没有包含ID0、ID1、tags、hooks,因为这些都是非必要信息,当然如果需要可自定修改脚本添加上

    邮件的配置文件monitor.yml内容如下:

    #发件人
    send_mail: abcd@qq.com
    #收件人邮箱,可写多个
    recv_mail:
      - 111111@qq.com
    #抄送人邮箱
    cc_mail:
      - 2222222@outlook.com 
    #smtp服务器地址
    smtp_address: smtp.qq.com
    #smtp端口
    smtp_port: 25
    #授权码
    auth_code: adfdtvteisffeff

    启动脚本后,触发告警,查看邮箱告警内容如图:

    标签