Created
December 27, 2017 00:15
-
-
Save jameshartig/924a38a47f99b9c561cf5863e6b9019a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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