diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..0b463f3 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,40 @@ +name: release + +on: + push: + tags: + - 'v*' + +jobs: + release: + runs-on: ubuntu-latest + permissions: + packages: write + contents: write + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - uses: actions/setup-go@v4 + with: + go-version: '^1.22' + + - run: go mod tidy + - run: go test ./... + + - name: Login to ghcr.io + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@v4 + with: + distribution: goreleaser + version: latest + args: release --clean + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 0000000..ed236d1 --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,23 @@ +project_name: adguard-exporter +before: + hooks: + - go mod tidy +builds: + - env: [CGO_ENABLED=0] + goos: + - linux + - windows + - darwin + goarch: + - amd64 + - arm64 + main: main.go +archives: + - format: tar.gz +checksum: + name_template: 'checksums.txt' +dockers: + - dockerfile: Dockerfile + image_templates: + - ghcr.io/henrywhitaker3/adguard-exporter:{{ .Tag }} + - ghcr.io/henrywhitaker3/adguard-exporter:latest diff --git a/Dockerfile b/Dockerfile index a650936..03ebea8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,22 +1,7 @@ -ARG IMAGE=scratch -ARG OS=linux -ARG ARCH=amd64 +FROM scratch +WORKDIR / -FROM golang:1.21.5-alpine3.17 as builder +COPY adguard-exporter /adguard-exporter +USER 65532:65532 -WORKDIR /go/src/github.com/henrywhitaker3/adguard-exporter -COPY . . - -RUN apk --no-cache add git alpine-sdk - -RUN GO111MODULE=on go mod vendor -RUN CGO_ENABLED=0 GOOS=$OS GOARCH=$ARCH go build -ldflags '-s -w' -o binary ./ - -FROM $IMAGE - -LABEL name="pihole-exporter" - -WORKDIR /root/ -COPY --from=builder /go/src/github.com/henrywhitaker3/adguard-exporter/binary pihole-exporter - -CMD ["./pihole-exporter"] +ENTRYPOINT ["/adguard-exporter"] diff --git a/go.mod b/go.mod index 332123b..c92b7c9 100644 --- a/go.mod +++ b/go.mod @@ -2,8 +2,6 @@ module github.com/henrywhitaker3/adguard-exporter go 1.22 -toolchain go1.22.1 - require ( github.com/joho/godotenv v1.5.1 github.com/labstack/echo-contrib v0.16.0 diff --git a/internal/adguard/types.go b/internal/adguard/types.go index 5272eac..077a12b 100644 --- a/internal/adguard/types.go +++ b/internal/adguard/types.go @@ -16,7 +16,7 @@ type Stats struct { BlockedSafesearchQueries int `json:"num_blocked_safesearch"` BlockedParentalQueries int `json:"num_blocked_parental"` AvgProcessingTime float32 `json:"avg_processing_time"` - TopQueriedDomains []map[string]int `json:"top_queired_domains"` + TopQueriedDomains []map[string]int `json:"top_queried_domains"` TopBlockedDomains []map[string]int `json:"top_blocked_domains"` TopClients []map[string]int `json:"top_clients"` TopUpstreamsResponses []map[string]int `json:"top_upstreams_responses"` diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go index fa33919..d6618e8 100644 --- a/internal/metrics/metrics.go +++ b/internal/metrics/metrics.go @@ -48,6 +48,31 @@ var ( Name: "avg_processing_time_seconds", Namespace: "adguard", }, []string{"server"}) + TopQueriedDomains = prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Name: "top_queried_domains", + Namespace: "adguard", + Help: "The number of queries for the top domains", + }, []string{"server", "domain"}) + TopBlockedDomains = prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Name: "top_blocked_domains", + Namespace: "adguard", + Help: "The number of blocked queries for the top domains", + }, []string{"server", "domain"}) + TopClients = prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Name: "top_clients", + Namespace: "adguard", + Help: "The number of queries for the top clients", + }, []string{"server", "client"}) + TopUpstreams = prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Name: "top_upstreams", + Namespace: "adguard", + Help: "The number of repsonses for the top upstream servers", + }, []string{"server", "upstream"}) + TopUpstreamsAvgTimes = prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Name: "top_upstreams_avg_response_time_seconds", + Namespace: "adguard", + Help: "The average response time for each of the top upstream servers", + }, []string{"server", "upstream"}) // DHCP DhcpEnabled = prometheus.NewGaugeVec(prometheus.GaugeOpts{ @@ -76,6 +101,11 @@ func Init() { prometheus.MustRegister(BlockedSafesearch) prometheus.MustRegister(BlockedSafebrowsing) prometheus.MustRegister(AvgProcessingTime) + prometheus.MustRegister(TopBlockedDomains) + prometheus.MustRegister(TopClients) + prometheus.MustRegister(TopQueriedDomains) + prometheus.MustRegister(TopUpstreams) + prometheus.MustRegister(TopUpstreamsAvgTimes) // Status prometheus.MustRegister(Running) diff --git a/internal/worker/worker.go b/internal/worker/worker.go index 507b814..fb3ba76 100644 --- a/internal/worker/worker.go +++ b/internal/worker/worker.go @@ -54,6 +54,32 @@ func collectStats(ctx context.Context, client *adguard.Client) { metrics.BlockedSafesearch.WithLabelValues(client.Url()).Set(float64(stats.BlockedSafesearchQueries)) metrics.BlockedSafebrowsing.WithLabelValues(client.Url()).Set(float64(stats.BlockedSafebrowsingQueries)) metrics.AvgProcessingTime.WithLabelValues(client.Url()).Set(float64(stats.AvgProcessingTime)) + + for _, c := range stats.TopClients { + for key, val := range c { + metrics.TopClients.WithLabelValues(client.Url(), key).Set(float64(val)) + } + } + for _, c := range stats.TopUpstreamsResponses { + for key, val := range c { + metrics.TopUpstreams.WithLabelValues(client.Url(), key).Set(float64(val)) + } + } + for _, c := range stats.TopQueriedDomains { + for key, val := range c { + metrics.TopQueriedDomains.WithLabelValues(client.Url(), key).Set(float64(val)) + } + } + for _, c := range stats.TopBlockedDomains { + for key, val := range c { + metrics.TopBlockedDomains.WithLabelValues(client.Url(), key).Set(float64(val)) + } + } + for _, c := range stats.TopUpstreamsAvgTimes { + for key, val := range c { + metrics.TopUpstreamsAvgTimes.WithLabelValues(client.Url(), key).Set(float64(val)) + } + } } func collectStatus(ctx context.Context, client *adguard.Client) {