目录
代码:debug.go
package Debug
import (
"fmt"
"time"
"runtime"
"path/filepath"
"strings"
"os"
"io"
)
var LOGFILE = "./log/serverlog.log"
const (
LOG_LEVEL_DEBUG = 0
LOG_LEVEL_INFO = 1
LOG_LEVEL_WARNING = 2
LOG_LEVEL_ERROR = 3
LOG_LEVEL_EMERGENCY = 4
LOG_LEVEL_BUTT = 5
)
var LOG_LEVEL = []string{
"DEBUG",
"INFORMATION",
"WARNING",
"ERROR",
"EMERGENCY",
"UNKNOW",
}
//CurrentTime 当前时间,2018-12-22 14:41:21.4728403
func CurrentTime() string {
t := time.Now()
//fmt.Println(time.Now().Format("2006-01-02 15:04:05")) // 这是个奇葩,必须是这个时间点, 据说是go诞生之日, 记忆方法:6-1-2-3-4-5
cur := fmt.Sprintf("%s.%2d", time.Now().Format("2006-01-02 15:04:05"), t.Nanosecond())
return cur
}
func LOG_RECODE(level int, format string, a ...interface{}){
var strLog,fmtInfo string
funcInfo := ""
pc,filepath,line,ok := runtime.Caller(2)
if ok {
funcInfo = fmt.Sprintf("file:%s, line:%d, func:%s",FileName(filepath),line,FuncName(pc))
}
fmtInfo = fmt.Sprintf(format,a...)
strLog = CurrentTime() +"\t[" + LOG_LEVEL[level] + ": " + funcInfo + "]: " + fmtInfo + "\n"
WriteWithGolog(LOGFILE,strLog)
}
func WriteWithGolog(filename,content string) {
f, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
if err != nil {
return
}
data :=[]byte(content)
n, err := f.Write(data)
if err == nil && n < len(data) {
err = io.ErrShortWrite
}
if err1 := f.Close(); err == nil {
err = err1
}
return
}
func FileName(files string) string {
_, fileName := filepath.Split(files)
return fileName
}
func FuncName(pc uintptr) string{
var funcname string
funcname = runtime.FuncForPC(pc).Name() // main.(*MyStruct).foo
funcname = filepath.Ext(funcname) // .foo
funcname = strings.TrimPrefix(funcname, ".") // foo
return funcname
}
日志记录格式:日期+级别+文件名+行数+函数名+日志信息
再写个main函数,然后调用就行。记录如下:
2019-01-12 22:45:30.976932400 [DEBUG: file:WebServer.go, line:39, func:main]: Test for file 1
2019-01-12 22:45:31.51732300 [DEBUG: file:WebServer.go, line:35, func:test]: Test for file 2
2019-01-12 22:45:31.783777000 [DEBUG: file:WebServer.go, line:39, func:main]: Test for file 1
2019-01-12 22:45:31.857608400 [DEBUG: file:WebServer.go, line:35, func:test]: Test for file 2
2019-01-12 22:45:32.384169800 [DEBUG: file:WebServer.go, line:39, func:main]: Test for file 1
2019-01-12 22:45:32.458970800 [DEBUG: file:WebServer.go, line:35, func:test]: Test for file 2
注意:
1、WriteWithGolog
函数中的os.OpenFile参数,一定要带上os.O_RDWR|os.O_CREATE|os.O_APPEND,表示允许读写,没有的时候创建文件 ,增量记录。
2、LOG_RECODE
函数中获取文件函数名,行数,文件名,这里使用的是runtime的caller函数。
pc,filepath,line,ok := runtime.Caller(1)
参数可以选择0,1,2,其结果如下:
0:
2019-01-13 11:37:37.213593000 [DEBUG: file:debug.go, line:44, func:LOG_RECODE]: Test for file 1
2019-01-13 11:37:37.289394400 [DEBUG: file:debug.go, line:44, func:LOG_RECODE]: Test for file 2
1:
2019-01-13 11:38:16.772960800 [DEBUG: file:WebServer.go, line:39, func:main]: Test for file 1
2019-01-13 11:38:16.850787900 [DEBUG: file:WebServer.go, line:35, func:test]: Test for file 2
2:
2019-01-13 11:38:48.853679400 [DEBUG: file:proc.go, line:198, func:main]: Test for file 1
2019-01-13 11:38:48.927507800 [DEBUG: file:WebServer.go, line:40, func:main]: Test for file 2
从上面看,我这里的日志记录,用1是最合适的。
关于FuncName
主要区别是在FuncName中的runtime.FuncForPC(pc).Name()
func FuncName(pc uintptr) string{
var funcname string
funcname = runtime.FuncForPC(pc).Name() // main.(*MyStruct).foo
fmt.Println("test1 " + funcname)
funcname = filepath.Ext(funcname) // .foo
fmt.Println("test2 " + funcname)
funcname = strings.TrimPrefix(funcname, ".") // foo
fmt.Println("test3 " + funcname)
return funcname
}
0:
This is a Web Server test
test1 WebServer/Debug.LOG_RECODE
test2 .LOG_RECODE
test3 LOG_RECODE
1:
This is a Web Server test
test1 main.test
test2 .test
test3 test
2:
This is a Web Server test
test1 main.main
test2 .main
test3 main
mian
package main
import (
"WebServer/Debug"
"crypto/rand"
"crypto/tls"
"fmt"
"log"
"time"
)
const (
LOG_DEBUG = Debug.LOG_LEVEL_DEBUG //调试打印
LOG_INFO = Debug.LOG_LEVEL_INFO
LOG_WARNING = Debug.LOG_LEVEL_WARNING
LOG_ERROR = Debug.LOG_LEVEL_ERROR
LOG_EMERGENCY = Debug.LOG_LEVEL_EMERGENCY
LOG_BUTT = Debug.LOG_LEVEL_BUTT
)
func test(){
Debug.LOG_RECODE(LOG_DEBUG,"Test for file 2")
}
func main(){
fmt.Println("This is a Web Server test")
//Debug.LOG_RECODE(LOG_DEBUG,"Test for file 1")
test()
}