Browse Source

Make query logging (globally) configurable

Ask Bjørn Hansen 9 years ago
parent
commit
7b5172f982
7 changed files with 36 additions and 220 deletions
  1. 5 2
      README.md
  2. 5 2
      config.go
  3. 8 0
      dns/geodns.conf.sample
  4. 13 1
      geodns.go
  5. 3 4
      querylog/querylog.go
  6. 0 207
      querylog/querylog_easyjson.go
  7. 2 4
      server.go

+ 5 - 2
README.md

@@ -144,10 +144,13 @@ with `max_hosts` 2 then .4 will be returned about 4 times more often than .1.
 ## Configuration file
 
 The geodns.conf file allows you to specify a specific directory for the GeoIP
-data files and enable posting metrics to StatHat. See the `geodns.conf.sample`
-file for example configuration.
+data files and other options. See the `geodns.conf.sample` file for example
+configuration.
+
+The global configuration file is not reloaded at runtime.
 
 Most of the configuration is "per zone" and done in the zone .json files.
+The zone configuration files are automatically reloaded when they change.
 
 ## Zone format
 

+ 5 - 2
config.go

@@ -25,6 +25,11 @@ type AppConfig struct {
 		User     string
 		Password string
 	}
+	QueryLog struct {
+		Path    string
+		MaxSize int
+		Keep    int
+	}
 }
 
 var Config = new(AppConfig)
@@ -50,8 +55,6 @@ func (conf *AppConfig) GeoIPDirectory() string {
 
 func configWatcher(fileName string) {
 
-	configReader(fileName)
-
 	watcher, err := fsnotify.NewWatcher()
 	if err != nil {
 		fmt.Println(err)

+ 8 - 0
dns/geodns.conf.sample

@@ -7,6 +7,14 @@
 ;; Directory containing the GeoIP .dat database files
 ;directory=/usr/local/share/GeoIP/
 
+[querylog]
+;; directory to save query logs; disabled if not specified
+path = log/queries.log
+;; max size per file in megabytes before rotating (default 200)
+; maxsize = 100
+;; keep up to this many rotated log files (default 1)
+; keep = 2
+
 [stathat]
 ;; Add an API key to send query counts and other metrics to stathat
 ;apikey=abc123

+ 13 - 1
geodns.go

@@ -29,6 +29,7 @@ import (
 	"strings"
 	"time"
 
+	"github.com/abh/geodns/querylog"
 	"github.com/pborman/uuid"
 )
 
@@ -95,7 +96,6 @@ func main() {
 	}
 
 	srv := Server{}
-	srv.SetQueryLogger("log/queries.log")
 
 	if len(*flagLogFile) > 0 {
 		logToFileOpen(*flagLogFile)
@@ -155,11 +155,23 @@ func main() {
 		}()
 	}
 
+	// load geodns.conf config
+	configReader(configFileName)
+
+	// load (and re-load) zone data
 	go configWatcher(configFileName)
 
 	metrics := NewMetrics()
 	go metrics.Updater()
 
+	if qlc := Config.QueryLog; len(qlc.Path) > 0 {
+		ql, err := querylog.NewFileLogger(qlc.Path, qlc.MaxSize, qlc.Keep)
+		if err != nil {
+			log.Fatalf("Could not start file query logger: %s", err)
+		}
+		srv.SetQueryLogger(ql)
+	}
+
 	if *flaginter == "*" {
 		addrs, _ := net.InterfaceAddrs()
 		ips := make([]string, 0)

+ 3 - 4
querylog/querylog.go

@@ -29,13 +29,12 @@ type FileLogger struct {
 	logger lumberjack.Logger
 }
 
-func NewFileLogger(filename string) (*FileLogger, error) {
+func NewFileLogger(filename string, maxsize int, keep int) (*FileLogger, error) {
 	fl := &FileLogger{}
 	fl.logger = lumberjack.Logger{
 		Filename:   filename,
-		MaxSize:    500, // megabytes
-		MaxBackups: 3,
-		MaxAge:     28, //days
+		MaxSize:    maxsize, // megabytes
+		MaxBackups: keep,
 	}
 	return fl, nil
 }

+ 0 - 207
querylog/querylog_easyjson.go

@@ -1,207 +0,0 @@
-// AUTOGENERATED FILE: easyjson marshaller/unmarshallers.
-
-package querylog
-
-import (
-	json "encoding/json"
-	jlexer "github.com/mailru/easyjson/jlexer"
-	jwriter "github.com/mailru/easyjson/jwriter"
-)
-
-var _ = json.RawMessage{} // suppress unused package warning
-
-func easyjson_320612c2_decode_github_com_abh_geodns_querylog_FileLogger(in *jlexer.Lexer, out *FileLogger) {
-	if in.IsNull() {
-		in.Skip()
-		return
-	}
-	in.Delim('{')
-	for !in.IsDelim('}') {
-		key := in.UnsafeString()
-		in.WantColon()
-		if in.IsNull() {
-			in.Skip()
-			in.WantComma()
-			continue
-		}
-		switch key {
-		default:
-			in.SkipRecursive()
-		}
-		in.WantComma()
-	}
-	in.Delim('}')
-}
-func easyjson_320612c2_encode_github_com_abh_geodns_querylog_FileLogger(out *jwriter.Writer, in FileLogger) {
-	out.RawByte('{')
-	first := true
-	_ = first
-	out.RawByte('}')
-}
-func (v FileLogger) MarshalJSON() ([]byte, error) {
-	w := jwriter.Writer{}
-	easyjson_320612c2_encode_github_com_abh_geodns_querylog_FileLogger(&w, v)
-	return w.Buffer.BuildBytes(), w.Error
-}
-func (v FileLogger) MarshalEasyJSON(w *jwriter.Writer) {
-	easyjson_320612c2_encode_github_com_abh_geodns_querylog_FileLogger(w, v)
-}
-func (v *FileLogger) UnmarshalJSON(data []byte) error {
-	r := jlexer.Lexer{Data: data}
-	easyjson_320612c2_decode_github_com_abh_geodns_querylog_FileLogger(&r, v)
-	return r.Error()
-}
-func (v *FileLogger) UnmarshalEasyJSON(l *jlexer.Lexer) {
-	easyjson_320612c2_decode_github_com_abh_geodns_querylog_FileLogger(l, v)
-}
-func easyjson_320612c2_decode_github_com_abh_geodns_querylog_Entry(in *jlexer.Lexer, out *Entry) {
-	if in.IsNull() {
-		in.Skip()
-		return
-	}
-	in.Delim('{')
-	for !in.IsDelim('}') {
-		key := in.UnsafeString()
-		in.WantColon()
-		if in.IsNull() {
-			in.Skip()
-			in.WantComma()
-			continue
-		}
-		switch key {
-		case "Time":
-			out.Time = int64(in.Int64())
-		case "Origin":
-			out.Origin = string(in.String())
-		case "Name":
-			out.Name = string(in.String())
-		case "Qtype":
-			out.Qtype = uint16(in.Uint16())
-		case "Rcode":
-			out.Rcode = int(in.Int())
-		case "Answers":
-			out.Answers = int(in.Int())
-		case "Targets":
-			in.Delim('[')
-			if !in.IsDelim(']') {
-				out.Targets = make([]string, 0, 4)
-			} else {
-				out.Targets = nil
-			}
-			for !in.IsDelim(']') {
-				var v1 string
-				v1 = string(in.String())
-				out.Targets = append(out.Targets, v1)
-				in.WantComma()
-			}
-			in.Delim(']')
-		case "LabelName":
-			out.LabelName = string(in.String())
-		case "RemoteAddr":
-			out.RemoteAddr = string(in.String())
-		case "ClientAddr":
-			out.ClientAddr = string(in.String())
-		case "HasECS":
-			out.HasECS = bool(in.Bool())
-		default:
-			in.SkipRecursive()
-		}
-		in.WantComma()
-	}
-	in.Delim('}')
-}
-func easyjson_320612c2_encode_github_com_abh_geodns_querylog_Entry(out *jwriter.Writer, in Entry) {
-	out.RawByte('{')
-	first := true
-	_ = first
-	if !first {
-		out.RawByte(',')
-	}
-	first = false
-	out.RawString("\"Time\":")
-	out.Int64(int64(in.Time))
-	if !first {
-		out.RawByte(',')
-	}
-	first = false
-	out.RawString("\"Origin\":")
-	out.String(string(in.Origin))
-	if !first {
-		out.RawByte(',')
-	}
-	first = false
-	out.RawString("\"Name\":")
-	out.String(string(in.Name))
-	if !first {
-		out.RawByte(',')
-	}
-	first = false
-	out.RawString("\"Qtype\":")
-	out.Uint16(uint16(in.Qtype))
-	if !first {
-		out.RawByte(',')
-	}
-	first = false
-	out.RawString("\"Rcode\":")
-	out.Int(int(in.Rcode))
-	if !first {
-		out.RawByte(',')
-	}
-	first = false
-	out.RawString("\"Answers\":")
-	out.Int(int(in.Answers))
-	if !first {
-		out.RawByte(',')
-	}
-	first = false
-	out.RawString("\"Targets\":")
-	out.RawByte('[')
-	for v2, v3 := range in.Targets {
-		if v2 > 0 {
-			out.RawByte(',')
-		}
-		out.String(string(v3))
-	}
-	out.RawByte(']')
-	if !first {
-		out.RawByte(',')
-	}
-	first = false
-	out.RawString("\"LabelName\":")
-	out.String(string(in.LabelName))
-	if !first {
-		out.RawByte(',')
-	}
-	first = false
-	out.RawString("\"RemoteAddr\":")
-	out.String(string(in.RemoteAddr))
-	if !first {
-		out.RawByte(',')
-	}
-	first = false
-	out.RawString("\"ClientAddr\":")
-	out.String(string(in.ClientAddr))
-	if !first {
-		out.RawByte(',')
-	}
-	first = false
-	out.RawString("\"HasECS\":")
-	out.Bool(bool(in.HasECS))
-	out.RawByte('}')
-}
-func (v Entry) MarshalJSON() ([]byte, error) {
-	w := jwriter.Writer{}
-	easyjson_320612c2_encode_github_com_abh_geodns_querylog_Entry(&w, v)
-	return w.Buffer.BuildBytes(), w.Error
-}
-func (v Entry) MarshalEasyJSON(w *jwriter.Writer) {
-	easyjson_320612c2_encode_github_com_abh_geodns_querylog_Entry(w, v)
-}
-func (v *Entry) UnmarshalJSON(data []byte) error {
-	r := jlexer.Lexer{Data: data}
-	easyjson_320612c2_decode_github_com_abh_geodns_querylog_Entry(&r, v)
-	return r.Error()
-}
-func (v *Entry) UnmarshalEasyJSON(l *jlexer.Lexer) {
-	easyjson_320612c2_decode_github_com_abh_geodns_querylog_Entry(l, v)
-}

+ 2 - 4
server.go

@@ -18,10 +18,8 @@ func NewServer() *Server {
 
 // Setup the QueryLogger. For now it only supports writing to a file (and all
 // zones get logged to the same file).
-func (srv *Server) SetQueryLogger(file string) error {
-	var err error
-	srv.queryLogger, err = querylog.NewFileLogger(file)
-	return err
+func (srv *Server) SetQueryLogger(logger querylog.QueryLogger) {
+	srv.queryLogger = logger
 }
 
 func (srv *Server) setupServerFunc(Zone *Zone) func(dns.ResponseWriter, *dns.Msg) {