Skip to content

Commit

Permalink
fix Panic for prometheus metrics when CustomFields are set + only set…
Browse files Browse the repository at this point in the history
… labels for Loki for CustomFields and ExtraFields

Signed-off-by: Issif <issif+github@gadz.org>
  • Loading branch information
Issif authored and poiana committed Jun 17, 2022
1 parent 626f594 commit 44beeb3
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 33 deletions.
14 changes: 7 additions & 7 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func getConfig() *types.Configuration {
version := kingpin.Flag("version", "falcosidekick version").Short('v').Bool()
kingpin.Parse()

if *version != false {
if *version {
v := GetVersionInfo()
fmt.Println(v.String())
os.Exit(0)
Expand Down Expand Up @@ -334,7 +334,7 @@ func getConfig() *types.Configuration {
}
}

v.GetStringMapString("customfields")
v.GetStringMapString("Customfields")
v.GetStringMapString("Webhook.CustomHeaders")
v.GetStringMapString("CloudEvents.Extensions")
if err := v.Unmarshal(c); err != nil {
Expand All @@ -352,8 +352,8 @@ func getConfig() *types.Configuration {
}

if value, present := os.LookupEnv("WEBHOOK_CUSTOMHEADERS"); present {
customfields := strings.Split(value, ",")
for _, label := range customfields {
customheaders := strings.Split(value, ",")
for _, label := range customheaders {
tagkeys := strings.Split(label, ":")
if len(tagkeys) == 2 {
c.Webhook.CustomHeaders[tagkeys[0]] = tagkeys[1]
Expand All @@ -362,8 +362,8 @@ func getConfig() *types.Configuration {
}

if value, present := os.LookupEnv("CLOUDEVENTS_EXTENSIONS"); present {
customfields := strings.Split(value, ",")
for _, label := range customfields {
extensions := strings.Split(value, ",")
for _, label := range extensions {
tagkeys := strings.Split(label, ":")
if len(tagkeys) == 2 {
c.CloudEvents.Extensions[tagkeys[0]] = tagkeys[1]
Expand All @@ -384,7 +384,7 @@ func getConfig() *types.Configuration {
}

if c.Prometheus.ExtraLabels != "" {
c.Prometheus.ExtraLabelsList = strings.Split(strings.ReplaceAll(c.Loki.ExtraLabels, " ", ""), ",")
c.Prometheus.ExtraLabelsList = strings.Split(strings.ReplaceAll(c.Prometheus.ExtraLabels, " ", ""), ",")
}

c.Slack.MinimumPriority = checkPriority(c.Slack.MinimumPriority)
Expand Down
4 changes: 2 additions & 2 deletions config_example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ loki:
# 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
# extralabels: "" # comma separated list of fields to use as labels additionnally to rule, source, priority, tags and custom_fields
# extralabels: "" # comma separated list of fields to use as labels additionally to rule, source, priority, tags and custom_fields

nats:
# hostport: "" # nats://{domain or ip}:{port}, if not empty, NATS output is enabled
Expand Down Expand Up @@ -135,7 +135,7 @@ smtp:
# minimumpriority: "" # minimum priority of event for using this output, order is emergency|alert|critical|error|warning|notice|informational|debug or "" (default)

prometheus:
# extralabels: "" # comma separated list of fields to use as labels additionnally to rule, source, priority, tags and custom_fields
# extralabels: "" # comma separated list of fields to use as labels additionally to rule, source, priority, tags and custom_fields

statsd:
forwarder: "" # The address for the StatsD forwarder, in the form "host:port", if not empty StatsD is enabled
Expand Down
20 changes: 17 additions & 3 deletions handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,22 @@ func newFalcoPayload(payload io.Reader) (types.FalcoPayload, error) {
stats.Falco.Add(strings.ToLower(falcopayload.Priority.String()), 1)
promLabels := map[string]string{"rule": falcopayload.Rule, "priority": falcopayload.Priority.String(), "k8s_ns_name": kn, "k8s_pod_name": kp}
for key, value := range config.Customfields {
promLabels[key] = value
if regPromLabels.MatchString(key) {
promLabels[key] = value
}
}
for _, i := range config.Prometheus.ExtraLabelsList {
promLabels[strings.ReplaceAll(i, ".", "_")] = ""
for key, value := range falcopayload.OutputFields {
if key == i && regPromLabels.MatchString(strings.ReplaceAll(key, ".", "_")) {
switch v := value.(type) {
case string:
promLabels[strings.ReplaceAll(key, ".", "_")] = v
default:
continue
}
}
}
}
promStats.Falco.With(promLabels).Inc()

Expand Down Expand Up @@ -279,8 +294,7 @@ func forwardEvent(falcopayload types.FalcoPayload) {
if config.Fission.Function != "" && (falcopayload.Priority >= types.Priority(config.Fission.MinimumPriority) || falcopayload.Rule == testRule) {
go fissionClient.FissionCall(falcopayload)
}
if config.PolicyReport.Enabled == true {

if config.PolicyReport.Enabled {
go policyReportClient.UpdateOrCreatePolicyReport(falcopayload)
}

Expand Down
8 changes: 7 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"log"
"net/http"
"os"
"regexp"
"strings"

"github.com/DataDog/datadog-go/statsd"
Expand Down Expand Up @@ -58,6 +59,8 @@ var (
config *types.Configuration
stats *types.Statistics
promStats *types.PromStatistics

regPromLabels *regexp.Regexp
)

func init() {
Expand All @@ -68,6 +71,9 @@ func init() {
if testing {
return
}

regPromLabels, _ = regexp.Compile("^[a-zA-Z_:][a-zA-Z0-9_:]*$")

config = getConfig()
stats = getInitStats()
promStats = getInitPromStats(config)
Expand Down Expand Up @@ -434,7 +440,7 @@ func init() {
outputs.EnabledOutputs = append(outputs.EnabledOutputs, "WebUI")
}
}
if config.PolicyReport.Enabled == true {
if config.PolicyReport.Enabled {
var err error
policyReportClient, err = outputs.NewPolicyReportClient(config, stats, promStats, statsdClient, dogstatsdClient)
if err != nil {
Expand Down
15 changes: 11 additions & 4 deletions outputs/loki.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,15 @@ func newLokiPayload(falcopayload types.FalcoPayload, config *types.Configuration
for i, j := range falcopayload.OutputFields {
switch v := j.(type) {
case string:
if contains(config.Loki.ExtraLabelsList, i) {
s += strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(i, ".", ""), "]", ""), "[", "") + "=\"" + strings.ReplaceAll(v, "\"", "") + "\","
for k := range config.Customfields {
if i == k {
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, "\"", "") + "\","
}
}
default:
continue
Expand All @@ -47,9 +54,9 @@ func newLokiPayload(falcopayload types.FalcoPayload, config *types.Configuration

s += "rule=\"" + falcopayload.Rule + "\","
s += "source=\"" + falcopayload.Source + "\","
s += "priority=\"" + falcopayload.Priority.String() + "\","
s += "priority=\"" + falcopayload.Priority.String() + "\""

ls.Labels = "{" + s[:len(s)-1] + "}"
ls.Labels = "{" + s + "}"

return lokiPayload{Streams: []lokiStream{ls}}
}
Expand Down
9 changes: 0 additions & 9 deletions outputs/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,3 @@ func getSortedStringKeys(m map[string]interface{}) []string {
sort.Strings(keys)
return keys
}

func contains(slice []string, str string) bool {
for _, i := range slice {
if i == str {
return true
}
}
return false
}
19 changes: 12 additions & 7 deletions stats_prometheus.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"log"
"regexp"
"strings"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
Expand Down Expand Up @@ -38,22 +39,26 @@ func getOutputNewCounterVec() *prometheus.CounterVec {
}

func getFalcoNewCounterVec(config *types.Configuration) *prometheus.CounterVec {
regPromLabels, _ := regexp.Compile("^[a-zA-Z_:][a-zA-Z0-9_:]*$")
labelnames := []string{
"rule",
"priority",
"k8s_ns_name",
"k8s_pod_name",
}
labelnames = append(labelnames, config.Prometheus.ExtraLabelsList...)
for key := range config.Customfields {
matched, err := regexp.MatchString("^[a-zA-Z_:][a-zA-Z0-9_:]*$", key)
if err != nil {
log.Printf("Error matching prometheus label from custom fields. Err: %s", err)
for i := range config.Customfields {
if !regPromLabels.MatchString(i) {
log.Printf("[ERROR] : Custom field '%v' is not a valid prometheus label", i)
continue
}
if matched {
labelnames = append(labelnames, key)
labelnames = append(labelnames, i)
}
for _, i := range config.Prometheus.ExtraLabelsList {
if !regPromLabels.MatchString(strings.ReplaceAll(i, ".", "_")) {
log.Printf("[ERROR] : Extra field '%v' is not a valid prometheus label", i)
continue
}
labelnames = append(labelnames, strings.ReplaceAll(i, ".", "_"))
}
return promauto.NewCounterVec(
prometheus.CounterOpts{
Expand Down

0 comments on commit 44beeb3

Please sign in to comment.