|
|
|
package icslog
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"fmt"
|
|
|
|
"io/ioutil"
|
|
|
|
"log"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"runtime/debug"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
"sync"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"gitlab.com/ics_cinnamon/voiceStatistics/icsconf"
|
|
|
|
"gitlab.com/ics_cinnamon/voiceStatistics/icserror"
|
|
|
|
"gitlab.com/ics_cinnamon/voiceStatistics/icsutil"
|
|
|
|
)
|
|
|
|
|
|
|
|
type IcsLog struct {
|
|
|
|
logger *log.Logger
|
|
|
|
|
|
|
|
Output int
|
|
|
|
Level int
|
|
|
|
Path string
|
|
|
|
LogFileName string
|
|
|
|
LogFile *os.File
|
|
|
|
DiskLimit int
|
|
|
|
DelDay int
|
|
|
|
DelHour int
|
|
|
|
isRotate bool
|
|
|
|
logSize int
|
|
|
|
rotateNum int
|
|
|
|
|
|
|
|
buf bytes.Buffer
|
|
|
|
CurrentDate time.Time
|
|
|
|
conf *icsconf.LogConfig
|
|
|
|
//conf *icsconf.IcsConfig
|
|
|
|
IsDiskFull bool
|
|
|
|
|
|
|
|
M *sync.Mutex
|
|
|
|
}
|
|
|
|
|
|
|
|
//default max log size 30 megabytes
|
|
|
|
const DEFAULT_LOG_MAX_SIZE = 30
|
|
|
|
|
|
|
|
//default log rotate num
|
|
|
|
const DEFAULT_LOG_ROTATE_NUM = 10
|
|
|
|
|
|
|
|
//max log rotate num
|
|
|
|
const MAX_LOG_ROTATE_NUM = 99
|
|
|
|
|
|
|
|
const (
|
|
|
|
LOG_LEVEL_DEBUG2 = iota
|
|
|
|
LOG_LEVEL_DEBUG1
|
|
|
|
LOG_LEVEL_DEBUG
|
|
|
|
LOG_LEVEL_STATIS
|
|
|
|
LOG_LEVEL_INFO
|
|
|
|
LOG_LEVEL_WARN
|
|
|
|
LOG_LEVEL_ERROR
|
|
|
|
LOG_LEVEL_FATAL
|
|
|
|
LOG_LEVEL_MAX
|
|
|
|
)
|
|
|
|
|
|
|
|
//log output
|
|
|
|
const (
|
|
|
|
LOG_OUTPUT_FILE = 1 << (32 - 1 - iota)
|
|
|
|
LOG_OUTPUT_STDOUT
|
|
|
|
)
|
|
|
|
|
|
|
|
var IcsLogLevelStr [LOG_LEVEL_MAX]string
|
|
|
|
|
|
|
|
var gIcsLog *IcsLog
|
|
|
|
var onceLog sync.Once
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
IcsLogLevelStr[LOG_LEVEL_DEBUG2] = "DEBUG2"
|
|
|
|
IcsLogLevelStr[LOG_LEVEL_DEBUG1] = "DEBUG1"
|
|
|
|
IcsLogLevelStr[LOG_LEVEL_DEBUG] = "DEBUG"
|
|
|
|
IcsLogLevelStr[LOG_LEVEL_STATIS] = "STATISTICS"
|
|
|
|
IcsLogLevelStr[LOG_LEVEL_INFO] = "INFO"
|
|
|
|
IcsLogLevelStr[LOG_LEVEL_WARN] = "WARN"
|
|
|
|
IcsLogLevelStr[LOG_LEVEL_ERROR] = "ERROR"
|
|
|
|
IcsLogLevelStr[LOG_LEVEL_FATAL] = "FATAL"
|
|
|
|
}
|
|
|
|
|
|
|
|
//if fail, return icserror
|
|
|
|
func NewIcsLog(conf *icsconf.LogConfig, level int, output int, path string, disklimit int) (*IcsLog, *icserror.IcsError) {
|
|
|
|
//func NewIcsLog(conf *icsconf.IcsConfig, level int, output int, path string, disklimit int) (*IcsLog, *icserror.IcsError) {
|
|
|
|
//func NewIcsLog(conf *icsconf.IcsConfig, level interface{}, output interface{}, path string, disklimit int) (*IcsLog, *icserror.IcsError) {
|
|
|
|
var reterr *icserror.IcsError = nil
|
|
|
|
|
|
|
|
//singleton
|
|
|
|
onceLog.Do(func() {
|
|
|
|
gIcsLog = &IcsLog{
|
|
|
|
conf: conf,
|
|
|
|
Level: level,
|
|
|
|
Output: output,
|
|
|
|
Path: path,
|
|
|
|
DiskLimit: disklimit,
|
|
|
|
IsDiskFull: false,
|
|
|
|
logSize: DEFAULT_LOG_MAX_SIZE,
|
|
|
|
rotateNum: DEFAULT_LOG_ROTATE_NUM,
|
|
|
|
}
|
|
|
|
|
|
|
|
gIcsLog.M = &sync.Mutex{}
|
|
|
|
gIcsLog.isRotate = strings.Compare("YES", strings.ToUpper(gIcsLog.conf.RotateConfig.YesNo)) == 0
|
|
|
|
//gIcsLog.isRotate = strings.Compare("YES", strings.ToUpper(gIcsLog.conf.LogConfig.RotateConfig.YesNo)) == 0
|
|
|
|
var serr error
|
|
|
|
gIcsLog.logSize, serr = strconv.Atoi(gIcsLog.conf.RotateConfig.Size)
|
|
|
|
//gIcsLog.logSize, serr = strconv.Atoi(gIcsLog.conf.LogConfig.RotateConfig.Size)
|
|
|
|
if serr != nil {
|
|
|
|
gIcsLog.logSize = DEFAULT_LOG_MAX_SIZE
|
|
|
|
}
|
|
|
|
gIcsLog.rotateNum, serr = strconv.Atoi(gIcsLog.conf.RotateConfig.Num)
|
|
|
|
//gIcsLog.rotateNum, serr = strconv.Atoi(gIcsLog.conf.LogConfig.RotateConfig.Num)
|
|
|
|
if serr != nil {
|
|
|
|
gIcsLog.rotateNum = DEFAULT_LOG_ROTATE_NUM
|
|
|
|
}
|
|
|
|
if gIcsLog.rotateNum > MAX_LOG_ROTATE_NUM {
|
|
|
|
gIcsLog.rotateNum = MAX_LOG_ROTATE_NUM
|
|
|
|
}
|
|
|
|
|
|
|
|
gIcsLog.logger = log.New(&gIcsLog.buf, "", log.Ldate|log.Ltime|log.Lmicroseconds|log.Lshortfile)
|
|
|
|
|
|
|
|
gIcsLog.CurrentDate = time.Now()
|
|
|
|
gIcsLog.DelDay = conf.DelConfig.DelDay
|
|
|
|
gIcsLog.DelHour = conf.DelConfig.DelHour
|
|
|
|
|
|
|
|
//make log file - icsvg.log-yyyymmdd
|
|
|
|
yyyy, mm, dd := gIcsLog.CurrentDate.Date()
|
|
|
|
hh, mi := time.Now().Hour(), time.Now().Minute()
|
|
|
|
gIcsLog.LogFileName = fmt.Sprintf("%s/icsvs.log-%d%02d%02d.%02d.%02d", gIcsLog.Path, yyyy, mm, dd, hh, mi)
|
|
|
|
|
|
|
|
stat, err := os.Stat(gIcsLog.LogFileName)
|
|
|
|
if err == nil {
|
|
|
|
if gIcsLog.checkLogRotate() && stat.Size()/ONEMB >= int64(gIcsLog.logSize) {
|
|
|
|
rotateNum := gIcsLog.getTodayLogFileNum()
|
|
|
|
//fmt.Println("rotate num:", rotateNum)
|
|
|
|
if rotateNum > 0 && rotateNum < gIcsLog.rotateNum {
|
|
|
|
gIcsLog.shiftLogFiles(rotateNum)
|
|
|
|
|
|
|
|
var oerr error
|
|
|
|
oerr = os.MkdirAll(filepath.Dir(gIcsLog.LogFileName), 0777)
|
|
|
|
if oerr != nil {
|
|
|
|
icserror.ICSERRMakeDir.SetError(oerr)
|
|
|
|
icserror.ICSERRMakeDir.PrintWithCaller(0)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
gIcsLog.LogFile, oerr = os.OpenFile(gIcsLog.LogFileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
|
|
|
|
if oerr != nil {
|
|
|
|
//fmt.Println(gIcsLog.LogFileName)
|
|
|
|
icserror.ICSERRFileOpen.SetError(oerr)
|
|
|
|
reterr = icserror.ICSERRFileOpen
|
|
|
|
reterr.PrintWithCaller(0)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if stat.Size()/ONEMB < int64(gIcsLog.logSize) {
|
|
|
|
var oerr error
|
|
|
|
oerr = os.MkdirAll(filepath.Dir(gIcsLog.LogFileName), 0777)
|
|
|
|
if oerr != nil {
|
|
|
|
icserror.ICSERRMakeDir.SetError(oerr)
|
|
|
|
icserror.ICSERRMakeDir.PrintWithCaller(0)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
gIcsLog.LogFile, oerr = os.OpenFile(gIcsLog.LogFileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
|
|
|
|
if oerr != nil {
|
|
|
|
//fmt.Println(gIcsLog.LogFileName)
|
|
|
|
icserror.ICSERRFileOpen.SetError(oerr)
|
|
|
|
reterr = icserror.ICSERRFileOpen
|
|
|
|
reterr.PrintWithCaller(0)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
var oerr error
|
|
|
|
oerr = os.MkdirAll(filepath.Dir(gIcsLog.LogFileName), 0777)
|
|
|
|
if oerr != nil {
|
|
|
|
icserror.ICSERRMakeDir.SetError(oerr)
|
|
|
|
icserror.ICSERRMakeDir.PrintWithCaller(0)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
gIcsLog.LogFile, oerr = os.OpenFile(gIcsLog.LogFileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
|
|
|
|
if oerr != nil {
|
|
|
|
//fmt.Println(gIcsLog.LogFileName)
|
|
|
|
icserror.ICSERRFileOpen.SetError(oerr)
|
|
|
|
reterr = icserror.ICSERRFileOpen
|
|
|
|
reterr.PrintWithCaller(0)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
return gIcsLog, reterr
|
|
|
|
}
|
|
|
|
|
|
|
|
func GetIcsLog() *IcsLog {
|
|
|
|
return gIcsLog
|
|
|
|
}
|
|
|
|
|
|
|
|
func GetLogLevelID(str string) int {
|
|
|
|
switch str {
|
|
|
|
case "DEBUG2":
|
|
|
|
return LOG_LEVEL_DEBUG2
|
|
|
|
case "DEBUG1":
|
|
|
|
return LOG_LEVEL_DEBUG1
|
|
|
|
case "DEBUG":
|
|
|
|
return LOG_LEVEL_DEBUG
|
|
|
|
case "STATISTICS":
|
|
|
|
return LOG_LEVEL_STATIS
|
|
|
|
case "INFO":
|
|
|
|
return LOG_LEVEL_INFO
|
|
|
|
case "WARN":
|
|
|
|
return LOG_LEVEL_WARN
|
|
|
|
case "ERROR":
|
|
|
|
return LOG_LEVEL_ERROR
|
|
|
|
case "FATAL":
|
|
|
|
return LOG_LEVEL_FATAL
|
|
|
|
default:
|
|
|
|
return -1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func GetLogOutputID(str string) int {
|
|
|
|
switch str {
|
|
|
|
case "FILE":
|
|
|
|
return LOG_OUTPUT_FILE
|
|
|
|
default:
|
|
|
|
return LOG_OUTPUT_STDOUT
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *IcsLog) DelLog() {
|
|
|
|
//var derr *icserror.IcsError = nil
|
|
|
|
delLogCount := 0
|
|
|
|
|
|
|
|
defer func() {
|
|
|
|
if err := recover(); err != nil {
|
|
|
|
switch v := err.(type) {
|
|
|
|
case error:
|
|
|
|
icserror.ICSERRFileOpen.SetError(v)
|
|
|
|
s.Printf(LOG_LEVEL_WARN, -1, "PANIC! %s\n%s", icserror.ICSERRFileOpen.GetError().Error(), string(debug.Stack()))
|
|
|
|
default:
|
|
|
|
s.Print(LOG_LEVEL_WARN, -1, icserror.ICSERRFileOpen.GetError().Error())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//derr = icserror.ICSERRFileOpen
|
|
|
|
}()
|
|
|
|
|
|
|
|
// 1. Get Log Del Time
|
|
|
|
yyyy, mm, dd := s.CurrentDate.Date()
|
|
|
|
curTime, _ := time.Parse("2006-01-02", fmt.Sprintf("%d-%02d-%02d", yyyy, mm, dd))
|
|
|
|
delTime := curTime.AddDate(0, 0, -s.DelDay)
|
|
|
|
|
|
|
|
files, rderr := ioutil.ReadDir(s.Path)
|
|
|
|
if rderr != nil {
|
|
|
|
s.Printf(LOG_LEVEL_ERROR, -1, " Read Log Dir error - %s \n", rderr)
|
|
|
|
fmt.Printf("Read Log Dir error - %s", rderr)
|
|
|
|
} else {
|
|
|
|
var logYYYY, logMM, logDD string
|
|
|
|
for _, file := range files {
|
|
|
|
/*
|
|
|
|
TODO
|
|
|
|
1. 로그 파일을 시간으로 변환
|
|
|
|
2. 현재 시간 - 삭제기간
|
|
|
|
3. 둘 시간 차이가 0 이상 나면 삭제대상
|
|
|
|
*/
|
|
|
|
logTime := strings.SplitN(file.Name(), "-", -1)[1]
|
|
|
|
logYYYY, logMM, logDD = logTime[:4], logTime[4:6], logTime[6:8]
|
|
|
|
chgLogTime, perr := time.Parse("2006-01-02", fmt.Sprintf("%s-%s-%s", logYYYY, logMM, logDD))
|
|
|
|
if perr != nil {
|
|
|
|
s.Printf(LOG_LEVEL_ERROR, -1, " Log Time Parse error - %s \n", perr)
|
|
|
|
fmt.Printf("Log Time Parse error - %s", perr)
|
|
|
|
} else {
|
|
|
|
diff := delTime.Sub(chgLogTime)
|
|
|
|
|
|
|
|
// diff > 0 => delete log
|
|
|
|
if diff > 0 {
|
|
|
|
delResult := icsutil.DeleteFile(s.Path, file.Name())
|
|
|
|
if delResult != "" {
|
|
|
|
s.Printf(LOG_LEVEL_ERROR, -1, " Delete File error - %s \n", delResult)
|
|
|
|
} else {
|
|
|
|
s.Printf(LOG_LEVEL_INFO, -1, " Delete %s!!!!\n", file.Name())
|
|
|
|
fmt.Printf("Delete %s!!!!\n", file.Name())
|
|
|
|
delLogCount += 1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
s.Printf(LOG_LEVEL_INFO, -1, " Delete File Count - %d \n", delLogCount)
|
|
|
|
fmt.Printf("Log Delete Count : %d", delLogCount)
|
|
|
|
}
|