mirror of
https://github.com/unpoller/unpoller.git
synced 2026-03-31 06:24:21 -04:00
Add an ExtraLabels map[string]string field to the Loki Config struct so users can define static key=value labels that are merged into the stream labels of every log line sent to Loki. This allows users to distinguish streams (e.g., by environment or datacenter) without hardcoding values. Built-in dynamic labels (application, site_name, source, etc.) always take precedence over extra labels to preserve existing behavior. Example config (TOML): [loki.extra_labels] environment = "production" datacenter = "us-east-1" Closes #691 Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -34,8 +34,9 @@ type Config struct {
|
||||
Username string `json:"user" toml:"user" xml:"user" yaml:"user"`
|
||||
Password string `json:"pass" toml:"pass" xml:"pass" yaml:"pass"`
|
||||
TenantID string `json:"tenant_id" toml:"tenant_id" xml:"tenant_id" yaml:"tenant_id"`
|
||||
Interval cnfg.Duration `json:"interval" toml:"interval" xml:"interval" yaml:"interval"`
|
||||
Timeout cnfg.Duration `json:"timeout" toml:"timeout" xml:"timeout" yaml:"timeout"`
|
||||
Interval cnfg.Duration `json:"interval" toml:"interval" xml:"interval" yaml:"interval"`
|
||||
Timeout cnfg.Duration `json:"timeout" toml:"timeout" xml:"timeout" yaml:"timeout"`
|
||||
ExtraLabels map[string]string `json:"extra_labels" toml:"extra_labels" xml:"extra_labels" yaml:"extra_labels"`
|
||||
}
|
||||
|
||||
// Loki is the main library struct. This satisfies the poller.Output interface.
|
||||
|
||||
@@ -23,9 +23,10 @@ type Logs struct {
|
||||
|
||||
// Report is the temporary data generated by processing events.
|
||||
type Report struct {
|
||||
Start time.Time
|
||||
Oldest time.Time
|
||||
Collect poller.Collect
|
||||
Start time.Time
|
||||
Oldest time.Time
|
||||
Collect poller.Collect
|
||||
ExtraLabels map[string]string
|
||||
poller.Logger
|
||||
Counts map[string]int
|
||||
}
|
||||
@@ -33,11 +34,12 @@ type Report struct {
|
||||
// NewReport makes a new report.
|
||||
func (l *Loki) NewReport(start time.Time) *Report {
|
||||
return &Report{
|
||||
Start: start,
|
||||
Oldest: l.last,
|
||||
Collect: l.Collect,
|
||||
Logger: l,
|
||||
Counts: make(map[string]int),
|
||||
Start: start,
|
||||
Oldest: l.last,
|
||||
Collect: l.Collect,
|
||||
ExtraLabels: l.ExtraLabels,
|
||||
Logger: l,
|
||||
Counts: make(map[string]int),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,3 +97,14 @@ func CleanLabels(labels map[string]string) map[string]string {
|
||||
|
||||
return labels
|
||||
}
|
||||
|
||||
// MergeLabels merges extra into labels. Keys already present in labels are not overwritten.
|
||||
func MergeLabels(labels, extra map[string]string) map[string]string {
|
||||
for k, v := range extra {
|
||||
if _, exists := labels[k]; !exists {
|
||||
labels[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
return labels
|
||||
}
|
||||
|
||||
@@ -26,10 +26,10 @@ func (r *Report) Alarm(event *unifi.Alarm, logs *Logs) {
|
||||
|
||||
logs.Streams = append(logs.Streams, LogStream{
|
||||
Entries: [][]string{{strconv.FormatInt(event.Datetime.UnixNano(), 10), string(msg)}},
|
||||
Labels: CleanLabels(map[string]string{
|
||||
Labels: CleanLabels(MergeLabels(map[string]string{
|
||||
"application": "unifi_alarm",
|
||||
"source": event.SourceName,
|
||||
"site_name": event.SiteName,
|
||||
}),
|
||||
}, r.ExtraLabels)),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -26,10 +26,10 @@ func (r *Report) Anomaly(event *unifi.Anomaly, logs *Logs) {
|
||||
|
||||
logs.Streams = append(logs.Streams, LogStream{
|
||||
Entries: [][]string{{strconv.FormatInt(event.Datetime.UnixNano(), 10), string(msg)}},
|
||||
Labels: CleanLabels(map[string]string{
|
||||
Labels: CleanLabels(MergeLabels(map[string]string{
|
||||
"application": "unifi_anomaly",
|
||||
"source": event.SourceName,
|
||||
"site_name": event.SiteName,
|
||||
}),
|
||||
}, r.ExtraLabels)),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -27,11 +27,11 @@ func (r *Report) Event(event *unifi.Event, logs *Logs) {
|
||||
|
||||
logs.Streams = append(logs.Streams, LogStream{
|
||||
Entries: [][]string{{strconv.FormatInt(event.Datetime.UnixNano(), 10), string(msg)}},
|
||||
Labels: CleanLabels(map[string]string{
|
||||
Labels: CleanLabels(MergeLabels(map[string]string{
|
||||
"application": "unifi_event",
|
||||
"site_name": event.SiteName,
|
||||
"source": event.SourceName,
|
||||
}),
|
||||
}, r.ExtraLabels)),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -52,12 +52,12 @@ func (r *Report) SystemLogEvent(event *unifi.SystemLogEntry, logs *Logs) {
|
||||
|
||||
logs.Streams = append(logs.Streams, LogStream{
|
||||
Entries: [][]string{{strconv.FormatInt(event.Datetime().UnixNano(), 10), string(msg)}},
|
||||
Labels: CleanLabels(map[string]string{
|
||||
Labels: CleanLabels(MergeLabels(map[string]string{
|
||||
"application": "unifi_system_log",
|
||||
"site_name": event.SiteName,
|
||||
"source": event.SourceName,
|
||||
"category": event.Category,
|
||||
"severity": event.Severity,
|
||||
}),
|
||||
}, r.ExtraLabels)),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -26,10 +26,10 @@ func (r *Report) IDs(event *unifi.IDS, logs *Logs) {
|
||||
|
||||
logs.Streams = append(logs.Streams, LogStream{
|
||||
Entries: [][]string{{strconv.FormatInt(event.Datetime.UnixNano(), 10), string(msg)}},
|
||||
Labels: CleanLabels(map[string]string{
|
||||
Labels: CleanLabels(MergeLabels(map[string]string{
|
||||
"application": "unifi_ids",
|
||||
"source": event.SourceName,
|
||||
"site_name": event.SiteName,
|
||||
}),
|
||||
}, r.ExtraLabels)),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -34,14 +34,14 @@ func (r *Report) ProtectLogEvent(event *unifi.ProtectLogEntry, logs *Logs) {
|
||||
// Add event log line
|
||||
logs.Streams = append(logs.Streams, LogStream{
|
||||
Entries: [][]string{{strconv.FormatInt(event.Datetime().UnixNano(), 10), string(msg)}},
|
||||
Labels: CleanLabels(map[string]string{
|
||||
Labels: CleanLabels(MergeLabels(map[string]string{
|
||||
"application": "unifi_protect_log",
|
||||
"source": event.SourceName,
|
||||
"event_type": event.GetEventType(),
|
||||
"category": event.GetCategory(),
|
||||
"severity": event.GetSeverity(),
|
||||
"camera": event.Camera,
|
||||
}),
|
||||
}, r.ExtraLabels)),
|
||||
})
|
||||
|
||||
// Add thumbnail as separate log line if present
|
||||
@@ -57,12 +57,12 @@ func (r *Report) ProtectLogEvent(event *unifi.ProtectLogEntry, logs *Logs) {
|
||||
// Use timestamp + 1 nanosecond to ensure ordering (thumbnail after event)
|
||||
logs.Streams = append(logs.Streams, LogStream{
|
||||
Entries: [][]string{{strconv.FormatInt(event.Datetime().UnixNano()+1, 10), string(thumbnailJSON)}},
|
||||
Labels: CleanLabels(map[string]string{
|
||||
Labels: CleanLabels(MergeLabels(map[string]string{
|
||||
"application": "unifi_protect_thumbnail",
|
||||
"source": event.SourceName,
|
||||
"event_id": event.ID,
|
||||
"camera": event.Camera,
|
||||
}),
|
||||
}, r.ExtraLabels)),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user