unpoller_unpoller/pkg/lokiunifi/report.go

83 lines
2.0 KiB
Go

package lokiunifi
import (
"fmt"
"strings"
"time"
"github.com/unpoller/unifi"
"github.com/unpoller/unpoller/core/poller"
)
// LogStream contains a stream of logs (like a log file).
// This app uses one stream per log entry because each log may have different labels.
type LogStream struct {
Labels map[string]string `json:"stream"` // "the file name"
Entries [][]string `json:"values"` // "the log lines"
}
// Logs is the main logs-holding structure. This is the Loki-output format.
type Logs struct {
Streams []LogStream `json:"streams"` // "multiple files"
}
// Report is the temporary data generated by processing events.
type Report struct {
Start time.Time
Oldest time.Time
poller.Logger
Counts map[string]int
}
// NewReport makes a new report.
func (l *Loki) NewReport(start time.Time) *Report {
return &Report{
Start: start,
Oldest: l.last,
Logger: l,
Counts: make(map[string]int),
}
}
// ProcessEventLogs loops the event Logs, matches the interface type, calls the
// appropriate method for the data, and compiles the Logs into a Loki format.
// This runs once per interval, if there was no collection error.
func (r *Report) ProcessEventLogs(events *poller.Events) *Logs {
logs := &Logs{}
for _, e := range events.Logs {
switch event := e.(type) {
case *unifi.IDS:
r.IDS(event, logs)
case *unifi.Event:
r.Event(event, logs)
case *unifi.Alarm:
r.Alarm(event, logs)
case *unifi.Anomaly:
r.Anomaly(event, logs)
default: // unlikely.
r.LogErrorf("unknown event type: %T", e)
}
}
return logs
}
func (r *Report) String() string {
return fmt.Sprintf("%s: %d, %s: %d, %s: %d, %s: %d, Dur: %v",
typeEvent, r.Counts[typeEvent], typeIDS, r.Counts[typeIDS],
typeAlarm, r.Counts[typeAlarm], typeAnomaly, r.Counts[typeAnomaly],
time.Since(r.Start).Round(time.Millisecond))
}
// CleanLabels removes any tag that is empty.
func CleanLabels(labels map[string]string) map[string]string {
for i := range labels {
if strings.TrimSpace(labels[i]) == "" {
delete(labels, i)
}
}
return labels
}