上代码

log.go

package main

import (
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"io"
	"os"
	"path"
	"path/filepath"
	"strings"
	"time"
)
//根据时间检测目录,不存在则创建
func CreateDateDir(Path string) string {
	folderName := time.Now().Format("20060102")
	folderPath := filepath.Join(Path, folderName)
	if _, err := os.Stat(folderPath); os.IsNotExist(err) {
		// 必须分成两步:先创建文件夹、再修改权限
		os.Mkdir(folderPath, 0777) //0777也可以os.ModePerm
		os.Chmod(folderPath, 0777)
	}
	return folderPath
}
//使用io.WriteString()函数进行数据的写入,不存在则创建
func WriteWithIo(filePath, content string) {
	fileObj,err := os.OpenFile(filePath,os.O_RDWR|os.O_CREATE|os.O_APPEND,0777)
	if err != nil {
		fmt.Println("Failed to open the file",err.Error())
		os.Exit(2)
	}
	if  _,err := io.WriteString(fileObj,content);err == nil {
		fmt.Println("Successful appending to the file with os.OpenFile and io.WriteString.",content)
	}
}
//path转文件名
func uriToFilePath(thisPath string) string {
	pathArr := strings.Split(thisPath, "/")
	fileName := strings.Join(pathArr, "-")
	writePath := CreateDateDir(nowPath) //根据时间检测是否存在目录,不存在创建
	fileName = path.Join(writePath, fileName[1:len(fileName)] + ".log")
	return fileName
}
// 日志记录到文件中间件
type LogStr struct {
	Time string
	Code int
	Method string
	Uri string
	LatencyTime int64
	TimeUnit string
	Ip string
}
func LoggerToFile() gin.HandlerFunc {
	return func(c *gin.Context) {
		u := c.Request.URL;
		fileName := uriToFilePath(u.Path);// 通过uri获得日志文件名

		startTime := time.Now()// 开始时间
		timeStr := time.Now().Format("2006-01-02 15:04:05");// 开始时间string
		c.Next() // 处理请求
		endTime := time.Now()// 结束时间
		latencyTime := endTime.Sub(startTime).Microseconds()// 执行时间
		statusCode := c.Writer.Status()// 状态码
		reqMethod := c.Request.Method// 请求方式
		reqUri := c.Request.RequestURI// 请求路由
		clientIP := c.ClientIP()// 请求IP

		str := LogStr{Time:timeStr, Code:statusCode, Method:reqMethod, Uri:reqUri, LatencyTime:latencyTime, TimeUnit:"Microseconds", Ip:clientIP };
		jsonStr, _ := json.Marshal(str);
		WriteWithIo(fileName, string(jsonStr) + "\n");

	}
}

main.go

package main

import (
	"github.com/gin-gonic/gin"
	"net/http"
	"strconv"
)

type Test struct {
	Name string
	Age int
	Id int
}

const nowPath string = "/Users/why/Desktop/go/logs"; //默认日志绝对路径

func getData(c *gin.Context){
	name := c.Query("name");
	age, _  := strconv.Atoi( c.Query("age") );
	id, _ := strconv.Atoi( c.Query("id") );

	c.JSON(http.StatusOK, gin.H{
		"code" : http.StatusOK,
		"message" : "success",
		"data" : Test{Name: name, Age: age, Id: id},
	})
}
func getData1(c *gin.Context){
	name := c.Query("name");
	age, _  := strconv.Atoi( c.Query("age") );
	id, _ := strconv.Atoi( c.Query("id") );

	c.JSON(http.StatusOK, gin.H{
		"code" : http.StatusOK,
		"message" : "success",
		"data" : Test{Name: name, Age: age, Id: id},
	})
}

func main(){
	r := gin.Default();

	r.Use(LoggerToFile() );

	v1 := r.Group("v1")
	{
		v1.GET("/test", getData);
		v1.GET("/test1", getData1);
	}

	r.Run(":666");
}

页面结果

{
    code: 200,
    data: {
        Name: "why",
        Age: 18,
        Id: 1
    },
    message: "success"
}

日志结果

localhost:20191229 why$ pwd
/Users/why/Desktop/go/logs/20191229
localhost:20191229 why$ ll
total 16
-rwxr-xr-x  1 why  staff  422 12 29 20:36 v1-test.log
-rwxr-xr-x  1 why  staff  141 12 29 20:36 v1-test1.log
localhost:20191229 why$ tail -f v1-test.log
{"Time":"2020-01-12 17:24:49","Code":200,"Method":"GET","Uri":"/v1/test?id=1","LatencyTime":189,"TimeUnit":"Microseconds","Ip":"::1"}
{"Time":"2020-01-12 17:24:54","Code":200,"Method":"GET","Uri":"/v1/test?id=1","LatencyTime":75,"TimeUnit":"Microseconds","Ip":"::1"}
{"Time":"2020-01-12 17:24:56","Code":200,"Method":"GET","Uri":"/v1/test?id=1","LatencyTime":47,"TimeUnit":"Microseconds","Ip":"::1"}
{"Time":"2020-01-12 17:24:57","Code":200,"Method":"GET","Uri":"/v1/test?id=1","LatencyTime":32,"TimeUnit":"Microseconds","Ip":"::1"}
{"Time":"2020-01-12 17:24:58","Code":200,"Method":"GET","Uri":"/v1/test?id=1","LatencyTime":34,"TimeUnit":"Microseconds","Ip":"::1"}

 

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐