First merge from develop to main (WIP) #7
@@ -1,11 +1,10 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
@@ -30,9 +29,11 @@ func Init() {
|
||||
conf := &config{}
|
||||
if err := viper.ReadInConfig(); err != nil {
|
||||
// Dont generate config when using dev mode
|
||||
log.Fatalln("Can't read config!")
|
||||
slog.Error("[Config] Can't read config!", "err", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if err := viper.Unmarshal(conf); err != nil {
|
||||
log.Fatalln(err)
|
||||
slog.Error("[Condig] Can't unmarshal config!", "err", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
16
data/data.go
16
data/data.go
@@ -2,10 +2,12 @@ package data
|
||||
|
||||
import (
|
||||
"nixcn-cms/data/drivers"
|
||||
"os"
|
||||
|
||||
"log/slog"
|
||||
|
||||
"github.com/meilisearch/meilisearch-go"
|
||||
"github.com/redis/go-redis/v9"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
@@ -25,19 +27,22 @@ func Init() {
|
||||
}
|
||||
|
||||
if dbType != "postgres" {
|
||||
log.Fatal("[Database] Only support postgras db!")
|
||||
slog.Error("[Database] Only support postgras db!")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Conect to db
|
||||
db, err := drivers.Postgres(exDSN)
|
||||
if err != nil {
|
||||
log.Fatal("[Database] Error connecting to db!")
|
||||
slog.Error("[Database] Error connecting to db!")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Auto migrate
|
||||
err = db.AutoMigrate(&User{}, &Event{}, &Attendance{}, &Client{})
|
||||
if err != nil {
|
||||
log.Error("[Database] Error migrating database: ", err)
|
||||
slog.Error("[Database] Error migrating database!", "err", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
Database = db
|
||||
|
||||
@@ -52,7 +57,8 @@ func Init() {
|
||||
}
|
||||
rdb, err := drivers.Redis(rDSN)
|
||||
if err != nil {
|
||||
log.Fatal("[Redis] Error connecting to Redis: ", err)
|
||||
slog.Error("[Redis] Error connecting to Redis!", "err", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
Redis = rdb
|
||||
|
||||
|
||||
4
go.mod
4
go.mod
@@ -10,14 +10,13 @@ require (
|
||||
github.com/aliyun/credentials-go v1.4.5
|
||||
github.com/gin-gonic/gin v1.11.0
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0
|
||||
github.com/goccy/go-json v0.10.5
|
||||
github.com/golang-jwt/jwt/v5 v5.3.0
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/meilisearch/meilisearch-go v0.35.0
|
||||
github.com/redis/go-redis/v9 v9.17.2
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/spf13/viper v1.21.0
|
||||
golang.org/x/crypto v0.46.0
|
||||
golang.org/x/oauth2 v0.34.0
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
||||
gorm.io/datatypes v1.2.7
|
||||
gorm.io/driver/postgres v1.6.0
|
||||
@@ -44,7 +43,6 @@ require (
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.29.0 // indirect
|
||||
github.com/go-sql-driver/mysql v1.8.1 // indirect
|
||||
github.com/goccy/go-json v0.10.5 // indirect
|
||||
github.com/goccy/go-yaml v1.19.1 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
|
||||
5
go.sum
5
go.sum
@@ -193,8 +193,6 @@ github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjR
|
||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||
github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc=
|
||||
github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/assertions v1.1.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
@@ -292,8 +290,6 @@ golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
||||
golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
|
||||
golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
|
||||
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -315,7 +311,6 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/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-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func Init() {
|
||||
levelStr := os.Getenv("LOG_LEVEL")
|
||||
level, err := logrus.ParseLevel(levelStr)
|
||||
if err != nil {
|
||||
level = logrus.InfoLevel
|
||||
}
|
||||
logrus.SetLevel(level)
|
||||
|
||||
if level == logrus.DebugLevel {
|
||||
gin.SetMode(gin.DebugMode)
|
||||
} else {
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
gin.DisableConsoleColor()
|
||||
}
|
||||
|
||||
logrus.SetFormatter(&logrus.JSONFormatter{
|
||||
TimestampFormat: "2006-01-02 15:04:05",
|
||||
})
|
||||
|
||||
logrus.SetReportCaller(true)
|
||||
|
||||
file, err := os.OpenFile("app.log", os.O_APPEND|os.O_CREATE|os.O_RDWR, 0666)
|
||||
if err != nil {
|
||||
logrus.SetOutput(os.Stdout)
|
||||
logrus.Errorf("Error to create log file: %v", err)
|
||||
} else {
|
||||
logrus.SetOutput(io.MultiWriter(os.Stdout, file))
|
||||
}
|
||||
|
||||
logrus.RegisterExitHandler(func() {
|
||||
if file != nil {
|
||||
file.Sync()
|
||||
file.Close()
|
||||
}
|
||||
})
|
||||
}
|
||||
47
logger/slog.go
Normal file
47
logger/slog.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"io"
|
||||
"log/slog"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func Init() {
|
||||
levelStr := strings.ToLower(os.Getenv("LOG_LEVEL"))
|
||||
var level slog.Level
|
||||
switch levelStr {
|
||||
case "debug":
|
||||
level = slog.LevelDebug
|
||||
case "warn":
|
||||
level = slog.LevelWarn
|
||||
case "error":
|
||||
level = slog.LevelError
|
||||
default:
|
||||
level = slog.LevelInfo
|
||||
}
|
||||
|
||||
file, err := os.OpenFile("app.log", os.O_APPEND|os.O_CREATE|os.O_RDWR, 0666)
|
||||
var writer io.Writer = os.Stdout
|
||||
if err != nil {
|
||||
slog.Error("Error to create log file", "err", err)
|
||||
} else {
|
||||
writer = io.MultiWriter(os.Stdout, file)
|
||||
}
|
||||
|
||||
opts := &slog.HandlerOptions{
|
||||
Level: level,
|
||||
AddSource: true,
|
||||
ReplaceAttr: func(groups []string, a slog.Attr) slog.Attr {
|
||||
if a.Key == slog.TimeKey {
|
||||
return slog.String(a.Key, a.Value.Time().Format("2006-01-02 15:04:05"))
|
||||
}
|
||||
return a
|
||||
},
|
||||
}
|
||||
|
||||
handler := slog.NewJSONHandler(writer, opts)
|
||||
|
||||
logger := slog.New(handler)
|
||||
slog.SetDefault(logger)
|
||||
}
|
||||
@@ -3,11 +3,10 @@ package middleware
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"log/slog"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/sirupsen/logrus"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func GinLogger() gin.HandlerFunc {
|
||||
@@ -27,23 +26,24 @@ func GinLogger() gin.HandlerFunc {
|
||||
errorMessage = c.Errors.String()
|
||||
}
|
||||
|
||||
entry := log.WithFields(logrus.Fields{
|
||||
"status": c.Writer.Status(),
|
||||
"method": c.Request.Method,
|
||||
"uri": c.Request.RequestURI,
|
||||
"ip": c.ClientIP(),
|
||||
"latency": time.Since(startTime).String(),
|
||||
"user_agent": c.Request.UserAgent(),
|
||||
"request_body": string(body),
|
||||
"errors": errorMessage,
|
||||
})
|
||||
fields := []any{
|
||||
"status", c.Writer.Status(),
|
||||
"method", c.Request.Method,
|
||||
"uri", c.Request.RequestURI,
|
||||
"ip", c.ClientIP(),
|
||||
"latency", time.Since(startTime).String(),
|
||||
"user_agent", c.Request.UserAgent(),
|
||||
"request_body", string(body),
|
||||
"errors", errorMessage,
|
||||
}
|
||||
|
||||
if len(c.Errors) > 0 || c.Writer.Status() >= 500 {
|
||||
entry.Error("HTTP_ERROR")
|
||||
} else if c.Writer.Status() >= 400 {
|
||||
entry.Warn("HTTP_CLIENT_ERROR")
|
||||
status := c.Writer.Status()
|
||||
if len(c.Errors) > 0 || status >= 500 {
|
||||
slog.Error("HTTP_ERROR", fields...)
|
||||
} else if status >= 400 {
|
||||
slog.Warn("HTTP_CLIENT_ERROR", fields...)
|
||||
} else {
|
||||
entry.Info("HTTP_SUCCESS")
|
||||
slog.Info("HTTP_SUCCESS", fields...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"nixcn-cms/middleware"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func Start() {
|
||||
if !viper.GetBool("server.debug_mode") {
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
gin.DisableConsoleColor()
|
||||
}
|
||||
|
||||
r := gin.New()
|
||||
@@ -29,8 +30,8 @@ func Start() {
|
||||
MaxHeaderBytes: 1 << 20,
|
||||
}
|
||||
|
||||
log.Info("Starting server on " + viper.GetString("server.address"))
|
||||
slog.Info("[Server] Starting server on " + viper.GetString("server.address"))
|
||||
if err := server.ListenAndServe(); err != nil {
|
||||
log.Errorf("Error starting server: %v\n", err)
|
||||
slog.Error("[Server] Error starting server!", "err", err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user