func New(config Config) (*Collector, error) {
	if config.K8sClient == nil {
		return nil, microerror.Maskf(invalidConfigError, "%T.K8sClient must not be empty", config)
	}
	if config.Logger == nil {
		return nil, microerror.Maskf(invalidConfigError, "%T.Logger must not be empty", config)
	}
	if config.TCPClient == nil {
		return nil, microerror.Maskf(invalidConfigError, "%T.TCPClient must not be empty", config)
	}
	if config.UDPClient == nil {
		return nil, microerror.Maskf(invalidConfigError, "%T.UDPClient must not be empty", config)
	}
	if len(config.Hosts) == 0 {
		return nil, microerror.Maskf(invalidConfigError, "%T.Host must not be empty", config)
	}
	if len(config.Service) == 0 {
		return nil, microerror.Maskf(invalidConfigError, "%T.Service must not be empty", config)
	}
	var err error
	var tcpLatencyHistogramVec *histogramvec.HistogramVec
	{
		c := histogramvec.Config{
			BucketLimits: prometheus.ExponentialBuckets(bucketStart, bucketFactor, numBuckets),
		}
		tcpLatencyHistogramVec, err = histogramvec.New(c)
		if err != nil {
			return nil, microerror.Mask(err)
		}
	}
	var udpLatencyHistogramVec *histogramvec.HistogramVec
	{
		c := histogramvec.Config{
			BucketLimits: prometheus.ExponentialBuckets(bucketStart, bucketFactor, numBuckets),
		}
		udpLatencyHistogramVec, err = histogramvec.New(c)
		if err != nil {
			return nil, microerror.Mask(err)
		}
	}
	errorCount := prometheus.NewCounter(prometheus.CounterOpts{
		Name: prometheus.BuildFQName(namespace, "", "error_total"),
		Help: "Total number of internal errors.",
	})
	resolveErrorCount := prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Name: prometheus.BuildFQName(namespace, "", "resolve_error_total"),
			Help: "Total number of errors resolving hosts.",
		},
		[]string{"proto", "host"},
	)
	prometheus.MustRegister(errorCount)
	prometheus.MustRegister(resolveErrorCount)
	collector := &Collector{
		k8sClient: config.K8sClient,
		logger:    config.Logger,
		tcpClient: config.TCPClient,
		udpClient: config.UDPClient,
		disableTCPCheck: config.DisableTCPCheck,
		hosts:           config.Hosts,
		service:         config.Service,
		tcpLatencyHistogramVec: tcpLatencyHistogramVec,
		tcpLatencyHistogramDesc: prometheus.NewDesc(
			prometheus.BuildFQName(namespace, "", "tcp_latency_seconds"),
			"Histogram of latency of TCP DNS resolutions.",
			[]string{"host"},
			nil,
		),
		udpLatencyHistogramVec: udpLatencyHistogramVec,
		udpLatencyHistogramDesc: prometheus.NewDesc(
			prometheus.BuildFQName(namespace, "", "udp_latency_seconds"),
			"Histogram of latency of UDP DNS resolutions.",
			[]string{"host"},
			nil,
		),
		errorCount:        errorCount,
		resolveErrorCount: resolveErrorCount,
	}
	return collector, nil
}
New creates a Collector, given a Config.
package dns
import (
	"context"
	"fmt"
	"sync"
	"time"
	"github.com/giantswarm/exporterkit/histogramvec"
	"github.com/giantswarm/microerror"
	"github.com/giantswarm/micrologger"
	dnsclient "github.com/miekg/dns"
	"github.com/prometheus/client_golang/prometheus"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
)
const (
	namespace = "dns"
	bucketStart  = 0.001
	bucketFactor = 2
	numBuckets   = 15
)
type Config struct {
	K8sClient kubernetes.Interface
	Logger    micrologger.Logger
	TCPClient *dnsclient.Client
	UDPClient *dnsclient.Client
	DisableTCPCheck bool
	Hosts           []string
	Service         string
}
type Collector struct {
	k8sClient kubernetes.Interface
	logger    micrologger.Logger
	tcpClient *dnsclient.Client
	udpClient *dnsclient.Client
	disableTCPCheck bool
	hosts           []string
	service         string
	tcpLatencyHistogramVec  *histogramvec.HistogramVec
	tcpLatencyHistogramDesc *prometheus.Desc
	udpLatencyHistogramVec  *histogramvec.HistogramVec
	udpLatencyHistogramDesc *prometheus.Desc
	errorCount        prometheus.Counter
	resolveErrorCount *prometheus.CounterVec
}