mirror of
https://github.com/RWejlgaard/octopus_exporter.git
synced 2026-07-04 22:06:17 +00:00
Compare commits
No commits in common. "00f1b29ab0435614f463ef2f462dcfb117c943f0" and "dd1e39769e8a86775f2c38f3edcba5b1c0e2babd" have entirely different histories.
00f1b29ab0
...
dd1e39769e
11 changed files with 44 additions and 208 deletions
25
.github/dependabot.yml
vendored
25
.github/dependabot.yml
vendored
|
|
@ -1,25 +0,0 @@
|
||||||
version: 2
|
|
||||||
updates:
|
|
||||||
- package-ecosystem: gomod
|
|
||||||
directory: /
|
|
||||||
schedule:
|
|
||||||
interval: weekly
|
|
||||||
open-pull-requests-limit: 5
|
|
||||||
groups:
|
|
||||||
go-deps:
|
|
||||||
patterns:
|
|
||||||
- "*"
|
|
||||||
|
|
||||||
- package-ecosystem: github-actions
|
|
||||||
directory: /
|
|
||||||
schedule:
|
|
||||||
interval: weekly
|
|
||||||
groups:
|
|
||||||
actions:
|
|
||||||
patterns:
|
|
||||||
- "*"
|
|
||||||
|
|
||||||
- package-ecosystem: docker
|
|
||||||
directory: /
|
|
||||||
schedule:
|
|
||||||
interval: weekly
|
|
||||||
9
.github/workflows/pr-check.yml
vendored
9
.github/workflows/pr-check.yml
vendored
|
|
@ -8,16 +8,11 @@ jobs:
|
||||||
test:
|
test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: actions/setup-go@v6
|
- uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version-file: go.mod
|
go-version-file: go.mod
|
||||||
|
|
||||||
- name: Test
|
- name: Test
|
||||||
run: go test -race ./...
|
run: go test -race ./...
|
||||||
|
|
||||||
- name: Lint
|
|
||||||
uses: golangci/golangci-lint-action@v9
|
|
||||||
with:
|
|
||||||
version: latest
|
|
||||||
|
|
|
||||||
13
.github/workflows/release.yml
vendored
13
.github/workflows/release.yml
vendored
|
|
@ -12,7 +12,7 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: "!startsWith(github.event.head_commit.message, 'chore:')"
|
if: "!startsWith(github.event.head_commit.message, 'chore:')"
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
|
|
@ -49,26 +49,23 @@ jobs:
|
||||||
echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT
|
echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v4
|
uses: docker/setup-qemu-action@v3
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v4
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
- name: Log in to DockerHub
|
- name: Log in to DockerHub
|
||||||
uses: docker/login-action@v4
|
uses: docker/login-action@v3
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
password: ${{ secrets.DOCKERHUB_PAT }}
|
password: ${{ secrets.DOCKERHUB_PAT }}
|
||||||
|
|
||||||
- name: Build and push
|
- name: Build and push
|
||||||
uses: docker/build-push-action@v7
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
push: true
|
push: true
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
build-args: |
|
|
||||||
VERSION=${{ steps.version.outputs.version }}
|
|
||||||
COMMIT=${{ github.sha }}
|
|
||||||
tags: |
|
tags: |
|
||||||
rwejlgaard/octopus_exporter:${{ steps.version.outputs.version }}
|
rwejlgaard/octopus_exporter:${{ steps.version.outputs.version }}
|
||||||
rwejlgaard/octopus_exporter:latest
|
rwejlgaard/octopus_exporter:latest
|
||||||
|
|
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -1,5 +1,2 @@
|
||||||
.env
|
.env
|
||||||
coverage.out
|
coverage.out
|
||||||
/octopus_exporter
|
|
||||||
*.test
|
|
||||||
*.out
|
|
||||||
|
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
version: "2"
|
|
||||||
|
|
||||||
run:
|
|
||||||
timeout: 5m
|
|
||||||
|
|
||||||
linters:
|
|
||||||
default: standard
|
|
||||||
enable:
|
|
||||||
- errcheck
|
|
||||||
- govet
|
|
||||||
- ineffassign
|
|
||||||
- staticcheck
|
|
||||||
- unused
|
|
||||||
- misspell
|
|
||||||
- bodyclose
|
|
||||||
- gocritic
|
|
||||||
- unconvert
|
|
||||||
- unparam
|
|
||||||
exclusions:
|
|
||||||
rules:
|
|
||||||
- path: _test\.go
|
|
||||||
linters:
|
|
||||||
- errcheck
|
|
||||||
|
|
@ -1,17 +1,12 @@
|
||||||
FROM golang:1.26-alpine AS builder
|
FROM golang:1.24-alpine AS builder
|
||||||
ARG VERSION=dev
|
|
||||||
ARG COMMIT=none
|
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY go.mod go.sum ./
|
COPY go.mod go.sum ./
|
||||||
RUN go mod download
|
RUN go mod download
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN CGO_ENABLED=0 go build \
|
RUN CGO_ENABLED=0 go build -o /octopus_exporter ./cmd/octopus_exporter
|
||||||
-ldflags "-s -w -X main.version=${VERSION} -X main.commit=${COMMIT}" \
|
|
||||||
-o /octopus_exporter ./cmd/octopus_exporter
|
|
||||||
|
|
||||||
FROM scratch
|
FROM scratch
|
||||||
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
|
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
|
||||||
COPY --from=builder /octopus_exporter /octopus_exporter
|
COPY --from=builder /octopus_exporter /octopus_exporter
|
||||||
USER 65534:65534
|
|
||||||
EXPOSE 9359
|
EXPOSE 9359
|
||||||
ENTRYPOINT ["/octopus_exporter"]
|
ENTRYPOINT ["/octopus_exporter"]
|
||||||
|
|
|
||||||
16
README.md
16
README.md
|
|
@ -34,18 +34,7 @@ Gas metrics are only exposed if a smart gas meter is found on the account.
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `octopus_account_balance_pence` | GraphQL | Account balance in pence (positive = credit, negative = debit) |
|
| `octopus_account_balance_pence` | GraphQL | Account balance in pence (positive = credit, negative = debit) |
|
||||||
|
|
||||||
### Exporter health
|
Metrics are updated every 60 seconds.
|
||||||
|
|
||||||
| Metric | Description |
|
|
||||||
|---|---|
|
|
||||||
| `octopus_up` | 1 if the last poll cycle completed without errors, 0 otherwise |
|
|
||||||
| `octopus_last_poll_timestamp` | Unix timestamp of the last completed poll cycle |
|
|
||||||
| `octopus_poll_errors_total` | Total number of collector errors across all poll cycles |
|
|
||||||
| `octopus_token_refreshes_total` | Total number of successful JWT token refreshes |
|
|
||||||
| `octopus_rate_limit_retries_total` | Total number of 429 rate-limit retries |
|
|
||||||
| `octopus_build_info{version,commit}` | Build metadata (always 1) |
|
|
||||||
|
|
||||||
Metrics are refreshed every `POLL_INTERVAL` (default 60 seconds).
|
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
|
|
@ -59,7 +48,6 @@ Metrics are refreshed every `POLL_INTERVAL` (default 60 seconds).
|
||||||
| `OCTOPUS_GAS_SERIAL` | No | Filter gas meter by serial number |
|
| `OCTOPUS_GAS_SERIAL` | No | Filter gas meter by serial number |
|
||||||
| `OCTOPUS_GAS_DEVICE_ID` | No | Use a specific gas smart device ID directly |
|
| `OCTOPUS_GAS_DEVICE_ID` | No | Use a specific gas smart device ID directly |
|
||||||
| `PORT` | No | Port to expose metrics on (default: `9359`) |
|
| `PORT` | No | Port to expose metrics on (default: `9359`) |
|
||||||
| `POLL_INTERVAL` | No | How often to poll Octopus APIs (Go duration, default: `60s`) |
|
|
||||||
|
|
||||||
If no filter variables are set, the exporter auto-discovers the first smart meter of each type found on the account. Use `OCTOPUS_MPAN` / `OCTOPUS_MPRN` to pin to a specific meter on accounts with multiple meters.
|
If no filter variables are set, the exporter auto-discovers the first smart meter of each type found on the account. Use `OCTOPUS_MPAN` / `OCTOPUS_MPRN` to pin to a specific meter on accounts with multiple meters.
|
||||||
|
|
||||||
|
|
@ -91,7 +79,7 @@ services:
|
||||||
|
|
||||||
## Running from source
|
## Running from source
|
||||||
|
|
||||||
Requires Go 1.24+.
|
Requires Go 1.22+.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
git clone https://github.com/rwejlgaard/octopus_exporter
|
git clone https://github.com/rwejlgaard/octopus_exporter
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ func executeWithRetry(makeReq func() (*http.Request, error)) ([]byte, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if resp.StatusCode == http.StatusTooManyRequests {
|
if resp.StatusCode == http.StatusTooManyRequests {
|
||||||
_ = resp.Body.Close()
|
resp.Body.Close()
|
||||||
if attempt == maxRetries {
|
if attempt == maxRetries {
|
||||||
return nil, errors.New("rate limited: max retries exceeded")
|
return nil, errors.New("rate limited: max retries exceeded")
|
||||||
}
|
}
|
||||||
|
|
@ -82,7 +82,7 @@ func executeWithRetry(makeReq func() (*http.Request, error)) ([]byte, error) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
raw, err := io.ReadAll(resp.Body)
|
raw, err := io.ReadAll(resp.Body)
|
||||||
_ = resp.Body.Close()
|
resp.Body.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,12 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"errors"
|
"errors"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"syscall"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
|
@ -17,10 +14,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
apiKey string
|
apiKey string
|
||||||
port string
|
port string
|
||||||
version = "dev"
|
|
||||||
commit = "none"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func mustEnv(key string) string {
|
func mustEnv(key string) string {
|
||||||
|
|
@ -46,24 +41,9 @@ func counter(name, help string) prometheus.Counter {
|
||||||
return prometheus.NewCounter(prometheus.CounterOpts{Name: name, Help: help})
|
return prometheus.NewCounter(prometheus.CounterOpts{Name: name, Help: help})
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseInterval(key string, def time.Duration) time.Duration {
|
|
||||||
v := os.Getenv(key)
|
|
||||||
if v == "" {
|
|
||||||
return def
|
|
||||||
}
|
|
||||||
d, err := time.ParseDuration(v)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("invalid %s=%q, falling back to %s: %v", key, v, def, err)
|
|
||||||
return def
|
|
||||||
}
|
|
||||||
return d
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
apiKey = mustEnv("OCTOPUS_API_KEY")
|
apiKey = mustEnv("OCTOPUS_API_KEY")
|
||||||
port = envOrDefault("PORT", "9359")
|
port = envOrDefault("PORT", "9359")
|
||||||
pollInterval := parseInterval("POLL_INTERVAL", 60*time.Second)
|
|
||||||
log.Printf("octopus_exporter %s (%s), poll interval %s", version, commit, pollInterval)
|
|
||||||
|
|
||||||
token, err := getKrakenToken(apiKey)
|
token, err := getKrakenToken(apiKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -111,24 +91,16 @@ func main() {
|
||||||
|
|
||||||
// Exporter health
|
// Exporter health
|
||||||
exporterUp := gauge("octopus_up", "1 if the last poll cycle completed without errors, 0 otherwise")
|
exporterUp := gauge("octopus_up", "1 if the last poll cycle completed without errors, 0 otherwise")
|
||||||
lastPollTimestamp := gauge("octopus_last_poll_timestamp", "Unix timestamp of the last completed poll cycle")
|
|
||||||
pollErrors := counter("octopus_poll_errors_total", "Total number of collector errors per poll cycle")
|
pollErrors := counter("octopus_poll_errors_total", "Total number of collector errors per poll cycle")
|
||||||
tokenRefreshCount := counter("octopus_token_refreshes_total", "Total number of successful JWT token refreshes")
|
tokenRefreshCount := counter("octopus_token_refreshes_total", "Total number of successful JWT token refreshes")
|
||||||
rateLimitRetries = counter("octopus_rate_limit_retries_total", "Total number of 429 rate-limit retries across all requests")
|
rateLimitRetries = counter("octopus_rate_limit_retries_total", "Total number of 429 rate-limit retries across all requests")
|
||||||
|
|
||||||
buildInfo := prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
|
||||||
Name: "octopus_build_info",
|
|
||||||
Help: "Build metadata exposed as a constant gauge (always 1).",
|
|
||||||
}, []string{"version", "commit"})
|
|
||||||
buildInfo.WithLabelValues(version, commit).Set(1)
|
|
||||||
|
|
||||||
toRegister := []prometheus.Collector{
|
toRegister := []prometheus.Collector{
|
||||||
elecDemand, elecLastRead,
|
elecDemand, elecLastRead,
|
||||||
elecConsumption, elecConsumptionInterval,
|
elecConsumption, elecConsumptionInterval,
|
||||||
elecUnitRate, elecStandingCharge,
|
elecUnitRate, elecStandingCharge,
|
||||||
accountBalance,
|
accountBalance,
|
||||||
exporterUp, lastPollTimestamp, pollErrors, tokenRefreshCount, rateLimitRetries,
|
exporterUp, pollErrors, tokenRefreshCount, rateLimitRetries,
|
||||||
buildInfo,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -151,23 +123,10 @@ func main() {
|
||||||
|
|
||||||
prometheus.MustRegister(toRegister...)
|
prometheus.MustRegister(toRegister...)
|
||||||
|
|
||||||
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
http.Handle("/metrics", promhttp.Handler())
|
||||||
defer stop()
|
|
||||||
|
|
||||||
mux := http.NewServeMux()
|
|
||||||
mux.Handle("/metrics", promhttp.Handler())
|
|
||||||
mux.HandleFunc("/healthz", func(w http.ResponseWriter, _ *http.Request) {
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
_, _ = w.Write([]byte("ok"))
|
|
||||||
})
|
|
||||||
srv := &http.Server{
|
|
||||||
Addr: ":" + port,
|
|
||||||
Handler: mux,
|
|
||||||
ReadHeaderTimeout: 5 * time.Second,
|
|
||||||
}
|
|
||||||
go func() {
|
go func() {
|
||||||
log.Printf("serving metrics on :%s/metrics", port)
|
log.Printf("serving metrics on :%s/metrics", port)
|
||||||
if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
if err := http.ListenAndServe(":"+port, nil); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
@ -204,10 +163,7 @@ func main() {
|
||||||
return fn(newT)
|
return fn(newT)
|
||||||
}
|
}
|
||||||
|
|
||||||
ticker := time.NewTicker(pollInterval)
|
for {
|
||||||
defer ticker.Stop()
|
|
||||||
|
|
||||||
poll := func() {
|
|
||||||
var (
|
var (
|
||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
failedAny atomic.Bool
|
failedAny atomic.Bool
|
||||||
|
|
@ -340,22 +296,7 @@ func main() {
|
||||||
} else {
|
} else {
|
||||||
exporterUp.Set(1)
|
exporterUp.Set(1)
|
||||||
}
|
}
|
||||||
lastPollTimestamp.Set(float64(time.Now().Unix()))
|
|
||||||
}
|
|
||||||
|
|
||||||
poll()
|
time.Sleep(60 * time.Second)
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
log.Println("shutdown signal received, draining HTTP server")
|
|
||||||
shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
||||||
defer cancel()
|
|
||||||
if err := srv.Shutdown(shutdownCtx); err != nil {
|
|
||||||
log.Printf("HTTP shutdown error: %v", err)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
case <-ticker.C:
|
|
||||||
poll()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
19
go.mod
19
go.mod
|
|
@ -1,18 +1,15 @@
|
||||||
module github.com/pez/octopus_exporter
|
module github.com/pez/octopus_exporter
|
||||||
|
|
||||||
go 1.24
|
go 1.22
|
||||||
|
|
||||||
require github.com/prometheus/client_golang v1.23.2
|
require github.com/prometheus/client_golang v1.19.1
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||||
github.com/kr/text v0.2.0 // indirect
|
github.com/prometheus/client_model v0.5.0 // indirect
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
github.com/prometheus/common v0.48.0 // indirect
|
||||||
github.com/prometheus/client_model v0.6.2 // indirect
|
github.com/prometheus/procfs v0.12.0 // indirect
|
||||||
github.com/prometheus/common v0.66.1 // indirect
|
golang.org/x/sys v0.17.0 // indirect
|
||||||
github.com/prometheus/procfs v0.16.1 // indirect
|
google.golang.org/protobuf v1.33.0 // indirect
|
||||||
go.yaml.in/yaml/v2 v2.4.2 // indirect
|
|
||||||
golang.org/x/sys v0.35.0 // indirect
|
|
||||||
google.golang.org/protobuf v1.36.8 // indirect
|
|
||||||
)
|
)
|
||||||
|
|
|
||||||
58
go.sum
58
go.sum
|
|
@ -1,46 +1,20 @@
|
||||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
|
||||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
|
||||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
|
||||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE=
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc=
|
||||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
|
||||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||||
github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
|
|
||||||
github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
|
|
||||||
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
|
|
||||||
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
|
|
||||||
github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs=
|
|
||||||
github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA=
|
|
||||||
github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=
|
|
||||||
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
|
|
||||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
|
||||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
|
||||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
|
||||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
|
||||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
|
||||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
|
||||||
go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
|
|
||||||
go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
|
|
||||||
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
|
|
||||||
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
|
||||||
google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc=
|
|
||||||
google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue