Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
51608601cf | |||
121819ef13 | |||
305309a3c8 | |||
9adabd6723 | |||
1632256ded |
293
archive.go
293
archive.go
@ -5,24 +5,22 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"b612.me/staros"
|
|
||||||
|
|
||||||
"b612.me/starmap"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var archMap starmap.StarMapKV
|
var archMap starMapKV
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
archMap = starmap.NewStarMap()
|
archMap = newStarMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
type Archive interface {
|
type Archive interface {
|
||||||
ShouldArchiveNow(string, os.FileInfo) bool
|
ShouldArchiveNow(*StarLogger, string, os.FileInfo) bool
|
||||||
NextLogFilePath(string, os.FileInfo) string
|
NextLogFilePath(*StarLogger, string, os.FileInfo) string
|
||||||
|
ArchiveLogFilePath(*StarLogger, string, os.FileInfo) string
|
||||||
Interval() int64
|
Interval() int64
|
||||||
HookBeforArchive() func(string, os.FileInfo) error
|
HookBeforArchive() func(*StarLogger, string, string, os.FileInfo) error //archivePath;currentPath
|
||||||
HookAfterArchive() func(string, string, os.FileInfo) error
|
HookAfterArchive() func(*StarLogger, string, string, os.FileInfo) error //archivePath;currentPath
|
||||||
|
DoArchive() func(*StarLogger, string, string, os.FileInfo) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type logfileinfo struct {
|
type logfileinfo struct {
|
||||||
@ -41,7 +39,7 @@ func SetLogFile(path string, logger *StarLogger, appendMode bool) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !appendMode && staros.Exists(fullpath) {
|
if !appendMode && Exists(fullpath) {
|
||||||
os.Remove(fullpath)
|
os.Remove(fullpath)
|
||||||
}
|
}
|
||||||
fp, err := os.OpenFile(fullpath, fileMode, 0644)
|
fp, err := os.OpenFile(fullpath, fileMode, 0644)
|
||||||
@ -119,7 +117,7 @@ func StartArchive(logger *StarLogger, arch Archive) error {
|
|||||||
select {
|
select {
|
||||||
case <-stopChan:
|
case <-stopChan:
|
||||||
return
|
return
|
||||||
case <-time.After(time.Second * time.Duration(arch.Interval())):
|
case <-time.After(time.Millisecond * time.Duration(1000*arch.Interval())):
|
||||||
}
|
}
|
||||||
fileinfo, err := GetLogFileInfo(logger)
|
fileinfo, err := GetLogFileInfo(logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -131,21 +129,38 @@ func StartArchive(logger *StarLogger, arch Archive) error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
fullpath := archMap.MustGet(logger.logcore.id).(logfileinfo).fullpath
|
fullpath := archMap.MustGet(logger.logcore.id).(logfileinfo).fullpath
|
||||||
if !arch.ShouldArchiveNow(fullpath, fileinfo) {
|
if !arch.ShouldArchiveNow(logger, fullpath, fileinfo) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
newLogPath := arch.NextLogFilePath(fullpath, fileinfo)
|
newLogPath := arch.NextLogFilePath(logger, fullpath, fileinfo)
|
||||||
|
archiveLogPath := arch.ArchiveLogFilePath(logger, fullpath, fileinfo)
|
||||||
if arch.HookBeforArchive() != nil {
|
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)
|
logger.Errorf("error occur while executing hook before archive,detail is %v\n", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
err = CloseWithSwitching(logger)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if arch.DoArchive() == nil {
|
||||||
|
err = os.Rename(fullpath, archiveLogPath)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err = arch.DoArchive()(logger, fullpath, archiveLogPath, fileinfo)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("error occur while executing archive log file,detail is %v\n", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
if err := SetLogFile(newLogPath, logger, false); err != nil {
|
if err := SetLogFile(newLogPath, logger, false); err != nil {
|
||||||
logger.Errorf("error occur while executing coverting new log file,detail is %v\n", err)
|
logger.Errorf("error occur while executing coverting new log file,detail is %v\n", err)
|
||||||
continue
|
continue
|
||||||
} else {
|
} else {
|
||||||
logger.Debugln("Set Log Success")
|
logger.Debugln("Archive Log Success")
|
||||||
}
|
}
|
||||||
fileinfo, err = GetLogFileInfo(logger)
|
fileinfo, err = GetLogFileInfo(logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -153,7 +168,7 @@ func StartArchive(logger *StarLogger, arch Archive) error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if arch.HookAfterArchive() != nil {
|
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)
|
logger.Errorf("error occur while executing hook after archive,detail is %v\n", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -178,23 +193,49 @@ func StopArchive(logger *StarLogger) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ArchiveByDate struct {
|
type ArchiveByDate struct {
|
||||||
interval int64
|
interval int64
|
||||||
checkInterval int64
|
checkInterval int64
|
||||||
newFileNameStyle string
|
baseFileStyle string
|
||||||
hookBefor func(string, os.FileInfo) error
|
archiveStyle string
|
||||||
hookAfter func(string, string, os.FileInfo) error
|
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 {
|
func (abd *ArchiveByDate) ShouldArchiveNow(l *StarLogger, fullpath string, info os.FileInfo) bool {
|
||||||
if time.Now().Unix()-staros.GetFileCreationTime(info).Unix() > abd.interval {
|
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 true
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
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)
|
dir := filepath.Dir(oldpath)
|
||||||
newName := time.Now().Format(abd.newFileNameStyle)
|
if !abd.changeArchiveName {
|
||||||
|
base := filepath.Base(abd.baseFileStyle)
|
||||||
|
newName = base[:len(base)-len(filepath.Ext(base))] + 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 {
|
||||||
|
base := filepath.Base(abd.baseFileStyle)
|
||||||
|
newName = base[:len(base)-len(filepath.Ext(base))] + time.Now().Format(abd.archiveStyle)
|
||||||
|
} else {
|
||||||
|
newName = abd.baseFileStyle
|
||||||
|
}
|
||||||
return filepath.Join(dir, newName)
|
return filepath.Join(dir, newName)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,52 +243,83 @@ func (abd *ArchiveByDate) Interval() int64 {
|
|||||||
return abd.checkInterval
|
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 {
|
func (abd *ArchiveByDate) HookAfterArchive() func(*StarLogger, string, string, os.FileInfo) error {
|
||||||
return abd.hookAfter
|
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) {
|
func (abd *ArchiveByDate) DoArchive() func(*StarLogger, string, string, os.FileInfo) error {
|
||||||
|
return nil
|
||||||
abd.hookBefor = f
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (abd *ArchiveByDate) SetHookAfterArchive(f func(string, string, os.FileInfo) error) {
|
func (abd *ArchiveByDate) SetHookBeforArchive(f func(*StarLogger, string, string, os.FileInfo) error) {
|
||||||
|
abd.hookBefore = f
|
||||||
|
}
|
||||||
|
|
||||||
|
func (abd *ArchiveByDate) SetHookAfterArchive(f func(*StarLogger, string, string, os.FileInfo) error) {
|
||||||
abd.hookAfter = f
|
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{
|
return &ArchiveByDate{
|
||||||
interval: archInterval,
|
interval: archInterval,
|
||||||
checkInterval: checkInterval,
|
checkInterval: checkInterval,
|
||||||
newFileNameStyle: fileStyle,
|
changeArchiveName: changeArchiveName,
|
||||||
hookBefor: hookbefor,
|
baseFileStyle: baseFileName,
|
||||||
hookAfter: hookafter,
|
archiveStyle: archiveFileName,
|
||||||
|
hookBefore: hookbefore,
|
||||||
|
hookAfter: hookafter,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ArchiveBySize struct {
|
type ArchiveBySize struct {
|
||||||
size int64
|
size int64
|
||||||
checkInterval int64
|
checkInterval int64
|
||||||
newFileNameStyle string
|
changeArchiveName bool
|
||||||
hookBefor func(string, os.FileInfo) error
|
baseFileStyle string
|
||||||
hookAfter func(string, string, os.FileInfo) error
|
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 {
|
if info.Size() > abd.size {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
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)
|
dir := filepath.Dir(oldpath)
|
||||||
newName := time.Now().Format(abd.newFileNameStyle)
|
if !abd.changeArchiveName {
|
||||||
|
base := filepath.Base(abd.baseFileStyle)
|
||||||
|
newName = base[:len(base)-len(filepath.Ext(base))] + 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)
|
||||||
|
if abd.changeArchiveName {
|
||||||
|
base := filepath.Base(abd.baseFileStyle)
|
||||||
|
newName = base[:len(base)-len(filepath.Ext(base))] + time.Now().Format(abd.archiveStyle)
|
||||||
|
} else {
|
||||||
|
newName = abd.baseFileStyle
|
||||||
|
}
|
||||||
return filepath.Join(dir, newName)
|
return filepath.Join(dir, newName)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,30 +327,127 @@ func (abd *ArchiveBySize) Interval() int64 {
|
|||||||
return abd.checkInterval
|
return abd.checkInterval
|
||||||
}
|
}
|
||||||
|
|
||||||
func (abd *ArchiveBySize) HookBeforArchive() func(string, os.FileInfo) error {
|
func (abd *ArchiveBySize) HookBeforArchive() func(*StarLogger, string, string, os.FileInfo) error {
|
||||||
|
return abd.hookBefore
|
||||||
return abd.hookBefor
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (abd *ArchiveBySize) HookAfterArchive() func(string, string, os.FileInfo) error {
|
func (abd *ArchiveBySize) HookAfterArchive() func(*StarLogger, string, string, os.FileInfo) error {
|
||||||
return abd.hookAfter
|
return abd.hookAfter
|
||||||
}
|
}
|
||||||
|
|
||||||
func (abd *ArchiveBySize) SetHookBeforArchive(f func(string, os.FileInfo) error) {
|
func (abd *ArchiveBySize) SetHookBeforArchive(f func(*StarLogger, string, string, os.FileInfo) error) {
|
||||||
|
abd.hookBefore = f
|
||||||
abd.hookBefor = 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
|
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 (abd *ArchiveBySize) DoArchive() func(*StarLogger, string, string, os.FileInfo) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
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{
|
return &ArchiveBySize{
|
||||||
size: size,
|
size: size,
|
||||||
checkInterval: checkInterval,
|
checkInterval: checkInterval,
|
||||||
newFileNameStyle: fileStyle,
|
baseFileStyle: baseFileStyle,
|
||||||
hookBefor: hookbefor,
|
archiveStyle: archiveFileStyle,
|
||||||
hookAfter: hookafter,
|
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 {
|
||||||
|
base := filepath.Base(abd.baseFileStyle)
|
||||||
|
newName = base[:len(base)-len(filepath.Ext(base))] + 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 {
|
||||||
|
base := filepath.Base(abd.baseFileStyle)
|
||||||
|
newName = base[:len(base)-len(filepath.Ext(base))] + 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 (abd *ArchiveByDateSize) DoArchive() func(*StarLogger, string, string, os.FileInfo) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
17
archive_test.go
Normal file
17
archive_test.go
Normal file
@ -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, 10, 2, "test.log",
|
||||||
|
"_2006_01_02_15_04_05.log", true, nil, nil))
|
||||||
|
for {
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
l.Infoln("hahaha", time.Now())
|
||||||
|
}
|
||||||
|
}
|
2
core.go
2
core.go
@ -311,7 +311,7 @@ func (logger *starlog) Logln(thread string, isStd bool, isShow bool, level int,
|
|||||||
|
|
||||||
func (logger *starlog) Write(str ...interface{}) {
|
func (logger *starlog) Write(str ...interface{}) {
|
||||||
strs := fmt.Sprint(str...)
|
strs := fmt.Sprint(str...)
|
||||||
logger.Write(strs)
|
logger.write(strs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *starlog) Writef(format string, str ...interface{}) {
|
func (logger *starlog) Writef(format string, str ...interface{}) {
|
||||||
|
34
files.go
Normal file
34
files.go
Normal file
@ -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()
|
||||||
|
}
|
22
files_darwin.go
Normal file
22
files_darwin.go
Normal file
@ -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)
|
||||||
|
}
|
22
files_unix.go
Normal file
22
files_unix.go
Normal file
@ -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)
|
||||||
|
}
|
20
files_windows.go
Normal file
20
files_windows.go
Normal file
@ -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())
|
||||||
|
}
|
17
go.mod
17
go.mod
@ -2,19 +2,4 @@ module b612.me/starlog
|
|||||||
|
|
||||||
go 1.16
|
go 1.16
|
||||||
|
|
||||||
require (
|
require golang.org/x/sys v0.24.0
|
||||||
b612.me/starmap v1.2.2
|
|
||||||
b612.me/staros v1.1.5
|
|
||||||
golang.org/x/sys v0.4.0
|
|
||||||
)
|
|
||||||
|
|
||||||
require (
|
|
||||||
b612.me/notify v1.2.3 // indirect
|
|
||||||
b612.me/starcrypto v0.0.2 // indirect
|
|
||||||
b612.me/stario v0.0.7 // indirect
|
|
||||||
b612.me/starnet v0.1.6 // indirect
|
|
||||||
b612.me/win32api v0.0.1 // indirect
|
|
||||||
b612.me/wincmd v0.0.2 // indirect
|
|
||||||
golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064 // indirect
|
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
|
|
||||||
)
|
|
||||||
|
34
go.sum
34
go.sum
@ -1,32 +1,2 @@
|
|||||||
b612.me/notify v1.2.3 h1:4w5zDakubC8jIPg4JT8DANczSMxRhwEFjM/2A0dvuvY=
|
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
|
||||||
b612.me/notify v1.2.3/go.mod h1:VV29yq3KXTKJKSSjr5yS9bD2c2MGzuypYalfL9yGQ6M=
|
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
b612.me/starcrypto v0.0.2 h1:aRf1HcqK8GqHYxLAhWfFC4W/EqQLEFNEmxsBu3wG30o=
|
|
||||||
b612.me/starcrypto v0.0.2/go.mod h1:hz0xRnfWNpYOlVrIPoGrQOWPibq4YiUZ7qN5tsQbzPo=
|
|
||||||
b612.me/stario v0.0.7 h1:QbQcsHCVLE6vRgVrPN4+9DGiSaC6IWdtm4ClL2tpMUg=
|
|
||||||
b612.me/stario v0.0.7/go.mod h1:or4ssWcxQSjMeu+hRKEgtp0X517b3zdlEOAms8Qscvw=
|
|
||||||
b612.me/starmap v1.2.2 h1:1OQbd0XXU7G/cHvkj9lEZg8sLZWZEcYlRjYzDxRc4N0=
|
|
||||||
b612.me/starmap v1.2.2/go.mod h1:fXb1SF8+BrkHlhSMQAJ/DUTYpqhNimPukpqzUIRio4U=
|
|
||||||
b612.me/starnet v0.1.6 h1:/QaaKpuXfvJm6ayvk85jaLaKBmO1zx+XSxfnlSB3xGw=
|
|
||||||
b612.me/starnet v0.1.6/go.mod h1:JjFLTMPsWsPei7AiXwBTt4QCoB9gux1XS7SHv/Ux+D4=
|
|
||||||
b612.me/staros v1.1.5 h1:0Mkk0TOYoI9SOUf50X2Amb+/4p2lopMntOzV5nPKEeg=
|
|
||||||
b612.me/staros v1.1.5/go.mod h1:JcmVUeFbuITVnwPqxCr6R9yDbBmFrfyhdk2HVdZMXYw=
|
|
||||||
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.2 h1:Ub1WtelVT6a3vD4B6zDYo3UPO/t9ymnI3x1dQPJcrGw=
|
|
||||||
b612.me/wincmd v0.0.2/go.mod h1:bwpyCKfSDY8scSMo3Lrd0Qnqvpz7/CILL7oodfG0wgo=
|
|
||||||
golang.org/x/crypto v0.0.0-20220313003712-b769efc7c000/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
|
||||||
golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064 h1:S25/rfnfsMVgORT4/J61MJ7rdyseOZOyvLIrZEZ7s6s=
|
|
||||||
golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064/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/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
|
|
||||||
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
|
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
|
||||||
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=
|
|
||||||
|
149
stacks.go
Normal file
149
stacks.go
Normal file
@ -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
|
package starlog
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"b612.me/starmap"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
@ -13,7 +12,6 @@ var Std *StarLogger
|
|||||||
var stdmu sync.Mutex
|
var stdmu sync.Mutex
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
stacks = starmap.NewStarStack(1024)
|
|
||||||
rand.Seed(time.Now().UnixNano())
|
rand.Seed(time.Now().UnixNano())
|
||||||
stackStopChan = make(chan int)
|
stackStopChan = make(chan int)
|
||||||
Std = NewStarlog(nil)
|
Std = NewStarlog(nil)
|
||||||
|
15
typed.go
15
typed.go
@ -8,7 +8,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"b612.me/starlog/colorable"
|
"b612.me/starlog/colorable"
|
||||||
"b612.me/starmap"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -33,7 +32,7 @@ var (
|
|||||||
LvPanic: "PANIC",
|
LvPanic: "PANIC",
|
||||||
LvFatal: "FATAL",
|
LvFatal: "FATAL",
|
||||||
}
|
}
|
||||||
stacks *starmap.StarStack
|
stacks *starChanStack
|
||||||
stackStarted bool = false
|
stackStarted bool = false
|
||||||
stackStopChan chan int
|
stackStopChan chan int
|
||||||
stackMu sync.Mutex
|
stackMu sync.Mutex
|
||||||
@ -181,9 +180,12 @@ func StartStacks() {
|
|||||||
stackMu.Unlock()
|
stackMu.Unlock()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
unlock := make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
stackStarted = true
|
stackStarted = true
|
||||||
|
stacks = newStarChanStack(1024)
|
||||||
stackMu.Unlock()
|
stackMu.Unlock()
|
||||||
|
unlock <- struct{}{}
|
||||||
defer func() {
|
defer func() {
|
||||||
stackStarted = false
|
stackStarted = false
|
||||||
}()
|
}()
|
||||||
@ -193,10 +195,9 @@ func StartStacks() {
|
|||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
poped := stacks.MustPop()
|
poped, err := stacks.Pop()
|
||||||
if poped == nil {
|
if err != nil {
|
||||||
time.Sleep(time.Microsecond * 500)
|
return
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
val := poped.(logTransfer)
|
val := poped.(logTransfer)
|
||||||
if val.handlerFunc != nil {
|
if val.handlerFunc != nil {
|
||||||
@ -204,6 +205,7 @@ func StartStacks() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
<-unlock
|
||||||
}
|
}
|
||||||
|
|
||||||
func StopStacks() {
|
func StopStacks() {
|
||||||
@ -214,5 +216,6 @@ func StopStacks() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Stop() {
|
func Stop() {
|
||||||
|
stacks.Close()
|
||||||
StopStacks()
|
StopStacks()
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user