Skip to content

Commit 6d193ef

Browse files
committed
new billing api
1 parent 7da5131 commit 6d193ef

File tree

6 files changed

+50
-209
lines changed

6 files changed

+50
-209
lines changed

.github/workflows/release.yaml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ jobs:
1313
- uses: actions/checkout@v4
1414
- name: golangci-lint
1515
uses: golangci/golangci-lint-action@v3
16-
with:
17-
version: v1.48.0
1816

1917
docker-release:
2018
runs-on: ubuntu-latest
@@ -33,11 +31,11 @@ jobs:
3331
- uses: actions/checkout@v4
3432
- uses: actions/setup-go@v4
3533
with:
36-
go-version: 1.19
34+
go-version: "1.20"
3735
- name: Run GoReleaser
3836
uses: goreleaser/goreleaser-action@v4
3937
with:
4038
version: latest
41-
args: release --rm-dist
39+
args: release --clean
4240
env:
4341
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Prometheus exporter для получения информации по билл
66

77
Экспортер раз в час ходит по url `https://api.selectel.ru/v3/balances` с токеном в запросе, получает в json формате инфу по балансу средств на счете и отдает ее по url `/metrics` в формате prometheus.
88

9-
Для работы экспортера нужно получить API [токен](https://my.selectel.ru/profile/apikeys):
9+
Для работы экспортера нужно получить API [токен](https://my.selectel.ru/profile/apikeys)
1010

1111
## Как запустить
1212

@@ -19,7 +19,7 @@ version: '3'
1919

2020
services:
2121
selectel_exporter:
22-
image: mxssl/selectel-billing-exporter:1.0.0
22+
image: mxssl/selectel-billing-exporter:1.1.0
2323
ports:
2424
- "6789:80"
2525
restart: always
@@ -47,6 +47,7 @@ docker-compose logs
4747
### helm
4848

4949
[Установка helm чарта](https://github.com/mxssl/helm-charts/tree/main/charts/selectel-billing-exporter)
50+
5051
### Создание манифестов вручную
5152

5253
```yaml
@@ -65,10 +66,9 @@ spec:
6566
labels:
6667
component: selectel-billing
6768
spec:
68-
terminationGracePeriodSeconds: 10
6969
containers:
7070
- name: exporter
71-
image: mxssl/selectel-billing-exporter:1.0.2
71+
image: mxssl/selectel-billing-exporter:1.1.0
7272
command: ["./app"]
7373
ports:
7474
- containerPort: 80
@@ -110,12 +110,12 @@ kubectl apply -n exporters -f your-file.yaml
110110
111111
```yaml
112112
- alert: selectel_billing
113-
expr: selectel_billing_vpc_main{job="selectel_billing"} / 100 < 30000
113+
expr: selectel_billing_final_sum{job="selectel_billing"} < 30000
114114
for: 180s
115115
labels:
116116
severity: warning
117117
annotations:
118-
summary: "{{ $labels.instance }}: В облаке Selectel на счете VPC меньше 30 тыс рублей"
118+
summary: "{{ $labels.instance }}: В облаке Selectel на счете меньше 30 тыс рублей"
119119
description: "Необходимо пополнить счет облака Selectel"
120120
```
121121

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,4 @@ require (
2323
gopkg.in/yaml.v3 v3.0.1 // indirect
2424
)
2525

26-
go 1.19
26+
go 1.20

main.go

Lines changed: 17 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -18,46 +18,11 @@ import (
1818
var TOKEN string
1919

2020
type selectelBillingResponse struct {
21-
Status string `json:"status"`
22-
Data struct {
23-
Currency string `json:"currency"`
24-
IsPostpay bool `json:"is_postpay"`
25-
Discount int `json:"discount"`
26-
Primary struct {
27-
Main int `json:"main"`
28-
Bonus int `json:"bonus"`
29-
VkRub int `json:"vk_rub"`
30-
Ref int `json:"ref"`
31-
Hold struct {
32-
Main int `json:"main"`
33-
Bonus int `json:"bonus"`
34-
VkRub int `json:"vk_rub"`
35-
} `json:"hold"`
36-
} `json:"primary"`
37-
Storage struct {
38-
Main int `json:"main"`
39-
Bonus int `json:"bonus"`
40-
VkRub int `json:"vk_rub"`
41-
Prediction interface{} `json:"prediction"`
42-
Debt int `json:"debt"`
43-
Sum int `json:"sum"`
44-
} `json:"storage"`
45-
Vpc struct {
46-
Main int `json:"main"`
47-
Bonus int `json:"bonus"`
48-
VkRub int `json:"vk_rub"`
49-
Prediction interface{} `json:"prediction"`
50-
Debt int `json:"debt"`
51-
Sum int `json:"sum"`
52-
} `json:"vpc"`
53-
Vmware struct {
54-
Main int `json:"main"`
55-
Bonus int `json:"bonus"`
56-
VkRub int `json:"vk_rub"`
57-
Prediction interface{} `json:"prediction"`
58-
Debt int `json:"debt"`
59-
Sum int `json:"sum"`
60-
} `json:"vmware"`
21+
Data struct {
22+
Billings []struct {
23+
FinalSum int `json:"final_sum"`
24+
DebtSum int `json:"debt_sum"`
25+
} `json:"billings"`
6126
} `json:"data"`
6227
}
6328

@@ -110,23 +75,17 @@ func main() {
11075
}
11176

11277
func initGauges() map[string]prometheus.Gauge {
113-
selectelNames := make(map[string][]string)
114-
selectelStructFields := []string{"main", "bonus", "vk_rub", "debt", "sum"}
115-
selectelNames["primary"] = []string{"main", "bonus", "vk_rub", "ref", "hold_main", "hold_bonus", "hold_vk_rub"}
116-
selectelNames["storage"] = selectelStructFields
117-
selectelNames["vmware"] = selectelStructFields
118-
selectelNames["vpc"] = selectelStructFields
119-
12078
promGauges := make(map[string]prometheus.Gauge)
12179

122-
for name, fields := range selectelNames {
123-
for _, field := range fields {
124-
promGauges["selectel_billing_"+name+"_"+field] = prometheus.NewGauge(prometheus.GaugeOpts{
125-
Name: "selectel_billing_" + name + "_" + field,
126-
Help: "selectel billing " + name + " " + field,
127-
})
128-
}
129-
}
80+
promGauges["selectel_billing_final_sum"] = prometheus.NewGauge(prometheus.GaugeOpts{
81+
Name: "selectel_billing_final_sum",
82+
Help: "selectel billing final sum",
83+
})
84+
85+
promGauges["selectel_billing_debt_sum"] = prometheus.NewGauge(prometheus.GaugeOpts{
86+
Name: "selectel_billing_debt_sum",
87+
Help: "selectel billing debt sum",
88+
})
13089

13190
for _, v := range promGauges {
13291
prometheus.MustRegister(v)
@@ -145,35 +104,9 @@ func recordMetrics() {
145104
continue
146105
}
147106

148-
// primary
149-
gauge["selectel_billing_primary_main"].Set(float64(s.Data.Primary.Main))
150-
gauge["selectel_billing_primary_bonus"].Set(float64(s.Data.Primary.Bonus))
151-
gauge["selectel_billing_primary_vk_rub"].Set(float64(s.Data.Primary.VkRub))
152-
gauge["selectel_billing_primary_ref"].Set(float64(s.Data.Primary.Ref))
153-
gauge["selectel_billing_primary_hold_main"].Set(float64(s.Data.Primary.Hold.Main))
154-
gauge["selectel_billing_primary_hold_bonus"].Set(float64(s.Data.Primary.Hold.Bonus))
155-
gauge["selectel_billing_primary_hold_vk_rub"].Set(float64(s.Data.Primary.Hold.VkRub))
156-
157-
// storage
158-
gauge["selectel_billing_storage_main"].Set(float64(s.Data.Storage.Main))
159-
gauge["selectel_billing_storage_bonus"].Set(float64(s.Data.Storage.Bonus))
160-
gauge["selectel_billing_storage_vk_rub"].Set(float64(s.Data.Storage.VkRub))
161-
gauge["selectel_billing_storage_debt"].Set(float64(s.Data.Storage.Debt))
162-
gauge["selectel_billing_storage_sum"].Set(float64(s.Data.Storage.Sum))
163-
164-
// vpc
165-
gauge["selectel_billing_vpc_main"].Set(float64(s.Data.Vpc.Main))
166-
gauge["selectel_billing_vpc_bonus"].Set(float64(s.Data.Vpc.Bonus))
167-
gauge["selectel_billing_vpc_vk_rub"].Set(float64(s.Data.Vpc.VkRub))
168-
gauge["selectel_billing_vpc_debt"].Set(float64(s.Data.Vpc.Debt))
169-
gauge["selectel_billing_vpc_sum"].Set(float64(s.Data.Vpc.Sum))
170-
171-
// vmware
172-
gauge["selectel_billing_vmware_main"].Set(float64(s.Data.Vmware.Main))
173-
gauge["selectel_billing_vmware_bonus"].Set(float64(s.Data.Vmware.Bonus))
174-
gauge["selectel_billing_vmware_vk_rub"].Set(float64(s.Data.Vmware.VkRub))
175-
gauge["selectel_billing_vmware_debt"].Set(float64(s.Data.Vmware.Debt))
176-
gauge["selectel_billing_vmware_sum"].Set(float64(s.Data.Vmware.Sum))
107+
// записываем метрики
108+
gauge["selectel_billing_final_sum"].Set(float64(s.Data.Billings[0].FinalSum))
109+
gauge["selectel_billing_debt_sum"].Set(float64(s.Data.Billings[0].DebtSum))
177110

178111
time.Sleep(time.Hour * 1)
179112
}

main_test.go

Lines changed: 18 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -20,81 +20,24 @@ func TestSelectelBillingRequest(t *testing.T) {
2020
httpmock.RegisterResponder("GET", "https://api.selectel.ru/v3/balances",
2121
httpmock.NewStringResponder(200, string(testdata)))
2222

23-
expected := selectelBillingResponse{Status: "success", Data: struct {
24-
Currency string "json:\"currency\""
25-
IsPostpay bool "json:\"is_postpay\""
26-
Discount int "json:\"discount\""
27-
Primary struct {
28-
Main int "json:\"main\""
29-
Bonus int "json:\"bonus\""
30-
VkRub int "json:\"vk_rub\""
31-
Ref int "json:\"ref\""
32-
Hold struct {
33-
Main int "json:\"main\""
34-
Bonus int "json:\"bonus\""
35-
VkRub int "json:\"vk_rub\""
36-
} "json:\"hold\""
37-
} "json:\"primary\""
38-
Storage struct {
39-
Main int "json:\"main\""
40-
Bonus int "json:\"bonus\""
41-
VkRub int "json:\"vk_rub\""
42-
Prediction interface{} "json:\"prediction\""
43-
Debt int "json:\"debt\""
44-
Sum int "json:\"sum\""
45-
} "json:\"storage\""
46-
Vpc struct {
47-
Main int "json:\"main\""
48-
Bonus int "json:\"bonus\""
49-
VkRub int "json:\"vk_rub\""
50-
Prediction interface{} "json:\"prediction\""
51-
Debt int "json:\"debt\""
52-
Sum int "json:\"sum\""
53-
} "json:\"vpc\""
54-
Vmware struct {
55-
Main int "json:\"main\""
56-
Bonus int "json:\"bonus\""
57-
VkRub int "json:\"vk_rub\""
58-
Prediction interface{} "json:\"prediction\""
59-
Debt int "json:\"debt\""
60-
Sum int "json:\"sum\""
61-
} "json:\"vmware\""
62-
}{Currency: "rub", IsPostpay: false, Discount: 0, Primary: struct {
63-
Main int "json:\"main\""
64-
Bonus int "json:\"bonus\""
65-
VkRub int "json:\"vk_rub\""
66-
Ref int "json:\"ref\""
67-
Hold struct {
68-
Main int "json:\"main\""
69-
Bonus int "json:\"bonus\""
70-
VkRub int "json:\"vk_rub\""
71-
} "json:\"hold\""
72-
}{Main: 10000, Bonus: 10000, VkRub: 0, Ref: 0, Hold: struct {
73-
Main int "json:\"main\""
74-
Bonus int "json:\"bonus\""
75-
VkRub int "json:\"vk_rub\""
76-
}{Main: 0, Bonus: 0, VkRub: 0}}, Storage: struct {
77-
Main int "json:\"main\""
78-
Bonus int "json:\"bonus\""
79-
VkRub int "json:\"vk_rub\""
80-
Prediction interface{} "json:\"prediction\""
81-
Debt int "json:\"debt\""
82-
Sum int "json:\"sum\""
83-
}{Main: 203005, Bonus: 0, VkRub: 0, Prediction: interface{}(nil), Debt: 0, Sum: 203005}, Vpc: struct {
84-
Main int "json:\"main\""
85-
Bonus int "json:\"bonus\""
86-
VkRub int "json:\"vk_rub\""
87-
Prediction interface{} "json:\"prediction\""
88-
Debt int "json:\"debt\""
89-
Sum int "json:\"sum\""
90-
}{Main: 11250838, Bonus: 12345, VkRub: 0, Prediction: interface{}(nil), Debt: 0, Sum: 11150838}, Vmware: struct {
91-
Main int "json:\"main\""
92-
Bonus int "json:\"bonus\""
93-
VkRub int "json:\"vk_rub\""
94-
Prediction interface{} "json:\"prediction\""
95-
Debt int "json:\"debt\""
96-
Sum int "json:\"sum\""
97-
}{Main: 10000, Bonus: 10000, VkRub: 0, Prediction: interface{}(nil), Debt: 0, Sum: 20000}}}
23+
expected := selectelBillingResponse{
24+
Data: struct {
25+
Billings []struct {
26+
FinalSum int `json:"final_sum"`
27+
DebtSum int `json:"debt_sum"`
28+
} `json:"billings"`
29+
}{
30+
Billings: []struct {
31+
FinalSum int `json:"final_sum"`
32+
DebtSum int `json:"debt_sum"`
33+
}{
34+
{
35+
FinalSum: 33218108,
36+
DebtSum: 0,
37+
},
38+
},
39+
},
40+
}
9841

9942
actual := selectelBillingResponse{}
10043

Lines changed: 6 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,10 @@
11
{
2-
"status": "success",
32
"data": {
4-
"currency": "rub",
5-
"is_postpay": false,
6-
"discount": 0,
7-
"primary": {
8-
"main": 10000,
9-
"bonus": 10000,
10-
"vk_rub": 0,
11-
"ref": 0,
12-
"hold": {
13-
"main": 0,
14-
"bonus": 0,
15-
"vk_rub": 0
3+
"billings": [
4+
{
5+
"final_sum": 33218108,
6+
"debt_sum": 0
167
}
17-
},
18-
"storage": {
19-
"main": 203005,
20-
"bonus": 0,
21-
"vk_rub": 0,
22-
"prediction": null,
23-
"debt": 0,
24-
"sum": 203005
25-
},
26-
"vpc": {
27-
"main": 11250838,
28-
"bonus": 12345,
29-
"vk_rub": 0,
30-
"prediction": null,
31-
"debt": 0,
32-
"sum": 11150838
33-
},
34-
"vmware": {
35-
"main": 10000,
36-
"bonus": 10000,
37-
"vk_rub": 0,
38-
"prediction": null,
39-
"debt": 0,
40-
"sum": 20000
41-
}
8+
]
429
}
43-
}
10+
}

0 commit comments

Comments
 (0)