kapacitor 邮件推送没生效

目录

influxdb+kapacitor

告警脚本

原因

解决

kapacitor.conf  smtp模块

kapacitor如何开启邮件推送服务

append smtp服务

开启smtp服务

 smtp 服务具体实现


influxdb+kapacitor

通过编写tickscript脚本,从influxdb查询cpu|mem|net|blkio|docker等metric,当满足告警条件的时候就触发邮件推送。

收件地址没有在kapacitor.conf里面配置,而是通过代码获取用户输入的邮箱。

也就是说,用户在页面上填了哪些收件地址,到时候告警邮件就推送到哪里。也就省了每次去修改kapacitor.conf的麻烦。

 

influxdb, kapacitor都是直接从docker hub拉的镜像,并不是自己用dockerfile生产的。

这个influxdb+kapacitor告警服务是原来就做好的功能,只是一直都没有触发过邮件推送,哪怕已经满足触发告警条件。

告警脚本

var tickScriptStr = `
stream
    |from()
        .measurement('xx') // 指定measurement
        .where(lambda: "condition" == '#condition#') // 指定查询条件,#condition#的具体值在代码里面会被替换
    |window()
        .period(#span#s) // #span#会在代码里面替换
        .every(#span#s)
    |mean('xx') // 取的是当前measurement里面xx field的平均值
    |eval(lambda: 100.0 - "xx") // 这里是由于百分比,所以这里用了100-
        .as('used') 
    |alert()
        .message('dc: #dc# | host: #host# | type: cpu | {{ .Level}}: high cpu usage - {{ index .Fields "used" }}')
        .warn(lambda: "used" > #threshold#.0) // #threshold#在代码里面赋值
        .post('#arecord#') // 这里把告警信息post到某个http服务器
        .log('/root/alerts.log')` // 这里把告警日志存入容器的/root/alerts.log里面

脚本里面没有关于邮件收件地址的信息,是由于在代码里面动态加载的,获取用户输入的邮箱,再在tickSCRIPT脚本里面拼接。

类似这样: .email("aaa@aa")

原因

结合kapacitor 邮件推送文档:https://docs.influxdata.com/kapacitor/v1.5/event_handlers/email

与公司已有的kapacitor.conf,发现没有邮件推送是由于公司使用的kapacitor.conf,并没有enable [smtp]模块。

解决

根据[stmp]模块,是需要smtp服务器的host, port, username, password

问相关同事得到了公司邮件服务器host, port,由于是测试,username+password暂时用的自己的。

由于同事给的邮件服务器host,port不对,我调试了一下午。没有任何相关err  log,还去看了/var/log/messages,也没发现什么相关err。

看了kapacitor源码,在邮件推送相关模块只有出错才会打印日志。

问了几个同事,每个同事给的host + port都没有实现邮件推送。

后来问了之前做这个模块的同事,他说port应该是25,赶紧把端口改25测试,这下终于出现err log了。

err log很明显,已经明确告诉我host不对。

把host修改了,port改为25, ok了,邮件能正常推送了。

kapacitor.conf  smtp模块

[smtp]
  enabled = true  // 一定要启用,设置为true
  host = "公司的邮件服务器host"
  port = 25
  username = "公司某个邮件账号,也可以是你自己的邮件账号"
  password = "与username对应的密码"
  no-verify = false // 这个我使用的默认的false,没有修改
  global = false 
  state-changes-only = false
  from = "发件人的地址"
  idle-timeout = "30s"

kapacitor如何开启邮件推送服务

append smtp服务

kapacitor服务启动的时候会append smtp服务

代码位置:github.com/influxdata/kapacitor/cmd/kapacitord/run/commond.go 

// Run parses the config from args and runs the server.
func (cmd *Command) Run(args ...string) error {
    ...
    s, err := server.New(config, buildInfo, cmd.logService)
	if err != nil {
		return fmt.Errorf("create server: %s", err)
	}
    ...
    if err := s.Open(); err != nil {
		return fmt.Errorf("open server: %s", err)
	}
    ...
}

查看server.New()
// New returns a new instance of Server built from a config.
func New(c *Config, buildInfo BuildInfo, logService logging.Interface) (*Server, error) {
    ...
    s.appendSMTPService()
    ...
}

开启smtp服务

代码位置:github.com/influxdata/kapacitor/server/server.go

// Open opens all the services.
func (s *Server) Open() error {
    ...
    if err := s.startServices(); err != nil {
		s.Close()
		return err
	}
    ...
}

// service.Open()是一个interface,根据各自service的实现取开启各自的服务
func (s *Server) startServices() error {
    ...
    if err := service.Open(); err != nil {
			return fmt.Errorf("open service %T: %s", service, err)
	}
    ...
}

 smtp 服务具体实现

// stmp service open
func (s *Service) Open() error {
	s.mu.Lock()
	defer s.mu.Unlock()
	if s.opened {
		return nil
	}
	s.opened = true

	s.mail = make(chan *gomail.Message)

	s.wg.Add(1)
	go func() {
		defer s.wg.Done()
		s.runMailer()
	}()

	return nil
}

func (s *Service) runMailer() {
	var idleTimeout time.Duration
	var d *gomail.Dialer
	d, idleTimeout = s.dialer()

	var conn gomail.SendCloser
	defer func() {
		if conn != nil {
			conn.Close()
		}
	}()

	var err error
	open := false
	for {
		timer := time.NewTimer(idleTimeout)
		select {
		case <-s.updates:
			// Close old connection
			if conn != nil {
				if err := conn.Close(); err != nil {
					s.logger.Println("E! error closing connection to old SMTP server:", err)
				}
				conn = nil
			}
			// Create new dialer
			d, idleTimeout = s.dialer()
			open = false
		case m, ok := <-s.mail:
			if !ok {
				return
			}
			if !open {
				if conn, err = d.Dial(); err != nil {
					s.logger.Println("E! error connecting to SMTP server", err)
					break
				}
				open = true
			}
			if err := gomail.Send(conn, m); err != nil {
				s.logger.Println("E!", err)
			}
		// Close the connection to the SMTP server if no email was sent in
		// the last IdleTimeout duration.
		case <-timer.C:
			if open {
				if err := conn.Close(); err != nil {
					s.logger.Println("E! error closing connection to SMTP server:", err)
				}
				open = false
			}
		}
		timer.Stop()
	}
}

当AlertNode使用过滤(info, warn, crit)消息级别的时候会发现, 即使你直用了warn()但是有时候你收到的推送除了有WARNING还会有OK级别的,这是kapacitor内置的,原文在这:

https://docs.influxdata.com/kapacitor/v1.5/nodes/alert_node/#alert-event-data

这里明确说明了

Events are sent to handlers if the alert is in a state other than ‘OK’ or the alert just changed to the ‘OK’ state from a non ‘OK’ state (a.k.a. the alert recovered). Using the AlertNode.StateChangesOnly property events will only be sent to handlers if the alert changed state.

 

我看有好多与emil推送相关的问题。

https://github.com/influxdata/kapacitor/issues/1471

https://github.com/influxdata/kapacitor/issues/1472

https://github.com/influxdata/kapacitor/issues/805

https://github.com/influxdata/kapacitor/issues/716

https://github.com/influxdata/kapacitor/issues/602

https://github.com/influxdata/kapacitor/issues/607

https://github.com/influxdata/kapacitor/issues/278

httpport没生效:https://github.com/influxdata/kapacitor/issues/2212

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值