107 lines
2.1 KiB
Go
Raw Normal View History

package main
import (
"os"
)
// 作业2日志系统难度⭐⭐
// 题目: 实现支持多种输出方式的日志系统。
// 1. 定义Logger接口
type Logger interface {
Log(message string)
}
// 2. 实现ConsoleLogger控制台输出
type ConsoleLogger struct{}
func (c *ConsoleLogger) Log(message string) {
println("控制台日志:", message)
}
// 3. 实现FileLogger文件输出
type FileLogger struct {
filename string
logFile *os.File
size int64
}
func (f *FileLogger) Log(message string) {
// 模拟文件写入
println("文件日志:", message, "写入到文件:", f.filename)
// 如果没有指定文件名,使用默认文件名
if f.filename == "" {
f.filename = "app.log"
}
// O_APPEND
if f.logFile == nil {
logFile, err := os.OpenFile(f.filename, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
if err != nil {
panic(err)
}
// 获取当前日志文件的大小
fileInfo, err := f.logFile.Stat()
if err != nil {
panic(err)
}
// 初始文件大小
f.size = fileInfo.Size()
f.logFile = logFile
}
// 如果文件大小超过10M则创建新的文件
if f.size >= 10*1024*1024 {
f.logFile.Close()
f.filename = f.filename + ".1"
logFile, err := os.OpenFile(f.filename, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
if err != nil {
panic(err)
}
f.logFile = logFile
f.size = 0
}
n, err := f.logFile.WriteString(message + "\n")
if err != nil {
panic(err)
}
f.size += int64(n)
}
// 4. 实现MultiLogger同时输出到多个地方
type MultiLogger struct {
loggers []Logger
}
// 5. 实现MultiLogger
func (m *MultiLogger) Log(message string) {
for _, logger := range m.loggers {
logger.Log(message)
}
}
func (m *MultiLogger) Close() {
for _, logger := range m.loggers {
if fileLogger, ok := logger.(*FileLogger); ok {
if fileLogger.logFile != nil {
fileLogger.logFile.Close()
}
}
}
}
func main() {
logger := &MultiLogger{
loggers: []Logger{
&ConsoleLogger{},
&FileLogger{filename: "app.log"},
},
}
defer logger.Close()
logger.Log("应用启动")
logger.Log("用户登录")
}