Compare commits

..

7 Commits

@ -5,24 +5,21 @@ import (
"os"
"path/filepath"
"time"
"b612.me/staros"
"b612.me/starmap"
)
var archMap starmap.StarMapKV
var archMap starMapKV
func init() {
archMap = starmap.NewStarMap()
archMap = newStarMap()
}
type Archive interface {
ShouldArchiveNow(string, os.FileInfo) bool
NextLogFilePath(string, os.FileInfo) string
ShouldArchiveNow(*StarLogger, string, os.FileInfo) bool
NextLogFilePath(*StarLogger, string, os.FileInfo) string
ArchiveLogFilePath(*StarLogger, string, os.FileInfo) string
Interval() int64
HookBeforArchive() func(string, os.FileInfo) error
HookAfterArchive() func(string, string, os.FileInfo) error
HookBeforArchive() func(*StarLogger, string, string, os.FileInfo) error //archivePath;currentPath
HookAfterArchive() func(*StarLogger, string, string, os.FileInfo) error //archivePath;currentPath
}
type logfileinfo struct {
@ -41,7 +38,7 @@ func SetLogFile(path string, logger *StarLogger, appendMode bool) error {
if err != nil {
return err
}
if !appendMode && staros.Exists(fullpath) {
if !appendMode && Exists(fullpath) {
os.Remove(fullpath)
}
fp, err := os.OpenFile(fullpath, fileMode, 0644)
@ -119,7 +116,7 @@ func StartArchive(logger *StarLogger, arch Archive) error {
select {
case <-stopChan:
return
case <-time.After(time.Second * time.Duration(arch.Interval())):
case <-time.After(time.Millisecond * time.Duration(1000*arch.Interval())):
}
fileinfo, err := GetLogFileInfo(logger)
if err != nil {
@ -131,21 +128,30 @@ func StartArchive(logger *StarLogger, arch Archive) error {
continue
}
fullpath := archMap.MustGet(logger.logcore.id).(logfileinfo).fullpath
if !arch.ShouldArchiveNow(fullpath, fileinfo) {
if !arch.ShouldArchiveNow(logger, fullpath, fileinfo) {
continue
}
newLogPath := arch.NextLogFilePath(fullpath, fileinfo)
newLogPath := arch.NextLogFilePath(logger, fullpath, fileinfo)
archiveLogPath := arch.ArchiveLogFilePath(logger, fullpath, fileinfo)
if arch.HookBeforArchive() != nil {
if err := arch.HookBeforArchive()(fullpath, fileinfo); err != nil {
if err := arch.HookBeforArchive()(logger, archiveLogPath, fullpath, fileinfo); err != nil {
logger.Errorf("error occur while executing hook before archive,detail is %v\n", err)
continue
}
}
err = CloseWithSwitching(logger)
if err != nil {
continue
}
err = os.Rename(fullpath, archiveLogPath)
if err != nil {
continue
}
if err := SetLogFile(newLogPath, logger, false); err != nil {
logger.Errorf("error occur while executing coverting new log file,detail is %v\n", err)
continue
} else {
logger.Debugln("Set Log Success")
logger.Debugln("Archive Log Success")
}
fileinfo, err = GetLogFileInfo(logger)
if err != nil {
@ -153,7 +159,7 @@ func StartArchive(logger *StarLogger, arch Archive) error {
continue
}
if arch.HookAfterArchive() != nil {
if err := arch.HookAfterArchive()(fullpath, newLogPath, fileinfo); err != nil {
if err := arch.HookAfterArchive()(logger, archiveLogPath, newLogPath, fileinfo); err != nil {
logger.Errorf("error occur while executing hook after archive,detail is %v\n", err)
continue
}
@ -180,21 +186,45 @@ func StopArchive(logger *StarLogger) {
type ArchiveByDate struct {
interval int64
checkInterval int64
newFileNameStyle string
hookBefor func(string, os.FileInfo) error
hookAfter func(string, string, os.FileInfo) error
baseFileStyle string
archiveStyle string
lastSwitchTime time.Time
changeArchiveName bool
hookBefore func(*StarLogger, string, string, os.FileInfo) error
hookAfter func(*StarLogger, string, string, os.FileInfo) error
}
func (abd *ArchiveByDate) ShouldArchiveNow(fullpath string, info os.FileInfo) bool {
if time.Now().Unix()-staros.GetFileCreationTime(info).Unix() > abd.interval {
func (abd *ArchiveByDate) ShouldArchiveNow(l *StarLogger, fullpath string, info os.FileInfo) bool {
if abd.lastSwitchTime.IsZero() {
abd.lastSwitchTime = GetFileCreationTime(info)
}
sub := time.Now().Unix() - abd.lastSwitchTime.Unix()
if sub >= abd.interval || abd.interval-sub <= abd.checkInterval/2 {
return true
}
return false
}
func (abd *ArchiveByDate) NextLogFilePath(oldpath string, info os.FileInfo) string {
func (abd *ArchiveByDate) NextLogFilePath(l *StarLogger, oldpath string, info os.FileInfo) string {
var newName string
dir := filepath.Dir(oldpath)
newName := time.Now().Format(abd.newFileNameStyle)
if !abd.changeArchiveName {
newName = abd.baseFileStyle + time.Now().Format(abd.archiveStyle)
} else {
newName = abd.baseFileStyle
}
return filepath.Join(dir, newName)
}
func (abd *ArchiveByDate) ArchiveLogFilePath(l *StarLogger, oldpath string, info os.FileInfo) string {
var newName string
dir := filepath.Dir(oldpath)
if abd.changeArchiveName {
newName = filepath.Base(abd.baseFileStyle) + time.Now().Format(abd.archiveStyle)
} else {
newName = abd.baseFileStyle
}
return filepath.Join(dir, newName)
}
@ -202,30 +232,37 @@ func (abd *ArchiveByDate) Interval() int64 {
return abd.checkInterval
}
func (abd *ArchiveByDate) HookBeforArchive() func(string, os.FileInfo) error {
func (abd *ArchiveByDate) HookBeforArchive() func(*StarLogger, string, string, os.FileInfo) error {
return abd.hookBefor
return abd.hookBefore
}
func (abd *ArchiveByDate) HookAfterArchive() func(string, string, os.FileInfo) error {
return abd.hookAfter
func (abd *ArchiveByDate) HookAfterArchive() func(*StarLogger, string, string, os.FileInfo) error {
return func(logger *StarLogger, s string, s2 string, info os.FileInfo) error {
abd.lastSwitchTime = time.Now()
if abd.hookAfter != nil {
return abd.hookAfter(logger, s, s2, info)
}
return nil
}
}
func (abd *ArchiveByDate) SetHookBeforArchive(f func(string, os.FileInfo) error) {
abd.hookBefor = f
func (abd *ArchiveByDate) SetHookBeforArchive(f func(*StarLogger, string, string, os.FileInfo) error) {
abd.hookBefore = f
}
func (abd *ArchiveByDate) SetHookAfterArchive(f func(string, string, os.FileInfo) error) {
func (abd *ArchiveByDate) SetHookAfterArchive(f func(*StarLogger, string, string, os.FileInfo) error) {
abd.hookAfter = f
}
func NewArchiveByDate(archInterval int64, checkInterval int64, fileStyle string, hookbefor func(string, os.FileInfo) error, hookafter func(string, string, os.FileInfo) error) *ArchiveByDate {
func NewArchiveByDate(archInterval int64, checkInterval int64, baseFileName string, archiveFileName string, changeArchiveName bool, hookbefore func(*StarLogger, string, string, os.FileInfo) error, hookafter func(*StarLogger, string, string, os.FileInfo) error) *ArchiveByDate {
return &ArchiveByDate{
interval: archInterval,
checkInterval: checkInterval,
newFileNameStyle: fileStyle,
hookBefor: hookbefor,
changeArchiveName: changeArchiveName,
baseFileStyle: baseFileName,
archiveStyle: archiveFileName,
hookBefore: hookbefore,
hookAfter: hookafter,
}
}
@ -233,21 +270,39 @@ func NewArchiveByDate(archInterval int64, checkInterval int64, fileStyle string,
type ArchiveBySize struct {
size int64
checkInterval int64
newFileNameStyle string
hookBefor func(string, os.FileInfo) error
hookAfter func(string, string, os.FileInfo) error
changeArchiveName bool
baseFileStyle string
archiveStyle string
hookBefore func(*StarLogger, string, string, os.FileInfo) error
hookAfter func(*StarLogger, string, string, os.FileInfo) error
}
func (abd *ArchiveBySize) ShouldArchiveNow(fullpath string, info os.FileInfo) bool {
func (abd *ArchiveBySize) ShouldArchiveNow(l *StarLogger, fullpath string, info os.FileInfo) bool {
if info.Size() > abd.size {
return true
}
return false
}
func (abd *ArchiveBySize) NextLogFilePath(oldpath string, info os.FileInfo) string {
func (abd *ArchiveBySize) NextLogFilePath(l *StarLogger, oldpath string, info os.FileInfo) string {
var newName string
dir := filepath.Dir(oldpath)
if !abd.changeArchiveName {
newName = abd.baseFileStyle + time.Now().Format(abd.archiveStyle)
} else {
newName = abd.baseFileStyle
}
return filepath.Join(dir, newName)
}
func (abd *ArchiveBySize) ArchiveLogFilePath(l *StarLogger, oldpath string, info os.FileInfo) string {
var newName string
dir := filepath.Dir(oldpath)
newName := time.Now().Format(abd.newFileNameStyle)
if abd.changeArchiveName {
newName = filepath.Base(abd.baseFileStyle) + time.Now().Format(abd.archiveStyle)
} else {
newName = abd.baseFileStyle
}
return filepath.Join(dir, newName)
}
@ -255,30 +310,117 @@ func (abd *ArchiveBySize) Interval() int64 {
return abd.checkInterval
}
func (abd *ArchiveBySize) HookBeforArchive() func(string, os.FileInfo) error {
return abd.hookBefor
func (abd *ArchiveBySize) HookBeforArchive() func(*StarLogger, string, string, os.FileInfo) error {
return abd.hookBefore
}
func (abd *ArchiveBySize) HookAfterArchive() func(string, string, os.FileInfo) error {
func (abd *ArchiveBySize) HookAfterArchive() func(*StarLogger, string, string, os.FileInfo) error {
return abd.hookAfter
}
func (abd *ArchiveBySize) SetHookBeforArchive(f func(string, os.FileInfo) error) {
abd.hookBefor = f
func (abd *ArchiveBySize) SetHookBeforArchive(f func(*StarLogger, string, string, os.FileInfo) error) {
abd.hookBefore = f
}
func (abd *ArchiveBySize) SetHookAfterArchive(f func(string, string, os.FileInfo) error) {
func (abd *ArchiveBySize) SetHookAfterArchive(f func(*StarLogger, string, string, os.FileInfo) error) {
abd.hookAfter = f
}
func NewArchiveBySize(size int64, checkInterval int64, fileStyle string, hookbefor func(string, os.FileInfo) error, hookafter func(string, string, os.FileInfo) error) *ArchiveBySize {
func NewArchiveBySize(size int64, checkInterval int64, baseFileStyle, archiveFileStyle string, changeArchiveFileName bool, hookbefore func(*StarLogger, string, string, os.FileInfo) error, hookafter func(*StarLogger, string, string, os.FileInfo) error) *ArchiveBySize {
return &ArchiveBySize{
size: size,
checkInterval: checkInterval,
newFileNameStyle: fileStyle,
hookBefor: hookbefor,
baseFileStyle: baseFileStyle,
archiveStyle: archiveFileStyle,
hookBefore: hookbefore,
hookAfter: hookafter,
changeArchiveName: changeArchiveFileName,
}
}
type ArchiveByDateSize struct {
interval int64
size int64
checkInterval int64
changeArchiveName bool
lastSwitchTime time.Time
baseFileStyle string
archiveStyle string
hookBefore func(*StarLogger, string, string, os.FileInfo) error
hookAfter func(*StarLogger, string, string, os.FileInfo) error
}
func (abd *ArchiveByDateSize) ShouldArchiveNow(l *StarLogger, fullpath string, info os.FileInfo) bool {
if abd.lastSwitchTime.IsZero() {
abd.lastSwitchTime = GetFileCreationTime(info)
}
if info.Size() > abd.size {
return true
}
sub := time.Now().Unix() - abd.lastSwitchTime.Unix()
if sub >= abd.interval || abd.interval-sub <= abd.checkInterval/2 {
return true
}
return false
}
func (abd *ArchiveByDateSize) NextLogFilePath(l *StarLogger, oldpath string, info os.FileInfo) string {
var newName string
dir := filepath.Dir(oldpath)
if !abd.changeArchiveName {
newName = abd.baseFileStyle + time.Now().Format(abd.archiveStyle)
} else {
newName = abd.baseFileStyle
}
return filepath.Join(dir, newName)
}
func (abd *ArchiveByDateSize) ArchiveLogFilePath(l *StarLogger, oldpath string, info os.FileInfo) string {
var newName string
dir := filepath.Dir(oldpath)
if abd.changeArchiveName {
newName = filepath.Base(abd.baseFileStyle) + time.Now().Format(abd.archiveStyle)
} else {
newName = abd.baseFileStyle
}
return filepath.Join(dir, newName)
}
func (abd *ArchiveByDateSize) Interval() int64 {
return abd.checkInterval
}
func (abd *ArchiveByDateSize) HookBeforArchive() func(*StarLogger, string, string, os.FileInfo) error {
return abd.hookBefore
}
func (abd *ArchiveByDateSize) HookAfterArchive() func(*StarLogger, string, string, os.FileInfo) error {
return func(logger *StarLogger, s string, s2 string, info os.FileInfo) error {
abd.lastSwitchTime = time.Now()
if abd.hookAfter != nil {
return abd.hookAfter(logger, s, s2, info)
}
return nil
}
}
func (abd *ArchiveByDateSize) SetHookBeforArchive(f func(*StarLogger, string, string, os.FileInfo) error) {
abd.hookBefore = f
}
func (abd *ArchiveByDateSize) SetHookAfterArchive(f func(*StarLogger, string, string, os.FileInfo) error) {
abd.hookAfter = f
}
func NewArchiveByDateSize(size int64, interval int64, checkInterval int64, baseFileStyle, archiveFileStyle string, changeArchiveFileName bool, hookbefore func(*StarLogger, string, string, os.FileInfo) error, hookafter func(*StarLogger, string, string, os.FileInfo) error) *ArchiveByDateSize {
return &ArchiveByDateSize{
size: size,
interval: interval,
checkInterval: checkInterval,
baseFileStyle: baseFileStyle,
archiveStyle: archiveFileStyle,
hookBefore: hookbefore,
hookAfter: hookafter,
changeArchiveName: changeArchiveFileName,
}
}

@ -0,0 +1,17 @@
package starlog
import (
"testing"
"time"
)
func TestArchiveByDate(t *testing.T) {
l := Std
SetLogFile("test.log", l, true)
StartArchive(l, NewArchiveByDateSize(4096, 24, 2, "test.log",
"_2006_01_02_15_04_05.log", true, nil, nil))
for {
time.Sleep(time.Second)
l.Infoln("hahaha", time.Now())
}
}

@ -35,7 +35,7 @@ func generateCoreLogStr(skip int, logstr string) string {
return logStr
}
func (logger *starlog) build(thread string, isStd bool, isShow bool, handler func([]Attr, string), level int, logDetail string) {
func (logger *starlog) build(thread string, isStd bool, isShow bool, handler func(data LogData), level int, logDetail string) {
logger.mu.Lock()
defer logger.mu.Unlock()
var skip, line int = 3, 0
@ -80,19 +80,33 @@ func (logger *starlog) build(thread string, isStd bool, isShow bool, handler fun
}
if isShow {
if !logger.showColor {
if level >= logger.errOutputLevel {
fmt.Fprint(os.Stderr, logStr)
} else {
fmt.Print(logStr)
}
} else if !logger.onlyColorLevel {
//logcolor := NewColor(logger.colorList[level]...)
if level < logger.errOutputLevel {
logger.colorMe[level].Fprint(stdScreen, logStr)
} else {
logger.colorMe[level].Fprint(errScreen, logStr)
}
} else {
if level < logger.errOutputLevel {
fmt.Fprint(stdScreen, logStr)
} else {
fmt.Fprint(errScreen, logStr)
}
}
}
if handler != nil {
stacks.Push(logTransfer{
handlerFunc: handler,
colors: logger.colorList[level],
logStr: logStr,
LogData: LogData{
Log: logStr,
Colors: logger.colorList[level],
Name: logger.name,
},
})
}
if !logger.stopWriter {
@ -130,133 +144,133 @@ func (logger *starlog) println(str ...interface{}) string {
return fmt.Sprintln(str...)
}
func (logger *starlog) Debug(thread string, isStd bool, handler func([]Attr, string), str ...interface{}) {
func (logger *starlog) Debug(thread string, isStd bool, handler func(LogData), str ...interface{}) {
strs := fmt.Sprint(str...)
logger.build(thread, isStd, logger.showStd, handler, LvDebug, strs)
}
func (logger *starlog) Debugf(thread string, isStd bool, handler func([]Attr, string), format string, str ...interface{}) {
func (logger *starlog) Debugf(thread string, isStd bool, handler func(LogData), format string, str ...interface{}) {
strs := fmt.Sprintf(format, str...)
logger.build(thread, isStd, logger.showStd, handler, LvDebug, strs)
}
func (logger *starlog) Debugln(thread string, isStd bool, handler func([]Attr, string), str ...interface{}) {
func (logger *starlog) Debugln(thread string, isStd bool, handler func(LogData), str ...interface{}) {
strs := fmt.Sprintln(str...)
logger.build(thread, isStd, logger.showStd, handler, LvDebug, strs)
}
func (logger *starlog) Info(thread string, isStd bool, handler func([]Attr, string), str ...interface{}) {
func (logger *starlog) Info(thread string, isStd bool, handler func(LogData), str ...interface{}) {
strs := fmt.Sprint(str...)
logger.build(thread, isStd, logger.showStd, handler, LvInfo, strs)
}
func (logger *starlog) Infof(thread string, isStd bool, handler func([]Attr, string), format string, str ...interface{}) {
func (logger *starlog) Infof(thread string, isStd bool, handler func(LogData), format string, str ...interface{}) {
strs := fmt.Sprintf(format, str...)
logger.build(thread, isStd, logger.showStd, handler, LvInfo, strs)
}
func (logger *starlog) Infoln(thread string, isStd bool, handler func([]Attr, string), str ...interface{}) {
func (logger *starlog) Infoln(thread string, isStd bool, handler func(LogData), str ...interface{}) {
strs := fmt.Sprintln(str...)
logger.build(thread, isStd, logger.showStd, handler, LvInfo, strs)
}
func (logger *starlog) Notice(thread string, isStd bool, handler func([]Attr, string), str ...interface{}) {
func (logger *starlog) Notice(thread string, isStd bool, handler func(LogData), str ...interface{}) {
strs := fmt.Sprint(str...)
logger.build(thread, isStd, logger.showStd, handler, LvNotice, strs)
}
func (logger *starlog) Noticef(thread string, isStd bool, handler func([]Attr, string), format string, str ...interface{}) {
func (logger *starlog) Noticef(thread string, isStd bool, handler func(LogData), format string, str ...interface{}) {
strs := fmt.Sprintf(format, str...)
logger.build(thread, isStd, logger.showStd, handler, LvNotice, strs)
}
func (logger *starlog) Noticeln(thread string, isStd bool, handler func([]Attr, string), str ...interface{}) {
func (logger *starlog) Noticeln(thread string, isStd bool, handler func(LogData), str ...interface{}) {
strs := fmt.Sprintln(str...)
logger.build(thread, isStd, logger.showStd, handler, LvNotice, strs)
}
func (logger *starlog) Warning(thread string, isStd bool, handler func([]Attr, string), str ...interface{}) {
func (logger *starlog) Warning(thread string, isStd bool, handler func(LogData), str ...interface{}) {
strs := fmt.Sprint(str...)
logger.build(thread, isStd, logger.showStd, handler, LvWarning, strs)
}
func (logger *starlog) Warningf(thread string, isStd bool, handler func([]Attr, string), format string, str ...interface{}) {
func (logger *starlog) Warningf(thread string, isStd bool, handler func(LogData), format string, str ...interface{}) {
strs := fmt.Sprintf(format, str...)
logger.build(thread, isStd, logger.showStd, handler, LvWarning, strs)
}
func (logger *starlog) Warningln(thread string, isStd bool, handler func([]Attr, string), str ...interface{}) {
func (logger *starlog) Warningln(thread string, isStd bool, handler func(LogData), str ...interface{}) {
strs := fmt.Sprintln(str...)
logger.build(thread, isStd, logger.showStd, handler, LvWarning, strs)
}
func (logger *starlog) Error(thread string, isStd bool, handler func([]Attr, string), str ...interface{}) {
func (logger *starlog) Error(thread string, isStd bool, handler func(LogData), str ...interface{}) {
strs := fmt.Sprint(str...)
logger.build(thread, isStd, logger.showStd, handler, LvError, strs)
}
func (logger *starlog) Errorf(thread string, isStd bool, handler func([]Attr, string), format string, str ...interface{}) {
func (logger *starlog) Errorf(thread string, isStd bool, handler func(LogData), format string, str ...interface{}) {
strs := fmt.Sprintf(format, str...)
logger.build(thread, isStd, logger.showStd, handler, LvError, strs)
}
func (logger *starlog) Errorln(thread string, isStd bool, handler func([]Attr, string), str ...interface{}) {
func (logger *starlog) Errorln(thread string, isStd bool, handler func(LogData), str ...interface{}) {
strs := fmt.Sprintln(str...)
logger.build(thread, isStd, logger.showStd, handler, LvError, strs)
}
func (logger *starlog) Critical(thread string, isStd bool, handler func([]Attr, string), str ...interface{}) {
func (logger *starlog) Critical(thread string, isStd bool, handler func(LogData), str ...interface{}) {
strs := fmt.Sprint(str...)
logger.build(thread, isStd, logger.showStd, handler, LvCritical, strs)
}
func (logger *starlog) Criticalf(thread string, isStd bool, handler func([]Attr, string), format string, str ...interface{}) {
func (logger *starlog) Criticalf(thread string, isStd bool, handler func(LogData), format string, str ...interface{}) {
strs := fmt.Sprintf(format, str...)
logger.build(thread, isStd, logger.showStd, handler, LvCritical, strs)
}
func (logger *starlog) Criticalln(thread string, isStd bool, handler func([]Attr, string), str ...interface{}) {
func (logger *starlog) Criticalln(thread string, isStd bool, handler func(LogData), str ...interface{}) {
strs := fmt.Sprintln(str...)
logger.build(thread, isStd, logger.showStd, handler, LvCritical, strs)
}
func (logger *starlog) Fatal(thread string, isStd bool, handler func([]Attr, string), str ...interface{}) {
func (logger *starlog) Fatal(thread string, isStd bool, handler func(LogData), str ...interface{}) {
strs := fmt.Sprint(str...)
logger.build(thread, isStd, logger.showStd, handler, LvFatal, strs)
os.Exit(9)
}
func (logger *starlog) Fatalf(thread string, isStd bool, handler func([]Attr, string), format string, str ...interface{}) {
func (logger *starlog) Fatalf(thread string, isStd bool, handler func(LogData), format string, str ...interface{}) {
strs := fmt.Sprintf(format, str...)
logger.build(thread, isStd, logger.showStd, handler, LvFatal, strs)
os.Exit(9)
}
func (logger *starlog) Fatalln(thread string, isStd bool, handler func([]Attr, string), str ...interface{}) {
func (logger *starlog) Fatalln(thread string, isStd bool, handler func(LogData), str ...interface{}) {
strs := fmt.Sprintln(str...)
logger.build(thread, isStd, logger.showStd, handler, LvFatal, strs)
os.Exit(9)
}
func (logger *starlog) Panic(thread string, isStd bool, handler func([]Attr, string), str ...interface{}) {
func (logger *starlog) Panic(thread string, isStd bool, handler func(LogData), str ...interface{}) {
strs := fmt.Sprint(str...)
logger.build(thread, isStd, logger.showStd, handler, LvPanic, strs)
panic(str)
}
func (logger *starlog) Panicf(thread string, isStd bool, handler func([]Attr, string), format string, str ...interface{}) {
func (logger *starlog) Panicf(thread string, isStd bool, handler func(LogData), format string, str ...interface{}) {
strs := fmt.Sprintf(format, str...)
logger.build(thread, isStd, logger.showStd, handler, LvPanic, strs)
panic(fmt.Sprintf(format, str...))
}
func (logger *starlog) Panicln(thread string, isStd bool, handler func([]Attr, string), str ...interface{}) {
func (logger *starlog) Panicln(thread string, isStd bool, handler func(LogData), str ...interface{}) {
strs := fmt.Sprintln(str...)
logger.build(thread, isStd, logger.showStd, handler, LvPanic, strs)
panic(fmt.Sprintln(str...))
}
func (logger *starlog) Print(thread string, isStd bool, isShow bool, handler func([]Attr, string), str ...interface{}) {
func (logger *starlog) Print(thread string, isStd bool, isShow bool, handler func(LogData), str ...interface{}) {
strs := fmt.Sprint(str...)
if isShow {
fmt.Print(strs)
@ -264,7 +278,7 @@ func (logger *starlog) Print(thread string, isStd bool, isShow bool, handler fun
logger.write(strs)
}
func (logger *starlog) Printf(thread string, isStd bool, isShow bool, handler func([]Attr, string), format string, str ...interface{}) {
func (logger *starlog) Printf(thread string, isStd bool, isShow bool, handler func(LogData), format string, str ...interface{}) {
strs := fmt.Sprintf(format, str...)
if isShow {
fmt.Print(strs)
@ -272,7 +286,7 @@ func (logger *starlog) Printf(thread string, isStd bool, isShow bool, handler fu
logger.write(strs)
}
func (logger *starlog) Println(thread string, isStd bool, isShow bool, handler func([]Attr, string), str ...interface{}) {
func (logger *starlog) Println(thread string, isStd bool, isShow bool, handler func(LogData), str ...interface{}) {
strs := fmt.Sprintln(str...)
if isShow {
fmt.Print(strs)
@ -280,17 +294,32 @@ func (logger *starlog) Println(thread string, isStd bool, isShow bool, handler f
logger.write(strs)
}
func (logger *starlog) Log(thread string, isStd bool, isShow bool, level int, handler func([]Attr, string), str ...interface{}) {
func (logger *starlog) Log(thread string, isStd bool, isShow bool, level int, handler func(LogData), str ...interface{}) {
strs := fmt.Sprint(str...)
logger.build(thread, isStd, isShow, handler, level, strs)
}
func (logger *starlog) Logf(thread string, isStd bool, isShow bool, level int, handler func([]Attr, string), format string, str ...interface{}) {
func (logger *starlog) Logf(thread string, isStd bool, isShow bool, level int, handler func(LogData), format string, str ...interface{}) {
strs := fmt.Sprintf(format, str...)
logger.build(thread, isStd, isShow, handler, level, strs)
}
func (logger *starlog) Logln(thread string, isStd bool, isShow bool, level int, handler func([]Attr, string), str ...interface{}) {
func (logger *starlog) Logln(thread string, isStd bool, isShow bool, level int, handler func(LogData), str ...interface{}) {
strs := fmt.Sprintln(str...)
logger.build(thread, isStd, isShow, handler, level, strs)
}
func (logger *starlog) Write(str ...interface{}) {
strs := fmt.Sprint(str...)
logger.Write(strs)
}
func (logger *starlog) Writef(format string, str ...interface{}) {
strs := fmt.Sprintf(format, str...)
logger.Write(strs)
}
func (logger *starlog) Writeln(str ...interface{}) {
strs := fmt.Sprintln(str...)
logger.Write(strs)
}

@ -0,0 +1,34 @@
package starlog
import (
"os"
)
// 检测文件/文件夹是否存在
func Exists(path string) bool {
_, err := os.Stat(path)
if err != nil && os.IsNotExist(err) {
return false
}
return true
}
// IsFile 返回给定文件地址是否是一个文件,
// True为是一个文件,False为不是文件或路径无效
func IsFile(fpath string) bool {
s, err := os.Stat(fpath)
if err != nil {
return false
}
return !s.IsDir()
}
// IsFolder 返回给定文件地址是否是一个文件夹,
// True为是一个文件夹,False为不是文件夹或路径无效
func IsFolder(fpath string) bool {
s, err := os.Stat(fpath)
if err != nil {
return false
}
return s.IsDir()
}

@ -0,0 +1,22 @@
//go:build darwin
// +build darwin
package starlog
import (
"os"
"syscall"
"time"
)
func timespecToTime(ts syscall.Timespec) time.Time {
return time.Unix(int64(ts.Sec), int64(ts.Nsec))
}
func GetFileCreationTime(fileinfo os.FileInfo) time.Time {
return timespecToTime(fileinfo.Sys().(*syscall.Stat_t).Ctimespec)
}
func GetFileAccessTime(fileinfo os.FileInfo) time.Time {
return timespecToTime(fileinfo.Sys().(*syscall.Stat_t).Atimespec)
}

@ -0,0 +1,22 @@
//go:build linux
// +build linux
package starlog
import (
"os"
"syscall"
"time"
)
func timespecToTime(ts syscall.Timespec) time.Time {
return time.Unix(int64(ts.Sec), int64(ts.Nsec))
}
func GetFileCreationTime(fileinfo os.FileInfo) time.Time {
return timespecToTime(fileinfo.Sys().(*syscall.Stat_t).Ctim)
}
func GetFileAccessTime(fileinfo os.FileInfo) time.Time {
return timespecToTime(fileinfo.Sys().(*syscall.Stat_t).Atim)
}

@ -0,0 +1,20 @@
//go:build windows
// +build windows
package starlog
import (
"os"
"syscall"
"time"
)
func GetFileCreationTime(fileinfo os.FileInfo) time.Time {
d := fileinfo.Sys().(*syscall.Win32FileAttributeData)
return time.Unix(0, d.CreationTime.Nanoseconds())
}
func GetFileAccessTime(fileinfo os.FileInfo) time.Time {
d := fileinfo.Sys().(*syscall.Win32FileAttributeData)
return time.Unix(0, d.LastAccessTime.Nanoseconds())
}

@ -2,9 +2,4 @@ module b612.me/starlog
go 1.16
require (
b612.me/notify v1.2.0 // indirect
b612.me/starmap v1.2.0
b612.me/staros v1.1.2
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5
)
require golang.org/x/sys v0.24.0

@ -1,28 +1,2 @@
b612.me/notify v1.2.0 h1:RedXNMLqY+TozalmdIUM27EFvZp06pzeqHn/F9G1eEs=
b612.me/notify v1.2.0/go.mod h1:EPctpKCVnoZO1hUJTRYpOw3huTemua+SGNIuUCsnzOc=
b612.me/starcrypto v0.0.1 h1:xGngzXPUrVbqtWzNw2e+0eWsdG7GG1/X+ONDGIzdriI=
b612.me/starcrypto v0.0.1/go.mod h1:hz0xRnfWNpYOlVrIPoGrQOWPibq4YiUZ7qN5tsQbzPo=
b612.me/stario v0.0.5 h1:Q1OGF+8eOoK49zMzkyh80GWaMuknhey6+PWJJL9ZuNo=
b612.me/stario v0.0.5/go.mod h1:or4ssWcxQSjMeu+hRKEgtp0X517b3zdlEOAms8Qscvw=
b612.me/starmap v1.2.0 h1:sRUeMRUqOyb3pAQln5U6V07kIYp0714Z3gJ/g2nCJXc=
b612.me/starmap v1.2.0/go.mod h1:InIJXA3qVeMkvkUhCV/XPchCiNcJcVYdYV8EAOGbGZY=
b612.me/starnet v0.1.3 h1:UjY6M96gdPdJtxnQGzCttqSwFw93sDZSHiIGtdOlFfk=
b612.me/starnet v0.1.3/go.mod h1:j/dd6BKwQK80O4gfbGYg2aYtPH76gSdgpuKboK/DwN4=
b612.me/staros v1.1.2 h1:jBFU1KHgn0VpyitYKwC9Zwj1GjmDBGM+fuTyV0yGXRo=
b612.me/staros v1.1.2/go.mod h1:9kNWVJWNJfs2MiWEt7X3SO+ixYKPGqus1ShTy8hpfU0=
b612.me/win32api v0.0.1 h1:vLFB1xhO6pd9+zB2EyaapKB459Urv3v+C1YwgwOFEWo=
b612.me/win32api v0.0.1/go.mod h1:MHu0JBQjzxQ2yxpZPUBbn5un45o67eF5iWKa4Q9e0yE=
b612.me/wincmd v0.0.1 h1:4+RCFKHuD/JqAYsdtO6sTNKJs1nQVMQo87h6KhTJjkM=
b612.me/wincmd v0.0.1/go.mod h1:32xTM7qWAI7jx6qwTrig05rxejSYbSp7CX5WD7qsMxY=
golang.org/x/crypto v0.0.0-20220313003712-b769efc7c000 h1:SL+8VVnkqyshUSz5iNnXtrBQzvFF2SkROm6t5RczFAE=
golang.org/x/crypto v0.0.0-20220313003712-b769efc7c000/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5 h1:y/woIyUBFbpQGKS0u1aHF/40WUDnek3fPOyD08H5Vng=
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=

@ -0,0 +1,149 @@
package starlog
import (
"errors"
"io"
"os"
"sync"
"sync/atomic"
)
type starMapKV struct {
kvMap map[interface{}]interface{}
mu sync.RWMutex
}
func newStarMap() starMapKV {
var mp starMapKV
mp.kvMap = make(map[interface{}]interface{})
return mp
}
func (m *starMapKV) Get(key interface{}) (interface{}, error) {
var err error
m.mu.RLock()
defer m.mu.RUnlock()
data, ok := m.kvMap[key]
if !ok {
err = os.ErrNotExist
}
return data, err
}
func (m *starMapKV) MustGet(key interface{}) interface{} {
result, _ := m.Get(key)
return result
}
func (m *starMapKV) Store(key interface{}, value interface{}) error {
m.mu.Lock()
defer m.mu.Unlock()
m.kvMap[key] = value
return nil
}
func (m *starMapKV) Exists(key interface{}) bool {
m.mu.RLock()
defer m.mu.RUnlock()
_, ok := m.kvMap[key]
return ok
}
func (m *starMapKV) Delete(key interface{}) error {
m.mu.Lock()
defer m.mu.Unlock()
delete(m.kvMap, key)
return nil
}
func (m *starMapKV) Range(run func(k interface{}, v interface{}) bool) error {
for k, v := range m.kvMap {
if !run(k, v) {
break
}
}
return nil
}
type starChanStack struct {
data chan interface{}
cap uint64
current uint64
isClose atomic.Value
}
func newStarChanStack(cap uint64) *starChanStack {
rtnBuffer := new(starChanStack)
rtnBuffer.cap = cap
rtnBuffer.isClose.Store(false)
rtnBuffer.data = make(chan interface{}, cap)
return rtnBuffer
}
func (s *starChanStack) init() {
s.cap = 1024
s.data = make(chan interface{}, s.cap)
s.isClose.Store(false)
}
func (s *starChanStack) Free() uint64 {
return s.cap - s.current
}
func (s *starChanStack) Cap() uint64 {
return s.cap
}
func (s *starChanStack) Len() uint64 {
return s.current
}
func (s *starChanStack) Pop() (interface{}, error) {
if s.isClose.Load() == nil {
s.init()
}
if s.isClose.Load().(bool) {
return 0, io.EOF
}
data, ok := <-s.data
if !ok {
s.isClose.Store(true)
return 0, errors.New("channel read error")
}
for {
current := atomic.LoadUint64(&s.current)
if atomic.CompareAndSwapUint64(&s.current, current, current-1) {
break
}
}
return data, nil
}
func (s *starChanStack) Push(data interface{}) error {
defer func() {
recover()
}()
if s.isClose.Load() == nil {
s.init()
}
if s.isClose.Load().(bool) {
return io.EOF
}
s.data <- data
for {
current := atomic.LoadUint64(&s.current)
if atomic.CompareAndSwapUint64(&s.current, current, current+1) {
break
}
}
return nil
}
func (s *starChanStack) Close() error {
if s.isClose.Load() == nil {
s.init()
}
s.isClose.Store(true)
close(s.data)
return nil
}

@ -1,7 +1,6 @@
package starlog
import (
"b612.me/starmap"
"fmt"
"io"
"math/rand"
@ -13,10 +12,8 @@ var Std *StarLogger
var stdmu sync.Mutex
func init() {
stacks = starmap.NewStarStack(1024)
rand.Seed(time.Now().UnixNano())
stackStopChan = make(chan int)
StartStacks()
Std = NewStarlog(nil)
}
@ -262,10 +259,10 @@ func GetWriter() io.Writer {
return Std.GetWriter()
}
func SetHandler(f func([]Attr, string)) {
func SetHandler(f func(LogData)) {
Std.SetHandler(f)
}
func GetHandler() func([]Attr, string) {
func GetHandler() func(LogData) {
return Std.GetHandler()
}
func SetSwitching(sw bool) {

@ -28,10 +28,13 @@ func (logger *StarLogger) GetWriter() io.Writer {
return logger.logcore.output
}
func (logger *StarLogger) SetHandler(f func([]Attr, string)) {
func (logger *StarLogger) SetHandler(f func(LogData)) {
if f != nil {
StartStacks()
}
logger.handlerFunc = f
}
func (logger *StarLogger) GetHandler() func([]Attr, string) {
func (logger *StarLogger) GetHandler() func(LogData) {
return logger.handlerFunc
}
func (logger *StarLogger) SetSwitching(sw bool) {
@ -204,3 +207,15 @@ func (logger *StarLogger) Logf(showLog bool, level int, format string, str ...in
func (logger *StarLogger) Logln(showLog bool, level int, str ...interface{}) {
logger.logcore.Logln(logger.thread, logger.isStd, showLog, level, logger.handlerFunc, str...)
}
func (logger *StarLogger) Write(str ...interface{}) {
logger.logcore.Write(str...)
}
func (logger *StarLogger) Writef(format string, str ...interface{}) {
logger.logcore.Writef(format, str...)
}
func (logger *StarLogger) Writeln(str ...interface{}) {
logger.logcore.Writeln(str...)
}

@ -8,7 +8,6 @@ import (
"time"
"b612.me/starlog/colorable"
"b612.me/starmap"
)
const (
@ -33,16 +32,18 @@ var (
LvPanic: "PANIC",
LvFatal: "FATAL",
}
stacks *starmap.StarStack
stacks *starChanStack
stackStarted bool = false
stackStopChan chan int
stackMu sync.Mutex
stdScreen io.Writer = colorable.NewColorableStdout()
errScreen io.Writer = colorable.NewColorableStderr()
)
type starlog struct {
mu *sync.Mutex
output io.Writer
errOutputLevel int
showFuncName bool
showThread bool
showLevel bool
@ -53,28 +54,34 @@ type starlog struct {
onlyColorLevel bool
stopWriter bool
id string
name string
colorList map[int][]Attr
colorMe map[int]*Color
}
type StarLogger struct {
thread string
handlerFunc func([]Attr, string)
handlerFunc func(LogData)
logcore *starlog
isStd bool
}
type logTransfer struct {
handlerFunc func([]Attr, string)
colors []Attr
logStr string
handlerFunc func(LogData)
LogData
}
type LogData struct {
Name string
Log string
Colors []Attr
}
func newLogCore(out io.Writer) *starlog {
return &starlog{
mu: &sync.Mutex{},
output: out,
errOutputLevel: LvError,
showFuncName: true,
showThread: true,
showLevel: true,
@ -87,7 +94,7 @@ func newLogCore(out io.Writer) *starlog {
colorList: map[int][]Attr{
LvDebug: []Attr{FgWhite},
LvInfo: []Attr{FgGreen},
LvNotice: []Attr{FgBlue},
LvNotice: []Attr{FgCyan},
LvWarning: []Attr{FgYellow},
LvError: []Attr{FgMagenta},
LvCritical: []Attr{FgRed, Bold},
@ -97,7 +104,7 @@ func newLogCore(out io.Writer) *starlog {
colorMe: map[int]*Color{
LvDebug: NewColor([]Attr{FgWhite}...),
LvInfo: NewColor([]Attr{FgGreen}...),
LvNotice: NewColor([]Attr{FgBlue}...),
LvNotice: NewColor([]Attr{FgCyan}...),
LvWarning: NewColor([]Attr{FgYellow}...),
LvError: NewColor([]Attr{FgMagenta}...),
LvCritical: NewColor([]Attr{FgRed, Bold}...),
@ -116,6 +123,18 @@ func NewStarlog(out io.Writer) *StarLogger {
}
}
func (logger *StarLogger) StdErrLevel() int {
logger.logcore.mu.Lock()
defer logger.logcore.mu.Unlock()
return logger.logcore.errOutputLevel
}
func (logger *StarLogger) SetStdErrLevel(level int) {
logger.logcore.mu.Lock()
defer logger.logcore.mu.Unlock()
logger.logcore.errOutputLevel = level
}
func (logger *StarLogger) NewFlag() *StarLogger {
return &StarLogger{
thread: getRandomFlag(false),
@ -128,6 +147,16 @@ func (logger *StarLogger) SetNewRandomFlag() {
logger.thread = getRandomFlag(false)
}
func (logger *StarLogger) SetName(name string) {
logger.logcore.mu.Lock()
defer logger.logcore.mu.Unlock()
logger.logcore.name = name
}
func (logger *StarLogger) GetName() string {
return logger.logcore.name
}
func getRandomFlag(isMain bool) string {
rand.Seed(time.Now().UnixNano())
if isMain {
@ -151,9 +180,12 @@ func StartStacks() {
stackMu.Unlock()
return
}
unlock := make(chan struct{})
go func() {
stackStarted = true
stacks = newStarChanStack(1024)
stackMu.Unlock()
unlock <- struct{}{}
defer func() {
stackStarted = false
}()
@ -163,17 +195,17 @@ func StartStacks() {
return
default:
}
poped := stacks.MustPop()
if poped == nil {
time.Sleep(time.Microsecond * 500)
continue
poped, err := stacks.Pop()
if err != nil {
return
}
val := poped.(logTransfer)
if val.handlerFunc != nil {
val.handlerFunc(val.colors, val.logStr)
val.handlerFunc(val.LogData)
}
}
}()
<-unlock
}
func StopStacks() {
@ -184,5 +216,6 @@ func StopStacks() {
}
func Stop() {
stacks.Close()
StopStacks()
}

Loading…
Cancel
Save