Skip to content
Snippets Groups Projects
Commit 37df97c6 authored by Filippo Giunchedi's avatar Filippo Giunchedi
Browse files

Add mmkubernetes support

parent 041a30c6
Branches
No related tags found
No related merge requests found
......@@ -23,6 +23,7 @@ const (
rsyslogDynafileCache
rsyslogInputIMDUP
rsyslogForward
rsyslogKubernetes
)
type rsyslogExporter struct {
......@@ -121,6 +122,14 @@ func (re *rsyslogExporter) handleStatLine(rawbuf []byte) error {
for _, p := range f.toPoints() {
re.set(p)
}
case rsyslogKubernetes:
k, err := newKubernetesFromJSON(buf)
if err != nil {
return err
}
for _, p := range k.toPoints() {
re.set(p)
}
default:
return fmt.Errorf("unknown pstat type: %v", pstatType)
......
package main
import (
"encoding/json"
"fmt"
"regexp"
)
var (
apiNameRegexp = regexp.MustCompile(`mmkubernetes\((\S+)\)`)
)
type kubernetes struct {
Name string `json:"name"`
Url string
RecordSeen int64 `json:"recordseen"`
NamespaceMetaSuccess int64 `json:"namespacemetadatasuccess"`
NamespaceMetaNotFound int64 `json:"namespacemetadatanotfound"`
NamespaceMetaBusy int64 `json:"namespacemetadatabusy"`
NamespaceMetaError int64 `json:"namespacemetadataerror"`
PodMetaSuccess int64 `json:"podmetadatasuccess"`
PodMetaNotFound int64 `json:"podmetadatanotfound"`
PodMetaBusy int64 `json:"podmetadatabusy"`
PodMetaError int64 `json:"podmetadataerror"`
}
func newKubernetesFromJSON(b []byte) (*kubernetes, error) {
var pstat kubernetes
err := json.Unmarshal(b, &pstat)
if err != nil {
return nil, fmt.Errorf("failed to decode kubernetes stat `%v`: %v", string(b), err)
}
matches := apiNameRegexp.FindSubmatch([]byte(pstat.Name))
if matches != nil {
pstat.Url = string(matches[1])
}
return &pstat, nil
}
func (k *kubernetes) toPoints() []*point {
points := make([]*point, 9)
points[0] = &point{
Name: "kubernetes_namespace_metadata_success_total",
Type: counter,
Value: k.NamespaceMetaSuccess,
Description: "successful fetches of namespace metadata",
LabelName: "url",
LabelValue: k.Url,
}
points[1] = &point{
Name: "kubernetes_namespace_metadata_notfound_total",
Type: counter,
Value: k.NamespaceMetaNotFound,
Description: "notfound fetches of namespace metadata",
LabelName: "url",
LabelValue: k.Url,
}
points[2] = &point{
Name: "kubernetes_namespace_metadata_busy_total",
Type: counter,
Value: k.NamespaceMetaBusy,
Description: "busy fetches of namespace metadata",
LabelName: "url",
LabelValue: k.Url,
}
points[3] = &point{
Name: "kubernetes_namespace_metadata_error_total",
Type: counter,
Value: k.NamespaceMetaError,
Description: "error fetches of namespace metadata",
LabelName: "url",
LabelValue: k.Url,
}
points[4] = &point{
Name: "kubernetes_pod_metadata_success_total",
Type: counter,
Value: k.PodMetaSuccess,
Description: "successful fetches of pod metadata",
LabelName: "url",
LabelValue: k.Url,
}
points[5] = &point{
Name: "kubernetes_pod_metadata_notfound_total",
Type: counter,
Value: k.PodMetaNotFound,
Description: "notfound fetches of pod metadata",
LabelName: "url",
LabelValue: k.Url,
}
points[6] = &point{
Name: "kubernetes_pod_metadata_busy_total",
Type: counter,
Value: k.PodMetaBusy,
Description: "busy fetches of pod metadata",
LabelName: "url",
LabelValue: k.Url,
}
points[7] = &point{
Name: "kubernetes_pod_metadata_error_total",
Type: counter,
Value: k.PodMetaError,
Description: "error fetches of pod metadata",
LabelName: "url",
LabelValue: k.Url,
}
points[8] = &point{
Name: "kubernetes_record_seen_total",
Type: counter,
Value: k.RecordSeen,
Description: "records fetched from the api",
LabelName: "url",
LabelValue: k.Url,
}
return points
}
package main
import "testing"
var (
kubernetesLog = []byte(`{ "name": "mmkubernetes(https://host.domain.tld:6443)", "origin": "mmkubernetes", "recordseen": 477943, "namespacemetadatasuccess": 7, "namespacemetadatanotfound": 0, "namespacemetadatabusy": 0, "namespacemetadataerror": 0, "podmetadatasuccess": 26, "podmetadatanotfound": 0, "podmetadatabusy": 0, "podmetadataerror": 0 }`)
)
func TestNewKubernetesFromJSON(t *testing.T) {
logType := getStatType(kubernetesLog)
if logType != rsyslogKubernetes {
t.Errorf("detected pstat type should be %d but is %d", rsyslogKubernetes, logType)
}
pstat, err := newKubernetesFromJSON([]byte(kubernetesLog))
if err != nil {
t.Fatalf("expected parsing action not to fail, got: %v", err)
}
if want, got := "mmkubernetes(https://host.domain.tld:6443)", pstat.Name; want != got {
t.Errorf("wanted '%s', got '%s'", want, got)
}
if want, got := "https://host.domain.tld:6443", pstat.Url; want != got {
t.Errorf("wanted '%s', got '%s'", want, got)
}
if want, got := int64(477943), pstat.RecordSeen; want != got {
t.Errorf("wanted '%d', got '%d'", want, got)
}
if want, got := int64(7), pstat.NamespaceMetaSuccess; want != got {
t.Errorf("wanted '%d', got '%d'", want, got)
}
if want, got := int64(0), pstat.NamespaceMetaNotFound; want != got {
t.Errorf("wanted '%d', got '%d'", want, got)
}
if want, got := int64(0), pstat.NamespaceMetaBusy; want != got {
t.Errorf("wanted '%d', got '%d'", want, got)
}
if want, got := int64(0), pstat.NamespaceMetaError; want != got {
t.Errorf("wanted '%d', got '%d'", want, got)
}
if want, got := int64(26), pstat.PodMetaSuccess; want != got {
t.Errorf("wanted '%d', got '%d'", want, got)
}
if want, got := int64(0), pstat.PodMetaNotFound; want != got {
t.Errorf("wanted '%d', got '%d'", want, got)
}
if want, got := int64(0), pstat.PodMetaBusy; want != got {
t.Errorf("wanted '%d', got '%d'", want, got)
}
if want, got := int64(0), pstat.PodMetaError; want != got {
t.Errorf("wanted '%d', got '%d'", want, got)
}
}
func TestKubernetesToPoints(t *testing.T) {
pstat, err := newKubernetesFromJSON([]byte(kubernetesLog))
if err != nil {
t.Fatalf("expected parsing action not to fail, got: %v", err)
}
points := pstat.toPoints()
point := points[0]
if want, got := "kubernetes_namespace_metadata_success_total", point.Name; want != got {
t.Errorf("wanted '%s', got '%s'", want, got)
}
if want, got := "https://host.domain.tld:6443", point.LabelValue; want != got {
t.Errorf("wanted '%s', got '%s'", want, got)
}
point = points[1]
if want, got := "kubernetes_namespace_metadata_notfound_total", point.Name; want != got {
t.Errorf("wanted '%s', got '%s'", want, got)
}
point = points[2]
if want, got := "kubernetes_namespace_metadata_busy_total", point.Name; want != got {
t.Errorf("wanted '%s', got '%s'", want, got)
}
point = points[3]
if want, got := "kubernetes_namespace_metadata_error_total", point.Name; want != got {
t.Errorf("wanted '%s', got '%s'", want, got)
}
point = points[4]
if want, got := "kubernetes_pod_metadata_success_total", point.Name; want != got {
t.Errorf("wanted '%s', got '%s'", want, got)
}
point = points[5]
if want, got := "kubernetes_pod_metadata_notfound_total", point.Name; want != got {
t.Errorf("wanted '%s', got '%s'", want, got)
}
point = points[6]
if want, got := "kubernetes_pod_metadata_busy_total", point.Name; want != got {
t.Errorf("wanted '%s', got '%s'", want, got)
}
point = points[7]
if want, got := "kubernetes_pod_metadata_error_total", point.Name; want != got {
t.Errorf("wanted '%s', got '%s'", want, got)
}
point = points[8]
if want, got := "kubernetes_record_seen_total", point.Name; want != got {
t.Errorf("wanted '%s', got '%s'", want, got)
}
}
......@@ -20,6 +20,8 @@ func getStatType(buf []byte) rsyslogType {
return rsyslogDynafileCache
} else if strings.Contains(line, "omfwd") {
return rsyslogForward
} else if strings.Contains(line, "mmkubernetes") {
return rsyslogKubernetes
}
return rsyslogUnknown
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment