Skip to content

Commit e78eaa1

Browse files
Merge branch 'master' into repo_sync
2 parents 88b30a4 + 7786601 commit e78eaa1

File tree

7 files changed

+242
-110
lines changed

7 files changed

+242
-110
lines changed

.circleci/config.yml

Lines changed: 18 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,103 +1,33 @@
11
---
2-
version: 2.1
2+
# Prometheus has switched to GitHub action.
3+
# Circle CI is not disabled repository-wise so that previous pull requests
4+
# continue working.
5+
# This file does not generate any CircleCI workflow.
36

4-
orbs:
5-
prometheus: prometheus/[email protected]
7+
version: 2.1
68

79
executors:
8-
# This must match .promu.yml.
910
golang:
1011
docker:
11-
- image: cimg/go:1.25
12+
- image: busybox
1213

1314
jobs:
14-
test:
15+
noopjob:
1516
executor: golang
1617

1718
steps:
18-
- prometheus/setup_environment
19-
- run: GOHOSTARCH=386 GOARCH=386 make test
20-
- run: make
21-
- prometheus/store_artifact:
22-
file: postgres_exporter
23-
24-
integration:
25-
docker:
26-
- image: cimg/go:1.25
27-
- image: << parameters.postgres_image >>
28-
environment:
29-
POSTGRES_DB: circle_test
30-
POSTGRES_USER: postgres
31-
POSTGRES_PASSWORD: test
32-
33-
parameters:
34-
postgres_image:
35-
type: string
36-
37-
environment:
38-
DATA_SOURCE_NAME: 'postgresql://postgres:test@localhost:5432/circle_test?sslmode=disable'
39-
GOOPTS: '-v -tags integration'
40-
41-
steps:
42-
- checkout
43-
- setup_remote_docker
44-
- run: docker version
45-
- run: make build
46-
- run: make test
19+
- run:
20+
command: "true"
4721

4822
workflows:
4923
version: 2
50-
postgres_exporter:
24+
prometheus:
5125
jobs:
52-
- test:
53-
filters:
54-
tags:
55-
only: /.*/
56-
- integration:
57-
matrix:
58-
parameters:
59-
postgres_image:
60-
- cimg/postgres:13.22
61-
- cimg/postgres:14.19
62-
- cimg/postgres:15.14
63-
- cimg/postgres:16.10
64-
- cimg/postgres:17.6
65-
- prometheus/build:
66-
name: build
67-
parallelism: 3
68-
promu_opts: "-p linux/amd64 -p windows/amd64 -p linux/arm64 -p darwin/amd64 -p darwin/arm64 -p linux/386"
69-
filters:
70-
tags:
71-
ignore: /^v.*/
72-
branches:
73-
ignore: /^(main|master|release-.*|.*build-all.*)$/
74-
- prometheus/build:
75-
name: build_all
76-
parallelism: 12
77-
filters:
78-
branches:
79-
only: /^(main|master|release-.*|.*build-all.*)$/
80-
tags:
81-
only: /^v.*/
82-
- prometheus/publish_master:
83-
context: org-context
84-
docker_hub_organization: prometheuscommunity
85-
quay_io_organization: prometheuscommunity
86-
requires:
87-
- test
88-
- build_all
89-
filters:
90-
branches:
91-
only: master
92-
- prometheus/publish_release:
93-
context: org-context
94-
docker_hub_organization: prometheuscommunity
95-
quay_io_organization: prometheuscommunity
96-
requires:
97-
- test
98-
- build_all
99-
filters:
100-
tags:
101-
only: /^v.*/
102-
branches:
103-
ignore: /.*/
26+
- noopjob
27+
triggers:
28+
- schedule:
29+
cron: "0 0 30 2 *"
30+
filters:
31+
branches:
32+
only:
33+
- main

.github/workflows/ci.yml

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
---
2+
name: CI
3+
on:
4+
pull_request:
5+
push:
6+
7+
jobs:
8+
test_go:
9+
name: Go tests
10+
runs-on: ubuntu-latest
11+
container:
12+
# Whenever the Go version is updated here, .promu.yml
13+
# should also be updated.
14+
image: quay.io/prometheus/golang-builder:1.25-base
15+
steps:
16+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
17+
- uses: prometheus/promci@443c7fc2397e946bc9f5029e313a9c3441b9b86d # v0.4.7
18+
- uses: ./.github/promci/actions/setup_environment
19+
- run: make test
20+
- run: make GO_ONLY=1 SKIP_GOLANGCI_LINT=1
21+
integration_tests:
22+
name: Integration tests
23+
runs-on: ubuntu-latest
24+
strategy:
25+
matrix:
26+
# Define Postgres versions to test against.
27+
postgres_version:
28+
- 13.22
29+
- 14.19
30+
- 15.14
31+
- 16.10
32+
- 17.6
33+
services:
34+
postgres:
35+
image: postgres:${{ matrix.postgres_version }}
36+
env:
37+
POSTGRES_DB: circle_test
38+
POSTGRES_USER: postgres
39+
POSTGRES_PASSWORD: test
40+
# options: >-
41+
# --health-cmd="pg_isready -U postgres -d circle_test"
42+
# --health-interval=10s
43+
# --health-timeout=5s
44+
# --health-retries=5
45+
container:
46+
# Whenever the Go version is updated here, .promu.yml
47+
# should also be updated.
48+
image: quay.io/prometheus/golang-builder:1.25-base
49+
env:
50+
DATA_SOURCE_NAME: 'postgresql://postgres:test@postgres:5432/circle_test?sslmode=disable'
51+
GOOPTS: '-v -tags integration'
52+
steps:
53+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
54+
- uses: prometheus/promci@443c7fc2397e946bc9f5029e313a9c3441b9b86d # v0.4.7
55+
- uses: ./.github/promci/actions/setup_environment
56+
- run: make build
57+
- run: make test
58+
59+
60+
build:
61+
name: Build Prometheus for common architectures
62+
runs-on: ubuntu-latest
63+
if: |
64+
!(github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v'))
65+
&&
66+
!(github.event_name == 'pull_request' && startsWith(github.event.pull_request.base.ref, 'release-'))
67+
&&
68+
!(github.event_name == 'push' && github.event.ref == 'refs/heads/main')
69+
&&
70+
!(github.event_name == 'push' && github.event.ref == 'refs/heads/master')
71+
strategy:
72+
matrix:
73+
thread: [ 0, 1, 2 ]
74+
steps:
75+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
76+
- uses: prometheus/promci@443c7fc2397e946bc9f5029e313a9c3441b9b86d # v0.4.7
77+
- uses: ./.github/promci/actions/build
78+
with:
79+
promu_opts: "-p linux/amd64 -p windows/amd64 -p linux/arm64 -p darwin/amd64 -p darwin/arm64 -p linux/386"
80+
parallelism: 3
81+
thread: ${{ matrix.thread }}
82+
83+
build_all:
84+
name: Build Prometheus for all architectures
85+
runs-on: ubuntu-latest
86+
if: |
87+
(github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v'))
88+
||
89+
(github.event_name == 'pull_request' && startsWith(github.event.pull_request.base.ref, 'release-'))
90+
||
91+
(github.event_name == 'push' && github.event.ref == 'refs/heads/main')
92+
||
93+
(github.event_name == 'push' && github.event.ref == 'refs/heads/master')
94+
strategy:
95+
matrix:
96+
thread: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ]
97+
98+
# Whenever the Go version is updated here, .promu.yml
99+
# should also be updated.
100+
steps:
101+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
102+
- uses: prometheus/promci@443c7fc2397e946bc9f5029e313a9c3441b9b86d # v0.4.7
103+
- uses: ./.github/promci/actions/build
104+
with:
105+
parallelism: 12
106+
thread: ${{ matrix.thread }}
107+
108+
publish_main:
109+
# https://github.com/prometheus/promci/blob/52c7012f5f0070d7281b8db4a119e21341d43c91/actions/publish_main/action.yml
110+
name: Publish main branch artifacts
111+
runs-on: ubuntu-latest
112+
needs: [test_go, build_all]
113+
if: |
114+
(github.event_name == 'push' && github.event.ref == 'refs/heads/main')
115+
||
116+
(github.event_name == 'push' && github.event.ref == 'refs/heads/master')
117+
steps:
118+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
119+
- uses: prometheus/promci@443c7fc2397e946bc9f5029e313a9c3441b9b86d # v0.4.7
120+
- uses: ./.github/promci/actions/publish_main
121+
with:
122+
docker_hub_organization: prometheuscommunity
123+
docker_hub_login: ${{ secrets.docker_hub_login }}
124+
docker_hub_password: ${{ secrets.docker_hub_password }}
125+
quay_io_organization: prometheuscommunity
126+
quay_io_login: ${{ secrets.quay_io_login }}
127+
quay_io_password: ${{ secrets.quay_io_password }}
128+
129+
publish_release:
130+
name: Publish release artefacts
131+
runs-on: ubuntu-latest
132+
needs: [test_go, build_all]
133+
if: |
134+
(github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v'))
135+
steps:
136+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
137+
- uses: prometheus/promci@443c7fc2397e946bc9f5029e313a9c3441b9b86d # v0.4.7
138+
- uses: ./.github/promci/actions/publish_release
139+
with:
140+
docker_hub_organization: prometheuscommunity
141+
docker_hub_login: ${{ secrets.docker_hub_login }}
142+
docker_hub_password: ${{ secrets.docker_hub_password }}
143+
quay_io_organization: prometheuscommunity
144+
quay_io_login: ${{ secrets.quay_io_login }}
145+
quay_io_password: ${{ secrets.quay_io_password }}
146+
github_token: ${{ secrets.PROMBOT_GITHUB_TOKEN }}

collector/pg_long_running_transactions.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ package collector
1515

1616
import (
1717
"context"
18+
"database/sql"
1819
"log/slog"
1920

2021
"github.com/prometheus/client_golang/prometheus"
@@ -50,7 +51,7 @@ var (
5051
)
5152

5253
longRunningTransactionsQuery = `
53-
SELECT
54+
SELECT
5455
COUNT(*) as transactions,
5556
MAX(EXTRACT(EPOCH FROM clock_timestamp() - pg_stat_activity.xact_start)) AS oldest_timestamp_seconds
5657
FROM pg_catalog.pg_stat_activity
@@ -72,12 +73,20 @@ func (PGLongRunningTransactionsCollector) Update(ctx context.Context, instance *
7273
defer rows.Close()
7374

7475
for rows.Next() {
75-
var transactions, ageInSeconds float64
76+
var transactions float64
77+
var ageInSeconds sql.NullFloat64
7678

7779
if err := rows.Scan(&transactions, &ageInSeconds); err != nil {
7880
return err
7981
}
8082

83+
// If there are no long running transactions, ageInSeconds will be NULL
84+
// so we set it to 0
85+
age := 0.0
86+
if ageInSeconds.Valid {
87+
age = ageInSeconds.Float64
88+
}
89+
8190
ch <- prometheus.MustNewConstMetric(
8291
longRunningTransactionsCount,
8392
prometheus.GaugeValue,
@@ -86,7 +95,7 @@ func (PGLongRunningTransactionsCollector) Update(ctx context.Context, instance *
8695
ch <- prometheus.MustNewConstMetric(
8796
longRunningTransactionsAgeInSeconds,
8897
prometheus.GaugeValue,
89-
ageInSeconds,
98+
age,
9099
)
91100
}
92101
if err := rows.Err(); err != nil {

collector/pg_long_running_transactions_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,44 @@ func TestPGLongRunningTransactionsCollector(t *testing.T) {
6161
t.Errorf("there were unfulfilled exceptions: %s", err)
6262
}
6363
}
64+
65+
func TestPGLongRunningTransactionsCollectorNull(t *testing.T) {
66+
// Test when no long running transactions are present
67+
db, mock, err := sqlmock.New()
68+
if err != nil {
69+
t.Fatalf("Error opening a stub db connection: %s", err)
70+
}
71+
defer db.Close()
72+
inst := &instance{db: db}
73+
columns := []string{
74+
"transactions",
75+
"age_in_seconds",
76+
}
77+
rows := sqlmock.NewRows(columns).
78+
AddRow(0, nil)
79+
80+
mock.ExpectQuery(sanitizeQuery(longRunningTransactionsQuery)).WillReturnRows(rows)
81+
82+
ch := make(chan prometheus.Metric)
83+
go func() {
84+
defer close(ch)
85+
c := PGLongRunningTransactionsCollector{}
86+
87+
if err := c.Update(context.Background(), inst, ch); err != nil {
88+
t.Errorf("Error calling PGLongRunningTransactionsCollector.Update: %s", err)
89+
}
90+
}()
91+
expected := []MetricResult{
92+
{labels: labelMap{}, value: 0, metricType: dto.MetricType_GAUGE},
93+
{labels: labelMap{}, value: 0, metricType: dto.MetricType_GAUGE},
94+
}
95+
convey.Convey("Metrics comparison", t, func() {
96+
for _, expect := range expected {
97+
m := readMetric(<-ch)
98+
convey.So(expect, convey.ShouldResemble, m)
99+
}
100+
})
101+
if err := mock.ExpectationsWereMet(); err != nil {
102+
t.Errorf("there were unfulfilled exceptions: %s", err)
103+
}
104+
}

go.mod

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ require (
99
github.com/lib/pq v1.10.9
1010
github.com/prometheus/client_golang v1.23.2
1111
github.com/prometheus/client_model v0.6.2
12-
github.com/prometheus/common v0.67.2
12+
github.com/prometheus/common v0.67.4
1313
github.com/prometheus/exporter-toolkit v0.15.0
1414
github.com/smartystreets/goconvey v1.8.1
1515
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c
@@ -22,6 +22,8 @@ require (
2222
github.com/beorn7/perks v1.0.1 // indirect
2323
github.com/cespare/xxhash/v2 v2.3.0 // indirect
2424
github.com/coreos/go-systemd/v22 v22.6.0 // indirect
25+
github.com/golang-jwt/jwt/v5 v5.3.0 // indirect
26+
github.com/google/uuid v1.6.0 // indirect
2527
github.com/gopherjs/gopherjs v1.17.2 // indirect
2628
github.com/jpillora/backoff v1.0.0 // indirect
2729
github.com/jtolds/gls v4.20.0+incompatible // indirect
@@ -36,12 +38,12 @@ require (
3638
github.com/smarty/assertions v1.15.0 // indirect
3739
github.com/xhit/go-str2duration/v2 v2.1.0 // indirect
3840
go.yaml.in/yaml/v2 v2.4.3 // indirect
39-
golang.org/x/crypto v0.43.0 // indirect
40-
golang.org/x/net v0.46.0 // indirect
41+
golang.org/x/crypto v0.45.0 // indirect
42+
golang.org/x/net v0.47.0 // indirect
4143
golang.org/x/oauth2 v0.32.0 // indirect
42-
golang.org/x/sync v0.17.0 // indirect
43-
golang.org/x/sys v0.37.0 // indirect
44-
golang.org/x/text v0.30.0 // indirect
44+
golang.org/x/sync v0.18.0 // indirect
45+
golang.org/x/sys v0.38.0 // indirect
46+
golang.org/x/text v0.31.0 // indirect
4547
golang.org/x/time v0.13.0 // indirect
4648
google.golang.org/protobuf v1.36.10 // indirect
4749
)

0 commit comments

Comments
 (0)