首页 > 其他分享 >golang 标准库log的封装

golang 标准库log的封装

时间:2022-12-01 12:22:22浏览次数:76  
标签:src 封装 log err golang func return os

都知道golang的log库可以拿来就用,但对于生产来说还不够,需要基于log库做点封装。除了这些还有其他问题,比如打印字段定制化,性能问题。本文不讨论太多,只对log进行简单封装,实现log的持久化,分loglevel等功能。

参考:

代码结构

具体代码

main入口

package main

import (
	lu "go-stdLog/log_utils"
)

func main()  {
	lgfile, err := lu.MustOpen("log.txt", "logs")
	if err != nil {
		lu.Error("Failed to open log file:" + err.Error())
	}

	lu.Config(lu.DEBUG, lgfile)

	// balabala
	lu.Debug("msg")
	lu.Info("msg")
	lu.Warning("msg")
	lu.Error("msg")

}

log_utils.log

package log_utils

import (
	"fmt"
	"io/ioutil"
	"log"
	"mime/multipart"
	"os"
	"path"
	"runtime"
	"strings"
)

/*
 * reference: go原生log模块的简易封装 https://cloud.tencent.com/developer/article/1673063
 */
type Level int

const (
	DEBUG Level = iota
	INFO
	WARNING
	ERROR
	FATAL
)

var (
	logPrefix = ""
	levelFlags = []string{"DEBG", "INFO", "WARN", "ERRO", "FATL"}

	logger *log.Logger
	loggerf *log.Logger

	curLevel Level
	logfile *os.File
)

func init()  {
	curLevel = DEBUG
	logger = log.New(os.Stdout, "[Default] ", log.LstdFlags)
	logger.SetFlags(log.Ldate | log.Lmicroseconds | log.Llongfile)
}

func Println(l *log.Logger, v ...interface{})  {
	if l != nil {
		l.Output(3, fmt.Sprintln(v...))
	}
}

func Fatalln(l *log.Logger, v ...interface{})  {
	if l != nil {
		l.Output(3, fmt.Sprintln(v...))
		os.Exit(1)
	}
}

func setPrefix(level Level)  {
	// stdout
	logPrefix = fmt.Sprintf("[%s] ", levelFlags[level])
	logger.SetPrefix(logPrefix)
	// log file
	if loggerf != nil {
		loggerf.SetPrefix(logPrefix)
	}
}

func Debug(v ...interface{})  {
	setPrefix(DEBUG)
	if DEBUG >= curLevel {
		Println(logger, v)
		Println(loggerf, v)
	}

}

func Info(v ...interface{})  {
	setPrefix(INFO)
	if INFO >= curLevel {
		Println(logger, v)
		Println(loggerf, v)
	}

}

func Warning(v ...interface{})  {
	setPrefix(WARNING)
	if WARNING >= curLevel {
		Println(logger, v)
		Println(loggerf, v)
	}

}

func Error(v ...interface{})  {
	setPrefix(ERROR)
	if ERROR >= curLevel {
		Println(logger, v)
		Println(loggerf, v)
	}

}

func Fatal(v ...interface{})  {
	setPrefix(FATAL)
	if FATAL >= curLevel {
		Println(logger, v)
		Println(loggerf, v)
	}

}

func Config(level Level, lfile *os.File)  {
	curLevel = level
	loggerf = log.New(lfile, "[default] ", log.LstdFlags)
	loggerf.SetFlags(log.Ldate | log.Lmicroseconds | log.Llongfile)
}

// support file log
func getSize(f multipart.File) (int, error) {
	content, err := ioutil.ReadAll(f)

	return len(content), err
}

func getExt(filename string) string {
	return path.Ext(filename)
}

func checkIsExist(src string) bool {
	_, err := os.Stat(src)
	return os.IsNotExist(err)
}

func checkPermission(src string) bool {
	_, err := os.Stat(src)
	return os.IsPermission(err)
}

func mkdir(src string) error {
	err := os.MkdirAll(src, os.ModePerm)
	if err != nil {
		return err
	}

	return nil
}

func NotExistMkDir(src string) error {
	if exist := checkIsExist(src); exist {
		if err := mkdir(src); err != nil {
			return err
		}
	}

	return nil
}

func lastDir(dir string) string {

	return ""
}

func compareString(s1, s2 string) bool {
	if len(s1) != len(s2) {
		return false
	}

	for i, _ := range s1 {
		if s1[i] != s2[i] {
			return false
		}
	}

	return true
}

func Open(name string, flag int, perm os.FileMode) (*os.File, error) {
	f, err := os.OpenFile(name, flag, perm)
	if err != nil {
		return nil, err
	}

	return f, nil
}

func MustOpen(filename, filepath string) (*os.File, error) {
	dir, err := os.Getwd()
	if err != nil {
		return nil, fmt.Errorf("os.Getwd err: %v", err)
	}

	osTyp := runtime.GOOS
	if compareString(osTyp, "windows") {
		dirs := strings.Split(dir, "\\")
		dir = strings.Join(dirs[:], "\\")
	}

	var src string
	var perm bool
	if compareString(osTyp, "windows") {
		src = dir + "\\" + filepath
		perm = checkPermission(src)
	} else {
		src = path.Join(dir, filepath)
		perm = checkPermission(src)
	}

	if perm {
		return nil, fmt.Errorf("file.CheckPermission Permission denied src: %s", src)
	}

	err = NotExistMkDir(src)
	if err != nil {
		return nil, fmt.Errorf("file.IsNotExistMkDir src: %s, err: %v", src, err)
	}
	// default windows system
	f, err := Open(src + "\\" + filename, os.O_APPEND | os.O_CREATE | os.O_RDWR, 0644)
	if err != nil {
		return nil, fmt.Errorf("Fail to OpenFile :%v", err)
	}

	return f, nil
}

由于没有用到第三方库,不列出go.mod/go.sum。

测试结果

console

log文件

以上就是基于标准库log的简单实践,一般应用或不考虑性能情况下,可以试试上log库。

标签:src,封装,log,err,golang,func,return,os
From: https://www.cnblogs.com/davis12/p/16941053.html

相关文章

  • logback依赖
    <dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.25</version></dependency><dependency><groupId>ch.......
  • 不买NAS,也能用cpolar搭建私有云盘2 (安装Synology Assistant)
    在上篇文章中,我们为大家介绍了在虚拟机中安装群晖系统的第一部分如何操作,接下来,我们要继续安装SynologyAssistant,才能让群晖NAS能够被访问到。话不多说,现在就让我们开始吧......
  • Go实现整合 Logrus 输出json格式日志
    学习与交流:Go语言技术微信群商务合作加微信:LetsFenggoland全家桶激活码,支持所有版本,支持所有系统链接:http://web.52shizhan.cn/activity/s2abxc提取码:GJF9B1DK 现......
  • 我就往代码加了一行 log 日志,结果引发了 P1 级线上事故。。大家注意!
    作者:老鹰汤链接:https://juejin.cn/post/7156439842958606349线上事故回顾前段时间新增一个特别简单的功能,晚上上线前review代码时想到公司拼搏进取的价值观临时加一行lo......
  • golang流式编程
    https://blog.csdn.net/u012986012/article/details/126833564  借助一些设计模式、流式编程、函数编程的方法可以让我们的Golang代码更清晰优雅,本文中描述了在错误处......
  • Go-05 Golang中的运算符
    packagemainimport"fmt"/* Golang中的运算符 Golang内置的运算符: 1.算术运算符:+-*/% 2.关系运算符:!===>>=<<= 返回值是True或者False 3.逻辑运......
  • Installing golang-1.18 on openEuler
    一、Installinggolang-1.18onopenEulerhttps://golang.google.cn1下载mkdir/opt/software&&cd/opt/softwarewgethttps://golang.google.cn/dl/go1.18.linux......
  • Golang实现小型CMS内容管理功能(二):前端接入百度ueditor富文本编辑器
    当我们把接口都做好以后,我们需要去开发前端界面。添加文章功能里面,最重要的就是文章内容部分,需要配置上富文本编辑器,这样才能给我们的内容增加样式。 下载ueditor代码......
  • .NET6之MiniAPI(二十六):封装Dapper
    在上一篇说过,Dapper是通过扩展IDbConnection来达到实现的,那带来的一个问题就是隔离性不好,比如在做单元测试时,mock就有点困难,所以在实践中,我对Dapper作了扩展,下面分享出......
  • .NET6之MiniAPI(二十六):封装Dapper
    在上一篇说过,Dapper是通过扩展IDbConnection来达到实现的,那带来的一个问题就是隔离性不好,比如在做单元测试时,mock就有点困难,所以在实践中,我对Dapper作了扩展,下面分享出......