From b3d79f59e5b89dfd38bc41ca3780de2f0e6bce5d Mon Sep 17 00:00:00 2001 From: Kelly Kane Date: Mon, 26 Jan 2026 08:03:03 -0800 Subject: [PATCH] Add metadata for response Type and Class to Log. (#7806) --- plugin/log/README.md | 13 +++++++++++++ plugin/log/log.go | 13 +++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/plugin/log/README.md b/plugin/log/README.md index 52dd9d798..5c3ebc511 100644 --- a/plugin/log/README.md +++ b/plugin/log/README.md @@ -94,6 +94,19 @@ Each of these logs will be outputted with `log.Infof`, so a typical example look [INFO] [::1]:50759 - 29008 "A IN example.org. udp 41 false 4096" NOERROR qr,rd,ra,ad 68 0.037990251s ~~~ +## Additional metadata + +The log plugin adds the following metadata to allow for granular differentiation of NOERROR denial vs success messages. These are mapped from `plugin/pkg/response/classify.go` and `plugin/pkg/response/typify.go`. + +* `{/log/class}`: success, denial +* `{/log/type}`: NODATA, NXDOMAIN, NOERROR + +~~~ corefile +. { + log . "{proto} Request: {name} {type} {/log/class} {/log/type}" +} +~~~ + ## Examples Log all requests to stdout diff --git a/plugin/log/log.go b/plugin/log/log.go index 8a3575fd3..37ecc3084 100644 --- a/plugin/log/log.go +++ b/plugin/log/log.go @@ -6,6 +6,7 @@ import ( "time" "github.com/coredns/coredns/plugin" + "github.com/coredns/coredns/plugin/metadata" "github.com/coredns/coredns/plugin/pkg/dnstest" clog "github.com/coredns/coredns/plugin/pkg/log" "github.com/coredns/coredns/plugin/pkg/replacer" @@ -35,13 +36,21 @@ func (l Logger) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) rrw := dnstest.NewRecorder(w) rc, err := plugin.NextOrFailure(l.Name(), l.Next, ctx, rrw, r) + tpe, _ := response.Typify(rrw.Msg, time.Now().UTC()) + metadata.SetValueFunc(ctx, "log/type", func() string { + return tpe.String() + }) + + class := response.Classify(tpe) + metadata.SetValueFunc(ctx, "log/class", func() string { + return class.String() + }) + // If we don't set up a class in config, the default "all" will be added // and we shouldn't have an empty rule.Class. _, ok := rule.Class[response.All] var ok1 bool if !ok { - tpe, _ := response.Typify(rrw.Msg, time.Now().UTC()) - class := response.Classify(tpe) _, ok1 = rule.Class[class] } if ok || ok1 {