Skip to content

Commit

Permalink
chore: switch to slog for logging (#182)
Browse files Browse the repository at this point in the history
Fixes #177
  • Loading branch information
agaffney authored Aug 1, 2024
1 parent 888411e commit b4d796c
Show file tree
Hide file tree
Showing 7 changed files with 239 additions and 179 deletions.
66 changes: 41 additions & 25 deletions cmd/cdnsd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package main
import (
"flag"
"fmt"
"log/slog"
"net/http"
_ "net/http/pprof"
"os"
Expand All @@ -18,7 +19,6 @@ import (
"github.com/blinklabs-io/cdnsd/internal/config"
"github.com/blinklabs-io/cdnsd/internal/dns"
"github.com/blinklabs-io/cdnsd/internal/indexer"
"github.com/blinklabs-io/cdnsd/internal/logging"
"github.com/blinklabs-io/cdnsd/internal/state"
"github.com/blinklabs-io/cdnsd/internal/version"
)
Expand All @@ -43,33 +43,38 @@ func main() {
os.Exit(1)
}

// Configure logging
logging.Setup()
logger := logging.GetLogger()
// Sync logger on exit
defer func() {
if err := logger.Sync(); err != nil {
// We don't actually care about the error here, but we have to do something
// to appease the linter
return
}
}()
// Configure logger
logLevel := slog.LevelInfo
if cfg.Logging.Debug {
logLevel = slog.LevelDebug
}
logger := slog.New(
slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
Level: logLevel,
}),
)
slog.SetDefault(logger)

logger.Info(
slog.Info(
fmt.Sprintf("cdnsd %s started", version.GetVersionString()),
)

// Load state
if err := state.GetState().Load(); err != nil {
logger.Fatalf("failed to load state: %s", err)
slog.Error(
fmt.Sprintf("failed to load state: %s", err),
)
os.Exit(1)
}

// Start debug listener
if cfg.Debug.ListenPort > 0 {
logger.Infof(
"starting debug listener on %s:%d",
cfg.Debug.ListenAddress,
cfg.Debug.ListenPort,
slog.Info(
fmt.Sprintf(
"starting debug listener on %s:%d",
cfg.Debug.ListenAddress,
cfg.Debug.ListenPort,
),
)
go func() {
err := http.ListenAndServe(
Expand All @@ -81,24 +86,35 @@ func main() {
nil,
)
if err != nil {
logger.Fatalf("failed to start debug listener: %s", err)
slog.Error(
fmt.Sprintf("failed to start debug listener: %s", err),
)
os.Exit(1)
}
}()
}

// Start indexer
if err := indexer.GetIndexer().Start(); err != nil {
logger.Fatalf("failed to start indexer: %s", err)
slog.Error(
fmt.Sprintf("failed to start indexer: %s", err),
)
os.Exit(1)
}

// Start DNS listener
logger.Infof(
"starting DNS listener on %s:%d",
cfg.Dns.ListenAddress,
cfg.Dns.ListenPort,
slog.Info(
fmt.Sprintf(
"starting DNS listener on %s:%d",
cfg.Dns.ListenAddress,
cfg.Dns.ListenPort,
),
)
if err := dns.Start(); err != nil {
logger.Fatalf("failed to start DNS listener: %s", err)
slog.Error(
fmt.Sprintf("failed to start DNS listener: %s", err),
)
os.Exit(1)
}

// Wait forever
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ require (
github.com/kelseyhightower/envconfig v1.4.0
github.com/miekg/dns v1.1.61
go.uber.org/automaxprocs v1.5.3
go.uber.org/zap v1.27.0
gopkg.in/yaml.v2 v2.4.0
)

Expand Down Expand Up @@ -40,6 +39,7 @@ require (
github.com/x448/float16 v0.8.4 // indirect
go.opencensus.io v0.22.5 // indirect
go.uber.org/multierr v1.10.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/crypto v0.25.0 // indirect
golang.org/x/mod v0.18.0 // indirect
golang.org/x/net v0.26.0 // indirect
Expand Down
9 changes: 3 additions & 6 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,8 @@ type Config struct {
}

type LoggingConfig struct {
Healthchecks bool `yaml:"healthchecks" envconfig:"LOGGING_HEALTHCHECKS"`
Level string `yaml:"level" envconfig:"LOGGING_LEVEL"`
QueryLog bool `yaml:"queryLog" envconfig:"LOGGING_QUERY_LOG"`
Debug bool `yaml:"debug" envconfig:"LOGGING_DEBUG"`
QueryLog bool `yaml:"queryLog" envconfig:"LOGGING_QUERY_LOG"`
}

type DnsConfig struct {
Expand Down Expand Up @@ -65,9 +64,7 @@ type StateConfig struct {
// Singleton config instance with default values
var globalConfig = &Config{
Logging: LoggingConfig{
Level: "info",
Healthchecks: false,
QueryLog: true,
QueryLog: true,
},
Dns: DnsConfig{
ListenAddress: "",
Expand Down
100 changes: 66 additions & 34 deletions internal/dns/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ package dns

import (
"fmt"
"log/slog"
"math/rand"
"net"
"os"
"strings"

"github.com/blinklabs-io/cdnsd/internal/config"
"github.com/blinklabs-io/cdnsd/internal/logging"
"github.com/blinklabs-io/cdnsd/internal/state"

"github.com/miekg/dns"
Expand Down Expand Up @@ -49,21 +50,25 @@ func Start() error {

func startListener(server *dns.Server) {
if err := server.ListenAndServe(); err != nil {
logging.GetLogger().Fatalf("failed to start DNS listener: %s", err)
slog.Error(
fmt.Sprintf("failed to start DNS listener: %s", err),
)
os.Exit(1)
}
}

func handleQuery(w dns.ResponseWriter, r *dns.Msg) {
logger := logging.GetLogger()
cfg := config.GetConfig()
m := new(dns.Msg)

if cfg.Logging.QueryLog {
for _, q := range r.Question {
logger.Infof("query: name: %s, type: %s, class: %s",
q.Name,
dns.Type(q.Qtype).String(),
dns.Class(q.Qclass).String(),
slog.Info(
fmt.Sprintf("query: name: %s, type: %s, class: %s",
q.Name,
dns.Type(q.Qtype).String(),
dns.Class(q.Qclass).String(),
),
)
}
}
Expand All @@ -74,7 +79,9 @@ func handleQuery(w dns.ResponseWriter, r *dns.Msg) {
strings.TrimSuffix(r.Question[0].Name, "."),
)
if err != nil {
logger.Errorf("failed to lookup records in state: %s", err)
slog.Error(
fmt.Sprintf("failed to lookup records in state: %s", err),
)
return
}
if records != nil {
Expand All @@ -83,14 +90,18 @@ func handleQuery(w dns.ResponseWriter, r *dns.Msg) {
for _, tmpRecord := range records {
tmpRR, err := stateRecordToDnsRR(tmpRecord)
if err != nil {
logger.Errorf("failed to convert state record to dns.RR: %s", err)
slog.Error(
fmt.Sprintf("failed to convert state record to dns.RR: %s", err),
)
return
}
m.Answer = append(m.Answer, tmpRR)
}
// Send response
if err := w.WriteMsg(m); err != nil {
logger.Errorf("failed to write response: %s", err)
slog.Error(
fmt.Sprintf("failed to write response: %s", err),
)
}
// We found our answer, to return from handler
return
Expand All @@ -101,10 +112,12 @@ func handleQuery(w dns.ResponseWriter, r *dns.Msg) {
r.Question[0].Name,
)
if err != nil {
logger.Errorf(
"failed to lookup nameservers for %s: %s",
r.Question[0].Name,
err,
slog.Error(
fmt.Sprintf(
"failed to lookup nameservers for %s: %s",
r.Question[0].Name,
err,
),
)
}
if nameservers != nil {
Expand All @@ -119,15 +132,21 @@ func handleQuery(w dns.ResponseWriter, r *dns.Msg) {
// Send failure response
m.SetRcode(r, dns.RcodeServerFailure)
if err := w.WriteMsg(m); err != nil {
logger.Errorf("failed to write response: %s", err)
slog.Error(
fmt.Sprintf("failed to write response: %s", err),
)
}
logger.Errorf("failed to query domain nameserver: %s", err)
slog.Error(
fmt.Sprintf("failed to query domain nameserver: %s", err),
)
return
} else {
copyResponse(r, resp, m)
// Send response
if err := w.WriteMsg(m); err != nil {
logger.Errorf("failed to write response: %s", err)
slog.Error(
fmt.Sprintf("failed to write response: %s", err),
)
}
return
}
Expand Down Expand Up @@ -161,7 +180,9 @@ func handleQuery(w dns.ResponseWriter, r *dns.Msg) {
}
// Send response
if err := w.WriteMsg(m); err != nil {
logger.Errorf("failed to write response: %s", err)
slog.Error(
fmt.Sprintf("failed to write response: %s", err),
)
}
// We found our answer, to return from handler
return
Expand All @@ -177,15 +198,21 @@ func handleQuery(w dns.ResponseWriter, r *dns.Msg) {
// Send failure response
m.SetRcode(r, dns.RcodeServerFailure)
if err := w.WriteMsg(m); err != nil {
logger.Errorf("failed to write response: %s", err)
slog.Error(
fmt.Sprintf("failed to write response: %s", err),
)
}
logger.Errorf("failed to query domain nameserver: %s", err)
slog.Error(
fmt.Sprintf("failed to query domain nameserver: %s", err),
)
return
} else {
copyResponse(r, resp, m)
// Send response
if err := w.WriteMsg(m); err != nil {
logger.Errorf("failed to write response: %s", err)
slog.Error(
fmt.Sprintf("failed to write response: %s", err),
)
}
return
}
Expand All @@ -194,7 +221,9 @@ func handleQuery(w dns.ResponseWriter, r *dns.Msg) {
// Return NXDOMAIN if we have no information about the requested domain or any of its parents
m.SetRcode(r, dns.RcodeNameError)
if err := w.WriteMsg(m); err != nil {
logger.Errorf("failed to write response: %s", err)
slog.Error(
fmt.Sprintf("failed to write response: %s", err),
)
}
}

Expand Down Expand Up @@ -243,7 +272,6 @@ func randomNameserverAddress(nameservers map[string][]net.IP) net.IP {
}

func doQuery(msg *dns.Msg, address string, recursive bool) (*dns.Msg, error) {
logger := logging.GetLogger()
// Default to a random fallback server if no address is specified
if address == "" {
address = randomFallbackServer()
Expand All @@ -252,22 +280,26 @@ func doQuery(msg *dns.Msg, address string, recursive bool) (*dns.Msg, error) {
if !strings.Contains(address, ":") {
address = address + `:53`
}
logger.Debugf(
"querying %s: %s",
address,
formatMessageQuestionSection(msg.Question),
slog.Debug(
fmt.Sprintf(
"querying %s: %s",
address,
formatMessageQuestionSection(msg.Question),
),
)
resp, err := dns.Exchange(msg, address)
if err != nil {
return nil, err
}
logger.Debugf(
"response: rcode=%s, authoritative=%v, authority=%s, answer=%s, extra=%s",
dns.RcodeToString[resp.Rcode],
resp.Authoritative,
formatMessageAnswerSection(resp.Ns),
formatMessageAnswerSection(resp.Answer),
formatMessageAnswerSection(resp.Extra),
slog.Debug(
fmt.Sprintf(
"response: rcode=%s, authoritative=%v, authority=%s, answer=%s, extra=%s",
dns.RcodeToString[resp.Rcode],
resp.Authoritative,
formatMessageAnswerSection(resp.Ns),
formatMessageAnswerSection(resp.Answer),
formatMessageAnswerSection(resp.Extra),
),
)
// Immediately return authoritative response
if resp.Authoritative {
Expand Down
Loading

0 comments on commit b4d796c

Please sign in to comment.