Skip to content

Instantly share code, notes, and snippets.

@jameshartig
Created December 27, 2017 00:15
Show Gist options
  • Save jameshartig/924a38a47f99b9c561cf5863e6b9019a to your computer and use it in GitHub Desktop.
Save jameshartig/924a38a47f99b9c561cf5863e6b9019a to your computer and use it in GitHub Desktop.
package corednslmetric
import (
"fmt"
"log"
"net"
"net/http"
"bitbucket.org/levenlabs/llib/lmetric"
"github.com/coredns/coredns/plugin/metrics"
"github.com/gogo/protobuf/proto"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
dto "github.com/prometheus/client_model/go"
)
// Metrics wraps a prometheus.Metrics to expose lmetric metrics as well
type Metrics struct {
*metrics.Metrics
ln net.Listener
}
// Name implements the Handler interface.
func (m *Metrics) Name() string { return "lmetric" }
// Listen sets up a listener
func (m *Metrics) Listen() error {
ln, err := net.Listen("tcp", m.Metrics.Addr)
if err != nil {
log.Printf("[ERROR] Failed to start lmetric listener: %s", err)
return err
}
m.ln = ln
gatherers := prometheus.Gatherers{
lmetric.NewPrometheus(lmetric.TagMetrics()),
lmetric.NewPrometheus(lmetric.DefaultMetrics),
// since coredns has a vendor folder, the registery has different path and
// so none of the imports match up so we have to do this hacky thing
prometheus.GathererFunc(func() ([]*dto.MetricFamily, error) {
fs, err := m.Metrics.Reg.Gather()
if err != nil {
return nil, err
}
nfs := make([]*dto.MetricFamily, len(fs))
for i := range fs {
b, err := proto.Marshal(fs[i])
if err != nil {
return nil, fmt.Errorf("error marshalling coredns-style MetricFamily: %v", err)
}
nfs[i] = new(dto.MetricFamily)
if err = proto.Unmarshal(b, nfs[i]); err != nil {
return nil, fmt.Errorf("error unmarshalling coredns-style MetricFamily: %v", err)
}
}
return nfs, nil
}),
}
mux := http.NewServeMux()
mux.Handle("/metrics", promhttp.HandlerFor(gatherers, promhttp.HandlerOpts{
// we do this ourselves, and all gzip libraries are too stupid to
// realize when something is being double compressed
DisableCompression: true,
}))
go func() {
http.Serve(ln, mux)
}()
return nil
}
// Close closes the listener.
func (m *Metrics) Close() error {
if m.ln != nil {
return m.ln.Close()
}
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment