Skip to content

Commit 9015949

Browse files
committed
Initial commit
0 parents  commit 9015949

File tree

9 files changed

+489
-0
lines changed

9 files changed

+489
-0
lines changed

.github/workflows/release.yml

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
8+
jobs:
9+
build:
10+
name: Build and Release
11+
runs-on: ubuntu-latest
12+
13+
strategy:
14+
matrix:
15+
goos: [linux, darwin]
16+
goarch: [amd64, arm64]
17+
exclude:
18+
- goos: darwin
19+
goarch: arm64
20+
21+
steps:
22+
- name: Checkout code
23+
uses: actions/checkout@v4 # Updated to v4
24+
25+
- name: Set up Go
26+
uses: actions/setup-go@v5 # Updated to v5
27+
with:
28+
go-version: '^1.23'
29+
30+
- name: Build Go app
31+
env:
32+
GOOS: ${{ matrix.goos }}
33+
GOARCH: ${{ matrix.goarch }}
34+
run: |
35+
CGO_ENABLED=0 go build -o ./dns-exporter-${{ matrix.goos }}-${{ matrix.goarch }} --ldflags '-w -s -extldflags "-static"' .
36+
37+
- name: List files
38+
run: ls -lh
39+
40+
- name: Upload artifacts
41+
uses: actions/upload-artifact@v4 # Updated to v4
42+
with:
43+
name: dns-exporter-${{ matrix.goos }}-${{ matrix.goarch }}
44+
path: ./dns-exporter-${{ matrix.goos }}-${{ matrix.goarch }}
45+
46+
release:
47+
needs: build
48+
runs-on: ubuntu-latest
49+
steps:
50+
- name: Checkout code
51+
uses: actions/checkout@v4 # Updated to v4
52+
53+
- name: Download all artifacts
54+
uses: actions/download-artifact@v4 # Updated to v4
55+
56+
- name: List all downloaded artifacts
57+
run: ls -la
58+
59+
- name: Create GitHub Release
60+
uses: softprops/action-gh-release@v1
61+
if: startsWith(github.ref, 'refs/tags/')
62+
with:
63+
files: |
64+
./dns-exporter-*/*
65+
env:
66+
GITHUB_TOKEN: ${{ secrets.RELEASE_GITHUB_TOKEN }}

.gitignore

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# If you prefer the allow list template instead of the deny list, see community template:
2+
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
3+
#
4+
# Binaries for programs and plugins
5+
*.exe
6+
*.exe~
7+
*.dll
8+
*.so
9+
*.dylib
10+
11+
# Test binary, built with `go test -c`
12+
*.test
13+
14+
# Output of the go coverage tool, specifically when used with LiteIDE
15+
*.out
16+
17+
# Dependency directories (remove the comment below to include it)
18+
# vendor/
19+
20+
# Go workspace file
21+
go.work
22+
go.work.sum
23+
24+
# env file
25+
.env

Dockerfile

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
FROM golang:1.21.0 as builder
2+
3+
WORKDIR /app
4+
5+
COPY go.* /app
6+
COPY main.go /app
7+
8+
RUN CGO_ENABLED=0 GOOS=linux go build -o ./dns-exporter --ldflags '-extldflags "-static"' .
9+
10+
FROM scratch as runner
11+
12+
WORKDIR /app
13+
14+
COPY --from=builder /app/dns-exporter .
15+
EXPOSE 8080
16+
ENTRYPOINT ["/app/dns-exporter"]

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Denys Lemeshko
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# DNS Exporter for Prometheus
2+
3+
## Overview
4+
DNS Exporter is a Prometheus exporter that queries DNS records and exposes metrics related to query performance and success status.
5+
6+
This project was created as a result of issues with **pdnsd**, which caches DNS queries on hosts. The goal was to have a lightweight exporter to directly verify its operation on each server.
7+
8+
## Features
9+
- Supports querying multiple DNS records
10+
- Configurable DNS server
11+
- Uses `miekg/dns` library for DNS resolution
12+
- Prometheus metrics for monitoring query time, success rate, and last check timestamp
13+
- Configurable worker pool for parallel querying
14+
- Graceful timeout handling for DNS requests
15+
16+
## Installation
17+
18+
### Prerequisites
19+
- Go 1.18+
20+
- Prometheus server
21+
22+
### Build
23+
```sh
24+
# Clone the repository
25+
git clone https://github.com/wwwlde/dns-exporter.git
26+
cd dns-exporter
27+
28+
# Build the binary
29+
go build -o ./dns-exporter --ldflags '-extldflags "-static"' .
30+
```
31+
32+
### Run
33+
```sh
34+
./dns-exporter --config example.yaml --listen :8080 --timeout 1s --workers 5
35+
```
36+
37+
## Configuration
38+
The exporter requires a YAML configuration file specifying the DNS queries:
39+
40+
```yaml
41+
domains:
42+
- domain: "example.com"
43+
record_type: "A"
44+
- domain: "example.org"
45+
record_type: "MX"
46+
- domain: "google.com"
47+
record_type: "CNAME"
48+
dns_server: "127.0.0.1:53"
49+
```
50+
51+
## Prometheus Metrics
52+
The exporter exposes the following metrics at `/metrics`:
53+
54+
| Metric | Description |
55+
|--------|-------------|
56+
| `dnsexp_dns_query_time_seconds` | Time taken for the DNS query (seconds) |
57+
| `dnsexp_dns_query_success` | 1 if query was successful, 0 otherwise |
58+
| `dnsexp_dns_last_check_timestamp` | Timestamp of the last DNS query attempt |
59+
60+
## Example Prometheus Configuration
61+
Add the following job to your `prometheus.yml`:
62+
63+
```yaml
64+
scrape_configs:
65+
- job_name: 'dns_exporter'
66+
static_configs:
67+
- targets: ['localhost:8080']
68+
```
69+
70+
## License
71+
MIT License
72+
73+
## Author
74+
Denys Lemeshko - [GitHub](https://github.com/wwwlde)

example.yaml

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
domains:
3+
- domain: "example.com"
4+
record_type: "A"
5+
- domain: "google.com"
6+
record_type: "MX"
7+
- domain: "openai.com"
8+
record_type: "A"
9+
dns_server: "127.0.0.1:53"

go.mod

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
module dns-checker
2+
3+
go 1.23.5
4+
5+
require (
6+
github.com/miekg/dns v1.1.63
7+
github.com/prometheus/client_golang v1.20.5
8+
github.com/sirupsen/logrus v1.9.3
9+
github.com/spf13/cobra v1.8.1
10+
gopkg.in/yaml.v3 v3.0.1
11+
)
12+
13+
require (
14+
github.com/beorn7/perks v1.0.1 // indirect
15+
github.com/cespare/xxhash/v2 v2.3.0 // indirect
16+
github.com/inconshreveable/mousetrap v1.1.0 // indirect
17+
github.com/klauspost/compress v1.17.9 // indirect
18+
github.com/kr/text v0.2.0 // indirect
19+
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
20+
github.com/prometheus/client_model v0.6.1 // indirect
21+
github.com/prometheus/common v0.55.0 // indirect
22+
github.com/prometheus/procfs v0.15.1 // indirect
23+
github.com/spf13/pflag v1.0.5 // indirect
24+
golang.org/x/mod v0.18.0 // indirect
25+
golang.org/x/net v0.31.0 // indirect
26+
golang.org/x/sync v0.7.0 // indirect
27+
golang.org/x/sys v0.27.0 // indirect
28+
golang.org/x/tools v0.22.0 // indirect
29+
google.golang.org/protobuf v1.34.2 // indirect
30+
)

go.sum

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
2+
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
3+
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
4+
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
5+
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
6+
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
7+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
8+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
9+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
10+
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
11+
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
12+
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
13+
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
14+
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
15+
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
16+
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
17+
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
18+
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
19+
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
20+
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
21+
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
22+
github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY=
23+
github.com/miekg/dns v1.1.63/go.mod h1:6NGHfjhpmr5lt3XPLuyfDJi5AXbNIPM9PY6H6sF1Nfs=
24+
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
25+
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
26+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
27+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
28+
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
29+
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
30+
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
31+
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
32+
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
33+
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
34+
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
35+
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
36+
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
37+
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
38+
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
39+
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
40+
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
41+
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
42+
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
43+
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
44+
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
45+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
46+
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
47+
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
48+
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
49+
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
50+
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
51+
golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo=
52+
golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM=
53+
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
54+
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
55+
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
56+
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
57+
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
58+
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
59+
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
60+
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
61+
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
62+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
63+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
64+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
65+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
66+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
67+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

0 commit comments

Comments
 (0)