56 Star 153 Fork 40

青苗 / gmfs

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
logger.go 30.66 KB
一键复制 编辑 原始数据 按行查看 历史
= 提交于 2015-08-13 11:29 . golang 基于 gridFs 的分布式文件服务
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235
package logger
import (
"fmt"
"log"
"net/http"
_ "net/http/pprof"
"os"
"runtime"
"runtime/debug"
"strings"
"sync"
"time"
)
type LEVEL int //日志等级
type COLOR int //显示颜色
type STYLE int //显示样式
const (
ALL LEVEL = iota //所有日志
DEBUG //调试
INFO //信息
WARN //警告
ERROR //错误
FATAL //崩溃
)
const (
CLR_BLACK = COLOR(30) // 黑色
CLR_RED = COLOR(31) // 红色
CLR_GREEN = COLOR(32) // 绿色
CLR_YELLOW = COLOR(33) // 黄色
CLR_BLUE = COLOR(34) // 蓝色
CLR_PURPLE = COLOR(35) // 紫红色
CLR_CYAN = COLOR(36) // 青蓝色
CLR_WHITE = COLOR(37) // 白色
CLR_DEFAULT = COLOR(39) // 默认
)
const (
STYLE_DEFAULT = STYLE(0) //终端默认设置
STYLE_HIGHLIGHT = STYLE(1) //高亮显示
SYTLE_UNDERLINE = STYLE(4) //使用下划线
SYTLE_BLINK = STYLE(5) //闪烁
STYLE_INVERSE = STYLE(7) //反白显示
STYLE_INVISIBLE = STYLE(8) //不可见
)
const (
logFlags = log.Ldate | log.Lmicroseconds | log.Lshortfile //日志输出flag
logConsoleFlag = 0 //console输出flag
logDumpExceptionFlag = 0 //exception输出flag
logMaxSize = 512 * 1024 * 1024 //单个日志文件最大大小
)
/******************************************************************************
@brief
日志文件类结构
@author
chenzhiguo
@fork
github.com/baickl/logger
*******************************************************************************/
type LOG_FILE struct {
sync.RWMutex //线程锁
log_dir string //日志存放目录
log_filename string //日志基础名字
timestamp time.Time //日志创建时的时间戳
logfilepath string //当前日志路径
logfile *os.File //当前日志文件实例
logger *log.Logger //当前日志操作实例
}
var (
logLevel LEVEL = ALL //日志级别
logConsole bool = true //终端控制台显示控制,默认为true
logConsolePrefix string //终端控制台显示前缀
logFile *LOG_FILE //日志文件实例
)
/* 字符串 level 转换 */
func ConvLevel(level string) LEVEL {
if level == "all" || level == "ALL" {
return ALL
} else if level == "deubg" || level == "DEBUG" {
return DEBUG
} else if level == "info" || level == "INFO" {
return INFO
} else if level == "warn" || level == "WARN" {
return WARN
} else if level == "error" || level == "ERROR" {
return ERROR
} else if level == "fatal" || level == "FATAL" {
return FATAL
} else {
return WARN
}
}
/******************************************************************************
@brief
设置终端控制台是否显示日志
@param
isConsole 是否显示
@return
-
*******************************************************************************/
func SetConsole(isConsole bool) {
logConsole = isConsole
}
/******************************************************************************
@brief
设置终端控制台显示前缀
@param
prefix 要显示的前缀
@return
-
*******************************************************************************/
func SetConsolePrefix(prefix string) {
logConsolePrefix = prefix
}
/******************************************************************************
@brief
设置日志记录级别,低于这个级别的日志将会被丢弃
@param
_level 级别
@return
-
*******************************************************************************/
func SetLevel(_level LEVEL) {
logLevel = _level
}
/******************************************************************************
@brief
用颜色来显示字符串
@param
str 待显示的字符串
s 显示样式
fc 显示前景色
bc 显示背景色
@return
string 返回生成的格式化字符
*******************************************************************************/
func SprintColor(str string, s STYLE, fc, bc COLOR) string {
_fc := int(fc) //前景色
_bc := int(bc) + 10 //背景色
return fmt.Sprintf("%c[%d;%d;%dm%s%c[0m", 0x1B, int(s), _bc, _fc, str, 0x1B)
}
/******************************************************************************
@brief
日志系统初始化,需要提供存放目录和日志基础名字
例:
logger.Initialize("./log/","login_server")
那么日志系统会创建 ./log/20150516/login_server_1022.log 日志文件
@param
fileDir 日志存放路径
fileName 日志基础名称
@return
int 返回结果
*******************************************************************************/
func Initialize(fileDir, fileName string) {
//目录修正
dir := fileDir
if fileDir[len(fileDir)-1] == '\\' || fileDir[len(fileDir)-1] == '/' {
dir = fileDir[:len(fileDir)-1]
}
//初始化结构体
logFile = &LOG_FILE{log_dir: dir, log_filename: fileName, timestamp: time.Now()}
logFile.Lock()
defer logFile.Unlock()
//创建文件
fn := logFile.newlogfile()
var err error
logFile.logfile, err = os.OpenFile(fn, os.O_RDWR|os.O_APPEND|os.O_CREATE, os.ModePerm)
if err != nil {
panic(err)
}
//初始化日志
logFile.logger = log.New(logFile.logfile, "", logFlags)
log.SetFlags(logConsoleFlag)
logFile.logfilepath = fn
//启动文件监控模块
go fileMonitor()
}
/******************************************************************************
@brief
启动性能分析协程
@param
port 当前服务器端口,性能分析端口会监听端口:port+10000
@return
-
*******************************************************************************/
func StartPPROF(port int) {
go func(_port int) {
log.Println(http.ListenAndServe(fmt.Sprintf(":%d", 10000+_port), nil))
}(port)
}
/******************************************************************************
@brief
捕获异常处理函数,如果发现程序有异常以后,会在当前目录中创建异常目录,并将异常信息写入到文件中
例如:
func foo(){
defer logger.CatchException()
panic(123) //此panic会被logger.CatchException()函数捕获并记录
}
@param
-
@return
-
*******************************************************************************/
func CatchException() {
if err := recover(); err != nil {
logfile, err2 := os.OpenFile(newDumpFile(), os.O_RDWR|os.O_APPEND|os.O_CREATE, os.ModePerm)
if err2 != nil {
return
}
defer logfile.Close()
logger := log.New(logfile, "", logFlags)
logger.SetFlags(logDumpExceptionFlag)
strLog := fmt.Sprintf(`
===============================================================================
EXCEPTION: %#v
===============================================================================
%s`,
err,
string(debug.Stack()))
logger.Println(strLog)
fmt.Println(strLog)
}
}
/******************************************************************************
@brief
生成新的dump文件路径
@param
-
@return
string 返回dump文件路径
*******************************************************************************/
func newDumpFile() string {
now := time.Now()
filename := fmt.Sprintf("exceptions.%02d_%02d_%02d", now.Hour(), now.Minute(), now.Second())
dir := fmt.Sprintf("./exceptions/%04d-%02d-%02d/", now.Year(), int(now.Month()), now.Day())
os.MkdirAll(dir, os.ModePerm)
fn := fmt.Sprintf("%s%s.log", dir, filename)
if !isFileExist(fn) {
return fn
}
n := 1
for {
fn = fmt.Sprintf("%s%s_%d.log", dir, filename, n)
if !isFileExist(fn) {
break
}
n += 1
}
return fn
}
type Verbose bool
func V(level LEVEL) Verbose {
if logLevel >= level {
return Verbose(true)
}
return Verbose(false)
}
/******************************************************************************
@brief
输出Debug日志
@see
logger.Debug
*******************************************************************************/
func (v Verbose) Debug(arg interface{}) {
if !v {
return
}
defer catchError()
context := fmt.Sprintf("DEBUG %s", fmt.Sprintln(arg))
context = strings.TrimRight(context, "\n")
if logFile != nil {
logFile.RLock()
defer logFile.RUnlock()
logFile.logger.Output(2, context)
}
console(DEBUG, context)
}
/******************************************************************************
@brief
输出Debug日志
@see
logger.Info
*******************************************************************************/
func (v Verbose) Info(arg interface{}) {
if !v {
return
}
defer catchError()
context := fmt.Sprintf("INFO %s", fmt.Sprintln(arg))
context = strings.TrimRight(context, "\n")
if logFile != nil {
logFile.RLock()
defer logFile.RUnlock()
logFile.logger.Output(2, context)
}
console(INFO, context)
}
/******************************************************************************
@brief
输出Debug日志
@see
logger.Warn
*******************************************************************************/
func (v Verbose) Warn(arg interface{}) {
if !v {
return
}
defer catchError()
context := fmt.Sprintf("WARN %s", fmt.Sprintln(arg))
context = strings.TrimRight(context, "\n")
if logFile != nil {
logFile.RLock()
defer logFile.RUnlock()
logFile.logger.Output(2, context)
}
console(WARN, context)
}
/******************************************************************************
@brief
输出Debug日志
@see
logger.Error
*******************************************************************************/
func (v Verbose) Error(arg interface{}) {
if !v {
return
}
defer catchError()
context := fmt.Sprintf("ERROR %s", fmt.Sprintln(arg))
context = strings.TrimRight(context, "\n")
if logFile != nil {
logFile.RLock()
defer logFile.RUnlock()
logFile.logger.Output(2, context)
}
console(ERROR, context)
}
/******************************************************************************
@brief
输出Debug日志
@see
logger.Fatal
*******************************************************************************/
func (v Verbose) Fatal(arg interface{}) {
if !v {
return
}
defer catchError()
context := fmt.Sprintf("FATAL %s", fmt.Sprintln(arg))
context = strings.TrimRight(context, "\n")
if logFile != nil {
logFile.RLock()
defer logFile.RUnlock()
logFile.logger.Output(2, context)
}
console(FATAL, context)
}
/******************************************************************************
@brief
输出Debug日志
@see
logger.Debugf
*******************************************************************************/
func (v Verbose) Debugf(format string, args ...interface{}) {
if !v {
return
}
defer catchError()
context := fmt.Sprintf("DEBUG %s", fmt.Sprintf(format, args...))
context = strings.TrimRight(context, "\n")
if logFile != nil {
logFile.RLock()
defer logFile.RUnlock()
logFile.logger.Output(2, context)
}
console(DEBUG, context)
}
/******************************************************************************
@brief
输出Debug日志
@see
logger.Info
*******************************************************************************/
func (v Verbose) Infof(format string, args ...interface{}) {
if !v {
return
}
defer catchError()
context := fmt.Sprintf("INFO %s", fmt.Sprintf(format, args...))
context = strings.TrimRight(context, "\n")
if logFile != nil {
logFile.RLock()
defer logFile.RUnlock()
logFile.logger.Output(2, context)
}
console(INFO, context)
}
/******************************************************************************
@brief
输出Debug日志
@see
logger.Warnf
*******************************************************************************/
func (v Verbose) Warnf(format string, args ...interface{}) {
if !v {
return
}
defer catchError()
context := fmt.Sprintf("WARN %s", fmt.Sprintf(format, args...))
context = strings.TrimRight(context, "\n")
if logFile != nil {
logFile.RLock()
defer logFile.RUnlock()
logFile.logger.Output(2, context)
}
console(WARN, context)
}
/******************************************************************************
@brief
输出Debug日志
@see
logger.Errorf
*******************************************************************************/
func (v Verbose) Errorf(format string, args ...interface{}) {
if !v {
return
}
defer catchError()
context := fmt.Sprintf("ERROR %s", fmt.Sprintf(format, args...))
context = strings.TrimRight(context, "\n")
if logFile != nil {
logFile.RLock()
defer logFile.RUnlock()
logFile.logger.Output(2, context)
}
console(ERROR, context)
}
/******************************************************************************
@brief
输出Debug日志
@see
logger.Fatalf
*******************************************************************************/
func (v Verbose) Fatalf(format string, args ...interface{}) {
if !v {
return
}
defer catchError()
context := fmt.Sprintf("FATAL %s", fmt.Sprintf(format, args...))
context = strings.TrimRight(context, "\n")
if logFile != nil {
logFile.RLock()
defer logFile.RUnlock()
logFile.logger.Output(2, context)
}
console(FATAL, context)
}
/******************************************************************************
@brief
输出Debug日志
@see
logger.Debugln
*******************************************************************************/
func (v Verbose) Debugln(args ...interface{}) {
if !v {
return
}
defer catchError()
context := fmt.Sprintf("DEBUG %s", fmt.Sprintln(args...))
context = strings.TrimRight(context, "\n")
if logFile != nil {
logFile.RLock()
defer logFile.RUnlock()
logFile.logger.Output(2, context)
}
console(DEBUG, context)
}
/******************************************************************************
@brief
输出Debug日志
@see
logger.Infoln
*******************************************************************************/
func (v Verbose) Infoln(args ...interface{}) {
if !v {
return
}
defer catchError()
context := fmt.Sprintf("INFO %s", fmt.Sprintln(args...))
context = strings.TrimRight(context, "\n")
if logFile != nil {
logFile.RLock()
defer logFile.RUnlock()
logFile.logger.Output(2, context)
}
console(INFO, context)
}
/******************************************************************************
@brief
输出Debug日志
@see
logger.Warnln
*******************************************************************************/
func (v Verbose) Warnln(args ...interface{}) {
if !v {
return
}
defer catchError()
context := fmt.Sprintf("WARN %s", fmt.Sprintln(args...))
context = strings.TrimRight(context, "\n")
if logFile != nil {
logFile.RLock()
defer logFile.RUnlock()
logFile.logger.Output(2, context)
}
console(WARN, context)
}
/******************************************************************************
@brief
输出Debug日志
@see
logger.Errorln
*******************************************************************************/
func (v Verbose) Errorln(args ...interface{}) {
if !v {
return
}
defer catchError()
context := fmt.Sprintf("ERROR %s", fmt.Sprintln(args...))
context = strings.TrimRight(context, "\n")
if logFile != nil {
logFile.RLock()
defer logFile.RUnlock()
logFile.logger.Output(2, context)
}
console(ERROR, context)
}
/******************************************************************************
@brief
输出Debug日志
@see
logger.Fatalln
*******************************************************************************/
func (v Verbose) Fatalln(args ...interface{}) {
if !v {
return
}
defer catchError()
context := fmt.Sprintf("FATAL %s", fmt.Sprintln(args...))
context = strings.TrimRight(context, "\n")
if logFile != nil {
logFile.RLock()
defer logFile.RUnlock()
logFile.logger.Output(2, context)
}
console(FATAL, context)
}
/******************************************************************************
@brief
输出Debug日志
@param
arg 要输出的内容
@return
-
*******************************************************************************/
func Debug(arg interface{}) {
defer catchError()
if logLevel <= DEBUG {
context := fmt.Sprintf("DEBUG %s", fmt.Sprintln(arg))
context = strings.TrimRight(context, "\n")
if logFile != nil {
logFile.RLock()
defer logFile.RUnlock()
logFile.logger.Output(2, context)
}
console(DEBUG, context)
}
}
/******************************************************************************
@brief
输出Info日志
@param
arg 要输出的内容
@return
-
*******************************************************************************/
func Info(arg interface{}) {
defer catchError()
if logLevel <= INFO {
context := fmt.Sprintf("INFO %s", fmt.Sprintln(arg))
context = strings.TrimRight(context, "\n")
if logFile != nil {
logFile.RLock()
defer logFile.RUnlock()
logFile.logger.Output(2, context)
}
console(INFO, context)
}
}
/******************************************************************************
@brief
输出Warn日志
@param
arg 要输出的内容
@return
-
*******************************************************************************/
func Warn(arg interface{}) {
defer catchError()
if logLevel <= WARN {
context := fmt.Sprintf("WARN %s", fmt.Sprintln(arg))
context = strings.TrimRight(context, "\n")
if logFile != nil {
logFile.RLock()
defer logFile.RUnlock()
logFile.logger.Output(2, context)
}
console(WARN, context)
}
}
/******************************************************************************
@brief
输出Error日志
@param
arg 要输出的内容
@return
-
*******************************************************************************/
func Error(arg interface{}) {
defer catchError()
if logLevel <= ERROR {
context := fmt.Sprintf("ERROR %s", fmt.Sprintln(arg))
context = strings.TrimRight(context, "\n")
if logFile != nil {
logFile.RLock()
defer logFile.RUnlock()
logFile.logger.Output(2, context)
}
console(ERROR, context)
}
}
/******************************************************************************
@brief
输出Fatal日志
@param
arg 要输出的内容
@return
-
*******************************************************************************/
func Fatal(arg interface{}) {
defer catchError()
if logLevel <= FATAL {
context := fmt.Sprintf("FATAL %s", fmt.Sprintln(arg))
context = strings.TrimRight(context, "\n")
if logFile != nil {
logFile.RLock()
defer logFile.RUnlock()
logFile.logger.Output(2, context)
}
console(FATAL, context)
}
}
/******************************************************************************
@brief
输出Debug日志,支持格式化操作
@param
format 格式化字符或字符串
args 格式化参数
@return
-
*******************************************************************************/
func Debugf(format string, args ...interface{}) {
defer catchError()
if logLevel <= DEBUG {
context := fmt.Sprintf("DEBUG %s", fmt.Sprintf(format, args...))
context = strings.TrimRight(context, "\n")
if logFile != nil {
logFile.RLock()
defer logFile.RUnlock()
logFile.logger.Output(2, context)
}
console(DEBUG, context)
}
}
/******************************************************************************
@brief
输出Info日志,支持格式化操作
@param
format 格式化字符或字符串
args 格式化参数
@return
-
*******************************************************************************/
func Infof(format string, args ...interface{}) {
defer catchError()
if logLevel <= INFO {
context := fmt.Sprintf("INFO %s", fmt.Sprintf(format, args...))
context = strings.TrimRight(context, "\n")
if logFile != nil {
logFile.RLock()
defer logFile.RUnlock()
logFile.logger.Output(2, context)
}
console(INFO, context)
}
}
/******************************************************************************
@brief
输出Warn日志,支持格式化操作
@param
format 格式化字符或字符串
args 格式化参数
@return
-
*******************************************************************************/
func Warnf(format string, args ...interface{}) {
defer catchError()
if logLevel <= WARN {
context := fmt.Sprintf("WARN %s", fmt.Sprintf(format, args...))
context = strings.TrimRight(context, "\n")
if logFile != nil {
logFile.RLock()
defer logFile.RUnlock()
logFile.logger.Output(2, context)
}
console(WARN, context)
}
}
/******************************************************************************
@brief
输出Error日志,支持格式化操作
@param
format 格式化字符或字符串
args 格式化参数
@return
-
*******************************************************************************/
func Errorf(format string, args ...interface{}) {
defer catchError()
if logLevel <= ERROR {
context := fmt.Sprintf("ERROR %s", fmt.Sprintf(format, args...))
context = strings.TrimRight(context, "\n")
if logFile != nil {
logFile.RLock()
defer logFile.RUnlock()
logFile.logger.Output(2, context)
}
console(ERROR, context)
}
}
/******************************************************************************
@brief
输出Fatal日志,支持格式化操作
@param
format 格式化字符或字符串
args 格式化参数
@return
-
*******************************************************************************/
func Fatalf(format string, args ...interface{}) {
defer catchError()
if logLevel <= FATAL {
context := fmt.Sprintf("FATAL %s", fmt.Sprintf(format, args...))
context = strings.TrimRight(context, "\n")
if logFile != nil {
logFile.RLock()
defer logFile.RUnlock()
logFile.logger.Output(2, context)
}
console(FATAL, context)
}
}
/******************************************************************************
@brief
输出Debug日志
@param
format 格式化字符或字符串
args 格式化参数
@return
-
*******************************************************************************/
func Debugln(args ...interface{}) {
defer catchError()
if logLevel <= DEBUG {
context := fmt.Sprintf("DEBUG %s", fmt.Sprintln(args...))
context = strings.TrimRight(context, "\n")
if logFile != nil {
logFile.RLock()
defer logFile.RUnlock()
logFile.logger.Output(2, context)
}
console(DEBUG, context)
}
}
/******************************************************************************
@brief
输出Info日志
@param
format 格式化字符或字符串
args 格式化参数
@return
-
*******************************************************************************/
func Infoln(args ...interface{}) {
defer catchError()
if logLevel <= INFO {
context := fmt.Sprintf("INFO %s", fmt.Sprintln(args...))
context = strings.TrimRight(context, "\n")
if logFile != nil {
logFile.RLock()
defer logFile.RUnlock()
logFile.logger.Output(2, context)
}
console(INFO, context)
}
}
/******************************************************************************
@brief
输出Warn日志
@param
format 格式化字符或字符串
args 格式化参数
@return
-
*******************************************************************************/
func Warnln(args ...interface{}) {
defer catchError()
if logLevel <= WARN {
context := fmt.Sprintf("WARN %s", fmt.Sprintln(args...))
context = strings.TrimRight(context, "\n")
if logFile != nil {
logFile.RLock()
defer logFile.RUnlock()
logFile.logger.Output(2, context)
}
console(WARN, context)
}
}
/******************************************************************************
@brief
输出Error日志
@param
format 格式化字符或字符串
args 格式化参数
@return
-
*******************************************************************************/
func Errorln(args ...interface{}) {
defer catchError()
if logLevel <= ERROR {
context := fmt.Sprintf("ERROR %s", fmt.Sprintln(args...))
context = strings.TrimRight(context, "\n")
if logFile != nil {
logFile.RLock()
defer logFile.RUnlock()
logFile.logger.Output(2, context)
}
console(ERROR, context)
}
}
/******************************************************************************
@brief
输出Fatal日志
@param
format 格式化字符或字符串
args 格式化参数
@return
-
*******************************************************************************/
func Fatalln(args ...interface{}) {
defer catchError()
if logLevel <= FATAL {
context := fmt.Sprintf("FATAL %s", fmt.Sprintln(args...))
context = strings.TrimRight(context, "\n")
if logFile != nil {
logFile.RLock()
defer logFile.RUnlock()
logFile.logger.Output(2, context)
}
console(FATAL, context)
}
}
/******************************************************************************
@brief
输出检查日志是否需要重新命名,比如说跨天,大小变化,或是文件已经不存在
@param
-
@return
bool 返回true表示需要重命名,否则不需要
@history
*******************************************************************************/
func (f *LOG_FILE) isMustRename() bool {
//检查是否跨天
if f.checkFileDate() {
return true
}
//检查大小是否有变化
if f.checkFileSize() {
return true
}
//检查文件是否存在
if f.checkFileExist() {
return true
} else {
os.MkdirAll(f.log_dir, os.ModePerm)
}
return false
}
/******************************************************************************
@brief
检查文件日期是否已经跨天
@param
-
@return
bool 返回true表示已经跨天,否则没有
*******************************************************************************/
func (f *LOG_FILE) checkFileDate() bool {
if time.Now().YearDay() != f.timestamp.YearDay() {
return true
}
return false
}
/******************************************************************************
@brief
检查文件大小是否已经超过指定的大小
@param
-
@return
bool 返回true表示已经超过,否则没有
*******************************************************************************/
func (f *LOG_FILE) checkFileSize() bool {
fileInfo, err := os.Stat(f.logfilepath)
if err != nil {
return false
}
if fileInfo.Size() >= logMaxSize {
return true
}
return false
}
/******************************************************************************
@brief
检查文件大小是否存在
@param
-
@return
bool 返回true表示存在,否则表示没有有文件或是没有权限访问
*******************************************************************************/
func (f *LOG_FILE) checkFileExist() bool {
if !isFileExist(f.logfilepath) {
return true
}
return false
}
/******************************************************************************
@brief
执行文件重命名操作
@param
-
@return
-
*******************************************************************************/
func (f *LOG_FILE) rename() {
f.timestamp = time.Now()
fn := f.newlogfile()
if f.logfile != nil {
f.logfile.Close()
}
f.logfile, _ = os.OpenFile(fn, os.O_RDWR|os.O_APPEND|os.O_CREATE, os.ModePerm)
f.logger = log.New(logFile.logfile, "", logFlags)
f.logfilepath = fn
}
/******************************************************************************
@brief
获取新的日志文件的名称
@param
-
@return
string 返回名称
*******************************************************************************/
func (f *LOG_FILE) newlogfile() string {
dir := fmt.Sprintf("%s/%04d-%02d-%02d/", f.log_dir, f.timestamp.Year(), f.timestamp.Month(), f.timestamp.Day())
os.MkdirAll(dir, os.ModePerm)
filename := fmt.Sprintf("%s/%s.%02d_%02d_%02d", dir, f.log_filename, f.timestamp.Hour(), f.timestamp.Minute(), f.timestamp.Second())
fn := filename + ".log"
if !isFileExist(fn) {
return fn
}
n := 1
for {
fn = fmt.Sprintf("%s_%d.log", filename, n)
if !isFileExist(fn) {
break
}
n += 1
}
return fn
}
/******************************************************************************
@brief
判断文件是否存在
@param
file 文件路径
@return
bool 返回true表示文件存在,否则表示不存在
*******************************************************************************/
func isFileExist(file string) bool {
finfo, err := os.Stat(file)
if err != nil {
return false
}
if finfo.IsDir() {
return false
} else {
return true
}
}
/******************************************************************************
@brief
输出信息到终端控制台上
@param
ll 日志等级
args 要输出的内容
@return
-
*******************************************************************************/
func console(ll LEVEL, args string) {
if logConsole {
_, file, line, _ := runtime.Caller(2)
short := file
for i := len(file) - 1; i > 0; i-- {
if file[i] == '/' {
short = file[i+1:]
break
}
}
file = short
now := time.Now()
context := ""
if len(logConsolePrefix) > 0 {
context = fmt.Sprintf("==>[%04d/%02d/%02d_%02d:%02d:%02d.%06d] @%s #%s:%d %s", now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second(), time.Duration(now.Nanosecond())/(time.Microsecond), logConsolePrefix, file, line, args)
} else {
context = fmt.Sprintf("==>[%04d/%02d/%02d_%02d:%02d:%02d.%06d] #%s:%d %s", now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second(), time.Duration(now.Nanosecond())/(time.Microsecond), file, line, args)
}
switch ll {
case DEBUG:
log.Println(SprintColor(context, STYLE_DEFAULT, CLR_DEFAULT, CLR_DEFAULT))
case INFO:
log.Println(SprintColor(context, STYLE_DEFAULT, CLR_DEFAULT, CLR_DEFAULT))
case WARN:
log.Println(SprintColor(context, STYLE_DEFAULT, CLR_YELLOW, CLR_DEFAULT))
case ERROR:
log.Println(SprintColor(context, STYLE_HIGHLIGHT, CLR_RED, CLR_DEFAULT))
case FATAL:
log.Println(SprintColor(context, STYLE_HIGHLIGHT, CLR_PURPLE, CLR_DEFAULT))
default:
log.Println(SprintColor(context, STYLE_DEFAULT, CLR_DEFAULT, CLR_DEFAULT))
}
}
}
/******************************************************************************
@brief
捕获程序错误,仅供内部使用
@param
-
@return
-
*******************************************************************************/
func catchError() {
if err := recover(); err != nil {
log.Println("err", err)
}
}
/******************************************************************************
@brief
文件监控函数,循环检测文件是否需要重命名
@param
-
@return
-
*******************************************************************************/
func fileMonitor() {
timer := time.NewTicker(10 * time.Second)
for {
select {
case <-timer.C:
fileCheck()
}
}
}
/******************************************************************************
@brief
检查文件是否需要重命名,如果需要,那么执行重命名逻辑
@param
-
@return
*******************************************************************************/
func fileCheck() {
defer catchError()
if logFile != nil && logFile.isMustRename() {
logFile.Lock()
defer logFile.Unlock()
logFile.rename()
}
}
Go
1
https://gitee.com/jobob/gmfs.git
git@gitee.com:jobob/gmfs.git
jobob
gmfs
gmfs
8375e82f13e4

搜索帮助