add componentstatus metrics
This commit is contained in:
parent
19c73aa181
commit
5452f06393
|
|
@ -6,6 +6,7 @@ Any contribution to improving this documentation or adding sample usages will be
|
||||||
|
|
||||||
Per group of metrics there is one file for each metrics. See each file for specific documentation about the exposed metrics:
|
Per group of metrics there is one file for each metrics. See each file for specific documentation about the exposed metrics:
|
||||||
|
|
||||||
|
* [ComponentStatus Metrics](componentstatus-metrics.md)
|
||||||
* [CronJob Metrics](cronjob-metrics.md)
|
* [CronJob Metrics](cronjob-metrics.md)
|
||||||
* [DaemonSet Metrics](daemonset-metrics.md)
|
* [DaemonSet Metrics](daemonset-metrics.md)
|
||||||
* [Deployment Metrics](deployment-metrics.md)
|
* [Deployment Metrics](deployment-metrics.md)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
# Service Metrics
|
||||||
|
|
||||||
|
| Metric name| Metric type | Labels/tags |
|
||||||
|
| ---------- | ----------- | ----------- |
|
||||||
|
| kube_componentstatus_status_healthy | Gauge | `name`=<component-name> <br> `status`=<True\|False\|Unknow> |
|
||||||
|
|
@ -0,0 +1,103 @@
|
||||||
|
/*
|
||||||
|
Copyright 2017 The Kubernetes Authors All rights reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package collectors
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/golang/glog"
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
"golang.org/x/net/context"
|
||||||
|
"k8s.io/api/core/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/fields"
|
||||||
|
"k8s.io/client-go/kubernetes"
|
||||||
|
"k8s.io/client-go/tools/cache"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
descComponentStatusStatusHealthy = prometheus.NewDesc(
|
||||||
|
"kube_componentstatus_status_healthy",
|
||||||
|
"kube component status healthy status.",
|
||||||
|
[]string{"name", "status"}, nil,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
type ComponentStatusLister func() (v1.ComponentStatusList, error)
|
||||||
|
|
||||||
|
func (csl ComponentStatusLister) List() (v1.ComponentStatusList, error) {
|
||||||
|
return csl()
|
||||||
|
}
|
||||||
|
|
||||||
|
func RegisterComponentStatusCollector(registry prometheus.Registerer, kubeClient kubernetes.Interface, namespace string) {
|
||||||
|
client := kubeClient.CoreV1().RESTClient()
|
||||||
|
glog.Infof("collect componentstatuses with %s", client.APIVersion())
|
||||||
|
slw := cache.NewListWatchFromClient(client, "componentstatuses", v1.NamespaceAll, fields.Everything())
|
||||||
|
sinf := cache.NewSharedInformer(slw, &v1.ComponentStatus{}, resyncPeriod)
|
||||||
|
|
||||||
|
componentStatusLister := ComponentStatusLister(func() (componentStatuses v1.ComponentStatusList, err error) {
|
||||||
|
for _, m := range sinf.GetStore().List() {
|
||||||
|
componentStatuses.Items = append(componentStatuses.Items, *m.(*v1.ComponentStatus))
|
||||||
|
}
|
||||||
|
return componentStatuses, nil
|
||||||
|
})
|
||||||
|
|
||||||
|
registry.MustRegister(&componentStatusCollector{store: componentStatusLister})
|
||||||
|
go sinf.Run(context.Background().Done())
|
||||||
|
}
|
||||||
|
|
||||||
|
type componentStatusStore interface {
|
||||||
|
List() (componentStatuses v1.ComponentStatusList, err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// componentStatusCollector collects metrics about all components in the cluster.
|
||||||
|
type componentStatusCollector struct {
|
||||||
|
store componentStatusStore
|
||||||
|
}
|
||||||
|
|
||||||
|
// Describe implements the prometheus.Collector interface.
|
||||||
|
func (csc *componentStatusCollector) Describe(ch chan<- *prometheus.Desc) {
|
||||||
|
ch <- descComponentStatusStatusHealthy
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collect implements the prometheus.Collector interface.
|
||||||
|
func (csc *componentStatusCollector) Collect(ch chan<- prometheus.Metric) {
|
||||||
|
csl, err := csc.store.List()
|
||||||
|
if err != nil {
|
||||||
|
glog.Errorf("listing component status failed: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, s := range csl.Items {
|
||||||
|
csc.collectComponentStatus(ch, s)
|
||||||
|
}
|
||||||
|
glog.Infof("collected %d componentstatuses", len(csl.Items))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (csc *componentStatusCollector) collectComponentStatus(ch chan<- prometheus.Metric, s v1.ComponentStatus) {
|
||||||
|
addConstMetric := func(desc *prometheus.Desc, t prometheus.ValueType, v float64, lv ...string) {
|
||||||
|
lv = append([]string{s.Name}, lv...)
|
||||||
|
ch <- prometheus.MustNewConstMetric(desc, t, v, lv...)
|
||||||
|
}
|
||||||
|
addGauge := func(desc *prometheus.Desc, v float64, lv ...string) {
|
||||||
|
addConstMetric(desc, prometheus.GaugeValue, v, lv...)
|
||||||
|
}
|
||||||
|
for _, p := range s.Conditions {
|
||||||
|
if p.Type == v1.ComponentHealthy {
|
||||||
|
addGauge(descComponentStatusStatusHealthy, boolFloat64(p.Status == v1.ConditionTrue), string(v1.ConditionTrue))
|
||||||
|
addGauge(descComponentStatusStatusHealthy, boolFloat64(p.Status == v1.ConditionFalse), string(v1.ConditionFalse))
|
||||||
|
addGauge(descComponentStatusStatusHealthy, boolFloat64(p.Status == v1.ConditionUnknown), string(v1.ConditionUnknown))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,83 @@
|
||||||
|
/*
|
||||||
|
Copyright 2017 The Kubernetes Authors All rights reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package collectors
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"k8s.io/api/core/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
type mockcomponentStatusStore struct {
|
||||||
|
list func() (v1.ComponentStatusList, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mcs mockcomponentStatusStore) List() (v1.ComponentStatusList, error) {
|
||||||
|
return mcs.list()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestComponentStatusCollector(t *testing.T) {
|
||||||
|
// Fixed metadata on type and help text. We prepend this to every expected
|
||||||
|
// output so we only have to modify a single place when doing adjustments.
|
||||||
|
const metadata = `
|
||||||
|
# HELP kube_componentstatus_status_healthy kube component status healthy status.
|
||||||
|
# TYPE kube_componentstatus_status_healthy gauge
|
||||||
|
`
|
||||||
|
cases := []struct {
|
||||||
|
cms v1.ComponentStatusList
|
||||||
|
metrics []string // which metrics should be checked
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
// Verify phase enumerations.
|
||||||
|
{
|
||||||
|
cms: v1.ComponentStatusList{
|
||||||
|
Items: []v1.ComponentStatus{
|
||||||
|
{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "etcd1",
|
||||||
|
},
|
||||||
|
Conditions: []v1.ComponentCondition{
|
||||||
|
{
|
||||||
|
Type: v1.ComponentHealthy,
|
||||||
|
Status: v1.ConditionTrue,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: metadata + `
|
||||||
|
kube_componentstatus_status_healthy{name="etcd1",status="False"} 0
|
||||||
|
kube_componentstatus_status_healthy{name="etcd1",status="True"} 1
|
||||||
|
kube_componentstatus_status_healthy{name="etcd1",status="Unknown"} 0
|
||||||
|
`,
|
||||||
|
metrics: []string{"kube_componentstatus_status_healthy"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, c := range cases {
|
||||||
|
dc := &componentStatusCollector{
|
||||||
|
store: &mockcomponentStatusStore{
|
||||||
|
list: func() (v1.ComponentStatusList, error) {
|
||||||
|
return c.cms, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if err := gatherAndCompare(dc, c.want, c.metrics); err != nil {
|
||||||
|
t.Errorf("unexpected collecting result:\n%s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
2
main.go
2
main.go
|
|
@ -47,6 +47,7 @@ const (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
defaultCollectors = collectorSet{
|
defaultCollectors = collectorSet{
|
||||||
|
"componentstatuses": struct{}{},
|
||||||
"daemonsets": struct{}{},
|
"daemonsets": struct{}{},
|
||||||
"deployments": struct{}{},
|
"deployments": struct{}{},
|
||||||
"limitranges": struct{}{},
|
"limitranges": struct{}{},
|
||||||
|
|
@ -65,6 +66,7 @@ var (
|
||||||
"horizontalpodautoscalers": struct{}{},
|
"horizontalpodautoscalers": struct{}{},
|
||||||
}
|
}
|
||||||
availableCollectors = map[string]func(registry prometheus.Registerer, kubeClient clientset.Interface, namespace string){
|
availableCollectors = map[string]func(registry prometheus.Registerer, kubeClient clientset.Interface, namespace string){
|
||||||
|
"componentstatuses": collectors.RegisterComponentStatusCollector,
|
||||||
"cronjobs": collectors.RegisterCronJobCollector,
|
"cronjobs": collectors.RegisterCronJobCollector,
|
||||||
"daemonsets": collectors.RegisterDaemonSetCollector,
|
"daemonsets": collectors.RegisterDaemonSetCollector,
|
||||||
"deployments": collectors.RegisterDeploymentCollector,
|
"deployments": collectors.RegisterDeploymentCollector,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue