143 lines
3.6 KiB
Go
143 lines
3.6 KiB
Go
package log
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/jmoiron/sqlx"
|
|
)
|
|
|
|
type (
|
|
Logger struct {
|
|
DB *sqlx.DB
|
|
}
|
|
|
|
Log struct {
|
|
ID string `json:"id" db:"id"`
|
|
Level LogLevel `json:"level" db:"level"`
|
|
Type string `json:"type" db:"type"`
|
|
Content string `json:"content" db:"content"`
|
|
CreatedAt time.Time `json:"created_at" db:"created_at"`
|
|
}
|
|
)
|
|
|
|
const (
|
|
TYPE_ACCOUNT string = "account"
|
|
TYPE_MUSIC string = "music"
|
|
TYPE_ARTIST string = "artist"
|
|
TYPE_BLOG string = "blog"
|
|
TYPE_ARTWORK string = "artwork"
|
|
TYPE_FILES string = "files"
|
|
TYPE_MISC string = "misc"
|
|
)
|
|
|
|
type LogLevel int
|
|
const (
|
|
LEVEL_INFO LogLevel = 0
|
|
LEVEL_WARN LogLevel = 1
|
|
)
|
|
|
|
const DEFAULT_LOG_PAGE_LENGTH = 25
|
|
|
|
func (self *Logger) Info(logType string, format string, args ...any) {
|
|
logString := fmt.Sprintf(format, args...)
|
|
fmt.Printf("[%s] [%s] INFO: %s\n", time.Now().Format(time.UnixDate), logType, logString)
|
|
err := createLog(self.DB, LEVEL_INFO, logType, logString)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "WARN: Failed to push log to database: %v\n", err)
|
|
}
|
|
}
|
|
|
|
func (self *Logger) Warn(logType string, format string, args ...any) {
|
|
logString := fmt.Sprintf(format, args...)
|
|
fmt.Fprintf(os.Stderr, "[%s] [%s] WARN: %s\n", time.Now().Format(time.UnixDate), logType, logString)
|
|
err := createLog(self.DB, LEVEL_WARN, logType, logString)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "WARN: Failed to push log to database: %v\n", err)
|
|
}
|
|
}
|
|
|
|
func (self *Logger) Fetch(id string) (*Log, error) {
|
|
log := Log{}
|
|
err := self.DB.Get(&log, "SELECT * FROM auditlog WHERE id=$1", id)
|
|
return &log, err
|
|
}
|
|
|
|
func (self *Logger) Search(levelFilters []LogLevel, typeFilters []string, content string, limit int, offset int) ([]*Log, error) {
|
|
logs := []*Log{}
|
|
|
|
params := []any{ limit, offset }
|
|
conditions := ""
|
|
|
|
if len(content) > 0 {
|
|
content = "%" + content + "%"
|
|
conditions += " WHERE content LIKE $3"
|
|
params = append(params, content)
|
|
}
|
|
|
|
if len(levelFilters) > 0 {
|
|
if len(conditions) > 0 {
|
|
conditions += " AND level IN ("
|
|
} else {
|
|
conditions += " WHERE level IN ("
|
|
}
|
|
for i := range levelFilters {
|
|
conditions += fmt.Sprintf("$%d", len(params) + 1)
|
|
if i < len(levelFilters) - 1 {
|
|
conditions += ","
|
|
}
|
|
params = append(params, levelFilters[i])
|
|
}
|
|
conditions += ")"
|
|
}
|
|
|
|
if len(typeFilters) > 0 {
|
|
if len(conditions) > 0 {
|
|
conditions += " AND type IN ("
|
|
} else {
|
|
conditions += " WHERE type IN ("
|
|
}
|
|
for i := range typeFilters {
|
|
conditions += fmt.Sprintf("$%d", len(params) + 1)
|
|
if i < len(typeFilters) - 1 {
|
|
conditions += ","
|
|
}
|
|
params = append(params, typeFilters[i])
|
|
}
|
|
conditions += ")"
|
|
}
|
|
|
|
query := fmt.Sprintf(
|
|
"SELECT * FROM auditlog%s ORDER BY created_at DESC LIMIT $1 OFFSET $2",
|
|
conditions,
|
|
)
|
|
|
|
/*
|
|
fmt.Printf("%s (", query)
|
|
for i, param := range params {
|
|
fmt.Print(param)
|
|
if i < len(params) - 1 {
|
|
fmt.Print(", ")
|
|
}
|
|
}
|
|
fmt.Print(")\n")
|
|
*/
|
|
|
|
err := self.DB.Select(&logs, query, params...)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return logs, nil
|
|
}
|
|
|
|
func createLog(db *sqlx.DB, logLevel LogLevel, logType string, content string) error {
|
|
_, err := db.Exec(
|
|
"INSERT INTO auditlog (level, type, content) VALUES ($1,$2,$3)",
|
|
logLevel,
|
|
logType,
|
|
content,
|
|
)
|
|
return err
|
|
}
|