diff --git a/cmd/metrics/parser.go b/cmd/metrics/parser.go index 42566a4..ff2ef14 100644 --- a/cmd/metrics/parser.go +++ b/cmd/metrics/parser.go @@ -67,7 +67,7 @@ var MetricCmd = &cobra.Command{ continue } else { log.Debugf("matched: %s", res.DumpString()) - rx = append(rx, res.CopyData()) + rx = append(rx, res) } } if err := scanner.Err(); err != nil { diff --git a/pkg/metrics/matcher.go b/pkg/metrics/matcher.go index b9a468a..d53f9cc 100644 --- a/pkg/metrics/matcher.go +++ b/pkg/metrics/matcher.go @@ -16,13 +16,20 @@ func DefaultMatchRules() MatchRules { NewMetricMatcher("node").AddLabel("node").AddLabel("kernel_version"). AddLabel("os_image").AddLabel("container_runtime_version"). AddLabel("provider_id").AddLabel("internal_ip"), + NewMetricMatcher("node_role").SetHeader("kube_node_role"). + AddLabel("node").AddLabel("role").SetNameLabel("node"), - NewMetricMatcher("pod").AddLabel("namespace").AddLabel("pod").AddLabel("node"). - AddLabel("host_ip").AddLabel("pod_ip"), - NewMetricMatcher("container").SetHeader("kube_pod_container_info").AddLabel("namespace"). - AddLabel("pod").AddLabel("container").AddLabel("image_spec").AddLabel("image"), - NewMetricMatcher("pod_init_container").AddLabel("namespace").AddLabel("pod"). - AddLabel("container").AddLabel("image_spec").AddLabel("image"), + NewMetricMatcher("pod").AddLabel("namespace").AddLabel("pod"). + AddLabel("node").AddLabel("pod_ip"). + AddLabel("host_ip").AddLabel("host_network"), + NewMetricMatcher("container").SetHeader("kube_pod_container_info"). + AddLabel("namespace").AddLabel("pod"). + SetNameLabel("container").AddLabel("container"). + AddLabel("image").AddLabel("image_spec"), + NewMetricMatcher("init_container").SetHeader("kube_pod_init_container_info"). + AddLabel("namespace").AddLabel("pod"). + SetNameLabel("container").AddLabel("container"). + AddLabel("image").AddLabel("image_spec"), NewMetricMatcher("cronjob").AddLabel("namespace").AddLabel("cronjob"). AddLabel("schedule").AddLabel("concurrency_policy"), @@ -41,6 +48,16 @@ func DefaultMatchRules() MatchRules { AddLabel("gce_persistent_disk_name").AddLabel("ebs_volume_id").AddLabel("azure_disk_name"). AddLabel("nfs_server").AddLabel("nfs_path").AddLabel("csi_driver").AddLabel("csi_volume_handle"). AddLabel("local_path").AddLabel("local_fs").AddLabel("host_path").AddLabel("host_path_type"), + + NewMetricMatcher("validating_webhook").SetNameLabel("webhook_name"). + SetHeader("kube_validatingwebhookconfiguration_webhook_clientconfig_service"). + AddLabel("namespace").AddLabel("webhook_name"). + AddLabel("service_name").AddLabel("service_namespace"), + + NewMetricMatcher("mutating_webhook").SetNameLabel("webhook_name"). + SetHeader("kube_mutatingwebhookconfiguration_webhook_clientconfig_service"). + AddLabel("namespace").AddLabel("webhook_name"). + AddLabel("service_name").AddLabel("service_namespace"), } } @@ -61,7 +78,7 @@ func (m MatchRules) Match(target string) (*MetricMatcher, error) { if e != nil { continue } else { - return r, nil + return r.CopyData(), nil } } return nil, errors.New("no match found") diff --git a/pkg/metrics/parser.go b/pkg/metrics/parser.go index 11a1340..06cb553 100644 --- a/pkg/metrics/parser.go +++ b/pkg/metrics/parser.go @@ -28,9 +28,10 @@ type Label struct { } type MetricMatcher struct { - Name string `json:"type"` + Type string `json:"type"` Header string `json:"-"` Labels []Label `json:"labels"` + nameLabel string `json:"-"` grok *grok.Grok `json:"-"` finalPattern string ptr any `json:"-"` @@ -38,9 +39,10 @@ type MetricMatcher struct { func NewMetricMatcher(t string) *MetricMatcher { return &MetricMatcher{ - Name: t, - grok: grok.New(), - Labels: make([]Label, 0), + Type: t, + nameLabel: t, + grok: grok.New(), + Labels: make([]Label, 0), } } @@ -60,7 +62,7 @@ func (mt *MetricMatcher) Compile() error { return err } if mt.Header == "" { - mt.Header = `kube_` + mt.Name + `_info` // custom head + mt.Header = `kube_` + mt.Type + `_info` // custom head } header := mt.Header var body []string @@ -138,6 +140,15 @@ func (mt *MetricMatcher) DumpString() string { return string(b) } +func (mt *MetricMatcher) SetNameLabel(n string) *MetricMatcher { + mt.nameLabel = n + return mt +} + +func (mt *MetricMatcher) LabelNameOfName() string { + return mt.nameLabel +} + func init() { err := COMMON_MATCH_GROK.AddPatterns(MetricsPatterns) if err != nil { @@ -155,8 +166,9 @@ func (mt *MetricMatcher) CopyData() *MetricMatcher { newLabel = append(newLabel, label) } return &MetricMatcher{ - Name: strings.Clone(mt.Name), - Header: strings.Clone(mt.Header), - Labels: newLabel, + Type: strings.Clone(mt.Type), + Header: strings.Clone(mt.Header), + nameLabel: strings.Clone(mt.nameLabel), + Labels: newLabel, } } diff --git a/pkg/metrics/resource.go b/pkg/metrics/resource.go index 45e86d3..7968a91 100644 --- a/pkg/metrics/resource.go +++ b/pkg/metrics/resource.go @@ -48,10 +48,24 @@ func (rl *ResourceList) Print(writer ...io.Writer) { } } -type ResourceMergeHook func(m *MetricMatcher, resource ResourceList) (res *Resource, addFlag bool) +type ResourceMergeHook func(m *MetricMatcher, res ResourceList) (r *Resource, addFlag bool) + +var NodeMergeHook ResourceMergeHook = func(m *MetricMatcher, res ResourceList) (r *Resource, addFlag bool) { + if m.Type == "node" || m.Type == "node_role" { + for i := len(res) - 1; i >= 0; i-- { + c := res[i] + if m.FindLabel("node") == c.Name { + r = res[i] + return r, false + } + } + return NewResource("node"), true + } + return nil, true +} var EndpointMergeHook ResourceMergeHook = func(m *MetricMatcher, res ResourceList) (r *Resource, addFlag bool) { - if m.Name == "endpoint_address" || m.Name == "endpoint_port" { + if m.Type == "endpoint_address" || m.Type == "endpoint_port" { for i := len(res) - 1; i >= 0; i-- { c := res[i] if m.FindLabel("namespace") == c.Namespace && m.FindLabel("endpoint") == c.Name { @@ -62,7 +76,7 @@ var EndpointMergeHook ResourceMergeHook = func(m *MetricMatcher, res ResourceLis return NewResource("endpoint"), true /* for i, c := range res { - if m.FindLabel("namespace") == c.Namespace && m.FindLabel("endpoint") == c.Name { + if m.FindLabel("namespace") == c.Namespace && m.FindLabel("endpoint") == c.Type { r = res[i] return r, false } @@ -76,7 +90,7 @@ var EndpointMergeHook ResourceMergeHook = func(m *MetricMatcher, res ResourceLis func ConvertToResource(r []*MetricMatcher, hooks ...ResourceMergeHook) []*Resource { var res []*Resource if len(hooks) == 0 { - hooks = append(hooks, EndpointMergeHook) + hooks = append(hooks, EndpointMergeHook, NodeMergeHook) } for _, m := range r { @@ -90,7 +104,7 @@ func ConvertToResource(r []*MetricMatcher, hooks ...ResourceMergeHook) []*Resour } } - resourceType := m.Name + resourceType := m.Type if resource != nil { resourceType = resource.Type } @@ -99,11 +113,11 @@ func ConvertToResource(r []*MetricMatcher, hooks ...ResourceMergeHook) []*Resour } resource.Namespace = m.FindLabel("namespace") - resource.Name = m.FindLabel(resourceType) + resource.Name = m.FindLabel(m.LabelNameOfName()) // merge endpoint_address and endpoint_port for _, l := range m.Labels { - if l.Key != "namespace" && l.Key != resourceType { + if l.Key != "namespace" && l.Key != m.LabelNameOfName() { resource.AddLabelSpec(l) } }