1.场景
在一般应用中是将生成的日志记录到日志文件中,这里就用到: github.com/sirupsen/logrus
2.使用
1.将日志记录生成到文件
package log; //当前目录名
import (
"time"
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
"path"
"os"
"fmt"
)
const (
//FORMAT .
FORMAT = "20201111"
LOG_FILE_NAME = "system"
)
// 日志记录到文件
func LoggerToFile() gin.HandlerFunc {
logFileName := LOG_FILE_NAME+time.Now().Format(FORMAT) + ".log"
//获取所在目录
logFilePath, _ := os.Getwd()
//日志文件
fileName := path.Join(logFilePath, logFileName)
fi, _ := os.Stat(fileName)
if fi == nil {
os.Create(fileName) // 文件不存在就创建
}
//写入文件
src, err := os.OpenFile(fileName, os.O_APPEND|os.O_WRONLY, os.ModeAppend)
if err != nil {
fmt.Println("err", err)
}
//实例化
logger := logrus.New()
//设置输出
logger.Out = src
//设置日志级别
logger.SetLevel(logrus.DebugLevel)
//设置日志格式
logger.SetFormatter(&logrus.TextFormatter{})
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,
)
}
}
2.引用日志模块
package main
import (
"net/http"
"strconv"
"time"
"github.com/gin-gonic/gin"
logs "go/web/log" //引用日志模块,路径是:GOPATH下,所有文件目录
)
type User struct {
ID int64
Name string
Age int
CreatedTime time.Time
UpdatedTime time.Time
IsDeleted bool
}
func main() {
//初始化引擎
r := gin.Default()
r.Use(logs.LoggerToFile())
//简单的Get请求
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
//GET请求通过name获取参数 /user/test
r.GET("/user/:name", func(c *gin.Context) {
name := c.Param("name")
c.String(http.StatusOK, "Hello %s", name)
})
//GET请求通过正常的URL获取参数 /getuser?id=2
r.GET("/getuser", func(c *gin.Context) {
rid := c.DefaultQuery("id", "1")
id, _ := strconv.ParseInt(rid, 10, 64)
user := User{ID: id, Age: 32, CreatedTime: time.Now(), UpdatedTime: time.Now(), IsDeleted: true}
c.JSON(http.StatusOK, user)
})
//POST请求通过绑定获取对象
r.POST("/adduser", func(c *gin.Context) {
var user User
err := c.ShouldBind(&user)
if err == nil {
c.JSON(http.StatusOK, user)
} else {
c.String(http.StatusBadRequest, "请求参数错误", err)
}
})
//post 请求 json 格式话
r.GET("/json",func (c *gin.Context) {
c.JSON(http.StatusOK,gin.H{"name":"post 请求 json 格式话","age":18})
})
//delete 请求 xml 格式化
r.GET("/xml",func (c *gin.Context) {
c.XML(http.StatusOK,gin.H{"name":"delete 请求 xml 格式化","age":18})
})
//patch 请求 yaml 格式化
r.GET("/yaml",func (c *gin.Context) {
c.YAML(http.StatusOK,gin.H{"name":"patch 请求 yaml 格式化","age":18})
})
//get请求 html界面显示
r.GET("/html",func (c *gin.Context) {
r.LoadHTMLGlob("item/*") //这是前台的index
c.HTML(http.StatusOK,"index.html",nil)
})
//跳转到上传页面
r.GET("/preupload",func (c *gin.Context) {
r.LoadHTMLGlob("item/*") //这加载的页面目录
c.HTML(http.StatusOK,"upload.html",nil)
})
// 当访问地址为/upload时执行后面的函数
r.POST("/upload", func(c *gin.Context) {
//获取表单数据 参数为name值
f, err := c.FormFile("f1")
//错误处理
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"error": err,
})
return
} else {
//将文件保存至本项目根目录中
c.SaveUploadedFile(f, f.Filename)
//保存成功返回正确的Json数据
c.JSON(http.StatusOK, gin.H{
"message": "OK",
})
}
})
r.Run(":9002") // listen and serve on 0.0.0.0:9002
}