【Go】全局日志处理、按天生成日志文件、格式化日志输出

前言

最近在学fiber框架,关于日志处理我纠结了好长一段时间,我一直在纠结到底怎么样才能像 logback-spring.xml 实现同样的日志处理。。。怪我自己思维定势了,老是用Java的思维想去实现。

实现

全局日志

全局错误日志,用中间件来处理,有error错误,就将错误信息格式化输出到控制台,同时输出到文件。

import (
	"fmt"
	"github.com/gofiber/fiber/v2"
	"go-web1/log"
	"go-web1/sys/controller"
	"go-web1/sys/model"
	"net"
	"net/http"
	"os"
	"strings"
	"time"
)

func main() {
	app := fiber.New()
	// 中间件
	app.Use(Logger())   // 使用日志中间件
	app.Listen(fmt.Sprintf(":%d", 8080))
}

// 统一的日志格式化输出中间件
func Logger() fiber.Handler {
	return func(c *fiber.Ctx) error {
		start := time.Now()
		// 处理请求
		err := c.Next()
		var logMessage string
		if err != nil {
			// 记录日志
			logMessage = fmt.Sprintf("[%s] %s %s - %s ==> [Error] %s\n", start.Format("2006-01-02 15:04:05"), c.Method(), c.Path(), time.Since(start), err.Error())
		} else {
			// 记录日志
			logMessage = fmt.Sprintf("[%s] %s %s - %s\n", start.Format("2006-01-02 15:04:05"), c.Method(), c.Path(), time.Since(start))
		}
		// 输出到控制台
		fmt.Print(logMessage)
		// 输出到文件
		filename := "logs/" + time.Now().Format("2006-01-02") + ".log"
		file, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
		if err != nil {
			log.Error("日志文件的打开错误 : " + err.Error())
			return err
		}
		defer file.Close()
		if _, err := file.WriteString(logMessage); err != nil {
			log.Error("写入日志文件错误 : " + err.Error())
		}
		return err
	}
}

// ......省略其他代码

自定义格式化日志输出

全局日志输出,输出的日志都是api层的日志信息,有的时候我们在其他地方也需要打印日志信息,并且把它们也输出到文件中,并且日志的格式要和全局日志的输出格式一致。

我们先在项目根目录建一个 log 文件夹,里面建一个 log.go 文件,在这里实现自定义日志输出

【Go】全局日志处理、按天生成日志文件、格式化日志输出_第1张图片

import (
	"fmt"
	"os"
	"path/filepath"
	"runtime"
	"time"
)

func Info(msg string) {
	logOut(msg, "Info")
}

func Debug(msg string) {
	logOut(msg, "Debug")
}

func Error(msg string) {
	logOut(msg, "Error")
}

// 日志格式化输出
func logOut(msg string, level string) {
	start := time.Now()
	// 获取调用的文件和行号
	_, file, line, _ := runtime.Caller(2)
	file = filepath.Base(file)
	// 使用日志包记录日志,并包括级别、文件名和行号
	logMsg := fmt.Sprintf("[%s] - %s ==> [%s:%d] [%s] %s\n",
		start.Format("2006-01-02 15:04:05"),
		time.Since(start),
		file,
		line,
		level,
		msg,
	)
	fmt.Print(logMsg)  // 打印到控制台
	logOutFile(logMsg) // 输出到文件
}

// 日志输出到文件
func logOutFile(msg string) {
	// 输出到文件
	filename := "logs/" + time.Now().Format("2006-01-02") + ".log"
	file, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		fmt.Println("日志文件的打开错误 :", err)
	}
	defer file.Close()
	if _, err := file.WriteString(msg); err != nil {
		fmt.Println("写入日志文件错误 :", err)
	}
}

使用

// 在获取公钥的接口,输出错误日志
// 获取公钥
func GetKey(c *fiber.Ctx) error {
	err := errors.New("全局日志输出:获取公钥错误")
	log.Info("自定义日志输出:获取公钥错误")
	log.Debug("自定义日志输出:获取公钥错误")
	log.Error("自定义日志输出:获取公钥错误")
	//return c.Status(200).JSON(config.Success(util.GetPublicKey()))
	return err
}

输出

控制台

[2023-09-15 16:13:06] - 11.3557ms ==> [login_controller.go:15] [Info] 自定义日志输出:获取公钥错误
[2023-09-15 16:13:06] - 0s ==> [login_controller.go:16] [Debug] 自定义日志输出:获取公钥错误
[2023-09-15 16:13:06] - 55.5µs ==> [login_controller.go:17] [Error] 自定义日志输出:获取公钥错误
[2023-09-15 16:13:06] GET /sys/getKey - 12.5681ms ==> [Error] 全局日志输出:获取公钥错误

日志文件

[2023-09-15 16:13:06] - 11.3557ms ==> [login_controller.go:15] [Info] 自定义日志输出:获取公钥错误
[2023-09-15 16:13:06] - 0s ==> [login_controller.go:16] [Debug] 自定义日志输出:获取公钥错误
[2023-09-15 16:13:06] - 55.5µs ==> [login_controller.go:17] [Error] 自定义日志输出:获取公钥错误
[2023-09-15 16:13:06] GET /sys/getKey - 12.5681ms ==> [Error] 全局日志输出:获取公钥错误

可以看到,控制台和日志文件输出的是一样的。

你可能感兴趣的:(Go,golang,后端)