gitlab-exporter 7.0.5 → 7.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: de89f0131cde7415ce666ec09c4da388b53f4cbf57b8e7872f3e5538be257e30
4
- data.tar.gz: 4b84a64c0d3b26306628ec04dc2ce7b56b36eda349385a43855b1a968c2a8560
3
+ metadata.gz: 86ad2e8d49582c70ba5faa5e7a8744a0e812f5682447cc1e1f000e050a3b9451
4
+ data.tar.gz: 2a0f878e42abef28992284e0e372db960831025b7ff3cf71c676369210d05fea
5
5
  SHA512:
6
- metadata.gz: a292b9c5c4f24fab3014e6bc9ae5f3b86c86ff47d5034fce9280d1fa75372cbcd18e5d75a6e130c9de77fc662b1ef2fa6d1dd9f390a004236c727e311a9e02a3
7
- data.tar.gz: 6f1309c2abeeeca930d0485d66b9b714006f1d97814141fba7f6a2b4db063ee41f0181857de0044435d8e3b14d10e844d2ed595a5ce2505fe63a02ef6abce466
6
+ metadata.gz: 28d6f61e6df16ac17ba9e25ddea5d6a39c65940796898a2a6bad66c352ad47a1341593e3bb8dd7edaefd5281a787612beda9ff6f3f3700c6c458ad345fef055d
7
+ data.tar.gz: f7b2ff3ddd97529571e0517f4b8f9c7d42fe512f5d786a9c60dfae6337cafc56f5ae8eecaf98e3d85d0cb987e66363102bfec40a6ff4411524359cdf888f9d3e
@@ -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
- include:
31
- - template: Security/DAST.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab-foss/blob/master/lib/gitlab/ci/templates/Security/DAST.gitlab-ci.yml
32
- - 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
33
- - 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
34
- - 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
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
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- gitlab-exporter (7.0.5)
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.2)
17
+ connection_pool (2.2.3)
18
18
  diff-lcs (1.3)
19
- mustermann (1.0.3)
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.2)
23
+ pg (1.2.3)
23
24
  powerpack (0.1.1)
24
25
  quantile (0.2.1)
25
- rack (2.0.7)
26
- rack-protection (2.0.7)
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.3)
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
- sidekiq (5.2.7)
53
+ ruby2_keywords (0.0.2)
54
+ sidekiq (5.2.9)
53
55
  connection_pool (~> 2.2, >= 2.2.2)
54
- rack (>= 1.5.0)
56
+ rack (~> 2.0)
55
57
  rack-protection (>= 1.5.0)
56
- redis (>= 3.3.5, < 5)
57
- sinatra (2.0.7)
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.7)
62
+ rack-protection (= 2.0.8.1)
61
63
  tilt (~> 2.0)
62
- tilt (2.0.9)
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-(sub.pst).avg_leaf_density, est_pages, index_tuple_hdr_bm, maxalign, pagehdr, nulldatawidth, nulldatahdrwidth, sub.reltuples, sub.relpages -- (DEBUG INFO)
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
- 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, table_oid, tblname, idxname, relpages, fillfactor, is_na
24
- -- , stattuple.pgstatindex(quote_ident(nspname)||'.'||quote_ident(idxname)) AS pst, index_tuple_hdr_bm, maxalign, pagehdr, nulldatawidth, nulldatahdrwidth, reltuples -- (DEBUG INFO)
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
- SELECT maxalign, bs, nspname, tblname, idxname, reltuples, relpages, relam, table_oid, 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
41
- i.nspname, i.tblname, i.idxname, i.reltuples, i.relpages, i.relam, a.attrelid AS table_oid,
42
- current_setting('block_size')::numeric AS bs, fillfactor,
43
- CASE -- MAXALIGN: 4 on 32bits, 8 on 64bits (and mingw32 ?)
44
- WHEN version() ~ 'mingw32' OR version() ~ '64-bit|x86_64|ppc64|ia64|amd64' THEN 8
45
- ELSE 4
46
- END AS maxalign,
47
- /* per page header, fixed size: 20 for 7.X, 24 for others */
48
- 24 AS pagehdr,
49
- /* per page btree opaque data */
50
- 16 AS pageopqdata,
51
- /* per tuple header: add IndexAttributeBitMapData if some cols are null-able */
52
- CASE WHEN max(coalesce(s.null_frac,0)) = 0
53
- THEN 2 -- IndexTupleData size
54
- ELSE 2 + (( 32 + 8 - 1 ) / 8) -- IndexTupleData size + IndexAttributeBitMapData size ( max num filed per index + 8 - 1 /8)
55
- END AS index_tuple_hdr_bm,
56
- /* data len: we remove null values save space using it fractionnal part from stats */
57
- sum( (1-coalesce(s.null_frac, 0)) * coalesce(s.avg_width, 1024)) AS nulldatawidth,
58
- max( CASE WHEN a.atttypid = 'pg_catalog.name'::regtype THEN 1 ELSE 0 END ) > 0 AS is_na
59
- FROM pg_attribute AS a
60
- JOIN (
61
- SELECT nspname, tbl.relname AS tblname, idx.relname AS idxname, idx.reltuples, idx.relpages, idx.relam,
62
- indrelid, indexrelid, indkey::smallint[] AS attnum,
63
- coalesce(substring(
64
- array_to_string(idx.reloptions, ' ')
65
- from 'fillfactor=([0-9]+)')::smallint, 90) AS fillfactor
66
- FROM pg_index
67
- JOIN pg_class idx ON idx.oid=pg_index.indexrelid
68
- JOIN pg_class tbl ON tbl.oid=pg_index.indrelid
69
- JOIN pg_namespace ON pg_namespace.oid = idx.relnamespace
70
- WHERE pg_index.indisvalid AND tbl.relkind = 'r' AND idx.relpages > 0
71
- ) AS i ON a.attrelid = i.indexrelid
72
- JOIN pg_stats AS s ON s.schemaname = i.nspname
73
- AND ((s.tablename = i.tblname AND s.attname = pg_catalog.pg_get_indexdef(a.attrelid, a.attnum, TRUE)) -- stats from tbl
74
- OR (s.tablename = i.idxname AND s.attname = a.attname))-- stats from functionnal cols
75
- JOIN pg_type AS t ON a.atttypid = t.oid
76
- WHERE a.attnum > 0
77
- GROUP BY 1, 2, 3, 4, 5, 6, 7, 8, 9
78
- ) AS s1
79
- ) AS s2
80
- JOIN pg_am am ON s2.relam = am.oid WHERE am.amname = 'btree'
81
- ) AS sub
82
- WHERE NOT is_na
83
- AND nspname = 'public'
84
- ORDER BY 2,3,4;
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
- -- , stattuple.pgstattuple(tblid) AS pst
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(*) ) / 8 ELSE 0::int END
44
- + CASE WHEN tbl.relhasoids THEN 4 ELSE 0 END AS tpl_hdr_size,
45
- sum( (1-coalesce(s.null_frac, 0)) * coalesce(s.avg_width, 1024) ) AS tpl_data_size,
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 count(att.attname) <> count(s.attname) AS is_na
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 att.attnum > 0 AND NOT att.attisdropped
55
- AND tbl.relkind = 'r'
56
- GROUP BY 1,2,3,4,5,6,7,8,9,10, tbl.relhasoids
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
- AND schemaname= 'public';
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
- conn.exec(query).map_types!(tm)
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
@@ -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
@@ -1,5 +1,5 @@
1
1
  module GitLab
2
2
  module Exporter
3
- VERSION = "7.0.5".freeze
3
+ VERSION = "7.2.0".freeze
4
4
  end
5
5
  end
@@ -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)
@@ -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.5
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: