Browse Source

monitor urls status

haiswork 5 years ago
parent
commit
825294b20b
7 changed files with 138 additions and 1 deletions
  1. 18
    0
      .env.example
  2. 18
    0
      cmd/monitor/monitor.go
  3. 10
    1
      config/config.go
  4. 2
    0
      main.go
  5. 27
    0
      service/notice/email.go
  6. 55
    0
      service/service.go
  7. 8
    0
      service/store/cache/cache.go

+ 18
- 0
.env.example View File

@@ -0,0 +1,18 @@
1
+# dotenv file example
2
+# copy it to .env and change the config
3
+
4
+# App
5
+MONITOR_APP_DEBUG=true
6
+MONITOR_APP_SECRET=123456
7
+
8
+# NOTICE
9
+
10
+# SMTP
11
+MONITOR_NOTICE_SMTP_HOST=host
12
+MONITOR_NOTICE_SMTP_USER=user
13
+MONITOR_NOTICE_SMTP_PASSWORD=password
14
+MONITOR_NOTICE_EMAILS=466100496@qq.com
15
+
16
+# MONITOR
17
+MONITOR_MONITOR_TIMEOUT=500
18
+MONITOR_MONITOR_URLS=http://www.baidu.com;http://www.links123.com

+ 18
- 0
cmd/monitor/monitor.go View File

@@ -0,0 +1,18 @@
1
+package monitor
2
+
3
+import (
4
+	"git.links123.net/links123.com/monitor_status/service"
5
+	"github.com/spf13/cobra"
6
+)
7
+
8
+func RunCommand() *cobra.Command {
9
+	cmd := &cobra.Command{
10
+		Use:   "monitor",
11
+		Short: "Run the monitor service",
12
+		RunE: func(cmd *cobra.Command, args []string) error {
13
+			return service.Monitor()
14
+		},
15
+	}
16
+
17
+	return cmd
18
+}

+ 10
- 1
config/config.go View File

@@ -23,6 +23,10 @@ type appConfig struct {
23 23
 		Debug  bool   `mapstructure:"debug"`
24 24
 		Secret string `mapstructure:"secret"`
25 25
 	} `mapstructure:"app"`
26
+	Monitor struct {
27
+		Timeout int64  `mapstructure:"timeout"`
28
+		URLs    string `mapstructure:"urls"` // url_1;url_2
29
+	}
26 30
 	Notice struct {
27 31
 		SMTP struct {
28 32
 			Host     string `mapstructure:"host"`
@@ -30,7 +34,7 @@ type appConfig struct {
30 34
 			User     string `mapstructure:"user"`
31 35
 			Password string `mapstructure:"password"`
32 36
 		} `mapstructure:"smtp"`
33
-		URLs []string `mapstructure:"urls"`
37
+		Emails string `mapstructure:"emails"`
34 38
 	} `mapstructure:"notice"`
35 39
 }
36 40
 
@@ -50,6 +54,11 @@ func init() {
50 54
 	viper.SetDefault("notice.smtp.port", "port")
51 55
 	viper.SetDefault("notice.smtp.user", "user")
52 56
 	viper.SetDefault("notice.smtp.password", "password")
57
+	viper.SetDefault("notice.emails", "")
58
+
59
+	// monitor
60
+	viper.SetDefault("monitor.timeout", 500)
61
+	viper.SetDefault("monitor.urls", "")
53 62
 
54 63
 	// bind env
55 64
 	viper.SetEnvPrefix("monitor")

+ 2
- 0
main.go View File

@@ -2,6 +2,7 @@ package main
2 2
 
3 3
 import (
4 4
 	"git.links123.net/links123.com/monitor_status/cmd/http"
5
+	"git.links123.net/links123.com/monitor_status/cmd/monitor"
5 6
 	"git.links123.net/links123.com/monitor_status/cmd/version"
6 7
 	"github.com/spf13/cobra"
7 8
 )
@@ -19,6 +20,7 @@ func main() {
19 20
 	}
20 21
 
21 22
 	rootCmd.AddCommand(http.RunCommand())
23
+	rootCmd.AddCommand(monitor.RunCommand())
22 24
 	rootCmd.AddCommand(version.RunCommand(apiVersion, gitCommit, built))
23 25
 
24 26
 	if err := rootCmd.Execute(); err != nil {

+ 27
- 0
service/notice/email.go View File

@@ -0,0 +1,27 @@
1
+package notice
2
+
3
+import (
4
+    "net/smtp"
5
+    "strings"
6
+    "git.links123.net/links123.com/monitor_status/config"
7
+)
8
+
9
+func SendEmailBySMTP(subject, email, content string, html bool) error {
10
+    user := config.C.Notice.SMTP.User
11
+    host := config.C.Notice.SMTP.Host
12
+    port := config.C.Notice.SMTP.Port
13
+    pass := config.C.Notice.SMTP.Password
14
+
15
+    auth := smtp.PlainAuth("", user, pass, host)
16
+
17
+    contentType := "Content-Type:text/plain;charset=UTF-8"
18
+    if html {
19
+        contentType = "Content-Type:text/html;charset=UTF-8"
20
+    }
21
+
22
+    msg := []byte("To: " + email + "\r\nFrom: " + user + ">\r\nSubject: " + subject + "\r\n" + contentType + "\r\n\r\n" + content)
23
+
24
+    to := strings.Split(email, ";")
25
+
26
+    return smtp.SendMail(strings.Join([]string{host, port}, ":"), auth, user, to, msg)
27
+}

+ 55
- 0
service/service.go View File

@@ -1 +1,56 @@
1 1
 package service
2
+
3
+import (
4
+	"fmt"
5
+	"net/http"
6
+	"strings"
7
+	"time"
8
+
9
+	"git.links123.net/links123.com/monitor_status/config"
10
+	"git.links123.net/links123.com/monitor_status/service/notice"
11
+	"git.links123.net/links123.com/monitor_status/service/store/cache"
12
+)
13
+
14
+var httpClient = &http.Client{
15
+	Timeout: 10 * time.Second,
16
+}
17
+
18
+func Monitor() error {
19
+	urls := strings.Split(config.C.Monitor.URLs, ";")
20
+	for {
21
+		monitorStep(urls)
22
+
23
+		time.Sleep(10 * time.Second) //10s 间隔
24
+	}
25
+	return nil
26
+}
27
+
28
+func monitorStep(urls []string) {
29
+	for _, url := range urls {
30
+		err := monitorURL(url)
31
+		if cache.CheckMonitor(url, err) {
32
+			if err != nil {
33
+				notice.SendEmailBySMTP("url error", config.C.Notice.Emails, err.Error(), false)
34
+			} else {
35
+				notice.SendEmailBySMTP("url return ok", config.C.Notice.Emails, "return ok", false)
36
+			}
37
+		}
38
+	}
39
+}
40
+
41
+func monitorURL(url string) error {
42
+	startTime := time.Now()
43
+	resp, err := httpClient.Get(url)
44
+	if err != nil {
45
+		return err
46
+	}
47
+	defer resp.Body.Close()
48
+	if resp.StatusCode != http.StatusOK {
49
+		return fmt.Errorf("status code:%d url:%s", resp.StatusCode, url)
50
+	}
51
+	useTime := int64(time.Now().Sub(startTime) / time.Millisecond)
52
+	if useTime > config.C.Monitor.Timeout {
53
+		return fmt.Errorf("timeout url:%s,millisecond:%d", url, useTime)
54
+	}
55
+	return nil
56
+}

+ 8
- 0
service/store/cache/cache.go View File

@@ -1 +1,9 @@
1 1
 package cache
2
+
3
+var monitorCache map[string]bool = map[string]bool{}
4
+
5
+func CheckMonitor(url string, err error) bool {
6
+	willNotice := monitorCache[url] != (err != nil)
7
+	monitorCache[url] = err != nil
8
+	return willNotice
9
+}