-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from castai/create-scraper
Initialize project
- Loading branch information
Showing
26 changed files
with
2,256 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
name: Build | ||
|
||
on: | ||
push: | ||
branches: | ||
- main | ||
release: | ||
types: | ||
- published | ||
pull_request: | ||
branches: | ||
- main | ||
|
||
jobs: | ||
build: | ||
name: Build | ||
runs-on: ubuntu-20.04 | ||
steps: | ||
|
||
- name: Checkout | ||
uses: actions/checkout@v4 | ||
|
||
- name: Setup Go | ||
uses: actions/setup-go@v5 | ||
with: | ||
go-version: 1.22 | ||
|
||
|
||
- name: Get release tag | ||
if: github.event_name == 'release' | ||
run: echo "RELEASE_TAG=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV | ||
|
||
- name: Build Go binary amd64 | ||
run: go build -ldflags "-s -w -X main.GitCommit=$GITHUB_SHA -X main.GitRef=$GITHUB_REF -X main.Version=${RELEASE_TAG:-commit-$GITHUB_SHA}" -o bin/gpu-metrics-exporter-amd64 ./cmd/main.go | ||
env: | ||
GOOS: linux | ||
GOARCH: amd64 | ||
CGO_ENABLED: 0 | ||
|
||
- name: Build Go binary arm64 | ||
run: go build -ldflags "-s -w -X main.GitCommit=$GITHUB_SHA -X main.GitRef=$GITHUB_REF -X main.Version=${RELEASE_TAG:-commit-$GITHUB_SHA}" -o bin/gpu-metrics-exporter-arm64 ./cmd/main.go | ||
env: | ||
GOOS: linux | ||
GOARCH: arm64 | ||
CGO_ENABLED: 0 | ||
|
||
- name: Test | ||
run: go test -race ./... | ||
|
||
# - name: Set up QEMU | ||
# uses: docker/setup-qemu-action@v3 | ||
|
||
# - name: Set up Docker Buildx | ||
# uses: docker/setup-buildx-action@v3 | ||
|
||
# - name: Login to GitHub Container Registry | ||
# uses: docker/login-action@v2 | ||
# with: | ||
# registry: ghcr.io | ||
# username: ${{ github.actor }} | ||
# password: ${{ secrets.GITHUB_TOKEN }} | ||
|
||
# - name: Build and push PR | ||
# if: ${{ github.event_name == 'pull_request' }} | ||
# uses: docker/build-push-action@v5 | ||
# with: | ||
# context: . | ||
# platforms: linux/arm64,linux/amd64 | ||
# file: ./Dockerfile | ||
# push: true | ||
# tags: ghcr.io/castai/gpu-metrics-exporter/gpu-metrics-exporter:${{ github.sha }} | ||
|
||
# - name: Build and push main | ||
# if: ${{ github.event_name != 'pull_request' && github.event_name != 'release' }} | ||
# uses: docker/build-push-action@v5 | ||
# with: | ||
# context: . | ||
# platforms: linux/arm64,linux/amd64 | ||
# file: ./Dockerfile | ||
# push: true | ||
# tags: ghcr.io/castai/egressd/egressd:${{ github.sha }} | ||
|
||
# - name: Build and push release (egressd collector) | ||
# uses: docker/build-push-action@v5 | ||
# with: | ||
# context: . | ||
# push: true | ||
# platforms: linux/arm64,linux/amd64 | ||
# file: ./Dockerfile | ||
# tags: | | ||
# ghcr.io/castai/gpu-metrics-exporter/gpu-metrics-exporter:${{ env.RELEASE_TAG }} | ||
# ghcr.io/castai/gpu-metrics-exporter/gpu-metrics-exporter:latest |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
name: golangci-lint | ||
on: | ||
pull_request: | ||
permissions: | ||
contents: read | ||
jobs: | ||
golangci: | ||
name: lint | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: actions/setup-go@v5 | ||
with: | ||
go-version: 1.22.0 | ||
- name: golangci-lint | ||
uses: golangci/golangci-lint-action@v4 | ||
with: | ||
args: --timeout=5m |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
bin | ||
coverage.txt | ||
.vscode |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
linters-settings: | ||
golint: | ||
min-confidence: 0 | ||
gomnd: | ||
settings: | ||
mnd: | ||
# don't include the "operation" and "assign" | ||
checks: [argument,case,condition,return] | ||
govet: | ||
# shadow is marked as experimental feature, skip it for now. | ||
check-shadowing: false | ||
settings: | ||
printf: | ||
funcs: | ||
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof | ||
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf | ||
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf | ||
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf | ||
lll: | ||
line-length: 200 | ||
maligned: | ||
suggest-new: true | ||
misspell: | ||
locale: US | ||
revive: | ||
rules: | ||
- name: redefines-builtin-id | ||
disabled: true | ||
- name: nested-structs | ||
disabled: true | ||
gci: | ||
sections: | ||
- standard | ||
- default | ||
- prefix(github.com/castai) | ||
linters: | ||
disable-all: true | ||
enable: | ||
- dogsled | ||
- errcheck | ||
- gofmt | ||
- revive | ||
- goprintffuncname | ||
- gosimple | ||
- gosec | ||
- govet | ||
- ineffassign | ||
- lll | ||
- misspell | ||
- nakedret | ||
- exportloopref | ||
- staticcheck | ||
- stylecheck | ||
- typecheck | ||
- unconvert | ||
- unused | ||
- whitespace | ||
- errname | ||
- dupword | ||
- gci | ||
- containedctx | ||
- durationcheck | ||
- errorlint | ||
issues: | ||
# Excluding configuration per-path, per-linter, per-text and per-source | ||
exclude-rules: | ||
- path: _test\.go | ||
linters: | ||
- gomnd | ||
- bodyclose | ||
- gosec | ||
- linters: | ||
- gosec | ||
# Ignored gosec G107 rule because of many false positives. It states that `http.Get(url)` must not contain a variable. | ||
text: G107 | ||
- linters: | ||
- unparam | ||
# ignoring error where function always receives same value - mostly in tests | ||
text: "always receives" | ||
- linters: | ||
- revive | ||
# tolerate code where errors are returned as if-return | ||
text: "redundant if ...; err != nil check, just return error instead." | ||
run: | ||
skip-dirs: | ||
- gen | ||
- e2e |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
with-expecter: true | ||
dir: 'mock/{{replace .InterfaceDirRelative "internal" "" 1}}' | ||
packages: | ||
"github.com/castai/gpu-metrics-exporter/internal/exporter": | ||
interfaces: | ||
Exporter: | ||
Scraper: | ||
MetricMapper: | ||
HttpClient: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
FROM gcr.io/distroless/static-debian11:nonroot | ||
ARG TARGETARCH | ||
COPY bin/gpu-metrics-exporter-$TARGETARCH /usr/local/bin/gpu-metrics-exporter | ||
CMD ["gpu-metrics-exporter"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
.PHONY: lint | ||
lint: check-lint-dependencies | ||
golangci-lint run ./... | ||
|
||
.PHONY: fix-lint-lint | ||
fix-lint: check-lint-dependencies | ||
golangci-lint run ./... --fix | ||
|
||
.PHONY: build | ||
build: | ||
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags "-s -w" -o bin/gpu-metrics-exporter-amd64 ./cmd/main.go | ||
GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -ldflags "-s -w" -o bin/gpu-metrics-exporter-arm64 ./cmd/main.go | ||
docker buildx build --push --platform=linux/amd64,linux/arm64 -t $(TAG) . | ||
|
||
.PHONY: generate | ||
generate: | ||
go generate ./... | ||
|
||
SHELL := /bin/bash | ||
.PHONY: run | ||
run: | ||
go run ./cmd/main.go | ||
|
||
.PHONY: test | ||
test: | ||
go test ./... -race -coverprofile=coverage.txt -covermode=atomic | ||
|
||
.PHONY: gen-proto | ||
gen-proto: check-proto-dependencies | ||
protoc pb/metrics.proto --go_out=paths=source_relative:. | ||
|
||
.PHONY: check-lint-dependencies | ||
check-lint-dependencies: | ||
@which golangci-lint > /dev/null || (echo "golangci-lint not found, please install it" && exit 1) | ||
|
||
.PHONY: check-proto-dependencies | ||
check-proto-dependencies: | ||
@which protoc > /dev/null || (echo "protoc not found, please install it" && exit 1) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
package main | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"fmt" | ||
"net/http" | ||
"os" | ||
"os/signal" | ||
"syscall" | ||
"time" | ||
|
||
"github.com/sirupsen/logrus" | ||
"k8s.io/apimachinery/pkg/labels" | ||
"k8s.io/apimachinery/pkg/selection" | ||
"k8s.io/client-go/kubernetes" | ||
"k8s.io/client-go/tools/clientcmd" | ||
"k8s.io/client-go/util/flowcontrol" | ||
|
||
"github.com/castai/gpu-metrics-exporter/internal/config" | ||
"github.com/castai/gpu-metrics-exporter/internal/exporter" | ||
"github.com/castai/gpu-metrics-exporter/internal/server" | ||
) | ||
|
||
func main() { | ||
log := logrus.New() | ||
|
||
cfg, err := config.GetFromEnvironment() | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
logLevel, err := logrus.ParseLevel(cfg.LogLevel) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
log.SetLevel(logLevel) | ||
|
||
if err := run(cfg, log); err != nil && !errors.Is(err, context.Canceled) { | ||
log.Fatal(err) | ||
} | ||
} | ||
|
||
func run(cfg *config.Config, log logrus.FieldLogger) error { | ||
mux := server.NewServerMux(log) | ||
|
||
srv := &http.Server{ | ||
Addr: fmt.Sprintf(":%d", cfg.HTTPListenPort), | ||
Handler: mux, | ||
ReadHeaderTimeout: 3 * time.Second, | ||
} | ||
|
||
ctx, cancel := context.WithCancel(context.Background()) | ||
defer cancel() | ||
|
||
go func() { | ||
stopper := make(chan os.Signal, 1) | ||
signal.Notify(stopper, os.Interrupt, syscall.SIGTERM, syscall.SIGINT) | ||
<-stopper | ||
|
||
ctx, shutdownCancel := context.WithTimeout(context.Background(), 10*time.Second) | ||
defer shutdownCancel() | ||
if err := srv.Shutdown(ctx); err != nil { | ||
log.Errorf("http server shutdown: %v", err) | ||
} | ||
|
||
cancel() | ||
}() | ||
|
||
clientset, err := newKubernetesClientset(cfg) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
labelSelector, err := selectorFromMap(cfg.DCGMLabels) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
scraper := exporter.NewScraper(&http.Client{}, log) | ||
mapper := exporter.NewMapper() | ||
ex := exporter.NewExporter(exporter.Config{ | ||
ExportInterval: cfg.ExportInterval, | ||
Selector: labelSelector.String(), | ||
DCGMExporterPort: cfg.DCGMPort, | ||
DCGMExporterPath: cfg.DCGMMetricsEndpoint, | ||
Enabled: true, | ||
}, clientset, log, scraper, mapper) | ||
|
||
go func() { | ||
if err := ex.Start(ctx); err != nil && !errors.Is(err, context.Canceled) { | ||
log.Errorf("exporter stopped with error %v", err) | ||
cancel() | ||
} | ||
}() | ||
|
||
return srv.ListenAndServe() | ||
} | ||
|
||
func newKubernetesClientset(cfg *config.Config) (*kubernetes.Clientset, error) { | ||
config, err := clientcmd.BuildConfigFromFlags("", cfg.KubeConfigPath) | ||
if err != nil { | ||
return nil, err | ||
} | ||
config.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(float32(10), 25) | ||
|
||
clientset, err := kubernetes.NewForConfig(config) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return clientset, nil | ||
} | ||
|
||
func selectorFromMap(labelMap map[string]string) (labels.Selector, error) { | ||
selector := labels.NewSelector() | ||
var requirements labels.Requirements | ||
|
||
for label, value := range labelMap { | ||
req, err := labels.NewRequirement(label, selection.Equals, []string{value}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
requirements = append(requirements, *req) | ||
} | ||
|
||
return selector.Add(requirements...), nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
//go:generate go run github.com/vektra/mockery/[email protected] --all | ||
package mockery |
Oops, something went wrong.