-
Notifications
You must be signed in to change notification settings - Fork 0
/
logging.go
173 lines (163 loc) · 3.97 KB
/
logging.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
package database
import (
"database/sql"
"fmt"
"time"
)
type LogEvent struct {
Id uint
Name string
Description string
Level LogLevel
Time time.Time
}
type LogLevel uint
const (
LogLevelTrace LogLevel = iota
LogLevelDebug
LogLevelInfo
LogLevelWarn
LogLevelError
LogLevelFatal
)
// Creates (unless it exists) the table containing internal logging events
// For example a user logging in or altering a power states
func createLoggingEventTable() error {
if _, err := db.Exec(`
CREATE TABLE
IF NOT EXISTS
logs(
Id INT AUTO_INCREMENT,
Name VARCHAR(100),
Description TEXT,
Level INT,
Date DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (Id)
)`); err != nil {
log.Error("Could not create logging table: Executing query failed: ", err.Error())
return err
}
return nil
}
// Add a logged internal event based on `name`, `description`, and `level`
func AddLogEvent(name string, description string, level LogLevel) error {
query, err := db.Prepare(`
INSERT INTO
logs(
Id,
Name,
Description,
Level,
Date
)
VALUES (DEFAULT, ?, ?, ?, DEFAULT)`)
if err != nil {
log.Error("Failed to add log event: preparing query failed: ", err.Error())
return err
}
defer query.Close()
if _, err = query.Exec(name, description, level); err != nil {
log.Error("Failed to add log event: preparing query failed: ", err.Error())
return err
}
return nil
}
// Deletes log events older than 30 days in order to free storage space
// This function will later be used by a scheduler for daily jobs
func FlushOldLogs() (uint, error) {
res, err := db.Exec(`
DELETE FROM logs
WHERE
Date < NOW() - INTERVAL 30 DAY
`)
if err != nil {
log.Error("Failed to flush old log events: failed to execute query: ", err.Error())
return 0, err
}
deletedMessages, err := res.RowsAffected()
if err != nil {
log.Error("Could not evaluate outcome of `FlushOldLogs`: ", err.Error())
return 0, err
}
return uint(deletedMessages), nil
}
// Deletes all logs which are currently stored in the database
func FlushAllLogs() (uint, error) {
res, err := db.Exec(`
DELETE FROM logs
`)
if err != nil {
log.Error("Failed to flush all log events: failed to execute query: ", err.Error())
return 0, err
}
deletedMessages, err := res.RowsAffected()
if err != nil {
log.Error("Could not evaluate outcome of `FlushAllLogs`: ", err.Error())
return 0, err
}
return uint(deletedMessages), nil
}
// Deletes a log record matching the provided id
// Also returns a boolean indicating whether an entry has been deleted or not
func DeleteLogById(id uint) (bool, error) {
query, err := db.Prepare(`
DELETE FROM logs
WHERE Id=?
`)
if err != nil {
log.Error("Failed to delete log record: failed to prepare query: ", err.Error())
return false, err
}
defer query.Close()
res, err := query.Exec(id)
if err != nil {
log.Error("Failed to delete log record: failed to prepare query: ", err.Error())
return false, err
}
rowAffected, err := res.RowsAffected()
if err != nil {
log.Error("Failed to delete log record: failed to get affected rows: ", err.Error())
return false, err
}
return rowAffected > 0, nil
}
// Returns all logs currently in the database
func GetLogs() ([]LogEvent, error) {
res, err := db.Query(`
SELECT
Id,
Name,
Description,
Level,
Date
FROM logs`)
if err != nil {
log.Error("Could not get all logs: failed to execute query: ", err.Error())
return nil, err
}
defer res.Close()
logs := make([]LogEvent, 0)
for res.Next() {
var logItem LogEvent
var logTime sql.NullTime
err := res.Scan(
&logItem.Id,
&logItem.Name,
&logItem.Description,
&logItem.Level,
&logTime,
)
if err != nil {
log.Error("Could not list all logs: Failed to scan results ", err.Error())
return nil, err
}
if !logTime.Valid {
log.Error("Invalid time column when scanning logs")
return nil, fmt.Errorf("invalid time column when scanning logs")
} else {
logItem.Time = logTime.Time
logs = append(logs, logItem)
}
}
return logs, err
}