Skip to content

Commit

Permalink
feat(logger): new opentelemetry logger (#912)
Browse files Browse the repository at this point in the history
* new opentelemetry logger
* set minimum go version to 1.22
  • Loading branch information
dmachard authored Dec 22, 2024
1 parent 15360f3 commit b366bfe
Show file tree
Hide file tree
Showing 24 changed files with 608 additions and 57 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/bench-go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
strategy:
matrix:
os-version: [ 'ubuntu-latest' ]
go-version: [ '1.21', '1.22', '1.23' ]
go-version: [ '1.22', '1.23' ]
runs-on: ${{ matrix.os-version }}

steps:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:

strategy:
matrix:
go-version: ['1.21', '1.22', '1.23']
go-version: ['1.22', '1.23']

steps:
- uses: actions/checkout@v4
Expand All @@ -50,7 +50,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
go-version: ['1.21', '1.22', '1.23']
go-version: ['1.22', '1.23']
goos: [linux, freebsd, darwin, windows]
exclude:
- { os: macos-latest, goos: linux }
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/testing-go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ jobs:
strategy:
matrix:
os-version: [ 'ubuntu-24.04' ]
go-version: [ '1.21', '1.22', '1.23' ]
go-version: [ '1.22', '1.23' ]
package:
- '.'
- 'pkgconfig'
Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<p align="center">
<img src="https://goreportcard.com/badge/github.com/dmachard/go-dns-collector" alt="Go Report"/>
<img src="https://img.shields.io/badge/go%20version-min%201.21-green" alt="Go version"/>
<img src="https://img.shields.io/badge/go%20tests-521-green" alt="Go tests"/>
<img src="https://img.shields.io/badge/go%20version-min%201.22-green" alt="Go version"/>
<img src="https://img.shields.io/badge/go%20tests-527-green" alt="Go tests"/>
<img src="https://img.shields.io/badge/go%20bench-21-green" alt="Go bench"/>
<img src="https://img.shields.io/badge/go%20lines-32844-green" alt="Go lines"/>
<img src="https://img.shields.io/badge/go%20lines-33484-green" alt="Go lines"/>
</p>

<p align="center">
Expand Down Expand Up @@ -56,6 +56,7 @@
- [`File`](docs/loggers/logger_file.md) with automatic rotation and compression
- *Provide metrics and API*
- [`Prometheus`](docs/loggers/logger_prometheus.md) exporter
- [`OpenTelemetry`](docs/loggers/logger_opentelemetry.md) tracing dns
- [`Statsd`](docs/loggers/logger_statsd.md) support
- [`REST API`](docs/loggers/logger_restapi.md) with [swagger](https://generator.swagger.io/?url=https://raw.githubusercontent.com/dmachard/go-dnscollector/main/docs/swagger.yml) to search DNS domains
- *Send to remote host with generic transport protocol*
Expand Down
32 changes: 15 additions & 17 deletions dnsutils/dnsmessage.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,10 @@ import (
)

var (
DNSQuery = "QUERY"
DNSQueryQuiet = "Q"
DNSReply = "REPLY"
DNSReplyQuiet = "R"
PdnsDirectives = regexp.MustCompile(`^powerdns-*`)
GeoIPDirectives = regexp.MustCompile(`^geoip-*`)
SuspiciousDirectives = regexp.MustCompile(`^suspicious-*`)
PublicSuffixDirectives = regexp.MustCompile(`^publixsuffix-*`)
ExtractedDirectives = regexp.MustCompile(`^extracted-*`)
ReducerDirectives = regexp.MustCompile(`^reducer-*`)
MachineLearningDirectives = regexp.MustCompile(`^ml-*`)
FilteringDirectives = regexp.MustCompile(`^filtering-*`)
RawTextDirective = regexp.MustCompile(`^ *\{.*\}`)
ATagsDirectives = regexp.MustCompile(`^atags*`)
DNSQuery = "QUERY"
DNSQueryQuiet = "Q"
DNSReply = "REPLY"
DNSReplyQuiet = "R"
)

type DNSAnswer struct {
Expand Down Expand Up @@ -112,7 +102,7 @@ type DNSTap struct {
QueryZone string `json:"query-zone"`
}

type PowerDNS struct {
type CollectorPowerDNS struct {
Tags []string `json:"tags"`
OriginalRequestSubnet string `json:"original-request-subnet"`
AppliedPolicy string `json:"applied-policy"`
Expand All @@ -129,6 +119,10 @@ type PowerDNS struct {
DeviceID string `json:"device-id"`
}

type LoggerOpenTelemetry struct {
TraceID string `json:"trace-id"`
}

type TransformDNSGeo struct {
City string `json:"city"`
Continent string `json:"continent"`
Expand Down Expand Up @@ -209,8 +203,9 @@ type DNSMessage struct {
DNS DNS `json:"dns"`
EDNS DNSExtended `json:"edns"`
DNSTap DNSTap `json:"dnstap"`
PowerDNS *CollectorPowerDNS `json:"powerdns,omitempty"`
OpenTelemetry *LoggerOpenTelemetry `json:"opentelemetry,omitempty"`
Geo *TransformDNSGeo `json:"geoip,omitempty"`
PowerDNS *PowerDNS `json:"powerdns,omitempty"`
Suspicious *TransformSuspicious `json:"suspicious,omitempty"`
PublicSuffix *TransformPublicSuffix `json:"publicsuffix,omitempty"`
Extracted *TransformExtracted `json:"extracted,omitempty"`
Expand Down Expand Up @@ -264,14 +259,17 @@ func (dm *DNSMessage) Init() {
}

func (dm *DNSMessage) InitTransforms() {
// init transforms
dm.ATags = &TransformATags{}
dm.Filtering = &TransformFiltering{}
dm.MachineLearning = &TransformML{}
dm.Reducer = &TransformReducer{}
dm.Extracted = &TransformExtracted{}
dm.PublicSuffix = &TransformPublicSuffix{}
dm.Suspicious = &TransformSuspicious{}
dm.PowerDNS = &PowerDNS{}
dm.Geo = &TransformDNSGeo{}
dm.Relabeling = &TransformRelabeling{}
// init collectors & loggers
dm.PowerDNS = &CollectorPowerDNS{}
dm.OpenTelemetry = &LoggerOpenTelemetry{}
}
47 changes: 45 additions & 2 deletions dnsutils/dnsmessage_json_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func TestDnsMessage_Json_Collectors_Reference(t *testing.T) {
}{
{
collector: "powerdns",
dmRef: DNSMessage{PowerDNS: &PowerDNS{
dmRef: DNSMessage{PowerDNS: &CollectorPowerDNS{
OriginalRequestSubnet: "subnet",
AppliedPolicy: "basicrpz",
AppliedPolicyHit: "hit",
Expand Down Expand Up @@ -164,6 +164,49 @@ func TestDnsMessage_Json_Collectors_Reference(t *testing.T) {
}
}

func TestDnsMessage_Json_Loggers_Reference(t *testing.T) {
testcases := []struct {
logger string
dmRef DNSMessage
jsonRef string
}{
{
logger: "otel",
dmRef: DNSMessage{OpenTelemetry: &LoggerOpenTelemetry{
TraceID: "27c3e94ad6284eec9a50cfc5bd7384d6",
}},

jsonRef: `{
"opentelemetry": {
"trace-id": "27c3e94ad6284eec9a50cfc5bd7384d6"
}
}`,
},
}
for _, tc := range testcases {
t.Run(tc.logger, func(t *testing.T) {

tc.dmRef.Init()

var dmMap map[string]interface{}
err := json.Unmarshal([]byte(tc.dmRef.ToJSON()), &dmMap)
if err != nil {
t.Fatalf("could not unmarshal dm json: %s\n", err)
}

var refMap map[string]interface{}
err = json.Unmarshal([]byte(tc.jsonRef), &refMap)
if err != nil {
t.Fatalf("could not unmarshal ref json: %s\n", err)
}

if !reflect.DeepEqual(dmMap[tc.logger], refMap[tc.logger]) {
t.Errorf("json format different from reference, Get=%s Want=%s", dmMap[tc.logger], refMap[tc.logger])
}
})
}
}

func TestDnsMessage_Json_Transforms_Reference(t *testing.T) {

testcases := []struct {
Expand Down Expand Up @@ -558,7 +601,7 @@ func TestDnsMessage_JsonFlatten_Collectors_Reference(t *testing.T) {
}{
{
collector: "powerdns",
dm: DNSMessage{PowerDNS: &PowerDNS{
dm: DNSMessage{PowerDNS: &CollectorPowerDNS{
OriginalRequestSubnet: "subnet",
AppliedPolicy: "basicrpz",
AppliedPolicyHit: "hit",
Expand Down
36 changes: 36 additions & 0 deletions dnsutils/dnsmessage_text.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,40 @@ import (
"errors"
"fmt"
"log"
"regexp"
"strconv"
"strings"
"time"
)

var (
OtelDirectives = regexp.MustCompile(`^otel-*`)
PdnsDirectives = regexp.MustCompile(`^powerdns-*`)
GeoIPDirectives = regexp.MustCompile(`^geoip-*`)
SuspiciousDirectives = regexp.MustCompile(`^suspicious-*`)
PublicSuffixDirectives = regexp.MustCompile(`^publixsuffix-*`)
ExtractedDirectives = regexp.MustCompile(`^extracted-*`)
ReducerDirectives = regexp.MustCompile(`^reducer-*`)
MachineLearningDirectives = regexp.MustCompile(`^ml-*`)
FilteringDirectives = regexp.MustCompile(`^filtering-*`)
RawTextDirective = regexp.MustCompile(`^ *\{.*\}`)
ATagsDirectives = regexp.MustCompile(`^atags*`)
)

func (dm *DNSMessage) handleOpenTelemetryDirectives(directive string, s *strings.Builder) error {
if dm.OpenTelemetry == nil {
s.WriteString("-")
} else {
switch {
case directive == "otel-trace-id":
s.WriteString(dm.OpenTelemetry.TraceID)
default:
return errors.New(ErrorUnexpectedDirective + directive)
}
}
return nil
}

func (dm *DNSMessage) handleGeoIPDirectives(directive string, s *strings.Builder) error {
if dm.Geo == nil {
s.WriteString("-")
Expand Down Expand Up @@ -532,6 +561,13 @@ func (dm *DNSMessage) ToTextLine(format []string, fieldDelimiter string, fieldBo
s.WriteByte('-')
}

// more directives from loggers
case OtelDirectives.MatchString(directive):
err := dm.handleOpenTelemetryDirectives(directive, &s)
if err != nil {
return nil, err
}

// more directives from collectors
case PdnsDirectives.MatchString(directive):
err := dm.handlePdnsDirectives(directive, &s)
Expand Down
Loading

0 comments on commit b366bfe

Please sign in to comment.