diff --git a/apihandler.go b/apihandler.go index d48e598..3fb5872 100644 --- a/apihandler.go +++ b/apihandler.go @@ -5,6 +5,7 @@ package main import ( "crypto/tls" + "encoding/gob" "encoding/json" "fmt" "log" @@ -181,6 +182,33 @@ func APIcommand(conf *Config) func(w http.ResponseWriter, r *http.Request) { // Status: "stopping", // Msg: "Daemon was happy, but now winding down", // } + + case "export-greylist-dns-tapir": + // exportGreylistDnsTapir(w, r, conf.TemData) + td := conf.TemData + td.mu.RLock() + defer td.mu.RUnlock() + + greylist, ok := td.Lists["greylist"]["dns-tapir"] + if !ok { + resp.Error = true + resp.ErrorMsg = "Greylist 'dns-tapir' not found" + return + } + log.Printf("Found dns-tapir greylist: %v", greylist) + + w.Header().Set("Content-Type", "application/octet-stream") + w.Header().Set("Content-Disposition", "attachment; filename=greylist-dns-tapir.gob") + + encoder := gob.NewEncoder(w) + err := encoder.Encode(greylist) + if err != nil { + log.Printf("Error encoding greylist: %v", err) + resp.Error = true + resp.ErrorMsg = err.Error() + return + } + default: resp.ErrorMsg = fmt.Sprintf("Unknown command: %s", cp.Command) resp.Error = true @@ -243,6 +271,22 @@ func APIdebug(conf *Config) func(w http.ResponseWriter, r *http.Request) { resp.Msg = fmt.Sprintf("Zone %s is unknown", dp.Zone) } + case "mqtt-stats": + log.Printf("TEM debug MQTT stats") + resp.MqttStats = td.MqttEngine.Stats() + + case "reaper-stats": + log.Printf("TEM debug reaper stats") + resp.ReaperStats = make(map[string]map[time.Time][]string) + for SrcName, list := range td.Lists["greylist"] { + resp.ReaperStats[SrcName] = make(map[time.Time][]string) + for ts, items := range list.ReaperData { + for _, item := range items { + resp.ReaperStats[SrcName][ts] = append(resp.ReaperStats[SrcName][ts], item.Name) + } + } + } + case "colourlists": log.Printf("TEM debug white/black/grey lists") resp.Lists = map[string]map[string]*tapir.WBGlist{} @@ -315,6 +359,7 @@ func walkRoutes(router *mux.Router, address string) { // In practice APIdispatcher doesn't need a termination signal, as it will // just sit inside http.ListenAndServe, but we keep it for symmetry. func APIdispatcher(conf *Config, done <-chan struct{}) { + gob.Register(tapir.WBGlist{}) // Must register the type for gob encoding router := SetupRouter(conf) walkRoutes(router, viper.GetString("apiserver.address")) diff --git a/lists.go b/lists.go index e044e43..152d057 100644 --- a/lists.go +++ b/lists.go @@ -63,8 +63,8 @@ func (td *TemData) Greylisted(name string) bool { if _, exists := list.Names[name]; exists { return true } - case "trie": - return list.Trie.Search(name) != nil + // case "trie": + // return list.Trie.Search(name) != nil default: log.Fatalf("Unknown greylist format %s", list.Format) } diff --git a/logging.go b/logging.go new file mode 100644 index 0000000..81465cb --- /dev/null +++ b/logging.go @@ -0,0 +1,90 @@ +/* + * Johan Stenstam, johan.stenstam@internetstiftelsen.se + */ + +package main + +import ( + "fmt" + "log" + "os" + + "github.com/spf13/viper" + "gopkg.in/natefinch/lumberjack.v2" +) + +func SetupLogging(conf *Config) { + logfile := viper.GetString("log.file") + + if logfile != "" { + log.SetOutput(&lumberjack.Logger{ + Filename: logfile, + MaxSize: 20, + MaxBackups: 3, + MaxAge: 14, + }) + fmt.Printf("TEM standard logging to: %s\n", logfile) + } else { + TEMExiter("Error: standard log (key log.file) not specified") + } + + logfile = viper.GetString("policy.logfile") + if logfile != "" { + f, err := os.OpenFile(logfile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) + if err != nil { + TEMExiter("error opening TEM policy logfile '%s': %v", logfile, err) + } + + conf.Loggers.Policy = log.New(f, "policy: ", log.Lshortfile) + conf.Loggers.Policy.SetOutput(&lumberjack.Logger{ + Filename: logfile, + MaxSize: 20, + MaxBackups: 3, + MaxAge: 14, + }) + fmt.Printf("TEM policy logging to: %s\n", logfile) + } else { + log.Println("No policy logfile specified, using default") + conf.Loggers.Policy = log.Default() + } + + logfile = viper.GetString("dnsengine.logfile") + if logfile != "" { + f, err := os.OpenFile(logfile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) + if err != nil { + TEMExiter("error opening TEM dnsengine logfile '%s': %v", logfile, err) + } + + conf.Loggers.Dnsengine = log.New(f, "dnsengine: ", log.Lshortfile) + conf.Loggers.Dnsengine.SetOutput(&lumberjack.Logger{ + Filename: logfile, + MaxSize: 20, + MaxBackups: 3, + MaxAge: 14, + }) + fmt.Printf("TEM dnsengine logging to: %s\n", logfile) + } else { + log.Println("No dnsengine logfile specified, using default") + conf.Loggers.Dnsengine = log.Default() + } + + logfile = viper.GetString("mqtt.logfile") + if logfile != "" { + f, err := os.OpenFile(logfile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) + if err != nil { + TEMExiter("error opening TEM MQTT logfile '%s': %v", logfile, err) + } + + conf.Loggers.Mqtt = log.New(f, "mqtt: ", log.Lshortfile) + conf.Loggers.Mqtt.SetOutput(&lumberjack.Logger{ + Filename: logfile, + MaxSize: 20, + MaxBackups: 3, + MaxAge: 14, + }) + fmt.Printf("TEM MQTT logging to: %s\n", logfile) + } else { + log.Println("No MQTT logfile specified, using default") + conf.Loggers.Mqtt = log.Default() + } +}