goatcounter-systemd/caddy/log_parse.go

65 lines
1.5 KiB
Go
Raw Permalink Normal View History

2024-09-28 16:20:24 -04:00
package caddy
import (
"encoding/json"
"fmt"
"net/http"
"strings"
"time"
)
type LogEntry struct {
rawLogEntry
Timestamp time.Time
Duration time.Duration
}
type logRequest struct {
RemoteIP string `json:"remote_ip"`
RemotePort string `json:"remote_port"`
ClientIP string `json:"client_ip"`
Proto string `json:"proto"`
Method string `json:"method"`
Host string `json:"host"`
URI string `json:"uri"`
Headers http.Header `json:"headers"`
}
type rawLogEntry struct {
Level string `json:"level"`
Timestamp float64 `json:"ts"`
Logger string `json:"logger"`
Message string `json:"msg"`
Upstream string `json:"upstream"`
Duration float64 `json:"duration"`
Request logRequest `json:"request"`
}
func FromJSON(jsonData []byte) (logEntry LogEntry, err error) {
rawLogEntry := rawLogEntry{}
err = json.Unmarshal(jsonData, &rawLogEntry)
if err != nil {
return logEntry, fmt.Errorf("failed to JSON unmarshal caddy log entry: %w", err)
}
rawLogEntry.Request.Host = stripPort(rawLogEntry.Request.Host)
seconds := int64(rawLogEntry.Timestamp)
nanoSeconds := int64((rawLogEntry.Timestamp - float64(seconds)) * 1e9)
logEntry.Timestamp = time.Unix(seconds, nanoSeconds)
logEntry.Duration = time.Duration(float64(time.Second) * rawLogEntry.Duration)
logEntry.rawLogEntry = rawLogEntry
return logEntry, nil
}
func stripPort(host string) string {
portIndex := strings.Index(host, ":")
if portIndex >= 0 {
return host[:portIndex]
}
return host
}