mirror of
				https://github.com/coredns/coredns.git
				synced 2025-10-30 17:53:21 -04:00 
			
		
		
		
	After initial startup, see if prometheus is loaded and if so, register our metrics with it. Stop doing the init() func and just use the sync.Once so we don't double registrer our metrics.
		
			
				
	
	
		
			116 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			116 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package cache
 | |
| 
 | |
| import (
 | |
| 	"sync"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/coredns/coredns/plugin"
 | |
| 	"github.com/coredns/coredns/request"
 | |
| 
 | |
| 	"github.com/miekg/dns"
 | |
| 	"github.com/prometheus/client_golang/prometheus"
 | |
| 	"golang.org/x/net/context"
 | |
| )
 | |
| 
 | |
| // ServeDNS implements the plugin.Handler interface.
 | |
| func (c *Cache) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
 | |
| 	state := request.Request{W: w, Req: r}
 | |
| 
 | |
| 	qname := state.Name()
 | |
| 	qtype := state.QType()
 | |
| 	zone := plugin.Zones(c.Zones).Matches(qname)
 | |
| 	if zone == "" {
 | |
| 		return plugin.NextOrFailure(c.Name(), c.Next, ctx, w, r)
 | |
| 	}
 | |
| 
 | |
| 	do := state.Do() // TODO(): might need more from OPT record? Like the actual bufsize?
 | |
| 
 | |
| 	now := time.Now().UTC()
 | |
| 
 | |
| 	i, ttl := c.get(now, qname, qtype, do)
 | |
| 	if i != nil && ttl > 0 {
 | |
| 		resp := i.toMsg(r)
 | |
| 
 | |
| 		state.SizeAndDo(resp)
 | |
| 		resp, _ = state.Scrub(resp)
 | |
| 		w.WriteMsg(resp)
 | |
| 
 | |
| 		if c.prefetch > 0 {
 | |
| 			i.Freq.Update(c.duration, now)
 | |
| 		}
 | |
| 
 | |
| 		pct := 100
 | |
| 		if i.origTTL != 0 { // you'll never know
 | |
| 			pct = int(float64(ttl) / float64(i.origTTL) * 100)
 | |
| 		}
 | |
| 
 | |
| 		if c.prefetch > 0 && i.Freq.Hits() > c.prefetch && pct < c.percentage {
 | |
| 			// When prefetching we loose the item i, and with it the frequency
 | |
| 			// that we've gathered sofar. See we copy the frequencies info back
 | |
| 			// into the new item that was stored in the cache.
 | |
| 			prr := &ResponseWriter{ResponseWriter: w, Cache: c, prefetch: true}
 | |
| 			plugin.NextOrFailure(c.Name(), c.Next, ctx, prr, r)
 | |
| 
 | |
| 			if i1, _ := c.get(now, qname, qtype, do); i1 != nil {
 | |
| 				i1.Freq.Reset(now, i.Freq.Hits())
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		return dns.RcodeSuccess, nil
 | |
| 	}
 | |
| 
 | |
| 	crr := &ResponseWriter{ResponseWriter: w, Cache: c}
 | |
| 	return plugin.NextOrFailure(c.Name(), c.Next, ctx, crr, r)
 | |
| }
 | |
| 
 | |
| // Name implements the Handler interface.
 | |
| func (c *Cache) Name() string { return "cache" }
 | |
| 
 | |
| func (c *Cache) get(now time.Time, qname string, qtype uint16, do bool) (*item, int) {
 | |
| 	k := hash(qname, qtype, do)
 | |
| 
 | |
| 	if i, ok := c.ncache.Get(k); ok {
 | |
| 		cacheHits.WithLabelValues(Denial).Inc()
 | |
| 		return i.(*item), i.(*item).ttl(now)
 | |
| 	}
 | |
| 
 | |
| 	if i, ok := c.pcache.Get(k); ok {
 | |
| 		cacheHits.WithLabelValues(Success).Inc()
 | |
| 		return i.(*item), i.(*item).ttl(now)
 | |
| 	}
 | |
| 	cacheMisses.Inc()
 | |
| 	return nil, 0
 | |
| }
 | |
| 
 | |
| var (
 | |
| 	cacheSize = prometheus.NewGaugeVec(prometheus.GaugeOpts{
 | |
| 		Namespace: plugin.Namespace,
 | |
| 		Subsystem: "cache",
 | |
| 		Name:      "size",
 | |
| 		Help:      "The number of elements in the cache.",
 | |
| 	}, []string{"type"})
 | |
| 
 | |
| 	cacheCapacity = prometheus.NewGaugeVec(prometheus.GaugeOpts{
 | |
| 		Namespace: plugin.Namespace,
 | |
| 		Subsystem: "cache",
 | |
| 		Name:      "capacity",
 | |
| 		Help:      "The cache's capacity.",
 | |
| 	}, []string{"type"})
 | |
| 
 | |
| 	cacheHits = prometheus.NewCounterVec(prometheus.CounterOpts{
 | |
| 		Namespace: plugin.Namespace,
 | |
| 		Subsystem: "cache",
 | |
| 		Name:      "hits_total",
 | |
| 		Help:      "The count of cache hits.",
 | |
| 	}, []string{"type"})
 | |
| 
 | |
| 	cacheMisses = prometheus.NewCounter(prometheus.CounterOpts{
 | |
| 		Namespace: plugin.Namespace,
 | |
| 		Subsystem: "cache",
 | |
| 		Name:      "misses_total",
 | |
| 		Help:      "The count of cache misses.",
 | |
| 	})
 | |
| )
 | |
| 
 | |
| var once sync.Once
 |