Compare commits
No commits in common. "master" and "v1.0.6" have entirely different histories.
76
README.md
76
README.md
|
@ -1,77 +1,3 @@
|
||||||
# gologger
|
# gologger
|
||||||
|
|
||||||
GoLogger 是一个简单但功能强大的 Go 语言日志库,提供灵活的日志记录功能。它支持多种日志输出方式(控制台、文件等),并允许自定义日志格式。
|
a logger used in go
|
||||||
|
|
||||||
## 特性
|
|
||||||
- 支持多种日志级别:ERROR, WARN, INFO, DEBUG, TRACE
|
|
||||||
- 支持多种输出方式:控制台、文件(支持滚动策略)
|
|
||||||
- 可定制日志格式
|
|
||||||
- 支持按类别记录日志
|
|
||||||
|
|
||||||
## 安装
|
|
||||||
```bash
|
|
||||||
go get github.com/yourusername/gologger
|
|
||||||
```
|
|
||||||
|
|
||||||
## 快速开始
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/yourusername/gologger"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// 获取默认logger
|
|
||||||
logger := gologger.GetLogger("main")
|
|
||||||
|
|
||||||
// 设置全局日志级别
|
|
||||||
gologger.Configure(gologger.LoggersConfig{
|
|
||||||
Level: "info",
|
|
||||||
Appenders: []gologger.LogAppenderConfig{
|
|
||||||
{
|
|
||||||
Type: "console",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: "file",
|
|
||||||
Options: map[string]interface{}{
|
|
||||||
"filePath": "app.log",
|
|
||||||
"EnableRolling": true,
|
|
||||||
"MaxSize": 1024 * 1024 * 10, // 10MB
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
// 记录日志
|
|
||||||
logger.Info("Application started")
|
|
||||||
logger.Error("An error occurred")
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 配置说明
|
|
||||||
|
|
||||||
### 日志级别
|
|
||||||
支持的级别包括:off, error, warn, info, debug, trace
|
|
||||||
|
|
||||||
### 输出方式(Appenders)
|
|
||||||
|
|
||||||
1. **ConsoleAppender** - 控制台输出
|
|
||||||
配置示例:
|
|
||||||
```go
|
|
||||||
{
|
|
||||||
Type: "console",
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **FileAppender** - 文件输出,支持滚动策略
|
|
||||||
配置参数:
|
|
||||||
- filePath: 日志文件路径
|
|
||||||
- EnableRolling: 是否启用滚动(默认true)
|
|
||||||
- MaxSize: 单个文件最大大小(字节,默认10MB)
|
|
||||||
- MaxAge: 文件最大保存时间(秒,默认86400秒=24小时)
|
|
||||||
|
|
||||||
### 格式化器
|
|
||||||
可以通过SelectFormatter选择不同的日志格式:
|
|
||||||
- simple: 简单格式 `[timestamp] level : category - message`
|
|
||||||
- json: JSON 格式输出
|
|
16
console.go
16
console.go
|
@ -4,18 +4,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ConsoleAppender implements the LoggerAppender interface for console output.
|
|
||||||
// It uses color-coded templates for different log levels.
|
|
||||||
// Example:
|
|
||||||
// appender := &ConsoleAppender{
|
|
||||||
// formatter: NewSimpleFormatter(),
|
|
||||||
// }
|
|
||||||
// appender.Append(event)
|
|
||||||
// appender.Close()
|
|
||||||
type ConsoleAppender struct {
|
|
||||||
formatter LogFormatter
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ErrorTemplate = "\033[1;31m%s\033[0m"
|
ErrorTemplate = "\033[1;31m%s\033[0m"
|
||||||
WarnTemplate = "\033[1;33m%s\033[0m"
|
WarnTemplate = "\033[1;33m%s\033[0m"
|
||||||
|
@ -24,6 +12,10 @@ const (
|
||||||
TraceTemplate = "\033[1;35m%s\033[0m"
|
TraceTemplate = "\033[1;35m%s\033[0m"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type ConsoleAppender struct {
|
||||||
|
formatter LogFormatter
|
||||||
|
}
|
||||||
|
|
||||||
// Close implements LoggerAppender.
|
// Close implements LoggerAppender.
|
||||||
func (c *ConsoleAppender) Close() {
|
func (c *ConsoleAppender) Close() {
|
||||||
|
|
||||||
|
|
11
file.go
11
file.go
|
@ -8,17 +8,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// FileAppender implements the LoggerAppender interface for file output.
|
|
||||||
// It supports log rotation based on file size and age.
|
|
||||||
// Example:
|
|
||||||
// appender := &FileAppender{
|
|
||||||
// formatter: NewSimpleFormatter(),
|
|
||||||
// filePath: "app.log",
|
|
||||||
// EnableRolling: true,
|
|
||||||
// MaxSize: 1024 * 1024 * 10, // 10MB
|
|
||||||
// }
|
|
||||||
// appender.Append(event)
|
|
||||||
// appender.Close()
|
|
||||||
type FileAppender struct {
|
type FileAppender struct {
|
||||||
formatter LogFormatter
|
formatter LogFormatter
|
||||||
filePath string
|
filePath string
|
||||||
|
|
15
format.go
15
format.go
|
@ -1,5 +1,3 @@
|
||||||
// Package gologger provides a simple logging implementation with multiple appenders and formatters.
|
|
||||||
// It supports console, file, and HTTP logging with customizable formats.
|
|
||||||
package gologger
|
package gologger
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -8,19 +6,10 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// LogFormatter is a function type that formats a LogEvent into a string.
|
|
||||||
// Example:
|
|
||||||
//
|
|
||||||
// formatter := func(event LogEvent) string {
|
|
||||||
// return fmt.Sprintf("[%s] %s: %v", event.Ts.Format("2006-01-02"), event.Level, event.Data)
|
|
||||||
// }
|
|
||||||
type LogFormatter = func(LogEvent) string
|
|
||||||
|
|
||||||
const logTemplate = "[%s] %s : %s - %s\n"
|
const logTemplate = "[%s] %s : %s - %s\n"
|
||||||
|
|
||||||
// format is the default formatter that converts a LogEvent to a string using the default template.
|
type LogFormatter = func(LogEvent) string
|
||||||
// It handles both simple values and formatted strings.
|
|
||||||
// Template: "[timestamp] level : category - data"
|
|
||||||
func format(logEvent LogEvent) string {
|
func format(logEvent LogEvent) string {
|
||||||
data := logEvent.Ts.Format("2006-01-02 15:04:05")
|
data := logEvent.Ts.Format("2006-01-02 15:04:05")
|
||||||
msg := ""
|
msg := ""
|
||||||
|
|
75
main.go
75
main.go
|
@ -1,5 +1,3 @@
|
||||||
// Package gologger provides a simple logging implementation with multiple appenders and formatters.
|
|
||||||
// It supports console, file, and HTTP logging with customizable formats.
|
|
||||||
package gologger
|
package gologger
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -27,21 +25,7 @@ var logLevelMap map[string]int = map[string]int{
|
||||||
var loggerMap map[string]*Logger = map[string]*Logger{}
|
var loggerMap map[string]*Logger = map[string]*Logger{}
|
||||||
var appenderFactoryMap map[string]func(LogAppenderConfig) *LoggerAppender = map[string]func(LogAppenderConfig) *LoggerAppender{}
|
var appenderFactoryMap map[string]func(LogAppenderConfig) *LoggerAppender = map[string]func(LogAppenderConfig) *LoggerAppender{}
|
||||||
var appenders map[string]*LoggerAppender = map[string]*LoggerAppender{}
|
var appenders map[string]*LoggerAppender = map[string]*LoggerAppender{}
|
||||||
var loggerConfig LoggersConfig = LoggersConfig{
|
var loggerConfig LoggersConfig
|
||||||
Appenders: map[string]LogAppenderConfig{
|
|
||||||
"console": {
|
|
||||||
Type: "console",
|
|
||||||
Formatter: "text",
|
|
||||||
Options: map[string]interface{}{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Categories: map[string]LogConfig{
|
|
||||||
"default": {
|
|
||||||
Level: "error",
|
|
||||||
Appenders: []string{"console"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
type LogAppenderConfig struct {
|
type LogAppenderConfig struct {
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
|
@ -57,14 +41,6 @@ type LoggersConfig struct {
|
||||||
Appenders map[string]LogAppenderConfig `json:"appenders"`
|
Appenders map[string]LogAppenderConfig `json:"appenders"`
|
||||||
Categories map[string]LogConfig `json:"categories"`
|
Categories map[string]LogConfig `json:"categories"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logger represents a logger instance for a specific category.
|
|
||||||
// It maintains the log level and appenders for that category.
|
|
||||||
// Example:
|
|
||||||
//
|
|
||||||
// logger := GetLogger("mycategory")
|
|
||||||
// logger.Info("This is an info message")
|
|
||||||
// logger.Error("This is an error message")
|
|
||||||
type Logger struct {
|
type Logger struct {
|
||||||
category string
|
category string
|
||||||
level int
|
level int
|
||||||
|
@ -131,11 +107,13 @@ func GetLogger(name string) *Logger {
|
||||||
if ok {
|
if ok {
|
||||||
return makeLogger(name, logConfig)
|
return makeLogger(name, logConfig)
|
||||||
}
|
}
|
||||||
logConfig, ok = loggerConfig.Categories["default"]
|
if name == "default" {
|
||||||
l := makeLogger(name, logConfig)
|
return defaultLogger
|
||||||
|
}
|
||||||
|
l := *GetLogger("default")
|
||||||
l.category = name
|
l.category = name
|
||||||
loggerMap[name] = l
|
loggerMap[name] = &l
|
||||||
return l
|
return &l
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,15 +133,9 @@ func makeLogger(name string, config LogConfig) *Logger {
|
||||||
loggerMap[name] = logger
|
loggerMap[name] = logger
|
||||||
return logger
|
return logger
|
||||||
}
|
}
|
||||||
|
func Configure(config LoggersConfig) {
|
||||||
func ReconfigLoggers(config LoggersConfig) {
|
|
||||||
validateConfig(config)
|
|
||||||
loggerConfig = config
|
loggerConfig = config
|
||||||
for name, appenderConfig := range loggerConfig.Appenders {
|
for name, appenderConfig := range loggerConfig.Appenders {
|
||||||
oldappender, ok := appenders[name]
|
|
||||||
if ok {
|
|
||||||
(*oldappender).Close()
|
|
||||||
}
|
|
||||||
appenderFactory, ok := appenderFactoryMap[appenderConfig.Type]
|
appenderFactory, ok := appenderFactoryMap[appenderConfig.Type]
|
||||||
if ok {
|
if ok {
|
||||||
appenders[name] = appenderFactory(appenderConfig)
|
appenders[name] = appenderFactory(appenderConfig)
|
||||||
|
@ -171,39 +143,12 @@ func ReconfigLoggers(config LoggersConfig) {
|
||||||
appenders[name] = &consoleAppender
|
appenders[name] = &consoleAppender
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for name, logger := range loggerMap {
|
for name, _ := range loggerConfig.Categories {
|
||||||
logConfig, ok := loggerConfig.Categories[name]
|
GetLogger(name)
|
||||||
if !ok {
|
|
||||||
logConfig, _ = loggerConfig.Categories["default"]
|
|
||||||
}
|
|
||||||
logger.level = logLevelMap[strings.ToLower(logConfig.Level)]
|
|
||||||
if len(logConfig.Appenders) == 0 {
|
|
||||||
logger.appenders = []*LoggerAppender{&consoleAppender}
|
|
||||||
} else {
|
|
||||||
logger.appenders = make([]*LoggerAppender, len(logConfig.Appenders))
|
|
||||||
for i, appenderName := range logConfig.Appenders {
|
|
||||||
logger.appenders[i] = appenders[appenderName]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func validateConfig(config LoggersConfig) {
|
|
||||||
_, ok := loggerConfig.Categories["default"]
|
|
||||||
if !ok {
|
|
||||||
panic("default logger config not found")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func Configure(config LoggersConfig) {
|
|
||||||
validateConfig(config)
|
|
||||||
ReconfigLoggers(config)
|
|
||||||
}
|
|
||||||
|
|
||||||
func RegistAppender(typeName string, appenderCreatCb func(LogAppenderConfig) *LoggerAppender) {
|
func RegistAppender(typeName string, appenderCreatCb func(LogAppenderConfig) *LoggerAppender) {
|
||||||
|
|
||||||
appenderFactoryMap[typeName] = appenderCreatCb
|
appenderFactoryMap[typeName] = appenderCreatCb
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
|
||||||
loggerMap["default"] = defaultLogger
|
|
||||||
appenders["console"] = &consoleAppender
|
|
||||||
}
|
|
||||||
|
|
16
main_test.go
16
main_test.go
|
@ -5,12 +5,6 @@ import "testing"
|
||||||
|
|
||||||
func TestGetLogger(t *testing.T) {
|
func TestGetLogger(t *testing.T) {
|
||||||
// Initialize loggerMap and loggerConfig
|
// Initialize loggerMap and loggerConfig
|
||||||
|
|
||||||
dl := GetLogger("default")
|
|
||||||
if dl != defaultLogger {
|
|
||||||
t.Errorf("GetLogger(\"defult\") should return defaultLogger")
|
|
||||||
}
|
|
||||||
dl.Error("test")
|
|
||||||
Configure(LoggersConfig{
|
Configure(LoggersConfig{
|
||||||
Appenders: map[string]LogAppenderConfig{
|
Appenders: map[string]LogAppenderConfig{
|
||||||
"console": {
|
"console": {
|
||||||
|
@ -30,10 +24,12 @@ func TestGetLogger(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
dl.Info("test")
|
dl := GetLogger("default")
|
||||||
if dl.level != Info {
|
// if dl != defaultLogger {
|
||||||
t.Errorf("GetLogger(\"default\") should return defaultLogger")
|
// t.Errorf("GetLogger(\"defult\") should return defaultLogger")
|
||||||
}
|
// }
|
||||||
|
dl.Error("test")
|
||||||
|
|
||||||
al := GetLogger("app")
|
al := GetLogger("app")
|
||||||
|
|
||||||
if al == dl {
|
if al == dl {
|
||||||
|
|
Loading…
Reference in New Issue