mirror of
https://github.com/coredns/coredns.git
synced 2025-10-27 00:04:15 -04:00
plugin/log - Support for Metadata (#2251)
* - add metadata support to Log * - adapt ctx after rebase
This commit is contained in:
committed by
John Belamaric
parent
35c5474660
commit
94c9aae323
@@ -1,10 +1,12 @@
|
||||
package replacer
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/coredns/coredns/plugin/metadata"
|
||||
"github.com/coredns/coredns/plugin/pkg/dnstest"
|
||||
"github.com/coredns/coredns/request"
|
||||
|
||||
@@ -21,6 +23,7 @@ type Replacer interface {
|
||||
}
|
||||
|
||||
type replacer struct {
|
||||
ctx context.Context
|
||||
replacements map[string]string
|
||||
emptyValue string
|
||||
}
|
||||
@@ -31,9 +34,10 @@ type replacer struct {
|
||||
// values into the replacer. rr may be nil if it is not
|
||||
// available. emptyValue should be the string that is used
|
||||
// in place of empty string (can still be empty string).
|
||||
func New(r *dns.Msg, rr *dnstest.Recorder, emptyValue string) Replacer {
|
||||
func New(ctx context.Context, r *dns.Msg, rr *dnstest.Recorder, emptyValue string) Replacer {
|
||||
req := request.Request{W: rr, Req: r}
|
||||
rep := replacer{
|
||||
ctx: ctx,
|
||||
replacements: map[string]string{
|
||||
"{type}": req.Type(),
|
||||
"{name}": req.Name(),
|
||||
@@ -43,6 +47,7 @@ func New(r *dns.Msg, rr *dnstest.Recorder, emptyValue string) Replacer {
|
||||
"{size}": strconv.Itoa(req.Len()),
|
||||
"{remote}": addrToRFC3986(req.IP()),
|
||||
"{port}": req.Port(),
|
||||
"{local}": addrToRFC3986(req.LocalIP()),
|
||||
},
|
||||
emptyValue: emptyValue,
|
||||
}
|
||||
@@ -71,23 +76,36 @@ func New(r *dns.Msg, rr *dnstest.Recorder, emptyValue string) Replacer {
|
||||
// Replace performs a replacement of values on s and returns
|
||||
// the string with the replaced values.
|
||||
func (r replacer) Replace(s string) string {
|
||||
// Header replacements - these are case-insensitive, so we can't just use strings.Replace()
|
||||
for strings.Contains(s, headerReplacer) {
|
||||
idxStart := strings.Index(s, headerReplacer)
|
||||
endOffset := idxStart + len(headerReplacer)
|
||||
idxEnd := strings.Index(s[endOffset:], "}")
|
||||
if idxEnd > -1 {
|
||||
placeholder := strings.ToLower(s[idxStart : endOffset+idxEnd+1])
|
||||
replacement := r.replacements[placeholder]
|
||||
if replacement == "" {
|
||||
replacement = r.emptyValue
|
||||
|
||||
// declare a function that replace based on header matching
|
||||
fscanAndReplace := func(s string, header string, replace func(string) string) string {
|
||||
b := strings.Builder{}
|
||||
for strings.Contains(s, header) {
|
||||
idxStart := strings.Index(s, header)
|
||||
endOffset := idxStart + len(header)
|
||||
idxEnd := strings.Index(s[endOffset:], "}")
|
||||
if idxEnd > -1 {
|
||||
placeholder := strings.ToLower(s[idxStart : endOffset+idxEnd+1])
|
||||
replacement := replace(placeholder)
|
||||
if replacement == "" {
|
||||
replacement = r.emptyValue
|
||||
}
|
||||
b.WriteString(s[:idxStart])
|
||||
b.WriteString(replacement)
|
||||
s = s[endOffset+idxEnd+1:]
|
||||
} else {
|
||||
break
|
||||
}
|
||||
s = s[:idxStart] + replacement + s[endOffset+idxEnd+1:]
|
||||
} else {
|
||||
break
|
||||
}
|
||||
b.WriteString(s)
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// Header replacements - these are case-insensitive, so we can't just use strings.Replace()
|
||||
s = fscanAndReplace(s, headerReplacer, func(placeholder string) string {
|
||||
return r.replacements[placeholder]
|
||||
})
|
||||
|
||||
// Regular replacements - these are easier because they're case-sensitive
|
||||
for placeholder, replacement := range r.replacements {
|
||||
if replacement == "" {
|
||||
@@ -96,6 +114,16 @@ func (r replacer) Replace(s string) string {
|
||||
s = strings.Replace(s, placeholder, replacement, -1)
|
||||
}
|
||||
|
||||
// Metadata label replacements
|
||||
s = fscanAndReplace(s, headerLabelReplacer, func(placeholder string) string {
|
||||
// label place holder has the format {/<label>}
|
||||
fm := metadata.ValueFunc(r.ctx, placeholder[len(headerLabelReplacer):len(placeholder)-1])
|
||||
if fm != nil {
|
||||
return fm()
|
||||
}
|
||||
return ""
|
||||
})
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
@@ -161,4 +189,7 @@ func addrToRFC3986(addr string) string {
|
||||
return addr
|
||||
}
|
||||
|
||||
const headerReplacer = "{>"
|
||||
const (
|
||||
headerReplacer = "{>"
|
||||
headerLabelReplacer = "{/"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user