File: trace.go

package info (click to toggle)
dnss 0.1.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 368 kB
  • sloc: sh: 237; makefile: 6
file content (112 lines) | stat: -rw-r--r-- 2,570 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// Package trace extends golang.org/x/net/trace.
package trace

import (
	"fmt"
	"strconv"
	"strings"

	"blitiri.com.ar/go/log"
	"github.com/miekg/dns"

	nettrace "blitiri.com.ar/go/dnss/internal/nettrace"
)

// A Trace represents an active request.
type Trace struct {
	family string
	title  string
	t      nettrace.Trace
}

// New trace.
func New(family, title string) *Trace {
	t := &Trace{family, title, nettrace.New(family, title)}

	// The default for max events is 10, which is a bit short for our uses.
	// Expand it to 30 which should be large enough to keep most of the
	// traces.
	t.t.SetMaxEvents(30)
	return t
}

// Printf adds this message to the trace's log.
func (t *Trace) Printf(format string, a ...interface{}) {
	t.t.Printf(format, a...)
}

func (t *Trace) lprintf(n int, format string, a ...interface{}) {
	t.t.Printf(format, a...)

	// If -v=3, also log to the main log.
	if log.V(3) {
		log.Log(log.Debug, n+1, "%s %s: %s", t.family, t.title,
			quote(fmt.Sprintf(format, a...)))
	}
}

// Errorf adds this message to the trace's log, with an error level.
func (t *Trace) Errorf(format string, a ...interface{}) error {
	// Note we can't just call t.Error here, as it breaks caller logging.
	err := fmt.Errorf(format, a...)
	t.t.SetError()
	t.t.Printf("error: %v", err)

	log.Log(log.Info, 1, "%s %s: error: %s", t.family, t.title,
		quote(err.Error()))
	return err
}

// Error marks the trace as having seen an error, and also logs it to the
// trace's log.
func (t *Trace) Error(err error) error {
	t.t.SetError()
	t.t.Printf("error: %v", err)

	log.Log(log.Info, 1, "%s %s: error: %s", t.family, t.title,
		quote(err.Error()))

	return err
}

// Finish the trace. It should not be changed after this is called.
func (t *Trace) Finish() {
	t.t.Finish()
}

////////////////////////////////////////////////////////////
// DNS specific extensions
//

// Question adds the given question to the trace.
func (t *Trace) Question(qs []dns.Question) {
	if log.V(1) {
		t.lprintf(1, questionsToString(qs))
	}
}

func questionsToString(qs []dns.Question) string {
	var s []string
	for _, q := range qs {
		s = append(s, fmt.Sprintf("(%s %s %s)", q.Name,
			dns.TypeToString[q.Qtype], dns.ClassToString[q.Qclass]))
	}
	return "Q: " + strings.Join(s, " ; ")
}

// Answer adds the given DNS answer to the trace.
func (t *Trace) Answer(m *dns.Msg) {
	if !log.V(1) {
		return
	}

	t.lprintf(1, m.MsgHdr.String())
	for _, rr := range m.Answer {
		t.lprintf(1, rr.String())
	}
}

func quote(s string) string {
	qs := strconv.Quote(s)
	return qs[1 : len(qs)-1]
}