Forráskód Böngészése

日志组件合入

zwl 5 éve
szülő
commit
555ee96156
7 módosított fájl, 317 hozzáadás és 17 törlés
  1. 5 3
      account/account.go
  2. 53 9
      config/config.go
  3. 7 1
      config/config.xml
  4. 30 0
      log/mtp2_if/mtp2_if_2020-05-27.log
  5. 74 0
      logger/logger.go
  6. 109 4
      main.go
  7. 39 0
      token/token.go

+ 5 - 3
account/account.go

@@ -2,7 +2,7 @@ package account
 
 import (
 	"mtp2_if/db"
-	"mtp2_if/rediscli"
+	"mtp2_if/token"
 	"net/http"
 
 	"github.com/gin-gonic/gin"
@@ -39,9 +39,11 @@ func GetAccount(c *gin.Context) {
 		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
 	}
 
-	err = rediscli.CheckToken(account.AccountID, account.Token)
-	if err != nil {
+	var ok bool
+	ok, err = token.CheckToken(account.AccountID, account.Token)
+	if err != nil || !ok {
 		c.JSON(http.StatusBadRequest, gin.H{"token check failed": err.Error()})
+		return
 	}
 
 	engine := db.GetEngine()

+ 53 - 9
config/config.go

@@ -11,7 +11,13 @@ import (
 var SerCfg *ServiceConfig
 
 type WebConfig struct {
-	ListenPort int
+	ListenAddr string
+	DebugMode  bool
+}
+
+type LogConfig struct {
+	LogPath  string
+	LogLevel int
 }
 
 type DbConfig struct {
@@ -34,6 +40,7 @@ type RedisConfig struct {
 
 type ServiceConfig struct {
 	WebCfg   WebConfig
+	LogCfg   LogConfig
 	DbCfg    DbConfig
 	RedisCfg RedisConfig
 }
@@ -56,15 +63,44 @@ func (c *ServiceConfig) Init(path string) error {
 	// web配置
 	websettings := root.SelectElements("WebSetting")
 	for _, setting := range websettings {
-		web_listenport := setting.SelectElement("ListenPort")
-		if web_listenport == nil {
-			return errors.New("read web listen port failed")
+		web_listenaddr := setting.SelectElement("ListenAddress")
+		if web_listenaddr == nil {
+			return errors.New("read web listen address failed")
+		}
+		SerCfg.WebCfg.ListenAddr = web_listenaddr.SelectAttrValue("values", "0.0.0.0:8080")
+
+		// 调试模式
+		debug_mode := setting.SelectElement("DebugMode")
+		if debug_mode == nil {
+			return errors.New("read debug mode failed")
 		}
-		ret, err := strconv.ParseUint(web_listenport.SelectAttrValue("value", "8080"), 10, 32)
+		ret, err := strconv.ParseUint(debug_mode.SelectAttrValue("value", "0"), 10, 32)
 		if err != nil {
-			return errors.New("read web listen port is invalid:")
+			return errors.New("read debug mode is invalid:")
 		}
-		SerCfg.WebCfg.ListenPort = int(ret)
+		SerCfg.WebCfg.DebugMode = (ret == 1)
+	}
+
+	// 日志配置
+	logsettings := root.SelectElements("LogSetting")
+	for _, setting := range logsettings {
+		// 日志路径
+		log_path := setting.SelectElement("LogPath")
+		if log_path == nil {
+			return errors.New("read log path failed")
+		}
+		SerCfg.LogCfg.LogPath = log_path.SelectAttrValue("value", "./")
+
+		// 日志级别
+		log_level := setting.SelectElement("LogLevel")
+		if log_level == nil {
+			return errors.New("read log level failed")
+		}
+		ret, err := strconv.ParseUint(log_level.SelectAttrValue("value", "5"), 10, 32)
+		if err != nil {
+			return errors.New("read log level is invalid:")
+		}
+		SerCfg.LogCfg.LogLevel = int(ret)
 	}
 
 	// 数据库配置
@@ -178,8 +214,16 @@ func (c *ServiceConfig) Init(path string) error {
 	return nil
 }
 
-func (c *ServiceConfig) GetWebListenPort() int {
-	return SerCfg.WebCfg.ListenPort
+func (c *ServiceConfig) GetWebListenAddr() string {
+	return SerCfg.WebCfg.ListenAddr
+}
+
+func (c *ServiceConfig) GetDebugMode() bool {
+	return SerCfg.WebCfg.DebugMode
+}
+
+func (c *ServiceConfig) GetLogSetting() (string, int) {
+	return SerCfg.LogCfg.LogPath, SerCfg.LogCfg.LogLevel
 }
 
 func (c *ServiceConfig) GetDbDriver() string {

+ 7 - 1
config/config.xml

@@ -2,9 +2,15 @@
 
 <Configuration xmlns:http="http://www.w3.org/2001/XMLSchema-instance">
     <WebSetting>
-        <ListenPort value="8080"/>
+        <ListenAddress value="0.0.0.0:8080"/>
+        <DebugMode value="1"/>
     </WebSetting>
 
+    <LogSetting>
+        <LogPath value="log/mtp2_if"/>
+        <LogLevel value="5"/>
+    </LogSetting>
+
     <DbSetting>
         <DbDriver  value="oci8"/>
         <DbAddress value="192.168.31.117"/>

+ 30 - 0
log/mtp2_if/mtp2_if_2020-05-27.log

@@ -0,0 +1,30 @@
+time="2020-05-27 17:01:11" level=info msg="|200| 5.048922826s|            ::1|POST /account/accountopt/GetAccount" func=main.ginLoggerMiddleware.func1 file="/Users/wanghongliang/Repo/Muchinfo_Git/MTP20_IF/main.go:88"
+time="2020-05-27 17:01:15" level=info msg="|200|    2.75327ms|            ::1|POST /account/accountopt/GetAccount" func=main.ginLoggerMiddleware.func1 file="/Users/wanghongliang/Repo/Muchinfo_Git/MTP20_IF/main.go:88"
+time="2020-05-27 17:08:51" level=info msg="|404|        983ns|            ::1|GET /account/accountopt/getaccount" func=main.ginLoggerMiddleware.func1 file="/Users/wanghongliang/Repo/Muchinfo_Git/MTP20_IF/main.go:88"
+time="2020-05-27 17:08:52" level=info msg="|404|      1.096µs|            ::1|GET /favicon.ico" func=main.ginLoggerMiddleware.func1 file="/Users/wanghongliang/Repo/Muchinfo_Git/MTP20_IF/main.go:88"
+time="2020-05-27 17:09:20" level=info msg="|404|      1.364µs|            ::1|GET /account/accountopt/GetAccount" func=main.ginLoggerMiddleware.func1 file="/Users/wanghongliang/Repo/Muchinfo_Git/MTP20_IF/main.go:88"
+time="2020-05-27 17:09:25" level=info msg="|404|      1.119µs|            ::1|GET /account/accountopt/GetAccount" func=main.ginLoggerMiddleware.func1 file="/Users/wanghongliang/Repo/Muchinfo_Git/MTP20_IF/main.go:88"
+time="2020-05-27 17:09:35" level=info msg="|404|      1.047µs|            ::1|GET /account/accountopt/GetAccount%20-POST" func=main.ginLoggerMiddleware.func1 file="/Users/wanghongliang/Repo/Muchinfo_Git/MTP20_IF/main.go:88"
+time="2020-05-27 17:09:54" level=info msg="|404|      1.001µs|            ::1|GET /account/accountopt/GetAccount%20%20%20-H%20'content-type:%20application/json'%20%20%20-d%20'%7B%22token%22:%22testtoken%22,%20%22accountid%22:%20250000000001%7D'" func=main.ginLoggerMiddleware.func1 file="/Users/wanghongliang/Repo/Muchinfo_Git/MTP20_IF/main.go:88"
+time="2020-05-27 17:09:58" level=info msg="|404|      1.317µs|            ::1|GET /account/accountopt/GetAccount%20%20%20-H%20'content-type:%20application/json'%20%20%20-d%20'%7B%22token%22:%22testtoken%22,%20%22accountid%22:%20250000000001%7D'" func=main.ginLoggerMiddleware.func1 file="/Users/wanghongliang/Repo/Muchinfo_Git/MTP20_IF/main.go:88"
+time="2020-05-27 17:12:14" level=info msg="|200| 5.048496417s|            ::1|POST /account/accountopt/GetAccount" func=main.ginLoggerMiddleware.func1 file="/Users/wanghongliang/Repo/Muchinfo_Git/MTP20_IF/main.go:89"
+time="2020-05-27 18:02:09" level=info msg="|200| 5.047424002s|            ::1|POST /account/accountopt/GetAccount" func=main.ginLoggerMiddleware.func1 file="/Users/wanghongliang/Repo/Muchinfo_Git/MTP20_IF/main.go:149"
+time="2020-05-27 18:03:05" level=info msg="|404|      1.097µs|            ::1|GET /debug/pprof" func=main.ginLoggerMiddleware.func1 file="/Users/wanghongliang/Repo/Muchinfo_Git/MTP20_IF/main.go:149"
+time="2020-05-27 18:03:58" level=info msg="|404|      1.205µs|            ::1|GET /debug/pprof" func=main.ginLoggerMiddleware.func1 file="/Users/wanghongliang/Repo/Muchinfo_Git/MTP20_IF/main.go:149"
+time="2020-05-27 18:04:19" level=info msg="|404|      1.087µs|            ::1|POST /debug/pprof" func=main.ginLoggerMiddleware.func1 file="/Users/wanghongliang/Repo/Muchinfo_Git/MTP20_IF/main.go:149"
+time="2020-05-27 18:04:37" level=info msg="|404|        899ns|            ::1|POST /debug/pprof" func=main.ginLoggerMiddleware.func1 file="/Users/wanghongliang/Repo/Muchinfo_Git/MTP20_IF/main.go:149"
+time="2020-05-27 18:05:02" level=info msg="|404|      1.145µs|            ::1|GET /dubug/pprof" func=main.ginLoggerMiddleware.func1 file="/Users/wanghongliang/Repo/Muchinfo_Git/MTP20_IF/main.go:149"
+time="2020-05-27 18:05:05" level=info msg="|404|      1.147µs|            ::1|GET /dubug/pprof" func=main.ginLoggerMiddleware.func1 file="/Users/wanghongliang/Repo/Muchinfo_Git/MTP20_IF/main.go:149"
+time="2020-05-27 18:05:29" level=info msg="|404|      1.617µs|            ::1|POST /debug/pprof" func=main.ginLoggerMiddleware.func1 file="/Users/wanghongliang/Repo/Muchinfo_Git/MTP20_IF/main.go:149"
+time="2020-05-27 18:05:34" level=info msg="|404|        884ns|            ::1|POST /debug/pprof" func=main.ginLoggerMiddleware.func1 file="/Users/wanghongliang/Repo/Muchinfo_Git/MTP20_IF/main.go:149"
+time="2020-05-27 18:05:43" level=info msg="|404|      1.144µs|            ::1|POST /debug/pprof" func=main.ginLoggerMiddleware.func1 file="/Users/wanghongliang/Repo/Muchinfo_Git/MTP20_IF/main.go:149"
+time="2020-05-27 18:05:54" level=info msg="|200| 5.039367083s|            ::1|POST /account/accountopt/GetAccount" func=main.ginLoggerMiddleware.func1 file="/Users/wanghongliang/Repo/Muchinfo_Git/MTP20_IF/main.go:149"
+time="2020-05-27 18:06:03" level=info msg="|200|    927.751µs|            ::1|GET /debug/pprof/" func=main.ginLoggerMiddleware.func1 file="/Users/wanghongliang/Repo/Muchinfo_Git/MTP20_IF/main.go:149"
+time="2020-05-27 18:06:10" level=info msg="|200|  15.717803ms|            ::1|GET /debug/pprof/block?debug=1" func=main.ginLoggerMiddleware.func1 file="/Users/wanghongliang/Repo/Muchinfo_Git/MTP20_IF/main.go:149"
+time="2020-05-27 18:06:12" level=info msg="|200|   3.669608ms|            ::1|GET /debug/pprof/allocs?debug=1" func=main.ginLoggerMiddleware.func1 file="/Users/wanghongliang/Repo/Muchinfo_Git/MTP20_IF/main.go:149"
+time="2020-05-27 18:06:17" level=info msg="|200|   1.0023481s|            ::1|GET /debug/pprof/trace" func=main.ginLoggerMiddleware.func1 file="/Users/wanghongliang/Repo/Muchinfo_Git/MTP20_IF/main.go:149"
+time="2020-05-27 18:06:20" level=info msg="|200|     20.151µs|            ::1|GET /debug/pprof/cmdline" func=main.ginLoggerMiddleware.func1 file="/Users/wanghongliang/Repo/Muchinfo_Git/MTP20_IF/main.go:149"
+time="2020-05-27 18:06:23" level=info msg="|200|    769.332µs|            ::1|GET /debug/pprof/goroutine?debug=1" func=main.ginLoggerMiddleware.func1 file="/Users/wanghongliang/Repo/Muchinfo_Git/MTP20_IF/main.go:149"
+time="2020-05-27 18:06:37" level=info msg="|404|      1.106µs|            ::1|POST /debug/pprof" func=main.ginLoggerMiddleware.func1 file="/Users/wanghongliang/Repo/Muchinfo_Git/MTP20_IF/main.go:149"
+time="2020-05-27 18:06:45" level=info msg="|404|       1.62µs|            ::1|POST /debug/pprof" func=main.ginLoggerMiddleware.func1 file="/Users/wanghongliang/Repo/Muchinfo_Git/MTP20_IF/main.go:149"
+time="2020-05-27 18:06:53" level=info msg="|200|    1.99403ms|            ::1|POST /account/accountopt/GetAccount" func=main.ginLoggerMiddleware.func1 file="/Users/wanghongliang/Repo/Muchinfo_Git/MTP20_IF/main.go:149"

+ 74 - 0
logger/logger.go

@@ -0,0 +1,74 @@
+package logger
+
+import (
+	"os"
+	"path/filepath"
+	"time"
+
+	rotatelogs "github.com/lestrrat/go-file-rotatelogs"
+	"github.com/rifflock/lfshook"
+	"github.com/sirupsen/logrus"
+)
+
+var logger *logrus.Logger
+var logWriter *rotatelogs.RotateLogs
+
+func Init(logpath string, loglevel int) error {
+	// 创建日志目录
+	err := os.MkdirAll(logpath, os.ModePerm)
+	if err != nil {
+		return err
+	}
+
+	logger = logrus.New()
+	logname := filepath.Join(logpath, "mtp2_if")
+
+	// 显示行号等信息
+	logger.SetReportCaller(true)
+
+	// 设置日志输出
+	src, err := os.OpenFile(os.DevNull, os.O_APPEND|os.O_WRONLY, os.ModeAppend)
+	if err != nil {
+		return err
+	}
+	logger.SetOutput(src)
+
+	// 设置日志级别
+	logger.SetLevel(logrus.Level(loglevel))
+
+	// 设置分割规则
+	logWriter, err = rotatelogs.New(
+		logname+"_%Y-%m-%d.log",                   // 分割文件名
+		rotatelogs.WithMaxAge(7*24*time.Hour),     // 文件最长保存时间
+		rotatelogs.WithRotationTime(24*time.Hour), // 日志分割时间
+	)
+
+	// 映射日志级别与日志写对象
+	writerMap := lfshook.WriterMap{
+		logrus.PanicLevel: logWriter,
+		logrus.FatalLevel: logWriter,
+		logrus.ErrorLevel: logWriter,
+		logrus.WarnLevel:  logWriter,
+		logrus.InfoLevel:  logWriter,
+		logrus.DebugLevel: logWriter,
+		logrus.TraceLevel: logWriter,
+	}
+
+	// 创建日志文件钩子
+	lfHook := lfshook.NewHook(writerMap, &logrus.TextFormatter{
+		TimestampFormat: "2006-01-02 15:04:05",
+	})
+
+	// 添加日志钩子
+	logger.AddHook(lfHook)
+
+	return nil
+}
+
+func GetLogWriter() *rotatelogs.RotateLogs {
+	return logWriter
+}
+
+func GetLogger() *logrus.Logger {
+	return logger
+}

+ 109 - 4
main.go

@@ -1,24 +1,41 @@
 package main
 
 import (
-	"fmt"
+	"context"
+	"net/http"
+	"os"
+	"os/signal"
+	"syscall"
+	"time"
+
 	"mtp2_if/account"
 	"mtp2_if/config"
 	"mtp2_if/db"
 	"mtp2_if/goods"
+	"mtp2_if/logger"
 	"mtp2_if/rediscli"
+	"mtp2_if/token"
 
+	"github.com/DeanThompson/ginpprof"
 	"github.com/gin-gonic/gin"
 	_ "github.com/mattn/go-oci8"
 )
 
 func main() {
+	// 初始化配置
 	err := config.SerCfg.Init("config/config.xml")
 	if err != nil {
 		println("read config file failed:", err)
 		return
 	}
 
+	// 初始化日志组件
+	err = logger.Init(config.SerCfg.GetLogSetting())
+	if err != nil {
+		println("init logger failed:", err)
+		return
+	}
+
 	// 初始化数据库引擎
 	err = db.InitDbEngine()
 	if err != nil {
@@ -35,7 +52,22 @@ func main() {
 	}
 	defer rediscli.CloseReidsClient()
 
-	r := gin.Default()
+	// 初始化token校验
+	token.Init()
+
+	if config.SerCfg.GetDebugMode() {
+		gin.SetMode(gin.DebugMode)
+	} else {
+		gin.SetMode(gin.ReleaseMode)
+	}
+
+	r := gin.New()
+
+	// 设置日志中间件
+	r.Use(ginLoggerMiddleware())
+
+	// 设置奔溃中间件
+	r.Use(ginRecoveryMiddleware())
 
 	// 路由分组
 	gr := r.Group("/goods")
@@ -50,6 +82,79 @@ func main() {
 		aropt.POST("/GetAccount", account.GetAccount)
 	}
 
-	port := fmt.Sprintf(":%d", config.SerCfg.GetWebListenPort())
-	r.Run(port)
+	timeout := 15 * time.Second
+
+	// doubg模式启用pprof
+	if config.SerCfg.GetDebugMode() {
+		dm := r.Group("/debug/pprof")
+		ginpprof.WrapGroup(dm)
+		timeout = 60 * time.Second
+	}
+
+	// 声明web服务
+	webser := &http.Server{
+		Handler:      r,
+		Addr:         config.SerCfg.GetWebListenAddr(),
+		WriteTimeout: timeout,
+		ReadTimeout:  timeout,
+	}
+
+	cxt, cancel := context.WithCancel(context.Background())
+	defer cancel()
+
+	// 启动服务
+	c := make(chan struct{}, 1)
+	go func() {
+		defer close(c)
+		if err := webser.ListenAndServe(); err != nil {
+			logger.GetLogger().Errorf("Start service failed[%s].", err.Error())
+			c <- struct{}{}
+		}
+	}()
+
+	// 信号控制
+	s := make(chan os.Signal, 1)
+	signal.Notify(s, syscall.SIGINT, syscall.SIGTERM)
+	select {
+	case <-s:
+		logger.GetLogger().Debug("Shutdown service...")
+		timeCxt, tCancel := context.WithTimeout(cxt, 5*time.Second)
+		defer tCancel()
+
+		if err = webser.Shutdown(timeCxt); err != nil {
+			logger.GetLogger().Errorf("Shutdown service failed: %s", err.Error())
+		}
+	case <-c:
+
+	}
+
+	signal.Stop(s)
+	defer close(s)
+	logger.GetLogger().Debug("Service stopped")
+
+	//listenaddr := config.SerCfg.GetWebListenAddr()
+	//r.Run(listenaddr)
+}
+
+func ginLoggerMiddleware() gin.HandlerFunc {
+	return func(c *gin.Context) {
+		start := time.Now()
+		c.Next()
+		end := time.Now()
+		latency := end.Sub(start)
+		path := c.Request.URL.RequestURI()
+		clientip := c.ClientIP()
+		method := c.Request.Method
+		statuscode := c.Writer.Status()
+		logger.GetLogger().Infof("|%3d|%13v|%15s|%s %s",
+			statuscode,
+			latency,
+			clientip,
+			method,
+			path)
+	}
+}
+
+func ginRecoveryMiddleware() gin.HandlerFunc {
+	return gin.RecoveryWithWriter(logger.GetLogWriter())
 }

+ 39 - 0
token/token.go

@@ -0,0 +1,39 @@
+package token
+
+import (
+	"errors"
+	"fmt"
+	"mtp2_if/rediscli"
+)
+
+var TokenMap map[int]string
+
+func Init() {
+	TokenMap = make(map[int]string)
+	TokenMap[250000000001] = "testtoken"
+}
+
+func CheckToken(accountid int, token string) (bool, error) {
+
+	realToken, ok := TokenMap[accountid]
+	if ok {
+		if realToken != token {
+			return false, errors.New("token is invalid")
+		}
+	} else {
+		key := fmt.Sprintf("monitor:online_loginid::%d", accountid)
+		field := "Token"
+
+		realToken, err := rediscli.GetRedisClient().HGet(key, field).Result()
+		if err != nil {
+			return false, err
+		}
+
+		TokenMap[accountid] = realToken
+
+		if realToken != token {
+			return false, errors.New("token is invalid")
+		}
+	}
+	return true, nil
+}