Featured image of post Gin编写邮件告警接口(添加优化日志记录)

Gin编写邮件告警接口(添加优化日志记录)

的编程实现邮件接口报警编写邮件接口支持多人发送这个代码基于上面两个已经完成的功能上实现。实现下面功能日志分割日志记录效果图因为日常范围,我们在操作系统上,需要报警时,只能采用来使用。需要配置账号,密码。。。。。。。

GO的WEB编程(GIN实现邮件接口报警)

Gin编写邮件接口(支持多人发送)

这个代码基于上面两个已经完成的功能上实现。

实现下面功能

日志分割

日志记录

效果图

        

 

 

因为日常范围,我们在操作系统上,需要报警时,只能采用mailx来使用。需要配置账号,密码,和邮箱认证。如果需要多台使用的话,岂不是很麻烦,要配置多台,这个导致密码很不安全,容易泄露。所以,为了安全,有效,更方便,我们可以采用接口发送邮件。

(1)构建接口

(2)传入post的json情况

(3)把相应json转换字符

(4)发送邮件

代码放在一个main。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
package main

import (
	"fmt"
	"net/http"
	"net/smtp"
	"strings"

	"github.com/gin-gonic/gin"
	"github.com/natefinch/lumberjack"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

/*
支持多人发送
curl http://10.10.10.3:7070/send -H "Content-Type:application/json" -X POST -d '{"source":"heian","contacts":["账号@qq.com","账号@qq.com"],"subject":"多人测试","content":"现在进行多人测试"}'

*/

/*
zapcore.Core需要三个配置——Encoder,WriteSyncer,LogLevel
Encoder:编码器(如何写入日志)。我们将使用开箱即用的NewJSONEncoder()
WriterSyncer :指定日志将写到哪里去。我们使用zapcore.AddSync()
Log Level:哪种级别的日志将被写入。
*/
var sugarLogger *zap.SugaredLogger

func InitLogger() {
	writeSyncer := getLogWriter()
	encoder := getEncoder()
	core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel)

	logger := zap.New(core, zap.AddCaller())
	sugarLogger = logger.Sugar()
}

func getEncoder() zapcore.Encoder {
	encoderConfig := zap.NewProductionEncoderConfig()
	encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
	encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
	return zapcore.NewConsoleEncoder(encoderConfig)
}

func getLogWriter() zapcore.WriteSyncer {
	/*
		Lumberjack Logger采用以下属性作为输入:

		Filename: 日志文件的位置
		MaxSize:在进行切割之前,日志文件的最大大小(以MB为单位)
		MaxBackups:保留旧文件的最大个数
		MaxAges:保留旧文件的最大天数
		Compress:是否压缩/归档旧文件
	*/
	lumberJackLogger := &lumberjack.Logger{
		Filename:   "./logs/info.log",
		MaxSize:    10,
		MaxBackups: 5,
		MaxAge:     30,
		Compress:   false,
	}
	return zapcore.AddSync(lumberJackLogger)

}

// 定义接收数据的结构体
type User struct {
	// binding:"required"修饰的字段,若接收为空值,则报错,是必须字段
	Source   string   `form:"source" json:"source" uri:"source" xml:"source" binding:"required"`
	Contacts []string `form:"contacts" json:"contacts" uri:"contacts" xml:"contacts" binding:"required"`
	Subject  string   `form:"subject" json:"subject" uri:"subject" xml:"subject" binding:"required"`
	Content  string   `form:"content" json:"content" uri:"content" xml:"content" binding:"required"`
}

func SendToMail(user, sendUserName, password, host, to, subject, body, mailtype string) error {
	hp := strings.Split(host, ":")
	//fmt.Println(hp)
	auth := smtp.PlainAuth("", user, password, hp[0])
	var content_type string
	if mailtype == "html" {
		content_type = "Content-Type: text/" + mailtype + "; charset=UTF-8"
	} else {
		content_type = "Content-Type: text/plain" + "; charset=UTF-8"
	}

	msg := []byte("To: " + to + "\r\nFrom: " + sendUserName + "<" + user + ">" + "\r\nSubject: " + subject + "\r\n" + content_type + "\r\n\r\n" + body)
	send_to := strings.Split(to, ";")
	err := smtp.SendMail(host, auth, user, send_to, msg)
	//fmt.Println(err)
	return err
}

//获取ip
func GetRequestIP(c *gin.Context) string {
	reqIP := c.ClientIP()
	if reqIP == "::1" {
		reqIP = "127.0.0.1"
	}
	return reqIP
}
func PostMail(c *gin.Context) {
	c_ip := GetRequestIP(c)
	//fmt.Println(c_ip)
	sugarLogger.Debugf("调用 PostMail 接口Api,调用者IP: %s ", c_ip)
	 声明接收的变量
	var json User
	 requestbody中的数据,自动按照json格式解析到结构体
	//
	if err := c.ShouldBindJSON(&json); err != nil {
		//	// 返回错误信息
		//	// gin.H封装了生成json数据的工具
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		sugarLogger.Errorf("Error: %s", err.Error())
		return
	}
	//fmt.Println(json.Content, json.Contacts)
	//c.JSON(http.StatusOK, gin.H{"status": &json})
	sugarLogger.Infof("info: %s", json)
	user := "账号@qq.com"
	password := "密码"
	host := "smtp.qq.com:25"
	source := json.Source
	if source != "heian" {
		fmt.Println("Send mail error!,source 认证失败")
		sugarLogger.Errorf("Send mail error!,source 认证失败")
		c.JSON(http.StatusOK, gin.H{
			"error": "Send mail error!,source 认证失败",
		})
		return
	}
	//println(json.Contacts)
	to := json.Contacts
	if to[0] == "" {
		fmt.Println("Send mail error!,发送人为空")
		sugarLogger.Errorf("Send mail error!,发送人为空")
		c.JSON(http.StatusOK, gin.H{
			"error": "Send mail error!,发送人为空",
		})
		return
	}
	subject := json.Subject
	if strings.TrimSpace(subject) == "" {
		fmt.Println("Send mail error!标题为空")
		sugarLogger.Errorf("Send mail error!标题为空")
		c.JSON(http.StatusOK, gin.H{
			"error": "Send mail error!,标题为空",
		})
		return
	}
	body := `
		<!DOCTYPE html>
		<html lang="en">
		<head>
			<meta charset="iso-8859-15">
			<title>MMOGA POWER</title>
		</head>
		<body>
			` + fmt.Sprintf(json.Content) +
		`</body>
		</html>`

	sendUserName := "告警平台" //发送邮件的人名称
	fmt.Println("send email")

	for _, s := range to {
		//fmt.Println(i, s)
		err := SendToMail(user, sendUserName, password, host, s, subject, body, "html")
		//log.Printf("接收人:", s+"\n"+"标题:", json.Subject+"\n", "发送内容:", json.Content+"\n")
		fmt.Printf("接收人:%s \n 标题: %s \n 内容: %s \n", s, json.Subject, json.Content)
		sugarLogger.Infof("接收人: %s ,标题: %s, 内容: %s", s, json.Subject, json.Content)
		if err != nil {
			fmt.Println("Send mail error!\n")
			sugarLogger.Errorf("Error 调用者IP: %s ,Send mail error! !", c_ip)
			c.JSON(http.StatusOK, gin.H{
				"error": "Send mail error! !\n",
			})
			//fmt.Println(err)
		} else {
			fmt.Println("Send mail success!\n")
			sugarLogger.Infof("success 调用者IP: %s ,Send mail success! !", c_ip)
			c.JSON(http.StatusOK, gin.H{
				"success": "Send mail success! !\n",
			})
		}

	}

}

func main() {
	// 1.创建路由
	// 默认使用了2个中间件Logger(), Recovery()
	InitLogger()
	defer sugarLogger.Sync()
	r := gin.Default()
	// JSON绑定
	r.POST("send", PostMail)
	sugarLogger.Infof("Success! Port is start")
	r.Run(":7070")

}

未来的你,会感谢今天仍在努力奋斗的你