log with prefix

This commit is contained in:
celogeek 2022-02-05 18:39:26 +01:00
parent 9a7f58b9f7
commit 45683cbc0d
Signed by: celogeek
GPG Key ID: E6B7BDCFC446233A
8 changed files with 79 additions and 14 deletions

View File

@ -20,7 +20,6 @@ var (
mysqlUser = getEnv("MYSQL_USER", "photos") mysqlUser = getEnv("MYSQL_USER", "photos")
mysqlPassword = getEnv("MYSQL_PASSWD", "photos") mysqlPassword = getEnv("MYSQL_PASSWD", "photos")
mysqlDatabase = getEnv("MYSQL_DB", "photos") mysqlDatabase = getEnv("MYSQL_DB", "photos")
logger = log.New(os.Stderr, "[Photos] ", log.LstdFlags)
getEnvConfig = false getEnvConfig = false
getCurrentEnvConfig = false getCurrentEnvConfig = false
) )
@ -86,8 +85,10 @@ func main() {
return return
} }
if err := api.New(logger, config).Run(); err != nil { p := api.New(config)
logger.Fatal(err)
if err := p.Run(); err != nil {
log.Fatal(err)
} }
} }

View File

@ -35,7 +35,7 @@ func (s *Service) DBConnect() {
}) })
if err != nil { if err != nil {
s.Logger.Fatal(err) s.LogErr.Fatal("DB", err)
} }
s.DB = db s.DB = db

View File

@ -11,5 +11,5 @@ func (s *Service) Dump(o interface{}) {
enc.SetIndent("", " ") enc.SetIndent("", " ")
enc.Encode(o) enc.Encode(o)
s.Logger.Printf("%s", b.Bytes()) s.LogOk.Printf("Dump", "%s", b.Bytes())
} }

View File

@ -0,0 +1,34 @@
package api
import (
"fmt"
"io"
"os"
"time"
)
var logTimeFmt = "2006/01/02 - 15:04:05"
type Logger struct {
out io.StringWriter
prefix string
}
func (l *Logger) Print(prefix string, a ...interface{}) {
t := time.Now().UTC()
l.out.WriteString(fmt.Sprintf("[%s] %s | [%s] | %s\n", l.prefix, t.Format(logTimeFmt), prefix, fmt.Sprint(a...)))
}
func (l *Logger) Printf(prefix string, format string, a ...interface{}) {
l.Print(prefix, fmt.Sprintf(format, a...))
}
func (l *Logger) Fatal(prefix string, a ...interface{}) {
l.Print(prefix, a...)
os.Exit(1)
}
func (l *Logger) Fatalf(prefix string, format string, a ...interface{}) {
l.Printf(prefix, format, a...)
os.Exit(1)
}

View File

@ -19,7 +19,8 @@ type Service struct {
Gin *gin.Engine Gin *gin.Engine
DB *gorm.DB DB *gorm.DB
Config *ServiceConfig Config *ServiceConfig
Logger *log.Logger LogOk *Logger
LogErr *Logger
GormLogger gormlogger.Interface GormLogger gormlogger.Interface
} }
@ -28,11 +29,12 @@ type ServiceConfig struct {
Mysql *gomysql.Config Mysql *gomysql.Config
} }
func New(logger *log.Logger, config *ServiceConfig) *Service { func New(config *ServiceConfig) *Service {
return &Service{ return &Service{
Gin: gin.New(), Gin: gin.New(),
Config: config, Config: config,
Logger: logger, LogOk: &Logger{os.Stdout, "Photos"},
LogErr: &Logger{os.Stderr, "Photos"},
GormLogger: gormlogger.New( GormLogger: gormlogger.New(
log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
gormlogger.Config{ gormlogger.Config{
@ -55,16 +57,23 @@ func (s *Service) SetupRoutes() {
ac.POST("/login", s.Login) ac.POST("/login", s.Login)
ac.GET("/logout", s.RequireAuthToken, s.Logout) ac.GET("/logout", s.RequireAuthToken, s.Logout)
s.Gin.GET("/me", s.RequireSession, func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"status": "success",
"user": s.CurrentSession(c).Account.Login,
})
})
s.Gin.NoRoute(func(c *gin.Context) { s.Gin.NoRoute(func(c *gin.Context) {
s.Error(c, http.StatusNotFound, ErrReqNotFound) s.Error(c, http.StatusNotFound, ErrReqNotFound)
}) })
} }
func (s *Service) Run() error { func (s *Service) Run() error {
rand.Seed(time.Now().UnixNano()) rand.Seed(time.Now().UnixNano())
s.SetupRoutes() s.SetupRoutes()
s.SetupDB() s.SetupDB()
go s.SessionCleaner()
srv := &http.Server{ srv := &http.Server{
Addr: s.Config.Listen, Addr: s.Config.Listen,
@ -84,7 +93,7 @@ func (s *Service) Run() error {
// a timeout of 5 seconds. // a timeout of 5 seconds.
signal.Notify(quit, os.Interrupt) signal.Notify(quit, os.Interrupt)
<-quit <-quit
s.Logger.Print("shutdown ...") s.LogOk.Print("Exit", "shutdown ...")
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel() defer cancel()
@ -96,11 +105,11 @@ func (s *Service) Run() error {
if err != nil { if err != nil {
return err return err
} }
s.Logger.Print("closing database ...") s.LogOk.Print("Exit", "closing database ...")
if err := db.Close(); err != nil { if err := db.Close(); err != nil {
return err return err
} }
s.Logger.Print("exiting") s.LogOk.Print("Exit", "exiting")
return runError return runError
} }

View File

@ -9,7 +9,7 @@ import (
func (s *Service) Recovery(c *gin.Context) { func (s *Service) Recovery(c *gin.Context) {
defer func() { defer func() {
if err := recover(); err != nil { if err := recover(); err != nil {
s.Logger.Print("[PANIC]", err) s.LogErr.Print("PANIC", err)
s.Error(c, http.StatusInternalServerError, ErrUnexpected) s.Error(c, http.StatusInternalServerError, ErrUnexpected)
} }
}() }()

View File

@ -4,6 +4,7 @@ import (
"errors" "errors"
"net/http" "net/http"
"strings" "strings"
"time"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"gitlab.celogeek.com/photos/api/internal/photos/models" "gitlab.celogeek.com/photos/api/internal/photos/models"
@ -40,6 +41,20 @@ func (s *Service) RequireSession(c *gin.Context) {
return return
} }
s.DB.Select("updated_at").Save(sess) s.DB.Select("updated_at").Save(sess)
s.Logger.Printf("User: %s", sess.Account.Login) s.LogOk.Printf("Session", "User: %s", sess.Account.Login)
c.Set("session", sess) c.Set("session", sess)
} }
func (s *Service) CurrentSession(c *gin.Context) *models.Session {
return c.MustGet("session").(*models.Session)
}
func (s *Service) SessionCleaner() {
for range time.Tick(time.Minute) {
t := time.Now().UTC().Add(-3 * time.Hour).Truncate(time.Minute)
s.LogOk.Printf("Session", "Cleaning old session < %s", t)
if err := s.DB.Where("updated_at < ?", t).Delete(&models.Session{}).Error; err != nil {
s.LogErr.Printf("Session", "Cleaning failed: %s", err)
}
}
}

View File

@ -0,0 +1,6 @@
package models
type Photo struct {
ID uint32 `gorm:"primary_key"`
File string
}