From 6d193efd184edc10872f72fdf3162831f1a8fe39 Mon Sep 17 00:00:00 2001 From: mxssl Date: Sat, 9 Sep 2023 05:00:23 +0300 Subject: [PATCH] new billing api --- .github/workflows/release.yaml | 6 +- README.md | 12 +-- go.mod | 2 +- main.go | 101 ++++------------------- main_test.go | 93 ++++----------------- testdata/SelectelBillingRespExample.json | 45 ++-------- 6 files changed, 50 insertions(+), 209 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index b89e14a..f9f25ae 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -13,8 +13,6 @@ jobs: - uses: actions/checkout@v4 - name: golangci-lint uses: golangci/golangci-lint-action@v3 - with: - version: v1.48.0 docker-release: runs-on: ubuntu-latest @@ -33,11 +31,11 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-go@v4 with: - go-version: 1.19 + go-version: "1.20" - name: Run GoReleaser uses: goreleaser/goreleaser-action@v4 with: version: latest - args: release --rm-dist + args: release --clean env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/README.md b/README.md index 81e6f98..d55ab05 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Prometheus exporter для получения информации по билл Экспортер раз в час ходит по url `https://api.selectel.ru/v3/balances` с токеном в запросе, получает в json формате инфу по балансу средств на счете и отдает ее по url `/metrics` в формате prometheus. -Для работы экспортера нужно получить API [токен](https://my.selectel.ru/profile/apikeys): +Для работы экспортера нужно получить API [токен](https://my.selectel.ru/profile/apikeys) ## Как запустить @@ -19,7 +19,7 @@ version: '3' services: selectel_exporter: - image: mxssl/selectel-billing-exporter:1.0.0 + image: mxssl/selectel-billing-exporter:1.1.0 ports: - "6789:80" restart: always @@ -47,6 +47,7 @@ docker-compose logs ### helm [Установка helm чарта](https://github.com/mxssl/helm-charts/tree/main/charts/selectel-billing-exporter) + ### Создание манифестов вручную ```yaml @@ -65,10 +66,9 @@ spec: labels: component: selectel-billing spec: - terminationGracePeriodSeconds: 10 containers: - name: exporter - image: mxssl/selectel-billing-exporter:1.0.2 + image: mxssl/selectel-billing-exporter:1.1.0 command: ["./app"] ports: - containerPort: 80 @@ -110,12 +110,12 @@ kubectl apply -n exporters -f your-file.yaml ```yaml - alert: selectel_billing - expr: selectel_billing_vpc_main{job="selectel_billing"} / 100 < 30000 + expr: selectel_billing_final_sum{job="selectel_billing"} < 30000 for: 180s labels: severity: warning annotations: - summary: "{{ $labels.instance }}: В облаке Selectel на счете VPC меньше 30 тыс рублей" + summary: "{{ $labels.instance }}: В облаке Selectel на счете меньше 30 тыс рублей" description: "Необходимо пополнить счет облака Selectel" ``` diff --git a/go.mod b/go.mod index 05b8baa..14575d0 100644 --- a/go.mod +++ b/go.mod @@ -23,4 +23,4 @@ require ( gopkg.in/yaml.v3 v3.0.1 // indirect ) -go 1.19 +go 1.20 diff --git a/main.go b/main.go index c3e7a32..b69a61b 100644 --- a/main.go +++ b/main.go @@ -18,46 +18,11 @@ import ( var TOKEN string type selectelBillingResponse struct { - Status string `json:"status"` - Data struct { - Currency string `json:"currency"` - IsPostpay bool `json:"is_postpay"` - Discount int `json:"discount"` - Primary struct { - Main int `json:"main"` - Bonus int `json:"bonus"` - VkRub int `json:"vk_rub"` - Ref int `json:"ref"` - Hold struct { - Main int `json:"main"` - Bonus int `json:"bonus"` - VkRub int `json:"vk_rub"` - } `json:"hold"` - } `json:"primary"` - Storage struct { - Main int `json:"main"` - Bonus int `json:"bonus"` - VkRub int `json:"vk_rub"` - Prediction interface{} `json:"prediction"` - Debt int `json:"debt"` - Sum int `json:"sum"` - } `json:"storage"` - Vpc struct { - Main int `json:"main"` - Bonus int `json:"bonus"` - VkRub int `json:"vk_rub"` - Prediction interface{} `json:"prediction"` - Debt int `json:"debt"` - Sum int `json:"sum"` - } `json:"vpc"` - Vmware struct { - Main int `json:"main"` - Bonus int `json:"bonus"` - VkRub int `json:"vk_rub"` - Prediction interface{} `json:"prediction"` - Debt int `json:"debt"` - Sum int `json:"sum"` - } `json:"vmware"` + Data struct { + Billings []struct { + FinalSum int `json:"final_sum"` + DebtSum int `json:"debt_sum"` + } `json:"billings"` } `json:"data"` } @@ -110,23 +75,17 @@ func main() { } func initGauges() map[string]prometheus.Gauge { - selectelNames := make(map[string][]string) - selectelStructFields := []string{"main", "bonus", "vk_rub", "debt", "sum"} - selectelNames["primary"] = []string{"main", "bonus", "vk_rub", "ref", "hold_main", "hold_bonus", "hold_vk_rub"} - selectelNames["storage"] = selectelStructFields - selectelNames["vmware"] = selectelStructFields - selectelNames["vpc"] = selectelStructFields - promGauges := make(map[string]prometheus.Gauge) - for name, fields := range selectelNames { - for _, field := range fields { - promGauges["selectel_billing_"+name+"_"+field] = prometheus.NewGauge(prometheus.GaugeOpts{ - Name: "selectel_billing_" + name + "_" + field, - Help: "selectel billing " + name + " " + field, - }) - } - } + promGauges["selectel_billing_final_sum"] = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "selectel_billing_final_sum", + Help: "selectel billing final sum", + }) + + promGauges["selectel_billing_debt_sum"] = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "selectel_billing_debt_sum", + Help: "selectel billing debt sum", + }) for _, v := range promGauges { prometheus.MustRegister(v) @@ -145,35 +104,9 @@ func recordMetrics() { continue } - // primary - gauge["selectel_billing_primary_main"].Set(float64(s.Data.Primary.Main)) - gauge["selectel_billing_primary_bonus"].Set(float64(s.Data.Primary.Bonus)) - gauge["selectel_billing_primary_vk_rub"].Set(float64(s.Data.Primary.VkRub)) - gauge["selectel_billing_primary_ref"].Set(float64(s.Data.Primary.Ref)) - gauge["selectel_billing_primary_hold_main"].Set(float64(s.Data.Primary.Hold.Main)) - gauge["selectel_billing_primary_hold_bonus"].Set(float64(s.Data.Primary.Hold.Bonus)) - gauge["selectel_billing_primary_hold_vk_rub"].Set(float64(s.Data.Primary.Hold.VkRub)) - - // storage - gauge["selectel_billing_storage_main"].Set(float64(s.Data.Storage.Main)) - gauge["selectel_billing_storage_bonus"].Set(float64(s.Data.Storage.Bonus)) - gauge["selectel_billing_storage_vk_rub"].Set(float64(s.Data.Storage.VkRub)) - gauge["selectel_billing_storage_debt"].Set(float64(s.Data.Storage.Debt)) - gauge["selectel_billing_storage_sum"].Set(float64(s.Data.Storage.Sum)) - - // vpc - gauge["selectel_billing_vpc_main"].Set(float64(s.Data.Vpc.Main)) - gauge["selectel_billing_vpc_bonus"].Set(float64(s.Data.Vpc.Bonus)) - gauge["selectel_billing_vpc_vk_rub"].Set(float64(s.Data.Vpc.VkRub)) - gauge["selectel_billing_vpc_debt"].Set(float64(s.Data.Vpc.Debt)) - gauge["selectel_billing_vpc_sum"].Set(float64(s.Data.Vpc.Sum)) - - // vmware - gauge["selectel_billing_vmware_main"].Set(float64(s.Data.Vmware.Main)) - gauge["selectel_billing_vmware_bonus"].Set(float64(s.Data.Vmware.Bonus)) - gauge["selectel_billing_vmware_vk_rub"].Set(float64(s.Data.Vmware.VkRub)) - gauge["selectel_billing_vmware_debt"].Set(float64(s.Data.Vmware.Debt)) - gauge["selectel_billing_vmware_sum"].Set(float64(s.Data.Vmware.Sum)) + // записываем метрики + gauge["selectel_billing_final_sum"].Set(float64(s.Data.Billings[0].FinalSum)) + gauge["selectel_billing_debt_sum"].Set(float64(s.Data.Billings[0].DebtSum)) time.Sleep(time.Hour * 1) } diff --git a/main_test.go b/main_test.go index 2c4b5a7..2c91c7f 100644 --- a/main_test.go +++ b/main_test.go @@ -20,81 +20,24 @@ func TestSelectelBillingRequest(t *testing.T) { httpmock.RegisterResponder("GET", "https://api.selectel.ru/v3/balances", httpmock.NewStringResponder(200, string(testdata))) - expected := selectelBillingResponse{Status: "success", Data: struct { - Currency string "json:\"currency\"" - IsPostpay bool "json:\"is_postpay\"" - Discount int "json:\"discount\"" - Primary struct { - Main int "json:\"main\"" - Bonus int "json:\"bonus\"" - VkRub int "json:\"vk_rub\"" - Ref int "json:\"ref\"" - Hold struct { - Main int "json:\"main\"" - Bonus int "json:\"bonus\"" - VkRub int "json:\"vk_rub\"" - } "json:\"hold\"" - } "json:\"primary\"" - Storage struct { - Main int "json:\"main\"" - Bonus int "json:\"bonus\"" - VkRub int "json:\"vk_rub\"" - Prediction interface{} "json:\"prediction\"" - Debt int "json:\"debt\"" - Sum int "json:\"sum\"" - } "json:\"storage\"" - Vpc struct { - Main int "json:\"main\"" - Bonus int "json:\"bonus\"" - VkRub int "json:\"vk_rub\"" - Prediction interface{} "json:\"prediction\"" - Debt int "json:\"debt\"" - Sum int "json:\"sum\"" - } "json:\"vpc\"" - Vmware struct { - Main int "json:\"main\"" - Bonus int "json:\"bonus\"" - VkRub int "json:\"vk_rub\"" - Prediction interface{} "json:\"prediction\"" - Debt int "json:\"debt\"" - Sum int "json:\"sum\"" - } "json:\"vmware\"" - }{Currency: "rub", IsPostpay: false, Discount: 0, Primary: struct { - Main int "json:\"main\"" - Bonus int "json:\"bonus\"" - VkRub int "json:\"vk_rub\"" - Ref int "json:\"ref\"" - Hold struct { - Main int "json:\"main\"" - Bonus int "json:\"bonus\"" - VkRub int "json:\"vk_rub\"" - } "json:\"hold\"" - }{Main: 10000, Bonus: 10000, VkRub: 0, Ref: 0, Hold: struct { - Main int "json:\"main\"" - Bonus int "json:\"bonus\"" - VkRub int "json:\"vk_rub\"" - }{Main: 0, Bonus: 0, VkRub: 0}}, Storage: struct { - Main int "json:\"main\"" - Bonus int "json:\"bonus\"" - VkRub int "json:\"vk_rub\"" - Prediction interface{} "json:\"prediction\"" - Debt int "json:\"debt\"" - Sum int "json:\"sum\"" - }{Main: 203005, Bonus: 0, VkRub: 0, Prediction: interface{}(nil), Debt: 0, Sum: 203005}, Vpc: struct { - Main int "json:\"main\"" - Bonus int "json:\"bonus\"" - VkRub int "json:\"vk_rub\"" - Prediction interface{} "json:\"prediction\"" - Debt int "json:\"debt\"" - Sum int "json:\"sum\"" - }{Main: 11250838, Bonus: 12345, VkRub: 0, Prediction: interface{}(nil), Debt: 0, Sum: 11150838}, Vmware: struct { - Main int "json:\"main\"" - Bonus int "json:\"bonus\"" - VkRub int "json:\"vk_rub\"" - Prediction interface{} "json:\"prediction\"" - Debt int "json:\"debt\"" - Sum int "json:\"sum\"" - }{Main: 10000, Bonus: 10000, VkRub: 0, Prediction: interface{}(nil), Debt: 0, Sum: 20000}}} + expected := selectelBillingResponse{ + Data: struct { + Billings []struct { + FinalSum int `json:"final_sum"` + DebtSum int `json:"debt_sum"` + } `json:"billings"` + }{ + Billings: []struct { + FinalSum int `json:"final_sum"` + DebtSum int `json:"debt_sum"` + }{ + { + FinalSum: 33218108, + DebtSum: 0, + }, + }, + }, + } actual := selectelBillingResponse{} diff --git a/testdata/SelectelBillingRespExample.json b/testdata/SelectelBillingRespExample.json index c02212b..46be3cb 100644 --- a/testdata/SelectelBillingRespExample.json +++ b/testdata/SelectelBillingRespExample.json @@ -1,43 +1,10 @@ { - "status": "success", "data": { - "currency": "rub", - "is_postpay": false, - "discount": 0, - "primary": { - "main": 10000, - "bonus": 10000, - "vk_rub": 0, - "ref": 0, - "hold": { - "main": 0, - "bonus": 0, - "vk_rub": 0 + "billings": [ + { + "final_sum": 33218108, + "debt_sum": 0 } - }, - "storage": { - "main": 203005, - "bonus": 0, - "vk_rub": 0, - "prediction": null, - "debt": 0, - "sum": 203005 - }, - "vpc": { - "main": 11250838, - "bonus": 12345, - "vk_rub": 0, - "prediction": null, - "debt": 0, - "sum": 11150838 - }, - "vmware": { - "main": 10000, - "bonus": 10000, - "vk_rub": 0, - "prediction": null, - "debt": 0, - "sum": 20000 - } + ] } -} \ No newline at end of file +}