From b8e031f07fd1331a0efec8c331139d11048b9731 Mon Sep 17 00:00:00 2001 From: zhangshu <70257536+Appolli9527@users.noreply.github.com> Date: Thu, 18 Apr 2024 00:05:19 +0800 Subject: [PATCH] add config and init log --- .gitignore | 4 +- youtube_collection_server/Utils/LogUtil.go | 214 ++++++++++++++++++ youtube_collection_server/config.yml | 6 + youtube_collection_server/config/EnvConfig.go | 16 ++ youtube_collection_server/config/config.go | 34 +++ .../controller/UserController.go | 15 ++ youtube_collection_server/go.mod | 12 +- youtube_collection_server/go.sum | 16 ++ youtube_collection_server/main.go | 34 ++- youtube_collection_server/middle/Cors.go | 22 ++ 10 files changed, 361 insertions(+), 12 deletions(-) create mode 100644 youtube_collection_server/Utils/LogUtil.go create mode 100644 youtube_collection_server/config.yml create mode 100644 youtube_collection_server/config/EnvConfig.go create mode 100644 youtube_collection_server/config/config.go create mode 100644 youtube_collection_server/controller/UserController.go create mode 100644 youtube_collection_server/middle/Cors.go diff --git a/.gitignore b/.gitignore index 224add7..bd0f406 100644 --- a/.gitignore +++ b/.gitignore @@ -155,4 +155,6 @@ dmypy.json # Cython debug symbols cython_debug/ .vscode -youtube_collection_web/node_modules \ No newline at end of file +youtube_collection_web/node_modules +.idea +*/logs \ No newline at end of file diff --git a/youtube_collection_server/Utils/LogUtil.go b/youtube_collection_server/Utils/LogUtil.go new file mode 100644 index 0000000..da7a4aa --- /dev/null +++ b/youtube_collection_server/Utils/LogUtil.go @@ -0,0 +1,214 @@ +package utils + +import ( + "bytes" + "fmt" + "io" + "os" + "path" + "time" + + "github.com/gin-gonic/gin" + rotatelogs "github.com/lestrrat-go/file-rotatelogs" + "github.com/logrusorgru/aurora" + "github.com/rifflock/lfshook" + "github.com/sirupsen/logrus" +) + +var Logger *logrus.Logger +var isInit bool + +func CheckInitLog() bool { + return isInit +} +func init() { + isInit = false +} + +const ( + maxAgeHour = 168 + rotationHour = 24 +) + +type SaveFormatter struct { +} + +func (m *SaveFormatter) Format(entry *logrus.Entry) ([]byte, error) { + var b *bytes.Buffer + if entry.Buffer != nil { + b = entry.Buffer + } else { + b = &bytes.Buffer{} + } + timestamp := entry.Time.Format("2006-01-02 15:04:05") + var newLog string + newLog = fmt.Sprintf("[%s] [%s:%d] [%s] %s \n", timestamp, path.Base(entry.Caller.File), entry.Caller.Line, entry.Level, entry.Message) + b.WriteString(newLog) + return b.Bytes(), nil +} + +type ConsoleFormatter struct { +} + +func (m *ConsoleFormatter) Format(entry *logrus.Entry) ([]byte, error) { + var b *bytes.Buffer + if entry.Buffer != nil { + b = entry.Buffer + } else { + b = &bytes.Buffer{} + } + timestamp := entry.Time.Format("2006-01-02 15:04:05") + var newLog string + var levelString aurora.Value + switch entry.Level.String() { + case "info": + levelString = aurora.Green(entry.Level) + case "warning": + levelString = aurora.Yellow(entry.Level) + case "debug": + levelString = aurora.Gray(16-1, entry.Level) + case "error": + levelString = aurora.Red(entry.Level) + case "fatal": + levelString = aurora.Red(entry.Level) + case "panic": + levelString = aurora.Red(entry.Level) + } + newLog = fmt.Sprintf("[%s] [%s:%d] [%s] %s \n", timestamp, path.Base(entry.Caller.File), entry.Caller.Line, levelString, entry.Message) + b.WriteString(newLog) + return b.Bytes(), nil +} + +func InitLogger(env string, logPath string) *logrus.Logger { + logFilePath := "" + errFilePath := "" + if dir, err := os.Getwd(); err == nil { + logFilePath = dir + "/logs/" + logPath + "/all.log" + errFilePath = dir + "/logs/" + logPath + "/error.log" + } + + accessWriter, err := rotatelogs.New( + logFilePath+".%Y-%m-%d", + rotatelogs.WithLinkName(logFilePath), + rotatelogs.WithRotationTime(time.Hour*rotationHour), + rotatelogs.WithMaxAge(time.Hour*maxAgeHour), + ) + if err != nil { + panic(err) + } + errorWriter, err := rotatelogs.New( + errFilePath+".%Y-%m-%d", + rotatelogs.WithLinkName(errFilePath), + rotatelogs.WithRotationTime(time.Hour*rotationHour), + rotatelogs.WithMaxAge(time.Hour*maxAgeHour), + ) + if err != nil { + panic(err) + } + allWriter := io.MultiWriter(accessWriter, errorWriter) + //实例化 + logger := logrus.New() + logger.Out = os.Stdout + //设置日志格式 + logger.SetFormatter(&ConsoleFormatter{}) + logger.SetReportCaller(true) + //设置输出 + if env != "dev" { + logger.AddHook(lfshook.NewHook( + lfshook.WriterMap{ + logrus.DebugLevel: accessWriter, + logrus.InfoLevel: accessWriter, + logrus.ErrorLevel: allWriter, + logrus.PanicLevel: allWriter, + }, + &SaveFormatter{}, + )) + } + //设置日志级别 + logger.SetLevel(logrus.DebugLevel) + Logger = logger + isInit = true + return logger +} + +func InitReqLogger(env string, logPath string) *logrus.Logger { + logFilePath := "" + errFilePath := "" + if dir, err := os.Getwd(); err == nil { + logFilePath = dir + "/logs/" + logPath + "/req.log" + errFilePath = dir + "/logs/" + logPath + "/req-error.log" + } + + accessWriter, err := rotatelogs.New( + logFilePath+".%Y-%m-%d", + rotatelogs.WithLinkName(logFilePath), + rotatelogs.WithRotationTime(time.Hour*rotationHour), + rotatelogs.WithMaxAge(time.Hour*maxAgeHour), + ) + if err != nil { + panic(err) + } + errorWriter, err := rotatelogs.New( + errFilePath+".%Y-%m-%d", + rotatelogs.WithLinkName(errFilePath), + rotatelogs.WithRotationTime(time.Hour*rotationHour), + rotatelogs.WithMaxAge(time.Hour*maxAgeHour), + ) + if err != nil { + panic(err) + } + allWriter := io.MultiWriter(accessWriter, errorWriter) + //实例化 + logger := logrus.New() + logger.Out = os.Stdout + //设置日志格式 + logger.SetFormatter(&ConsoleFormatter{}) + logger.SetReportCaller(true) + //设置输出 + if env != "dev" { + logger.AddHook(lfshook.NewHook( + lfshook.WriterMap{ + logrus.DebugLevel: accessWriter, + logrus.InfoLevel: accessWriter, + logrus.ErrorLevel: allWriter, + logrus.PanicLevel: allWriter, + }, + &SaveFormatter{}, + )) + } + //设置日志级别 + logger.SetLevel(logrus.DebugLevel) + Logger = logger + isInit = true + return logger +} + +func LoggerToFile(env string, logPath string) gin.HandlerFunc { + logger := InitReqLogger(env, logPath) + return func(c *gin.Context) { + // 开始时间 + startTime := time.Now() + // 处理请求 + c.Next() + // 结束时间 + endTime := time.Now() + // 执行时间 + latencyTime := endTime.Sub(startTime) + // 请求方式 + reqMethod := c.Request.Method + // 请求路由 + reqUri := c.Request.RequestURI + // 状态码 + statusCode := c.Writer.Status() + // 请求IP + clientIP := c.ClientIP() + //日志格式 + logger.Infof("|%3d|%13v|%15s|%s|%s|", + statusCode, + latencyTime, + clientIP, + reqMethod, + reqUri, + ) + } +} diff --git a/youtube_collection_server/config.yml b/youtube_collection_server/config.yml new file mode 100644 index 0000000..05710fc --- /dev/null +++ b/youtube_collection_server/config.yml @@ -0,0 +1,6 @@ +server: + ip: 127.0.0.1 + port: 9999 +log: + logenv: test + logpath: server \ No newline at end of file diff --git a/youtube_collection_server/config/EnvConfig.go b/youtube_collection_server/config/EnvConfig.go new file mode 100644 index 0000000..99d18b7 --- /dev/null +++ b/youtube_collection_server/config/EnvConfig.go @@ -0,0 +1,16 @@ +package config + +type EnvConfig struct { + Server ServerEntity + Log LogEntity +} + +type ServerEntity struct { + Ip string + Port int +} + +type LogEntity struct { + LogEnv string + LogPath string +} diff --git a/youtube_collection_server/config/config.go b/youtube_collection_server/config/config.go new file mode 100644 index 0000000..7ebd0b0 --- /dev/null +++ b/youtube_collection_server/config/config.go @@ -0,0 +1,34 @@ +package config + +import ( + "flag" + "fmt" + "io/ioutil" + + utils "youtube_collection_server/Utils" + + "github.com/sirupsen/logrus" + "gopkg.in/yaml.v2" +) + +var configFile string +var MyEnv EnvConfig +var Logger *logrus.Logger + +func init() { + flag.StringVar(&configFile, "cf", "config.yml", "配置文件名") +} + +func InitConfig() { + flag.Parse() + //读取配置文件 + data, _ := ioutil.ReadFile(configFile) + err := yaml.Unmarshal(data, &MyEnv) + if err != nil { + fmt.Println("读取配置文件错误...") + return + } + //初始化日志 + Logger = utils.InitLogger(MyEnv.Log.LogEnv, MyEnv.Log.LogPath) + Logger.Info("初始化Logger成功...") +} diff --git a/youtube_collection_server/controller/UserController.go b/youtube_collection_server/controller/UserController.go new file mode 100644 index 0000000..62b1004 --- /dev/null +++ b/youtube_collection_server/controller/UserController.go @@ -0,0 +1,15 @@ +package controller + +import "github.com/gin-gonic/gin" + +type userController struct { +} + +var UserController userController + +func (m *userController) Test(c *gin.Context) { + c.JSON(200, gin.H{ + "username": "name1", + "data": "data1", + }) +} diff --git a/youtube_collection_server/go.mod b/youtube_collection_server/go.mod index 2abac47..dbc3c05 100644 --- a/youtube_collection_server/go.mod +++ b/youtube_collection_server/go.mod @@ -2,12 +2,17 @@ module youtube_collection_server go 1.22.2 +require ( + github.com/gin-gonic/gin v1.9.1 + github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible + github.com/sirupsen/logrus v1.9.3 +) + require ( github.com/bytedance/sonic v1.9.1 // indirect github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gin-contrib/sse v0.1.0 // indirect - github.com/gin-gonic/gin v1.9.1 github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.14.0 // indirect @@ -15,10 +20,14 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.2.4 // indirect github.com/leodido/go-urn v1.2.4 // indirect + github.com/lestrrat-go/strftime v1.0.6 // indirect + github.com/logrusorgru/aurora v2.0.3+incompatible github.com/mattn/go-isatty v0.0.19 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.11 // indirect golang.org/x/arch v0.3.0 // indirect @@ -27,5 +36,6 @@ require ( golang.org/x/sys v0.8.0 // indirect golang.org/x/text v0.9.0 // indirect google.golang.org/protobuf v1.30.0 // indirect + gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/youtube_collection_server/go.sum b/youtube_collection_server/go.sum index 1a77fa1..9aa7452 100644 --- a/youtube_collection_server/go.sum +++ b/youtube_collection_server/go.sum @@ -34,6 +34,13 @@ github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZX github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= +github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is= +github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible h1:Y6sqxHMyB1D2YSzWkLibYKgg+SwmyFU9dF2hn6MdTj4= +github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible/go.mod h1:ZQnN8lSECaebrkQytbHj4xNgtg8CR7RYXnPok8e0EHA= +github.com/lestrrat-go/strftime v1.0.6 h1:CFGsDEt1pOpFNU+TJB0nhz9jl+K0hZSLE205AhTIGQQ= +github.com/lestrrat-go/strftime v1.0.6/go.mod h1:f7jQKgV5nnJpYgdEasS+/y7EsTb8ykN2z68n3TtcTaw= +github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= +github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -43,8 +50,14 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 h1:mZHayPoR0lNmnHyvtYjDeq0zlVHn9K/ZXoy17ylucdo= +github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5/go.mod h1:GEXHk5HgEKCvEIIrSpFI3ozzG5xOKA2DVlEX/gGnewM= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -68,6 +81,7 @@ golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0 golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -80,6 +94,8 @@ google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cn google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/youtube_collection_server/main.go b/youtube_collection_server/main.go index 12d59f7..ace4605 100644 --- a/youtube_collection_server/main.go +++ b/youtube_collection_server/main.go @@ -1,20 +1,34 @@ package main import ( + "fmt" + utils "youtube_collection_server/Utils" + . "youtube_collection_server/config" + "youtube_collection_server/controller" + "youtube_collection_server/middle" + "github.com/gin-gonic/gin" ) func main() { + InitConfig() // 创建一个默认的路由引擎 - r := gin.Default() - // 配置路由 - f := func(c *gin.Context) { - c.JSON(200, gin.H{ - "username": "name1", - "data": "data1", - }) + router := gin.Default() + //初始化路由 + initRouter(router) + Logger.Infof("服务器启动成功...端口:%d", MyEnv.Server.Port) + router.Use(middle.Cors()) + err := router.Run(fmt.Sprintf(":"+"%d", MyEnv.Server.Port)) + if err != nil { + Logger.Error("服务器启动失败") + return + } +} + +func initRouter(router *gin.Engine) { + router.Use(utils.LoggerToFile(MyEnv.Log.LogEnv, MyEnv.Log.LogPath)) + noAuth := router.Group("") + { + noAuth.GET("/test", controller.UserController.Test) } - r.GET("/", f) - // 启动 HTTP 服务,默认在 0.0.0.0:8080 启动服务 - r.Run() } diff --git a/youtube_collection_server/middle/Cors.go b/youtube_collection_server/middle/Cors.go new file mode 100644 index 0000000..f0821ac --- /dev/null +++ b/youtube_collection_server/middle/Cors.go @@ -0,0 +1,22 @@ +package middle + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +func Cors() gin.HandlerFunc { + return func(context *gin.Context) { + method := context.Request.Method + context.Header("Access-Control-Allow-Origin", "*") + context.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token") + context.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS") + context.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type") + context.Header("Access-Control-Allow-Credentials", "true") + if method == "OPTIONS" { + context.AbortWithStatus(http.StatusNoContent) + } + context.Next() + } +}