From 82c2465f2216d45567dc20b7e168d57faa718b58 Mon Sep 17 00:00:00 2001 From: Thomas Labarussias Date: Fri, 17 Jan 2025 16:51:54 +0100 Subject: [PATCH] allow to set the format for the value in Loki log lines Signed-off-by: Thomas Labarussias --- config.go | 1 + config_example.yaml | 1 + docs/outputs/loki.md | 25 +++++++++++++------------ outputs/loki.go | 9 ++++++++- stats_prometheus.go | 7 +++---- types/types.go | 1 + 6 files changed, 27 insertions(+), 17 deletions(-) diff --git a/config.go b/config.go index 26c632353..df01054f3 100644 --- a/config.go +++ b/config.go @@ -145,6 +145,7 @@ var httpOutputDefaults = map[string]map[string]any{ "APIKey": "", "MinimumPriority": "", "Tenant": "", + "Format": "text", "Endpoint": "/loki/api/v1/push", "ExtraLabels": "", }, diff --git a/config_example.yaml b/config_example.yaml index 1a20cb1a4..fe0648ae1 100644 --- a/config_example.yaml +++ b/config_example.yaml @@ -156,6 +156,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 + # format: "text" # Format for the log entry value: json, text (default) # 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 # customHeaders: # Custom headers to add in POST, useful for Authentication diff --git a/docs/outputs/loki.md b/docs/outputs/loki.md index 593862e5c..b00a30c15 100644 --- a/docs/outputs/loki.md +++ b/docs/outputs/loki.md @@ -14,18 +14,19 @@ ## Configuration -| Setting | Env var | Default value | Description | -| ---------------------- | ---------------------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | -| `loki.hostport` | `LOKI_HOSTPORT` | | http://{domain or ip}:{port}, if not empty, Loki output is **enabled** | -| `loki.user` | `LOKI_USER` | | User for Grafana Logs | -| `loki.apikey` | `LOKI_APIKEY` | | API KEy for Grafana Logs | -| `loki.tenant` | `LOKI_TENANT` | | Add the tenant header if needed | -| `loki.endpoint` | `LOKI_ENDPOINT` | `/loki/api/v1/push` | The endpoint URL path, more info : https://grafana.com/docs/loki/latest/api/#post-apiprompush | -| `loki.extralabels` | `LOKI_EXTRALABELS` | | comma separated list of fields to use as labels additionally to `rule`, `source`, `priority`, `tags` and `custom_fields` | -| `loki.customheaders` | `LOKI_CUSTOMHEADERS` | | Custom headers to add in POST, useful for Authentication | -| `loki.mutualtls` | `LOKI_MUTUALTLS` | `false` | Authenticate to the output with TLS, if true, checkcert flag will be ignored (server cert will always be checked) | -| `loki.checkcert` | `LOKI_CHECKCERT` | `/api/v1/alerts` | Check if ssl certificate of the output is valid | `mattermost.minimumpriority` | `MATTERMOST_MINIMUMPRIORITY` | `""` (= `debug`) | Minimum priority of event for using this output, order is `emergency,alert,critical,error,warning,notice,informational,debug or ""` -| `loki.minimumpriority` | `LOKI_MINIMUMPRIORITY` | `""` (= `debug`) | Minimum priority of event for using this output, order is `emergency,alert,critical,error,warning,notice,informational,debug or ""` | +| Setting | Env var | Default value | Description | | | | | +| ---------------------- | ---------------------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | ---------------------------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------- | +| `loki.hostport` | `LOKI_HOSTPORT` | | http://{domain or ip}:{port}, if not empty, Loki output is **enabled** | | | | | +| `loki.user` | `LOKI_USER` | | User for Grafana Logs | | | | | +| `loki.apikey` | `LOKI_APIKEY` | | API KEy for Grafana Logs | | | | | +| `loki.tenant` | `LOKI_TENANT` | | Add the tenant header if needed | | | | | +| `loki.format` | `LOKI_FORMAT` | `text` | Format for the log entry value: json, text | | | | | +| `loki.endpoint` | `LOKI_ENDPOINT` | `/loki/api/v1/push` | The endpoint URL path, more info : https://grafana.com/docs/loki/latest/api/#post-apiprompush | | | | | +| `loki.extralabels` | `LOKI_EXTRALABELS` | | comma separated list of fields to use as labels additionally to `rule`, `source`, `priority`, `tags` and `custom_fields` | | | | | +| `loki.customheaders` | `LOKI_CUSTOMHEADERS` | | Custom headers to add in POST, useful for Authentication | | | | | +| `loki.mutualtls` | `LOKI_MUTUALTLS` | `false` | Authenticate to the output with TLS, if true, checkcert flag will be ignored (server cert will always be checked) | | | | | +| `loki.checkcert` | `LOKI_CHECKCERT` | `/api/v1/alerts` | Check if ssl certificate of the output is valid | `mattermost.minimumpriority` | `MATTERMOST_MINIMUMPRIORITY` | `""` (= `debug`) | Minimum priority of event for using this output, order is `emergency,alert,critical,error,warning,notice,informational,debug or ""` | +| `loki.minimumpriority` | `LOKI_MINIMUMPRIORITY` | `""` (= `debug`) | Minimum priority of event for using this output, order is `emergency,alert,critical,error,warning,notice,informational,debug or ""` | | | | | > [!NOTE] diff --git a/outputs/loki.go b/outputs/loki.go index c7966fdf9..962d8021a 100644 --- a/outputs/loki.go +++ b/outputs/loki.go @@ -75,10 +75,17 @@ func newLokiPayload(falcopayload types.FalcoPayload, config *types.Configuration s["tags"] = strings.Join(falcopayload.Tags, ",") } + var v string + if config.Loki.Format == "json" { + v = falcopayload.String() + } else { + v = falcopayload.Output + } + return lokiPayload{Streams: []lokiStream{ { Stream: s, - Values: []lokiValue{[]string{fmt.Sprintf("%v", falcopayload.Time.UnixNano()), falcopayload.Output}}, + Values: []lokiValue{[]string{fmt.Sprintf("%v", falcopayload.Time.UnixNano()), v}}, }, }} } diff --git a/stats_prometheus.go b/stats_prometheus.go index b35ba4fba..1a5af5417 100644 --- a/stats_prometheus.go +++ b/stats_prometheus.go @@ -4,7 +4,6 @@ package main import ( "fmt" - "log" "regexp" "strings" @@ -57,21 +56,21 @@ func getFalcoNewCounterVec(config *types.Configuration) *prometheus.CounterVec { } for i := range config.Customfields { if !regPromLabels.MatchString(strings.ReplaceAll(i, ".", "_")) { - utils.Log(utils.ErrorLvl, "", fmt.Sprintf("Custom field '%v' is not a valid prometheus label", i)) + utils.Log(utils.ErrorLvl, "Prometheus", fmt.Sprintf("Custom field '%v' is not a valid prometheus label", i)) continue } labelnames = append(labelnames, strings.ReplaceAll(i, ".", "_")) } for i := range config.Templatedfields { if !regPromLabels.MatchString(strings.ReplaceAll(i, ".", "_")) { - log.Printf("[ERROR] : Templated field '%v' is not a valid prometheus label", i) + utils.Log(utils.ErrorLvl, "Prometheus", fmt.Sprintf("Templated field '%v' is not a valid prometheus label", i)) continue } labelnames = append(labelnames, strings.ReplaceAll(i, ".", "_")) } for _, i := range config.Prometheus.ExtraLabelsList { if !regPromLabels.MatchString(strings.ReplaceAll(i, ".", "_")) { - utils.Log(utils.ErrorLvl, "", fmt.Sprintf("Extra field '%v' is not a valid prometheus label", i)) + utils.Log(utils.ErrorLvl, "Prometheus", fmt.Sprintf("Extra field '%v' is not a valid prometheus label", i)) continue } labelnames = append(labelnames, strings.ReplaceAll(i, ".", "_")) diff --git a/types/types.go b/types/types.go index c5007f9d2..9f1f33699 100644 --- a/types/types.go +++ b/types/types.go @@ -343,6 +343,7 @@ type LokiOutputConfig struct { APIKey string MinimumPriority string Tenant string + Format string Endpoint string ExtraLabels string ExtraLabelsList []string