都知道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