diff --git a/main.go b/main.go
index 9534568..6e126df 100644
--- a/main.go
+++ b/main.go
@@ -12,6 +12,7 @@ import (
"html/template"
"log"
"net/http"
+ "strconv"
"sync"
"syscall"
@@ -126,6 +127,17 @@ func listAgents(w http.ResponseWriter, r *http.Request) {
}
}
+ if strings.Contains(r.Header.Get("Accept"), "application") {
+ w.Header().Set("Content-Type", "application/json")
+ jsonData, err := json.Marshal(agents)
+ if err != nil {
+ http.Error(w, "Failed to encode agents to JSON", http.StatusInternalServerError)
+ return
+ }
+ w.Write(jsonData)
+ return
+ }
+
if err != nil {
http.Error(w, "Failed to fetch agents", http.StatusInternalServerError)
return
@@ -162,12 +174,31 @@ func getAgentIds(w http.ResponseWriter, r *http.Request) {
}
func logsHandler(w http.ResponseWriter, r *http.Request) {
- var logs[] logger.LogEntry
- logs, err := logger.FetchLogs(10)
+ // Warning this bit me in the nose: var count is []string, but
+ // variable = count[0] is casted to int automatically
+ // when the string is a number. Jesus Christ, this is odd behavior!
+ levels := r.URL.Query()["level"]
+ countStr := r.URL.Query()["limit"]
+ var limit int = 10
+ if len(countStr) > 0 {
+ parsedCount, err := strconv.Atoi(countStr[0])
+ if err == nil {
+ limit = parsedCount
+ } else {
+ http.Error(w, "Invalid count value", http.StatusBadRequest)
+ return
+ }
+ }
- // for i, logLine := range logs {
- // logs[i].Message = strings.ReplaceAll(logLine.Message, `"`, `\"`)
- // }
+ // This enables not only `level` GET parameters but also selecting by paths
+ // For example /logs/error is now identical to /logs?level=error
+ parts := strings.Split(strings.TrimPrefix(r.URL.Path, "/logs/"), "/")
+ if (len(levels) == 0) && len(parts) > 0 && parts[0] != "" {
+ levels = []string{parts[0]}
+ }
+
+ // Call the police... I mean logger
+ logs, err := logger.FetchLogs(limit, levels)
if err != nil {
http.Error(w, "Error fetching logs", http.StatusInternalServerError)
@@ -176,16 +207,6 @@ func logsHandler(w http.ResponseWriter, r *http.Request) {
renderTemplate(w, "templates/partials/logs_partial.html", logs)
-
-// fmt.Fprintf(w, "
")
-// // for _, logEntry := range logsToSend {
-// for _, logEntry := range logs {
-// fmt.Fprintf(w, "
[%s] [%s] %s
", logEntry.Timestamp, logEntry.Level, logEntry.Message)
-// }
-// fmt.Fprintf(w, "
")
-
- // w.Header().Set("Content-Type", "application/json")
- // json.NewEncoder(w).Encode(logs)
}
@@ -211,6 +232,7 @@ func main() {
webMux.HandleFunc("/agentIds", getAgentIds)
webMux.HandleFunc("/agents/{agentId}", agentsHandler)
webMux.HandleFunc("/logs", logsHandler)
+ webMux.HandleFunc("/logs/{level}", logsHandler)
db = database.InitDB (cfg.Database.Username, cfg.Database.Password, cfg.Database.Host, cfg.Database.Port, cfg.Database.Name)
defer db.Close()
diff --git a/src/logger/logger.go b/src/logger/logger.go
index 5fb7a09..2075f16 100644
--- a/src/logger/logger.go
+++ b/src/logger/logger.go
@@ -95,21 +95,40 @@ func InsertLog(level LogLevel, message string) error {
return nil
}
-func FetchLogs(limit int) ([]LogEntry, error) {
+func FetchLogs(limit int, levels []string) ([]LogEntry, error) {
lite_dbMutex.Lock()
defer lite_dbMutex.Unlock()
- query := `SELECT timestamp, level, message FROM logs ORDER BY timestamp DESC LIMIT ?`
- rows, err := Lite_db.Query(query, limit)
+ if len(levels) == 0 {
+ levels = []string{"%"}
+ }
+
+ var args []interface{}
+ placeholders := make([]string, len(levels))
+
+ for i, level := range levels {
+ placeholders[i] = "level LIKE ?"
+ args = append(args, level)
+ }
+
+ query := fmt.Sprintf(`
+ SELECT timestamp, level, message
+ FROM logs
+ WHERE %s
+ ORDER BY timestamp DESC
+ LIMIT ?`, strings.Join(placeholders, " OR "))
+
+ args = append(args, limit)
+
+ // rows, err := Lite_db.Query(query, level, limit)
+ rows, err := Lite_db.Query(query, args...)
if err != nil {
return nil, fmt.Errorf("Error fetching logs: %w", err)
}
defer rows.Close()
- // var logs []string
var logs []LogEntry
for rows.Next() {
- // var message string
var logEntry LogEntry
if err := rows.Scan( &logEntry.Timestamp, &logEntry.Level, &logEntry.Message); err != nil {
return nil, fmt.Errorf("Error scanning row: %w", err)
diff --git a/templates/index.html b/templates/index.html
index a261aa2..501096a 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -90,20 +90,36 @@
@@ -140,23 +156,32 @@
-
- Logs
-
-
-
-
-
-
-
-
-
-
+
+
+
Details
+
Select an agent to view details.
+
-
-
-
Details
-
Select an agent to view details.
+
+
Logs
+
+
+
+
+
diff --git a/templates/partials/logs_partial.html b/templates/partials/logs_partial.html
index d2a771c..2ab5f80 100644
--- a/templates/partials/logs_partial.html
+++ b/templates/partials/logs_partial.html
@@ -1,5 +1,5 @@
{{range .}}
-
- ts={{.Timestamp}} level={{.Level}} msg="{{.Message}}"
-
+
+ ts={{.Timestamp}} level={{.Level}}msg="{{.Message}}"
+
{{end}}