feat: DH-HIS Web Giao Ban Go v1.0.1 (Favicon, Exe icon, System Tray, Gitea auto-update)

This commit is contained in:
ongtrieuhau
2026-10-26 00:10:07 -07:00
commit 228d4d14df
32 changed files with 5914 additions and 0 deletions
+121
View File
@@ -0,0 +1,121 @@
package logger
import (
"fmt"
"io"
"os"
"path/filepath"
"sync"
"time"
)
type LogEntry struct {
Timestamp string `json:"timestamp"`
Level string `json:"level"`
Message string `json:"message"`
}
type RingLogger struct {
mu sync.RWMutex
entries []LogEntry
maxSize int
file *os.File
multiOut io.Writer
}
var globalLogger *RingLogger
var once sync.Once
func Init(logFilePath string, maxSize int) *RingLogger {
once.Do(func() {
if maxSize <= 0 {
maxSize = 500
}
dir := filepath.Dir(logFilePath)
if dir != "" && dir != "." {
_ = os.MkdirAll(dir, 0755)
}
f, err := os.OpenFile(logFilePath, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
var out io.Writer = os.Stdout
if err == nil {
out = io.MultiWriter(os.Stdout, f)
}
globalLogger = &RingLogger{
entries: make([]LogEntry, 0, maxSize),
maxSize: maxSize,
file: f,
multiOut: out,
}
})
return globalLogger
}
func Get() *RingLogger {
if globalLogger == nil {
return Init("logs/app.log", 500)
}
return globalLogger
}
func (l *RingLogger) Log(level, message string) {
ts := time.Now().Format("2006-01-02 15:04:05")
entry := LogEntry{
Timestamp: ts,
Level: level,
Message: message,
}
l.mu.Lock()
if len(l.entries) >= l.maxSize {
l.entries = l.entries[1:]
}
l.entries = append(l.entries, entry)
l.mu.Unlock()
line := fmt.Sprintf("[%s] [%s] %s\n", ts, level, message)
if l.multiOut != nil {
_, _ = l.multiOut.Write([]byte(line))
}
}
func (l *RingLogger) GetEntries(limit int, levelFilter string) []LogEntry {
l.mu.RLock()
defer l.mu.RUnlock()
result := make([]LogEntry, 0, len(l.entries))
for i := len(l.entries) - 1; i >= 0; i-- {
e := l.entries[i]
if levelFilter != "" && levelFilter != "ALL" && e.Level != levelFilter {
continue
}
result = append(result, e)
if limit > 0 && len(result) >= limit {
break
}
}
return result
}
func (l *RingLogger) Clear() {
l.mu.Lock()
defer l.mu.Unlock()
l.entries = make([]LogEntry, 0, l.maxSize)
}
func Info(format string, a ...interface{}) {
Get().Log("INFO", fmt.Sprintf(format, a...))
}
func Warn(format string, a ...interface{}) {
Get().Log("WARN", fmt.Sprintf(format, a...))
}
func Error(format string, a ...interface{}) {
Get().Log("ERROR", fmt.Sprintf(format, a...))
}
func SQL(format string, a ...interface{}) {
Get().Log("SQL", fmt.Sprintf(format, a...))
}