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
将request的body中的数据,自动按照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")
}
|