diff --git a/cmd/containerd/command/main.go b/cmd/containerd/command/main.go index 21967a17b..54e420e3a 100644 --- a/cmd/containerd/command/main.go +++ b/cmd/containerd/command/main.go @@ -30,6 +30,7 @@ import ( "github.com/containerd/containerd/defaults" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/log" + "github.com/containerd/containerd/metrics" "github.com/containerd/containerd/mount" "github.com/containerd/containerd/services/server" srvconfig "github.com/containerd/containerd/services/server/config" @@ -218,6 +219,7 @@ can be used and modified as necessary as a custom configuration.` serve(ctx, l, server.ServeDebug) } if config.Metrics.Address != "" { + metrics.Register() l, err := net.Listen("tcp", config.Metrics.Address) if err != nil { return errors.Wrapf(err, "failed to get listener for metrics endpoint") diff --git a/metrics/buildinfo.go b/metrics/buildinfo.go new file mode 100644 index 000000000..3121a423d --- /dev/null +++ b/metrics/buildinfo.go @@ -0,0 +1,50 @@ +/* + Copyright The containerd Authors. + + 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 metrics + +import ( + "github.com/containerd/containerd/version" + goMetrics "github.com/docker/go-metrics" + "github.com/prometheus/client_golang/prometheus" +) + +func newBuildInfoCollector(ns *goMetrics.Namespace) *Collector { + return &Collector{ + ns: ns, + m: metric{ + name: "build_info", + help: "Build information on containerd", + unit: goMetrics.Total, + vt: prometheus.CounterValue, + labels: []string{ + "version", + "revision", + }, + getValues: func() []value { + return []value{ + { + l: []string{ + version.Version, + version.Revision, + }, + v: float64(1), + }, + } + }, + }, + } +} diff --git a/metrics/metrics.go b/metrics/metrics.go new file mode 100644 index 000000000..4afa23b2f --- /dev/null +++ b/metrics/metrics.go @@ -0,0 +1,72 @@ +/* + Copyright The containerd Authors. + + 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 metrics + +import ( + goMetrics "github.com/docker/go-metrics" + "github.com/prometheus/client_golang/prometheus" +) + +// Collector provides the ability to collect generic metrics and export +// them in the prometheus format +type Collector struct { + ns *goMetrics.Namespace + m metric +} + +type metric struct { + name string + help string + unit goMetrics.Unit + vt prometheus.ValueType + labels []string + // getValues returns the value and labels for the data + getValues func() []value +} + +type value struct { + v float64 + l []string +} + +// Describe prometheus metrics +func (c *Collector) Describe(ch chan<- *prometheus.Desc) { + m := c.m + ch <- c.ns.NewDesc(m.name, m.help, m.unit, m.labels...) +} + +// Collect prometheus metrics +func (c *Collector) Collect(ch chan<- prometheus.Metric) { + m := c.m + for _, v := range m.getValues() { + ch <- prometheus.MustNewConstMetric( + c.ns.NewDesc(m.name, m.help, m.unit, m.labels...), + m.vt, + v.v, + v.l..., + ) + } +} + +// Register a prometheus namespace for generic metrics +func Register() { + ns := goMetrics.NewNamespace("containerd", "", nil) + + c := newBuildInfoCollector(ns) + ns.Add(c) + goMetrics.Register(ns) +}