home to your local SPACEGIRL 💫 arimelody.space
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

log search implementation

+71 -15
+55 -12
log/log.go
··· 15 15 16 16 Log struct { 17 17 ID string `json:"id" db:"id"` 18 + Level LogLevel `json:"level" db:"level"` 18 19 Type string `json:"type" db:"type"` 19 20 Content string `json:"content" db:"content"` 20 21 CreatedAt time.Time `json:"created_at" db:"created_at"` ··· 34 35 LEVEL_INFO LogLevel = 0 35 36 LEVEL_WARN LogLevel = 1 36 37 ) 38 + 39 + const DEFAULT_LOG_PAGE_LENGTH = 25 37 40 38 41 func (self *Logger) Info(logType string, format string, args ...any) { 39 42 logString := fmt.Sprintf(format, args...) ··· 58 61 // we won't need to push fatal logs to DB, as these usually precede a panic or crash 59 62 } 60 63 61 - func (self *Logger) Fetch(id string) *Log { 62 - // TODO: log fetch 63 - return nil 64 + func (self *Logger) Fetch(id string) (*Log, error) { 65 + log := Log{} 66 + err := self.DB.Get(&log, "SELECT * FROM auditlog WHERE id=$1", id) 67 + return &log, err 64 68 } 65 69 66 - func (self *Logger) Search(typeFilters []string, content string, offset int, limit int) []Log { 67 - // TODO: log search 68 - return []Log{} 69 - } 70 + func (self *Logger) Search(levelFilters []LogLevel, typeFilters []string, content string, offset int, limit int) ([]*Log, error) { 71 + logs := []*Log{} 72 + 73 + params := []any{ limit, offset } 74 + conditions := "" 75 + 76 + if len(content) > 0 { 77 + content = "%" + content + "%" 78 + conditions += " WHERE content LIKE $3" 79 + params = append(params, content) 80 + } 81 + 82 + if len(levelFilters) > 0 { 83 + conditions += " AND level IN (" 84 + for i := range levelFilters { 85 + conditions += fmt.Sprintf("$%d", len(params) + 1) 86 + if i < len(levelFilters) - 1 { 87 + conditions += "," 88 + } 89 + params = append(params, levelFilters[i]) 90 + } 91 + conditions += ")" 92 + } 93 + 94 + if len(typeFilters) > 0 { 95 + conditions += " AND type IN (" 96 + for i := range typeFilters { 97 + conditions += fmt.Sprintf("$%d", len(params) + 1) 98 + if i < len(typeFilters) - 1 { 99 + conditions += "," 100 + } 101 + params = append(params, typeFilters[i]) 102 + } 103 + conditions += ")" 104 + } 105 + 106 + query := fmt.Sprintf( 107 + "SELECT * FROM auditlog%s ORDER BY created_at DESC LIMIT $1 OFFSET $2", 108 + conditions, 109 + ) 110 + 111 + // TODO: remove after testing 112 + fmt.Println(query) 70 113 71 - func (self *Logger) Delete(id string) error { 72 - // TODO: log deletion 73 - // consider: logging the deletion of logs? 74 - // or just not deleting logs at all 75 - return nil 114 + err := self.DB.Select(&logs, query, params...) 115 + if err != nil { 116 + return nil, err 117 + } 118 + return logs, nil 76 119 } 77 120 78 121 func createLog(db *sqlx.DB, logLevel LogLevel, logType string, content string) error {
+16 -3
main.go
··· 3 3 import ( 4 4 "errors" 5 5 "fmt" 6 - "log" 6 + stdLog "log" 7 7 "math" 8 8 "math/rand" 9 9 "net/http" ··· 20 20 "arimelody-web/model" 21 21 "arimelody-web/templates" 22 22 "arimelody-web/view" 23 + "arimelody-web/log" 23 24 24 25 "github.com/jmoiron/sqlx" 25 26 _ "github.com/lib/pq" ··· 341 342 342 343 fmt.Printf("Account \"%s\" deleted successfully.\n", account.Username) 343 344 return 344 - 345 + 346 + case "testLogSearch": 347 + // TODO: rename to "logs"; add parameters 348 + logger := log.Logger { DB: app.DB } 349 + logs, err := logger.Search([]log.LogLevel{ log.LEVEL_INFO, log.LEVEL_WARN }, []string{ log.TYPE_ACCOUNT, log.TYPE_MUSIC }, "ari", 0, 100) 350 + if err != nil { 351 + fmt.Fprintf(os.Stderr, "FATAL: Failed to fetch logs: %v\n", err) 352 + os.Exit(1) 353 + } 354 + for _, log := range(logs) { 355 + fmt.Printf("[%s] [%s] [%d] [%s] %s\n", log.CreatedAt.Format(time.UnixDate), log.ID, log.Level, log.Type, log.Content) 356 + } 357 + return 345 358 } 346 359 347 360 // command help ··· 401 414 // start the web server! 402 415 mux := createServeMux(&app) 403 416 fmt.Printf("Now serving at http://%s:%d\n", app.Config.Host, app.Config.Port) 404 - log.Fatal( 417 + stdLog.Fatal( 405 418 http.ListenAndServe(fmt.Sprintf("%s:%d", app.Config.Host, app.Config.Port), 406 419 HTTPLog(DefaultHeaders(mux)), 407 420 ))