Compare commits
6 Commits
4473d46af6
...
7f15eb4e36
Author | SHA1 | Date | |
---|---|---|---|
![]() |
7f15eb4e36 | ||
![]() |
e6de5c461d | ||
![]() |
4065555565 | ||
![]() |
f82e6db6f8 | ||
![]() |
cb55fecbc6 | ||
![]() |
ac9c772fb6 |
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.vscode/settings.json
|
||||||
|
*.log
|
||||||
|
*.log.*
|
44
README.md
Normal file
44
README.md
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
# Simple Log
|
||||||
|
|
||||||
|
A very simple log system(golang).
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go get github.com/lion187chen/simplelog
|
||||||
|
```
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/lion187chen/simplelog"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CreateLog(file string, level simplelog.Level) *simplelog.Log {
|
||||||
|
switch file {
|
||||||
|
case "":
|
||||||
|
return new(simplelog.Log).InitStd(level, simplelog.Ltime|simplelog.Lfile|simplelog.Llevel)
|
||||||
|
default:
|
||||||
|
return new(simplelog.Log).InitRotating(file, 1024*10, 10, level)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
log := CreateLog("./log/MS.log", simplelog.LevelInfo)
|
||||||
|
for i := 0; i < 10000000; i++ {
|
||||||
|
log.Trace("hello world")
|
||||||
|
log.Debug("hello world")
|
||||||
|
log.Info("hello world")
|
||||||
|
log.Warn("hello world")
|
||||||
|
log.Error("hello world")
|
||||||
|
log.Fatal("hello world")
|
||||||
|
time.Sleep(8 * time.Millisecond)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
29
demo/main.go
Normal file
29
demo/main.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/lion187chen/simplelog"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CreateLog(file string, level simplelog.Level) *simplelog.Log {
|
||||||
|
switch file {
|
||||||
|
case "":
|
||||||
|
return new(simplelog.Log).InitStd(level, simplelog.Ltime|simplelog.Lfile|simplelog.Llevel)
|
||||||
|
default:
|
||||||
|
return new(simplelog.Log).InitRotating(file, 1024*10, 10, level)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
log := CreateLog("./log/MS.log", simplelog.LevelInfo)
|
||||||
|
for i := 0; i < 10000000; i++ {
|
||||||
|
log.Trace("hello world")
|
||||||
|
log.Debug("hello world")
|
||||||
|
log.Info("hello world")
|
||||||
|
log.Warn("hello world")
|
||||||
|
log.Error("hello world")
|
||||||
|
log.Fatal("hello world")
|
||||||
|
time.Sleep(8 * time.Millisecond)
|
||||||
|
}
|
||||||
|
}
|
@ -2,11 +2,22 @@ package simplelog
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func isFileExist(filename string) bool {
|
||||||
|
info, e := os.Stat(filename)
|
||||||
|
|
||||||
|
if e == nil {
|
||||||
|
return !info.IsDir()
|
||||||
|
} else {
|
||||||
|
return os.IsExist(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// FileHandler writes log to a file.
|
// FileHandler writes log to a file.
|
||||||
type FileHandler struct {
|
type FileHandler struct {
|
||||||
fd *os.File
|
fd *os.File
|
||||||
@ -48,6 +59,29 @@ type RotatingFileHandler struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *RotatingFileHandler) InitRotating(name string, maxBytes int, backupCount int) (*RotatingFileHandler, error) {
|
func (h *RotatingFileHandler) InitRotating(name string, maxBytes int, backupCount int) (*RotatingFileHandler, error) {
|
||||||
|
h.fileName = name
|
||||||
|
h.maxBytes = maxBytes
|
||||||
|
h.backupCount = backupCount
|
||||||
|
|
||||||
|
if isFileExist(name) {
|
||||||
|
var err error
|
||||||
|
h.fd, err = os.OpenFile(name, os.O_CREATE|os.O_RDONLY, 0666)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
f, err := h.fd.Stat()
|
||||||
|
if err != nil {
|
||||||
|
h.fd.Close()
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if f.Size() < int64(h.maxBytes) {
|
||||||
|
h.fd.Seek(0, io.SeekEnd)
|
||||||
|
} else {
|
||||||
|
h._doRollover()
|
||||||
|
}
|
||||||
|
return h, nil
|
||||||
|
}
|
||||||
|
|
||||||
dir := path.Dir(name)
|
dir := path.Dir(name)
|
||||||
os.MkdirAll(dir, 0777)
|
os.MkdirAll(dir, 0777)
|
||||||
|
|
||||||
@ -55,10 +89,6 @@ func (h *RotatingFileHandler) InitRotating(name string, maxBytes int, backupCoun
|
|||||||
return nil, fmt.Errorf("invalid max bytes")
|
return nil, fmt.Errorf("invalid max bytes")
|
||||||
}
|
}
|
||||||
|
|
||||||
h.fileName = name
|
|
||||||
h.maxBytes = maxBytes
|
|
||||||
h.backupCount = backupCount
|
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
h.fd, err = os.OpenFile(name, os.O_CREATE|os.O_WRONLY, 0666)
|
h.fd, err = os.OpenFile(name, os.O_CREATE|os.O_WRONLY, 0666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -106,6 +136,10 @@ func (h *RotatingFileHandler) doRollover() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h._doRollover()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *RotatingFileHandler) _doRollover() {
|
||||||
if h.backupCount > 0 {
|
if h.backupCount > 0 {
|
||||||
h.fd.Close()
|
h.fd.Close()
|
||||||
|
|
||||||
|
2
go.mod
2
go.mod
@ -1,3 +1,3 @@
|
|||||||
module blacktea.cpolar.cn/OrgGo/simplelog
|
module github.com/lion187chen/simplelog
|
||||||
|
|
||||||
go 1.21.0
|
go 1.21.0
|
||||||
|
62
simplelog.go
62
simplelog.go
@ -28,9 +28,11 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Level int
|
||||||
|
|
||||||
// log level, from low to high, more higher means more serious
|
// log level, from low to high, more higher means more serious
|
||||||
const (
|
const (
|
||||||
LevelTrace = iota
|
LevelTrace Level = iota
|
||||||
LevelDebug
|
LevelDebug
|
||||||
LevelInfo
|
LevelInfo
|
||||||
LevelWarn
|
LevelWarn
|
||||||
@ -39,7 +41,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Ltime = 1 << iota //print timestamp format as "2006/01/02 15:04:05.000"
|
Ltime = 1 << iota // print timestamp format as "2006/01/02 15:04:05.000"
|
||||||
Lfile // print file name and line format as file.go:123
|
Lfile // print file name and line format as file.go:123
|
||||||
Llevel // print log level format as [Trace|Debug|Info...]
|
Llevel // print log level format as [Trace|Debug|Info...]
|
||||||
)
|
)
|
||||||
@ -60,7 +62,7 @@ func (i *atomicInt32) Get() int {
|
|||||||
return int(atomic.LoadInt32((*int32)(i)))
|
return int(atomic.LoadInt32((*int32)(i)))
|
||||||
}
|
}
|
||||||
|
|
||||||
type SimpleLog struct {
|
type Log struct {
|
||||||
level atomicInt32
|
level atomicInt32
|
||||||
flag int
|
flag int
|
||||||
|
|
||||||
@ -91,8 +93,8 @@ type SimpleLog struct {
|
|||||||
// log.Lfile
|
// log.Lfile
|
||||||
// log.Llevel
|
// log.Llevel
|
||||||
// 的组合
|
// 的组合
|
||||||
func (l *SimpleLog) Init(handler StreamHandler, level, flag int) *SimpleLog {
|
func (l *Log) Init(handler StreamHandler, level Level, flag int) *Log {
|
||||||
l.level.Set(level)
|
l.level.Set(int(level))
|
||||||
l.handler = handler
|
l.handler = handler
|
||||||
|
|
||||||
l.flag = flag
|
l.flag = flag
|
||||||
@ -103,7 +105,7 @@ func (l *SimpleLog) Init(handler StreamHandler, level, flag int) *SimpleLog {
|
|||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *SimpleLog) InitStd(level, flag int) *SimpleLog {
|
func (l *Log) InitStd(level Level, flag int) *Log {
|
||||||
handler, e := NewStreamHandle(os.Stdout)
|
handler, e := NewStreamHandle(os.Stdout)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
panic(e)
|
panic(e)
|
||||||
@ -112,7 +114,7 @@ func (l *SimpleLog) InitStd(level, flag int) *SimpleLog {
|
|||||||
return l.Init(handler, level, flag)
|
return l.Init(handler, level, flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *SimpleLog) InitFile(name string, level, flag int) *SimpleLog {
|
func (l *Log) InitFile(name string, level Level, flag int) *Log {
|
||||||
handler, e := new(FileHandler).InitFile(name)
|
handler, e := new(FileHandler).InitFile(name)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
panic(e)
|
panic(e)
|
||||||
@ -121,7 +123,7 @@ func (l *SimpleLog) InitFile(name string, level, flag int) *SimpleLog {
|
|||||||
return l.Init(handler, level, flag)
|
return l.Init(handler, level, flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *SimpleLog) InitRotating(name string, maxBytes, backupCount, level int) *SimpleLog {
|
func (l *Log) InitRotating(name string, maxBytes, backupCount int, level Level) *Log {
|
||||||
handler, e := new(RotatingFileHandler).InitRotating(name, maxBytes, backupCount)
|
handler, e := new(RotatingFileHandler).InitRotating(name, maxBytes, backupCount)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
panic(e)
|
panic(e)
|
||||||
@ -130,7 +132,7 @@ func (l *SimpleLog) InitRotating(name string, maxBytes, backupCount, level int)
|
|||||||
return l.Init(handler, level, Ltime|Lfile|Llevel)
|
return l.Init(handler, level, Ltime|Lfile|Llevel)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *SimpleLog) InitTimedRotating(name string, when int8, interval, level int) *SimpleLog {
|
func (l *Log) InitTimedRotating(name string, when int8, interval int, level Level) *Log {
|
||||||
handler, e := new(TimedRotatingFileHandler).InitTimedRotating(name, when, interval)
|
handler, e := new(TimedRotatingFileHandler).InitTimedRotating(name, when, interval)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
panic(e)
|
panic(e)
|
||||||
@ -139,7 +141,7 @@ func (l *SimpleLog) InitTimedRotating(name string, when int8, interval, level in
|
|||||||
return l.Init(handler, level, Ltime|Lfile|Llevel)
|
return l.Init(handler, level, Ltime|Lfile|Llevel)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *SimpleLog) popBuf() []byte {
|
func (l *Log) popBuf() []byte {
|
||||||
l.bufMutex.Lock()
|
l.bufMutex.Lock()
|
||||||
var buf []byte
|
var buf []byte
|
||||||
if len(l.bufs) == 0 {
|
if len(l.bufs) == 0 {
|
||||||
@ -153,7 +155,7 @@ func (l *SimpleLog) popBuf() []byte {
|
|||||||
return buf
|
return buf
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *SimpleLog) putBuf(buf []byte) {
|
func (l *Log) putBuf(buf []byte) {
|
||||||
l.bufMutex.Lock()
|
l.bufMutex.Lock()
|
||||||
if len(l.bufs) < maxBufPoolSize {
|
if len(l.bufs) < maxBufPoolSize {
|
||||||
buf = buf[0:0]
|
buf = buf[0:0]
|
||||||
@ -162,7 +164,7 @@ func (l *SimpleLog) putBuf(buf []byte) {
|
|||||||
l.bufMutex.Unlock()
|
l.bufMutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *SimpleLog) Close() {
|
func (l *Log) Close() {
|
||||||
if l.closed.Get() == 1 {
|
if l.closed.Get() == 1 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -172,12 +174,12 @@ func (l *SimpleLog) Close() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set log level, any log level less than it will not log
|
// set log level, any log level less than it will not log
|
||||||
func (l *SimpleLog) SetLevel(level int) {
|
func (l *Log) SetLevel(level Level) {
|
||||||
l.level.Set(level)
|
l.level.Set(int(level))
|
||||||
}
|
}
|
||||||
|
|
||||||
// name can be in ["trace", "debug", "info", "warn", "error", "fatal"]
|
// name can be in ["trace", "debug", "info", "warn", "error", "fatal"]
|
||||||
func (l *SimpleLog) SetLevelByName(name string) {
|
func (l *Log) SetLevelByName(name string) {
|
||||||
name = strings.ToLower(name)
|
name = strings.ToLower(name)
|
||||||
switch name {
|
switch name {
|
||||||
case "trace":
|
case "trace":
|
||||||
@ -195,7 +197,7 @@ func (l *SimpleLog) SetLevelByName(name string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *SimpleLog) SetHandler(h StreamHandler) {
|
func (l *Log) SetHandler(h StreamHandler) {
|
||||||
if l.closed.Get() == 1 {
|
if l.closed.Get() == 1 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -208,13 +210,13 @@ func (l *SimpleLog) SetHandler(h StreamHandler) {
|
|||||||
l.hMutex.Unlock()
|
l.hMutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *SimpleLog) Output(callDepth int, level int, format string, v ...interface{}) {
|
func (l *Log) Output(callDepth int, level Level, format string, v ...interface{}) {
|
||||||
if l.closed.Get() == 1 {
|
if l.closed.Get() == 1 {
|
||||||
// closed
|
// closed
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if l.level.Get() > level {
|
if l.level.Get() > int(level) {
|
||||||
// higher level can be logged
|
// higher level can be logged
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -288,61 +290,61 @@ func (l *SimpleLog) Output(callDepth int, level int, format string, v ...interfa
|
|||||||
}
|
}
|
||||||
|
|
||||||
// log with Trace level
|
// log with Trace level
|
||||||
func (l *SimpleLog) Trace(v ...interface{}) {
|
func (l *Log) Trace(v ...interface{}) {
|
||||||
l.Output(2, LevelTrace, "", v...)
|
l.Output(2, LevelTrace, "", v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// log with Debug level
|
// log with Debug level
|
||||||
func (l *SimpleLog) Debug(v ...interface{}) {
|
func (l *Log) Debug(v ...interface{}) {
|
||||||
l.Output(2, LevelDebug, "", v...)
|
l.Output(2, LevelDebug, "", v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// log with info level
|
// log with info level
|
||||||
func (l *SimpleLog) Info(v ...interface{}) {
|
func (l *Log) Info(v ...interface{}) {
|
||||||
l.Output(2, LevelInfo, "", v...)
|
l.Output(2, LevelInfo, "", v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// log with warn level
|
// log with warn level
|
||||||
func (l *SimpleLog) Warn(v ...interface{}) {
|
func (l *Log) Warn(v ...interface{}) {
|
||||||
l.Output(2, LevelWarn, "", v...)
|
l.Output(2, LevelWarn, "", v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// log with error level
|
// log with error level
|
||||||
func (l *SimpleLog) Error(v ...interface{}) {
|
func (l *Log) Error(v ...interface{}) {
|
||||||
l.Output(2, LevelError, "", v...)
|
l.Output(2, LevelError, "", v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// log with fatal level
|
// log with fatal level
|
||||||
func (l *SimpleLog) Fatal(v ...interface{}) {
|
func (l *Log) Fatal(v ...interface{}) {
|
||||||
l.Output(2, LevelFatal, "", v...)
|
l.Output(2, LevelFatal, "", v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// log with Trace level
|
// log with Trace level
|
||||||
func (l *SimpleLog) Tracef(format string, v ...interface{}) {
|
func (l *Log) Tracef(format string, v ...interface{}) {
|
||||||
l.Output(2, LevelTrace, format, v...)
|
l.Output(2, LevelTrace, format, v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// log with Debug level
|
// log with Debug level
|
||||||
func (l *SimpleLog) Debugf(format string, v ...interface{}) {
|
func (l *Log) Debugf(format string, v ...interface{}) {
|
||||||
l.Output(2, LevelDebug, format, v...)
|
l.Output(2, LevelDebug, format, v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// log with info level
|
// log with info level
|
||||||
func (l *SimpleLog) Infof(format string, v ...interface{}) {
|
func (l *Log) Infof(format string, v ...interface{}) {
|
||||||
l.Output(2, LevelInfo, format, v...)
|
l.Output(2, LevelInfo, format, v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// log with warn level
|
// log with warn level
|
||||||
func (l *SimpleLog) Warnf(format string, v ...interface{}) {
|
func (l *Log) Warnf(format string, v ...interface{}) {
|
||||||
l.Output(2, LevelWarn, format, v...)
|
l.Output(2, LevelWarn, format, v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// log with error level
|
// log with error level
|
||||||
func (l *SimpleLog) Errorf(format string, v ...interface{}) {
|
func (l *Log) Errorf(format string, v ...interface{}) {
|
||||||
l.Output(2, LevelError, format, v...)
|
l.Output(2, LevelError, format, v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// log with fatal level
|
// log with fatal level
|
||||||
func (l *SimpleLog) Fatalf(format string, v ...interface{}) {
|
func (l *Log) Fatalf(format string, v ...interface{}) {
|
||||||
l.Output(2, LevelFatal, format, v...)
|
l.Output(2, LevelFatal, format, v...)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user