From 063f75c3e20545bf36de0c8cb72524b723664ede Mon Sep 17 00:00:00 2001 From: Thomas Labarussias Date: Tue, 23 Aug 2022 15:41:17 +0200 Subject: [PATCH] update Loki output to reflect the new API (version before of Loki <1 are now deprecated) Signed-off-by: Thomas Labarussias --- config.go | 2 +- config_example.yaml | 2 +- outputs/loki.go | 37 +++++++++++++++++-------------------- outputs/loki_test.go | 12 ++++++------ 4 files changed, 25 insertions(+), 28 deletions(-) diff --git a/config.go b/config.go index 35e41fee5..f4943f9db 100644 --- a/config.go +++ b/config.go @@ -120,7 +120,7 @@ func getConfig() *types.Configuration { v.SetDefault("Loki.MutualTLS", false) v.SetDefault("Loki.CheckCert", true) v.SetDefault("Loki.Tenant", "") - v.SetDefault("Loki.Endpoint", "/api/prom/push") + v.SetDefault("Loki.Endpoint", "/loki/api/v1/push") v.SetDefault("Loki.ExtraLabels", "") v.SetDefault("AWS.AccessKeyID", "") diff --git a/config_example.yaml b/config_example.yaml index 3d30e72a7..5a0bea759 100644 --- a/config_example.yaml +++ b/config_example.yaml @@ -86,7 +86,7 @@ loki: # mutualtls: false # if true, checkcert flag will be ignored (server cert will always be checked) # checkcert: true # check if ssl certificate of the output is valid (default: true) # tenant: "" # Add the tenant header if needed. Tenant header is enabled only if not empty - # endpoint: "/api/prom/push" # The endpoint URL path, default is "/api/prom/push" more info : https://grafana.com/docs/loki/latest/api/#post-apiprompush + # endpoint: "/loki/api/v1/push" # The endpoint URL path, default is "/loki/api/v1/push" more info : https://grafana.com/docs/loki/latest/api/#post-apiprompush # extralabels: "" # comma separated list of fields to use as labels additionally to rule, source, priority, tags and custom_fields nats: diff --git a/outputs/loki.go b/outputs/loki.go index 0b2beb6fa..dba447e6b 100644 --- a/outputs/loki.go +++ b/outputs/loki.go @@ -1,9 +1,9 @@ package outputs import ( + "fmt" "log" "strings" - "time" "github.com/falcosecurity/falcosidekick/types" ) @@ -13,34 +13,32 @@ type lokiPayload struct { } type lokiStream struct { - Labels string `json:"labels"` - Entries []lokiEntry `json:"entries"` + Stream map[string]string `json:"stream"` + Values []lokiValue `json:"values"` } -type lokiEntry struct { - Ts string `json:"ts"` - Line string `json:"line"` -} +type lokiValue = []string // The Content-Type to send along with the request const LokiContentType = "application/json" func newLokiPayload(falcopayload types.FalcoPayload, config *types.Configuration) lokiPayload { - le := lokiEntry{Ts: falcopayload.Time.Format(time.RFC3339), Line: falcopayload.Output} - ls := lokiStream{Entries: []lokiEntry{le}} + s := make(map[string]string, 3+len(falcopayload.OutputFields)+len(config.Loki.ExtraLabelsList)+len(falcopayload.Tags)) + s["rule"] = falcopayload.Rule + s["source"] = falcopayload.Source + s["priority"] = falcopayload.Priority.String() - var s string for i, j := range falcopayload.OutputFields { switch v := j.(type) { case string: for k := range config.Customfields { if i == k { - s += strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(i, ".", ""), "]", ""), "[", "") + "=\"" + strings.ReplaceAll(v, "\"", "") + "\"," + s[strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(i, ".", ""), "]", ""), "[", "")] = strings.ReplaceAll(v, "\"", "") } } for _, k := range config.Loki.ExtraLabelsList { if i == k { - s += strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(i, ".", ""), "]", ""), "[", "") + "=\"" + strings.ReplaceAll(v, "\"", "") + "\"," + s[strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(i, ".", ""), "]", ""), "[", "")] = strings.ReplaceAll(v, "\"", "") } } default: @@ -49,16 +47,15 @@ func newLokiPayload(falcopayload types.FalcoPayload, config *types.Configuration } if len(falcopayload.Tags) != 0 { - s += "tags=\"" + strings.Join(falcopayload.Tags, ",") + "\"," + s["tags"] = strings.Join(falcopayload.Tags, ",") } - s += "rule=\"" + falcopayload.Rule + "\"," - s += "source=\"" + falcopayload.Source + "\"," - s += "priority=\"" + falcopayload.Priority.String() + "\"" - - ls.Labels = "{" + s + "}" - - return lokiPayload{Streams: []lokiStream{ls}} + return lokiPayload{Streams: []lokiStream{ + { + Stream: s, + Values: []lokiValue{[]string{fmt.Sprintf("%v", falcopayload.Time.UnixNano()), falcopayload.Output}}, + }, + }} } // LokiPost posts event to Loki diff --git a/outputs/loki_test.go b/outputs/loki_test.go index eb093687c..58d0a2568 100644 --- a/outputs/loki_test.go +++ b/outputs/loki_test.go @@ -13,13 +13,13 @@ func TestNewLokiPayload(t *testing.T) { expectedOutput := lokiPayload{ Streams: []lokiStream{ { - Labels: "{tags=\"test,example\",rule=\"Test rule\",source=\"syscalls\",priority=\"Debug\"}", - Entries: []lokiEntry{ - { - Ts: "2001-01-01T01:10:00Z", - Line: "This is a test from falcosidekick", - }, + Stream: map[string]string{ + "tags": "test,example", + "rule": "Test rule", + "source": "syscalls", + "priority": "Debug", }, + Values: []lokiValue{[]string{"978311400000000000", "This is a test from falcosidekick"}}, }, }, }