gitlab-exporter 7.0.5 → 7.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitlab-ci.yml +23 -11
- data/Gemfile.lock +15 -13
- data/lib/gitlab_exporter/database/base.rb +6 -1
- data/lib/gitlab_exporter/database/bloat.rb +5 -1
- data/lib/gitlab_exporter/database/bloat_btree.sql +84 -67
- data/lib/gitlab_exporter/database/bloat_table.sql +13 -12
- data/lib/gitlab_exporter/database/ci_builds.rb +7 -10
- data/lib/gitlab_exporter/database/remote_mirrors.rb +1 -1
- data/lib/gitlab_exporter/database/row_count.rb +10 -4
- data/lib/gitlab_exporter/database/tuple_stats.rb +2 -2
- data/lib/gitlab_exporter/git.rb +2 -2
- data/lib/gitlab_exporter/prober.rb +3 -2
- data/lib/gitlab_exporter/process.rb +1 -1
- data/lib/gitlab_exporter/sidekiq.rb +2 -1
- data/lib/gitlab_exporter/version.rb +1 -1
- data/lib/gitlab_exporter/web_exporter.rb +6 -1
- data/spec/database/bloat_spec.rb +5 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 86ad2e8d49582c70ba5faa5e7a8744a0e812f5682447cc1e1f000e050a3b9451
|
4
|
+
data.tar.gz: 2a0f878e42abef28992284e0e372db960831025b7ff3cf71c676369210d05fea
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 28d6f61e6df16ac17ba9e25ddea5d6a39c65940796898a2a6bad66c352ad47a1341593e3bb8dd7edaefd5281a787612beda9ff6f3f3700c6c458ad345fef055d
|
7
|
+
data.tar.gz: f7b2ff3ddd97529571e0517f4b8f9c7d42fe512f5d786a9c60dfae6337cafc56f5ae8eecaf98e3d85d0cb987e66363102bfec40a6ff4411524359cdf888f9d3e
|
data/.gitlab-ci.yml
CHANGED
@@ -1,17 +1,26 @@
|
|
1
|
+
include:
|
2
|
+
- template: Security/DAST.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab-foss/blob/master/lib/gitlab/ci/templates/Security/DAST.gitlab-ci.yml
|
3
|
+
- template: Security/Container-Scanning.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab-foss/blob/master/lib/gitlab/ci/templates/Security/Container-Scanning.gitlab-ci.yml
|
4
|
+
- template: Security/Dependency-Scanning.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab-foss/blob/master/lib/gitlab/ci/templates/Security/Dependency-Scanning.gitlab-ci.yml
|
5
|
+
- template: Security/License-Scanning.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab-foss/blob/master/lib/gitlab/ci/templates/Security/License-Scanning.gitlab-ci.yml
|
6
|
+
- template: Security/SAST.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab-foss/blob/master/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml
|
7
|
+
- template: Security/Secret-Detection.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab-foss/-/blob/master/lib/gitlab/ci/templates/Security/Secret-Detection.gitlab-ci.yml
|
8
|
+
|
1
9
|
default:
|
2
10
|
image: "ruby:2.3"
|
3
|
-
before_script:
|
4
|
-
- git config --global user.email "bot@gitlab.com"
|
5
|
-
- git config --global user.name "Bot User"
|
6
|
-
- bundle install -j $(nproc) --path vendor
|
7
11
|
cache:
|
8
12
|
paths:
|
9
13
|
- vendor
|
10
14
|
tags:
|
11
15
|
- gitlab-org
|
12
16
|
|
17
|
+
.before_scripts: &before_scripts
|
18
|
+
- git config --global user.email "bot@gitlab.com"
|
19
|
+
- git config --global user.name "Bot User"
|
20
|
+
- bundle install -j $(nproc) --path vendor
|
21
|
+
|
13
22
|
workflow:
|
14
|
-
rules:
|
23
|
+
rules: &workflow_rules
|
15
24
|
# For merge requests, create a pipeline.
|
16
25
|
- if: '$CI_MERGE_REQUEST_IID'
|
17
26
|
# For `master` branch, create a pipeline (this includes on schedules, pushes, merges, etc.).
|
@@ -22,15 +31,18 @@ workflow:
|
|
22
31
|
rspec:
|
23
32
|
script:
|
24
33
|
- bundle exec rspec spec -f d -c
|
34
|
+
before_script: *before_scripts
|
25
35
|
|
26
36
|
rubocop:
|
27
37
|
script:
|
28
38
|
- bundle exec rubocop
|
39
|
+
before_script: *before_scripts
|
29
40
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
- template: Security/SAST.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab-foss/blob/master/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml
|
41
|
+
license_scanning:
|
42
|
+
rules: *workflow_rules
|
43
|
+
|
44
|
+
gemnasium-dependency_scanning:
|
45
|
+
rules: *workflow_rules
|
36
46
|
|
47
|
+
secret_detection:
|
48
|
+
rules: *workflow_rules
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
gitlab-exporter (7.0
|
4
|
+
gitlab-exporter (7.2.0)
|
5
5
|
connection_pool (~> 2.2.1)
|
6
6
|
pg (~> 1.1)
|
7
7
|
quantile (~> 0.2.0)
|
@@ -14,19 +14,20 @@ GEM
|
|
14
14
|
remote: https://rubygems.org/
|
15
15
|
specs:
|
16
16
|
ast (2.4.0)
|
17
|
-
connection_pool (2.2.
|
17
|
+
connection_pool (2.2.3)
|
18
18
|
diff-lcs (1.3)
|
19
|
-
mustermann (1.
|
19
|
+
mustermann (1.1.1)
|
20
|
+
ruby2_keywords (~> 0.0.1)
|
20
21
|
parser (2.5.1.0)
|
21
22
|
ast (~> 2.4.0)
|
22
|
-
pg (1.2.
|
23
|
+
pg (1.2.3)
|
23
24
|
powerpack (0.1.1)
|
24
25
|
quantile (0.2.1)
|
25
|
-
rack (2.
|
26
|
-
rack-protection (2.0.
|
26
|
+
rack (2.2.3)
|
27
|
+
rack-protection (2.0.8.1)
|
27
28
|
rack
|
28
29
|
rainbow (2.1.0)
|
29
|
-
redis (4.1.
|
30
|
+
redis (4.1.4)
|
30
31
|
redis-namespace (1.6.0)
|
31
32
|
redis (>= 3.0.4)
|
32
33
|
rspec (3.7.0)
|
@@ -49,17 +50,18 @@ GEM
|
|
49
50
|
ruby-progressbar (~> 1.7)
|
50
51
|
unicode-display_width (~> 1.0, >= 1.0.1)
|
51
52
|
ruby-progressbar (1.8.1)
|
52
|
-
|
53
|
+
ruby2_keywords (0.0.2)
|
54
|
+
sidekiq (5.2.9)
|
53
55
|
connection_pool (~> 2.2, >= 2.2.2)
|
54
|
-
rack (
|
56
|
+
rack (~> 2.0)
|
55
57
|
rack-protection (>= 1.5.0)
|
56
|
-
redis (>= 3.3.5, <
|
57
|
-
sinatra (2.0.
|
58
|
+
redis (>= 3.3.5, < 4.2)
|
59
|
+
sinatra (2.0.8.1)
|
58
60
|
mustermann (~> 1.0)
|
59
61
|
rack (~> 2.0)
|
60
|
-
rack-protection (= 2.0.
|
62
|
+
rack-protection (= 2.0.8.1)
|
61
63
|
tilt (~> 2.0)
|
62
|
-
tilt (2.0.
|
64
|
+
tilt (2.0.10)
|
63
65
|
unicode-display_width (1.6.0)
|
64
66
|
|
65
67
|
PLATFORMS
|
@@ -16,8 +16,9 @@ module GitLab
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
def initialize(args)
|
19
|
+
def initialize(args, logger: nil)
|
20
20
|
@connection_string = args[:connection_string]
|
21
|
+
@logger = logger
|
21
22
|
end
|
22
23
|
|
23
24
|
def run
|
@@ -33,10 +34,14 @@ module GitLab
|
|
33
34
|
begin
|
34
35
|
yield conn
|
35
36
|
rescue PG::UnableToSend => e
|
37
|
+
@logger.warn "Error sending to the database: #{e}" if @logger
|
36
38
|
conn.reset
|
37
39
|
raise e
|
38
40
|
end
|
39
41
|
end
|
42
|
+
rescue PG::Error => e
|
43
|
+
@logger.error "Error connecting to the database: #{e}" if @logger
|
44
|
+
raise e
|
40
45
|
end
|
41
46
|
end
|
42
47
|
end
|
@@ -3,6 +3,8 @@ module GitLab
|
|
3
3
|
module Database
|
4
4
|
# Helper to collect bloat metrics.
|
5
5
|
class BloatCollector < Base
|
6
|
+
attr_writer :logger
|
7
|
+
|
6
8
|
def run(type = :btree)
|
7
9
|
execute(self.class.query_for(type)).each_with_object({}) do |row, h|
|
8
10
|
h[row["object_name"]] = row
|
@@ -39,9 +41,11 @@ module GitLab
|
|
39
41
|
|
40
42
|
def initialize(opts,
|
41
43
|
metrics: PrometheusMetrics.new,
|
42
|
-
collector: BloatCollector.new(connection_string: opts[:connection_string])
|
44
|
+
collector: BloatCollector.new(connection_string: opts[:connection_string]),
|
45
|
+
logger: nil)
|
43
46
|
@metrics = metrics
|
44
47
|
@collector = collector
|
48
|
+
@collector.logger = logger
|
45
49
|
@bloat_types = opts[:bloat_types] || %i(btree table)
|
46
50
|
end
|
47
51
|
|
@@ -12,73 +12,90 @@ SELECT current_database(), nspname AS schemaname, tblname, idxname AS object_nam
|
|
12
12
|
END AS bloat_size,
|
13
13
|
100 * (relpages-est_pages_ff)::float / relpages AS bloat_ratio,
|
14
14
|
is_na
|
15
|
-
-- , 100-(
|
15
|
+
-- , 100-(pst).avg_leaf_density AS pst_avg_bloat, est_pages, index_tuple_hdr_bm, maxalign, pagehdr, nulldatawidth, nulldatahdrwidth, reltuples, relpages -- (DEBUG INFO)
|
16
16
|
FROM (
|
17
17
|
SELECT coalesce(1 +
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
18
|
+
ceil(reltuples/floor((bs-pageopqdata-pagehdr)/(4+nulldatahdrwidth)::float)), 0 -- ItemIdData size + computed avg size of a tuple (nulldatahdrwidth)
|
19
|
+
) AS est_pages,
|
20
|
+
coalesce(1 +
|
21
|
+
ceil(reltuples/floor((bs-pageopqdata-pagehdr)*fillfactor/(100*(4+nulldatahdrwidth)::float))), 0
|
22
|
+
) AS est_pages_ff,
|
23
|
+
bs, nspname, tblname, idxname, relpages, fillfactor, is_na
|
24
|
+
-- , pgstatindex(idxoid) AS pst, index_tuple_hdr_bm, maxalign, pagehdr, nulldatawidth, nulldatahdrwidth, reltuples -- (DEBUG INFO)
|
25
25
|
FROM (
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
) AS
|
82
|
-
|
83
|
-
|
84
|
-
|
26
|
+
SELECT maxalign, bs, nspname, tblname, idxname, reltuples, relpages, idxoid, fillfactor,
|
27
|
+
( index_tuple_hdr_bm +
|
28
|
+
maxalign - CASE -- Add padding to the index tuple header to align on MAXALIGN
|
29
|
+
WHEN index_tuple_hdr_bm%maxalign = 0 THEN maxalign
|
30
|
+
ELSE index_tuple_hdr_bm%maxalign
|
31
|
+
END
|
32
|
+
+ nulldatawidth + maxalign - CASE -- Add padding to the data to align on MAXALIGN
|
33
|
+
WHEN nulldatawidth = 0 THEN 0
|
34
|
+
WHEN nulldatawidth::integer%maxalign = 0 THEN maxalign
|
35
|
+
ELSE nulldatawidth::integer%maxalign
|
36
|
+
END
|
37
|
+
)::numeric AS nulldatahdrwidth, pagehdr, pageopqdata, is_na
|
38
|
+
-- , index_tuple_hdr_bm, nulldatawidth -- (DEBUG INFO)
|
39
|
+
FROM (
|
40
|
+
SELECT n.nspname, i.tblname, i.idxname, i.reltuples, i.relpages,
|
41
|
+
i.idxoid, i.fillfactor, current_setting('block_size')::numeric AS bs,
|
42
|
+
CASE -- MAXALIGN: 4 on 32bits, 8 on 64bits (and mingw32 ?)
|
43
|
+
WHEN version() ~ 'mingw32' OR version() ~ '64-bit|x86_64|ppc64|ia64|amd64' THEN 8
|
44
|
+
ELSE 4
|
45
|
+
END AS maxalign,
|
46
|
+
/* per page header, fixed size: 20 for 7.X, 24 for others */
|
47
|
+
24 AS pagehdr,
|
48
|
+
/* per page btree opaque data */
|
49
|
+
16 AS pageopqdata,
|
50
|
+
/* per tuple header: add IndexAttributeBitMapData if some cols are null-able */
|
51
|
+
CASE WHEN max(coalesce(s.null_frac,0)) = 0
|
52
|
+
THEN 2 -- IndexTupleData size
|
53
|
+
ELSE 2 + (( 32 + 8 - 1 ) / 8) -- IndexTupleData size + IndexAttributeBitMapData size ( max num filed per index + 8 - 1 /8)
|
54
|
+
END AS index_tuple_hdr_bm,
|
55
|
+
/* data len: we remove null values save space using it fractionnal part from stats */
|
56
|
+
sum( (1-coalesce(s.null_frac, 0)) * coalesce(s.avg_width, 1024)) AS nulldatawidth,
|
57
|
+
max( CASE WHEN i.atttypid = 'pg_catalog.name'::regtype THEN 1 ELSE 0 END ) > 0 AS is_na
|
58
|
+
FROM (
|
59
|
+
SELECT ct.relname AS tblname, ct.relnamespace, ic.idxname, ic.attpos, ic.indkey, ic.indkey[ic.attpos], ic.reltuples, ic.relpages, ic.tbloid, ic.idxoid, ic.fillfactor,
|
60
|
+
coalesce(a1.attnum, a2.attnum) AS attnum, coalesce(a1.attname, a2.attname) AS attname, coalesce(a1.atttypid, a2.atttypid) AS atttypid,
|
61
|
+
CASE WHEN a1.attnum IS NULL
|
62
|
+
THEN ic.idxname
|
63
|
+
ELSE ct.relname
|
64
|
+
END AS attrelname
|
65
|
+
FROM (
|
66
|
+
SELECT idxname, reltuples, relpages, tbloid, idxoid, fillfactor, indkey,
|
67
|
+
pg_catalog.generate_series(1,indnatts) AS attpos
|
68
|
+
FROM (
|
69
|
+
SELECT ci.relname AS idxname, ci.reltuples, ci.relpages, i.indrelid AS tbloid,
|
70
|
+
i.indexrelid AS idxoid,
|
71
|
+
coalesce(substring(
|
72
|
+
array_to_string(ci.reloptions, ' ')
|
73
|
+
from 'fillfactor=([0-9]+)')::smallint, 90) AS fillfactor,
|
74
|
+
i.indnatts,
|
75
|
+
pg_catalog.string_to_array(pg_catalog.textin(
|
76
|
+
pg_catalog.int2vectorout(i.indkey)),' ')::int[] AS indkey
|
77
|
+
FROM pg_catalog.pg_index i
|
78
|
+
JOIN pg_catalog.pg_class ci ON ci.oid = i.indexrelid
|
79
|
+
WHERE ci.relam=(SELECT oid FROM pg_am WHERE amname = 'btree')
|
80
|
+
AND ci.relpages > 0
|
81
|
+
) AS idx_data
|
82
|
+
) AS ic
|
83
|
+
JOIN pg_catalog.pg_class ct ON ct.oid = ic.tbloid
|
84
|
+
LEFT JOIN pg_catalog.pg_attribute a1 ON
|
85
|
+
ic.indkey[ic.attpos] <> 0
|
86
|
+
AND a1.attrelid = ic.tbloid
|
87
|
+
AND a1.attnum = ic.indkey[ic.attpos]
|
88
|
+
LEFT JOIN pg_catalog.pg_attribute a2 ON
|
89
|
+
ic.indkey[ic.attpos] = 0
|
90
|
+
AND a2.attrelid = ic.idxoid
|
91
|
+
AND a2.attnum = ic.attpos
|
92
|
+
) i
|
93
|
+
JOIN pg_catalog.pg_namespace n ON n.oid = i.relnamespace
|
94
|
+
JOIN pg_catalog.pg_stats s ON s.schemaname = n.nspname
|
95
|
+
AND s.tablename = i.attrelname
|
96
|
+
AND s.attname = i.attname
|
97
|
+
GROUP BY 1,2,3,4,5,6,7,8,9,10,11
|
98
|
+
) AS rows_data_stats
|
99
|
+
) AS rows_hdr_pdg_stats
|
100
|
+
) AS relation_stats
|
101
|
+
ORDER BY nspname, tblname, idxname;
|
@@ -1,5 +1,5 @@
|
|
1
1
|
-- Originally from: https://github.com/ioguix/pgsql-bloat-estimation/blob/master/table/table_bloat.sql
|
2
|
-
/* WARNING: executed with a non-superuser role, the query inspect only tables you are granted to read.
|
2
|
+
/* WARNING: executed with a non-superuser role, the query inspect only tables and materialized view (9.3+) you are granted to read.
|
3
3
|
* This query is compatible with PostgreSQL 9.0 and more
|
4
4
|
*/
|
5
5
|
SELECT current_database(), schemaname, tblname AS object_name, bs*tblpages AS real_size,
|
@@ -16,12 +16,12 @@ SELECT current_database(), schemaname, tblname AS object_name, bs*tblpages AS re
|
|
16
16
|
THEN 100 * (tblpages - est_tblpages_ff)/tblpages::float
|
17
17
|
ELSE 0
|
18
18
|
END AS bloat_ratio, is_na
|
19
|
-
-- , (pst).free_percent + (pst).dead_tuple_percent AS real_frag
|
19
|
+
-- , tpl_hdr_size, tpl_data_size, (pst).free_percent + (pst).dead_tuple_percent AS real_frag -- (DEBUG INFO)
|
20
20
|
FROM (
|
21
21
|
SELECT ceil( reltuples / ( (bs-page_hdr)/tpl_size ) ) + ceil( toasttuples / 4 ) AS est_tblpages,
|
22
22
|
ceil( reltuples / ( (bs-page_hdr)*fillfactor/(tpl_size*100) ) ) + ceil( toasttuples / 4 ) AS est_tblpages_ff,
|
23
23
|
tblpages, fillfactor, bs, tblid, schemaname, tblname, heappages, toastpages, is_na
|
24
|
-
-- ,
|
24
|
+
-- , tpl_hdr_size, tpl_data_size, pgstattuple(tblid) AS pst -- (DEBUG INFO)
|
25
25
|
FROM (
|
26
26
|
SELECT
|
27
27
|
( 4 + tpl_hdr_size + tpl_data_size + (2*ma)
|
@@ -29,6 +29,7 @@ FROM (
|
|
29
29
|
- CASE WHEN ceil(tpl_data_size)::int%ma = 0 THEN ma ELSE ceil(tpl_data_size)::int%ma END
|
30
30
|
) AS tpl_size, bs - page_hdr AS size_per_block, (heappages + toastpages) AS tblpages, heappages,
|
31
31
|
toastpages, reltuples, toasttuples, bs, page_hdr, tblid, schemaname, tblname, fillfactor, is_na
|
32
|
+
-- , tpl_hdr_size, tpl_data_size
|
32
33
|
FROM (
|
33
34
|
SELECT
|
34
35
|
tbl.oid AS tblid, ns.nspname AS schemaname, tbl.relname AS tblname, tbl.reltuples,
|
@@ -40,24 +41,24 @@ FROM (
|
|
40
41
|
current_setting('block_size')::numeric AS bs,
|
41
42
|
CASE WHEN version()~'mingw32' OR version()~'64-bit|x86_64|ppc64|ia64|amd64' THEN 8 ELSE 4 END AS ma,
|
42
43
|
24 AS page_hdr,
|
43
|
-
23 + CASE WHEN MAX(coalesce(null_frac,0)) > 0 THEN ( 7 + count(
|
44
|
-
|
45
|
-
sum( (1-coalesce(s.null_frac, 0)) * coalesce(s.avg_width,
|
44
|
+
23 + CASE WHEN MAX(coalesce(s.null_frac,0)) > 0 THEN ( 7 + count(s.attname) ) / 8 ELSE 0::int END
|
45
|
+
+ CASE WHEN bool_or(att.attname = 'oid' and att.attnum < 0) THEN 4 ELSE 0 END AS tpl_hdr_size,
|
46
|
+
sum( (1-coalesce(s.null_frac, 0)) * coalesce(s.avg_width, 0) ) AS tpl_data_size,
|
46
47
|
bool_or(att.atttypid = 'pg_catalog.name'::regtype)
|
47
|
-
OR
|
48
|
+
OR sum(CASE WHEN att.attnum > 0 THEN 1 ELSE 0 END) <> count(s.attname) AS is_na
|
48
49
|
FROM pg_attribute AS att
|
49
50
|
JOIN pg_class AS tbl ON att.attrelid = tbl.oid
|
50
51
|
JOIN pg_namespace AS ns ON ns.oid = tbl.relnamespace
|
51
52
|
LEFT JOIN pg_stats AS s ON s.schemaname=ns.nspname
|
52
53
|
AND s.tablename = tbl.relname AND s.inherited=false AND s.attname=att.attname
|
53
54
|
LEFT JOIN pg_class AS toast ON tbl.reltoastrelid = toast.oid
|
54
|
-
WHERE
|
55
|
-
AND tbl.relkind
|
56
|
-
GROUP BY 1,2,3,4,5,6,7,8,9,10
|
55
|
+
WHERE NOT att.attisdropped
|
56
|
+
AND tbl.relkind in ('r','m')
|
57
|
+
GROUP BY 1,2,3,4,5,6,7,8,9,10
|
57
58
|
ORDER BY 2,3
|
58
59
|
) AS s
|
59
60
|
) AS s2
|
60
61
|
) AS s3
|
61
|
-
WHERE NOT is_na
|
62
|
+
-- WHERE NOT is_na
|
62
63
|
-- AND tblpages*((pst).free_percent + (pst).dead_tuple_percent)::float4/100 >= 1
|
63
|
-
|
64
|
+
ORDER BY schemaname, tblname;
|
@@ -21,8 +21,7 @@ module GitLab
|
|
21
21
|
ON namespaces.id = projects.namespace_id
|
22
22
|
LEFT JOIN namespace_statistics
|
23
23
|
ON namespace_statistics.namespace_id = namespaces.id
|
24
|
-
JOIN application_settings
|
25
|
-
ON application_settings.id = 1
|
24
|
+
JOIN application_settings ON (TRUE)
|
26
25
|
WHERE ci_builds.type = 'Ci::Build'
|
27
26
|
AND ci_builds.status = '%s'
|
28
27
|
-- The created_at filter has been introduced for performance reasons only
|
@@ -95,8 +94,7 @@ module GitLab
|
|
95
94
|
ON namespaces.id = projects.namespace_id
|
96
95
|
LEFT JOIN namespace_statistics
|
97
96
|
ON namespace_statistics.namespace_id = namespaces.id
|
98
|
-
JOIN application_settings
|
99
|
-
ON application_settings.id = 1
|
97
|
+
JOIN application_settings ON (TRUE)
|
100
98
|
WHERE ci_builds.type = 'Ci::Build'
|
101
99
|
AND ci_builds.status = 'running'
|
102
100
|
-- The created_at filter has been introduced for performance reasons only
|
@@ -175,8 +173,7 @@ module GitLab
|
|
175
173
|
ON namespaces.id = projects.namespace_id
|
176
174
|
LEFT JOIN namespace_statistics
|
177
175
|
ON namespace_statistics.namespace_id = namespaces.id
|
178
|
-
JOIN application_settings
|
179
|
-
ON application_settings.id = 1
|
176
|
+
JOIN application_settings ON (TRUE)
|
180
177
|
WHERE ci_builds.type = 'Ci::Build'
|
181
178
|
AND ci_builds.status IN ('running', 'pending')
|
182
179
|
-- The created_at filter has been introduced for performance reasons only
|
@@ -265,8 +262,8 @@ module GitLab
|
|
265
262
|
|
266
263
|
DEFAULT_UNARCHIVED_TRACES_OFFSET_MINUTES = 1440
|
267
264
|
|
268
|
-
def initialize(opts)
|
269
|
-
super(opts)
|
265
|
+
def initialize(opts, logger: nil)
|
266
|
+
super(opts, logger: logger)
|
270
267
|
|
271
268
|
@allowed_repeated_commands_count = opts[:allowed_repeated_commands_count]
|
272
269
|
@created_builds_counting_disabled = opts[:created_builds_counting_disabled]
|
@@ -420,14 +417,14 @@ module GitLab
|
|
420
417
|
|
421
418
|
# The prober which is called when gathering metrics
|
422
419
|
class CiBuildsProber
|
423
|
-
def initialize(opts, metrics: PrometheusMetrics.new)
|
420
|
+
def initialize(opts, metrics: PrometheusMetrics.new, logger: nil)
|
424
421
|
@metrics = metrics
|
425
422
|
|
426
423
|
collector_opts = { connection_string: opts[:connection_string],
|
427
424
|
allowed_repeated_commands_count: opts[:allowed_repeated_commands_count],
|
428
425
|
created_builds_counting_disabled: opts[:created_builds_counting_disabled],
|
429
426
|
unarchived_traces_offset_minutes: opts[:unarchived_traces_offset_minutes] }
|
430
|
-
@collector = CiBuildsCollector.new(collector_opts)
|
427
|
+
@collector = CiBuildsCollector.new(collector_opts, logger: logger)
|
431
428
|
end
|
432
429
|
|
433
430
|
def probe_db
|
@@ -35,7 +35,7 @@ module GitLab
|
|
35
35
|
|
36
36
|
# The prober which is called when gathering metrics
|
37
37
|
class RemoteMirrorsProber
|
38
|
-
def initialize(opts, metrics: PrometheusMetrics.new)
|
38
|
+
def initialize(opts, metrics: PrometheusMetrics.new, logger: nil) # rubocop:disable Lint/UnusedMethodArgument
|
39
39
|
@metrics = metrics
|
40
40
|
@collector = RemoteMirrorsCollector.new(
|
41
41
|
connection_string: opts[:connection_string],
|
@@ -175,6 +175,14 @@ module GitLab
|
|
175
175
|
|
176
176
|
def execute(query)
|
177
177
|
with_connection_pool do |conn|
|
178
|
+
conn.exec(query).map_types!(type_map_for_results(conn))
|
179
|
+
end
|
180
|
+
rescue PG::UndefinedTable, PG::UndefinedColumn
|
181
|
+
nil
|
182
|
+
end
|
183
|
+
|
184
|
+
def type_map_for_results(conn)
|
185
|
+
@type_map_for_results ||= begin
|
178
186
|
tm = PG::BasicTypeMapForResults.new(conn)
|
179
187
|
|
180
188
|
# Remove warning message:
|
@@ -187,10 +195,8 @@ module GitLab
|
|
187
195
|
tm.add_coder(old_coder.dup.tap { |c| c.oid = value[:oid] })
|
188
196
|
end
|
189
197
|
|
190
|
-
|
198
|
+
tm
|
191
199
|
end
|
192
|
-
rescue PG::UndefinedTable, PG::UndefinedColumn
|
193
|
-
nil
|
194
200
|
end
|
195
201
|
|
196
202
|
# Not private so I can test it without meta programming tricks
|
@@ -212,7 +218,7 @@ module GitLab
|
|
212
218
|
|
213
219
|
# The prober which is called when gathering metrics
|
214
220
|
class RowCountProber
|
215
|
-
def initialize(opts, metrics: PrometheusMetrics.new)
|
221
|
+
def initialize(opts, metrics: PrometheusMetrics.new, logger: nil) # rubocop:disable Lint/UnusedMethodArgument
|
216
222
|
@metrics = metrics
|
217
223
|
@collector = RowCountCollector.new(
|
218
224
|
connection_string: opts[:connection_string],
|
@@ -25,9 +25,9 @@ module GitLab
|
|
25
25
|
|
26
26
|
# Probes the DB specified by opts[:connection_string] for tuple stats, then converts them to metrics
|
27
27
|
class TuplesProber
|
28
|
-
def initialize(opts, metrics: PrometheusMetrics.new)
|
28
|
+
def initialize(opts, metrics: PrometheusMetrics.new, logger: nil)
|
29
29
|
@metrics = metrics
|
30
|
-
@collector = TupleStatsCollector.new(connection_string: opts[:connection_string])
|
30
|
+
@collector = TupleStatsCollector.new(connection_string: opts[:connection_string], logger: logger)
|
31
31
|
end
|
32
32
|
|
33
33
|
def probe_db
|
data/lib/gitlab_exporter/git.rb
CHANGED
@@ -62,7 +62,7 @@ module GitLab
|
|
62
62
|
# Optionally takes a metrics object which by default is a PrometheusMetrics, useful to change the
|
63
63
|
# metrics writer to something else.
|
64
64
|
class GitProber
|
65
|
-
def initialize(opts, metrics: PrometheusMetrics.new)
|
65
|
+
def initialize(opts, metrics: PrometheusMetrics.new, logger: nil) # rubocop:disable Lint/UnusedMethodArgument
|
66
66
|
@metrics = metrics
|
67
67
|
@labels = opts[:labels] || {}
|
68
68
|
@git = Git.new(opts[:source])
|
@@ -85,7 +85,7 @@ module GitLab
|
|
85
85
|
|
86
86
|
# A special prober for git processes
|
87
87
|
class GitProcessProber
|
88
|
-
def initialize(opts, metrics: PrometheusMetrics.new)
|
88
|
+
def initialize(opts, metrics: PrometheusMetrics.new, logger: nil) # rubocop:disable Lint/UnusedMethodArgument
|
89
89
|
@opts = opts
|
90
90
|
@metrics = metrics
|
91
91
|
end
|
@@ -2,9 +2,10 @@ module GitLab
|
|
2
2
|
module Exporter
|
3
3
|
# A class to combine multiple probers into one
|
4
4
|
class Prober
|
5
|
-
def initialize(prober_opts, metrics: PrometheusMetrics.new)
|
5
|
+
def initialize(prober_opts, metrics: PrometheusMetrics.new, logger: nil)
|
6
6
|
@prober_opts = prober_opts
|
7
7
|
@metrics = metrics
|
8
|
+
@logger = logger
|
8
9
|
|
9
10
|
resolve_prober_classes
|
10
11
|
end
|
@@ -12,7 +13,7 @@ module GitLab
|
|
12
13
|
def probe_all
|
13
14
|
@prober_opts.each do |_probe_name, params|
|
14
15
|
Utils.wrap_in_array(params[:opts]).each do |opts|
|
15
|
-
prober = params[:class].new(opts, metrics: @metrics)
|
16
|
+
prober = params[:class].new(opts, metrics: @metrics, logger: @logger)
|
16
17
|
params[:methods].each do |meth|
|
17
18
|
prober.send(meth)
|
18
19
|
end
|
@@ -59,7 +59,7 @@ module GitLab
|
|
59
59
|
|
60
60
|
# Probes a process for info then writes metrics to a target
|
61
61
|
class ProcessProber
|
62
|
-
def initialize(options, metrics: PrometheusMetrics.new)
|
62
|
+
def initialize(options, metrics: PrometheusMetrics.new, logger: nil) # rubocop:disable Lint/UnusedMethodArgument
|
63
63
|
@metrics = metrics
|
64
64
|
@name = options[:name]
|
65
65
|
@pids = if options[:pid_or_pattern] =~ /^\d+$/
|
@@ -10,9 +10,10 @@ module GitLab
|
|
10
10
|
QUEUE_JOB_STATS_SCRIPT = File.read(File.expand_path("#{__FILE__}/../sidekiq_queue_job_stats.lua")).freeze
|
11
11
|
QUEUE_JOB_STATS_SHA = Digest::SHA1.hexdigest(QUEUE_JOB_STATS_SCRIPT).freeze
|
12
12
|
|
13
|
-
def initialize(opts, metrics: PrometheusMetrics.new)
|
13
|
+
def initialize(opts, metrics: PrometheusMetrics.new, logger: nil)
|
14
14
|
@opts = opts
|
15
15
|
@metrics = metrics
|
16
|
+
@logger = logger
|
16
17
|
|
17
18
|
Sidekiq.configure_client do |config|
|
18
19
|
config.redis = redis_options
|
@@ -42,6 +42,11 @@ module GitLab
|
|
42
42
|
|
43
43
|
memory_threshold = (config[:server] && config[:server][:memory_threshold]) || 1024
|
44
44
|
use MemoryKillerMiddleware, memory_threshold
|
45
|
+
use Rack::Logger
|
46
|
+
end
|
47
|
+
|
48
|
+
def logger
|
49
|
+
request.logger
|
45
50
|
end
|
46
51
|
|
47
52
|
def setup_server(config)
|
@@ -62,7 +67,7 @@ module GitLab
|
|
62
67
|
|
63
68
|
get "/#{probe_name}" do
|
64
69
|
content_type "text/plain; version=0.0.4"
|
65
|
-
prober = Prober.new(opts, metrics: PrometheusMetrics.new(include_timestamp: false))
|
70
|
+
prober = Prober.new(opts, metrics: PrometheusMetrics.new(include_timestamp: false), logger: logger)
|
66
71
|
|
67
72
|
prober.probe_all
|
68
73
|
prober.write_to(response)
|
data/spec/database/bloat_spec.rb
CHANGED
@@ -43,7 +43,11 @@ describe GitLab::Exporter::Database::BloatProber do
|
|
43
43
|
end
|
44
44
|
|
45
45
|
describe "#probe_db" do
|
46
|
-
subject { described_class.new(opts, metrics: metrics, collector: collector).probe_db }
|
46
|
+
subject { described_class.new(opts, metrics: metrics, collector: collector, logger: STDOUT).probe_db }
|
47
|
+
|
48
|
+
before do
|
49
|
+
expect(collector).to receive(:logger=).with(STDOUT)
|
50
|
+
end
|
47
51
|
|
48
52
|
it "invokes the collector for each bloat type" do
|
49
53
|
expect(collector).to receive(:run).with(:btree)
|
metadata
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gitlab-exporter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 7.0
|
4
|
+
version: 7.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pablo Carranza
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
date: 2016-07-27 00:00:00.000000000 Z
|
@@ -191,7 +191,7 @@ homepage: http://gitlab.com
|
|
191
191
|
licenses:
|
192
192
|
- MIT
|
193
193
|
metadata: {}
|
194
|
-
post_install_message:
|
194
|
+
post_install_message:
|
195
195
|
rdoc_options: []
|
196
196
|
require_paths:
|
197
197
|
- lib
|
@@ -207,7 +207,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
207
207
|
version: '0'
|
208
208
|
requirements: []
|
209
209
|
rubygems_version: 3.0.3
|
210
|
-
signing_key:
|
210
|
+
signing_key:
|
211
211
|
specification_version: 4
|
212
212
|
summary: GitLab metrics exporter
|
213
213
|
test_files:
|