gitlab-exporter 6.0.0 → 6.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1378d48a7af04eee678edaa21da6d5795baa5828d0b06853b816e8c6b8e8d489
4
- data.tar.gz: e221a2070050abee80662777a94afee1d4369ae8f108583f28f640cc2fc2517b
3
+ metadata.gz: 61203f2c5d53c61f05151255076c5004c65a254c2445d632ae8c7262ae0e1f82
4
+ data.tar.gz: 66b13da650dd0e66b3a4d639bf1738de51474e047e0df878893a5b675d158827
5
5
  SHA512:
6
- metadata.gz: d7c222835cd8bc99f412f95fb17457310857634b4c9c9b9b2ffb3a1f5b7002b05445f6331f4e0cdd74a4319d4bf0730e68070acd043168b65d8bfacf52da1e88
7
- data.tar.gz: e4d5aababedf60ee0865f5b9c455011f0941acb2d8ad0bb21bb6c4a2021aeba23ac3d2123238d8cc7932e70bc508dca43f3e396031b57b199c6aff752d86d457
6
+ metadata.gz: 7ab02d67cc6e2bf4e443e73f49138eb7549961d535a1c7425e7f9a7872ec7095f6ad77522105eee8111c674cbdebbfec304296953c884dd006832d452079414c
7
+ data.tar.gz: 81bf3b39c8cb1462dabbf51be56057efb9fddfbe0db6da4d6f1f7827f71f4a8cebf04e5890caf07ccaa588b873897dfef32e91d7276361a6fe629349eb2691b0
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- gitlab-exporter (6.0.0)
4
+ gitlab-exporter (6.1.0)
5
5
  connection_pool (~> 2.2.1)
6
6
  pg (~> 1.1)
7
7
  quantile (~> 0.2.0)
@@ -23,7 +23,7 @@ GEM
23
23
  pg (1.2.2)
24
24
  powerpack (0.1.1)
25
25
  quantile (0.2.1)
26
- rack (2.1.2)
26
+ rack (2.2.2)
27
27
  rack-protection (2.0.8.1)
28
28
  rack
29
29
  rainbow (2.1.0)
@@ -60,6 +60,9 @@ probes:
60
60
  - soft_deleted_projects
61
61
  - orphaned_projects
62
62
  - uploads
63
+ - users
64
+ - projects
65
+ - groups
63
66
  remote_mirrors:
64
67
  class_name: Database::RemoteMirrorsProber
65
68
  <<: *db_common
@@ -79,7 +79,40 @@ module GitLab
79
79
  joins: "LEFT JOIN namespaces ON projects.namespace_id = namespaces.id",
80
80
  where: "namespaces.id IS NULL"
81
81
  },
82
- uploads: { select: :uploads }
82
+ uploads: { select: :uploads },
83
+ users: {
84
+ select: :users,
85
+ joins: "LEFT JOIN
86
+ (
87
+ SELECT
88
+ members.user_id,
89
+ MAX(access_level) as access_level
90
+ FROM members
91
+ GROUP BY members.user_id
92
+ ) AS u
93
+ ON users.id = u.user_id",
94
+ where: "ghost IS NULL AND bot_type IS NULL",
95
+ fields: {
96
+ admin: {},
97
+ external: {},
98
+ state: {},
99
+ access_level: { definition: "COALESCE(u.access_level, 0)" }
100
+ }
101
+ },
102
+ projects: {
103
+ select: :projects,
104
+ fields: {
105
+ visibility_level: {},
106
+ archived: {}
107
+ }
108
+ },
109
+ groups: {
110
+ select: :namespaces,
111
+ fields: {
112
+ visibility_level: {},
113
+ root: { definition: "(parent_id IS NULL)" }
114
+ }
115
+ }
83
116
  }.freeze
84
117
 
85
118
  def initialize(args)
@@ -105,21 +138,37 @@ module GitLab
105
138
 
106
139
  def count_from_query_hash(query_hash)
107
140
  result = execute(construct_query(query_hash))
108
- return 0 unless result
141
+ return [{ "count": 0, "labels": {} }] unless result
109
142
 
110
- result[0]["count"]
143
+ result.map do |row|
144
+ labels = {}
145
+ (query_hash[:fields] || []).each do |key, _| labels[key] = row[key.to_s] end
146
+ { "count": row["count"], "labels": labels }
147
+ end
111
148
  end
112
149
 
113
150
  def successful_check?(query)
114
151
  result = execute("SELECT EXISTS (#{query})")
115
152
  return unless result
116
153
 
117
- result[0]["exists"] == "t"
154
+ result[0]["exists"]
118
155
  end
119
156
 
120
157
  def execute(query)
121
158
  with_connection_pool do |conn|
122
- conn.exec(query)
159
+ tm = PG::BasicTypeMapForResults.new(conn)
160
+
161
+ # Remove warning message:
162
+ # Warning: no type cast defined for type "name" with oid 19.
163
+ # Please cast this type explicitly to TEXT to be safe for future changes.
164
+ # Warning: no type cast defined for type "regproc" with oid 24.
165
+ # Please cast this type explicitly to TEXT to be safe for future changes.
166
+ [{ "type": "text", "oid": 19 }, { "type": "int4", "oid": 24 }].each do |value|
167
+ old_coder = tm.coders.find { |c| c.name == value[:type] }
168
+ tm.add_coder(old_coder.dup.tap { |c| c.oid = value[:oid] })
169
+ end
170
+
171
+ conn.exec(query).map_types!(tm)
123
172
  end
124
173
  rescue PG::UndefinedTable, PG::UndefinedColumn
125
174
  nil
@@ -127,9 +176,16 @@ module GitLab
127
176
 
128
177
  # Not private so I can test it without meta programming tricks
129
178
  def construct_query(query)
130
- query_string = "SELECT COUNT(*) FROM #{query[:select]} "
131
- query_string << "#{query[:joins]} " if query[:joins]
132
- query_string << "WHERE #{query[:where]}" if query[:where]
179
+ query_string = "SELECT COUNT(*)"
180
+ (query[:fields] || []).each do |key, value|
181
+ query_string << ", "
182
+ query_string << "(#{value[:definition]}) AS " if value[:definition]
183
+ query_string << key.to_s
184
+ end
185
+ query_string << " FROM #{query[:select]}"
186
+ query_string << " #{query[:joins]}" if query[:joins]
187
+ query_string << " WHERE #{query[:where]}" if query[:where]
188
+ query_string << " GROUP BY " + query[:fields].keys.join(", ") if query[:fields]
133
189
  query_string << ";"
134
190
  end
135
191
  end
@@ -146,8 +202,11 @@ module GitLab
146
202
 
147
203
  def probe_db
148
204
  results = @collector.run
149
- results.each do |key, value|
150
- @metrics.add("gitlab_database_rows", value.to_f, query_name: key.to_s)
205
+ results.each do |query_name, result|
206
+ labels = { query_name: query_name.to_s }
207
+ result.each do |row|
208
+ @metrics.add("gitlab_database_rows", row[:count].to_f, **labels, **row[:labels])
209
+ end
151
210
  end
152
211
 
153
212
  self
@@ -1,5 +1,5 @@
1
1
  module GitLab
2
2
  module Exporter
3
- VERSION = "6.0.0".freeze
3
+ VERSION = "6.1.0".freeze
4
4
  end
5
5
  end
@@ -4,7 +4,8 @@ require "gitlab_exporter/database/row_count"
4
4
  describe GitLab::Exporter::Database::RowCountCollector do
5
5
  let(:query) {
6
6
  { project_1: { select: :projects, where: "id=1" },
7
- project_2: { select: :projects, where: "id=2" } }
7
+ project_2: { select: :projects, where: "id=2" },
8
+ project_3: { select: :projects, fields: { is_public: { definition: "visibility_level == 20" } } } }
8
9
  }
9
10
  let(:collector) { described_class.new(connection_string: "host=localhost") }
10
11
 
@@ -12,19 +13,31 @@ describe GitLab::Exporter::Database::RowCountCollector do
12
13
  before do
13
14
  stub_const("GitLab::Exporter::Database::RowCountCollector::QUERIES", query)
14
15
 
15
- allow(collector).to receive(:count_from_query_hash).with(query[:project_1]).and_return(3)
16
- allow(collector).to receive(:count_from_query_hash).with(query[:project_2]).and_return(6)
16
+ allow(collector).to receive(:execute).with("SELECT COUNT(*) FROM projects WHERE id=1;").and_return(false)
17
+ allow(collector).to receive(:execute).with("SELECT COUNT(*) FROM projects WHERE id=2;").and_return(
18
+ [{ "count" => 6 }]
19
+ )
20
+ allow(collector).to receive(:execute).with(
21
+ "SELECT COUNT(*), (visibility_level == 20) AS is_public FROM projects GROUP BY is_public;"
22
+ ).and_return(
23
+ [{ "count" => 3, "is_public" => true }, { "count" => 6, "is_public" => false }]
24
+ )
17
25
  end
18
26
 
19
27
  it "executes all the queries" do
20
- expect(collector.run).to eq(project_1: 3, project_2: 6)
28
+ expect(collector.run).to eq(
29
+ project_1: [{ count: 0, labels: {} }],
30
+ project_2: [{ count: 6, labels: {} }],
31
+ project_3: [{ count: 3, labels: { is_public: true } },
32
+ { count: 6, labels: { is_public: false } }]
33
+ )
21
34
  end
22
35
 
23
36
  context "when selected_queries is passed" do
24
37
  let(:collector) { described_class.new(connection_string: "host=localhost", selected_queries: ["project_2"]) }
25
38
 
26
39
  it "executes the selected queries" do
27
- expect(collector.run).to eq(project_2: 6)
40
+ expect(collector.run).to eq(project_2: [{ count: 6, labels: {} }])
28
41
  end
29
42
  end
30
43
  end
@@ -33,5 +46,10 @@ describe GitLab::Exporter::Database::RowCountCollector do
33
46
  it "accepts a table and where clause" do
34
47
  expect(collector.send(:construct_query, query[:project_1])).to eq "SELECT COUNT(*) FROM projects WHERE id=1;"
35
48
  end
49
+
50
+ it "accepts a table and group (field) clause" do
51
+ expect(collector.send(:construct_query, query[:project_3])).to eq \
52
+ "SELECT COUNT(*), (visibility_level == 20) AS is_public FROM projects GROUP BY is_public;"
53
+ end
36
54
  end
37
55
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gitlab-exporter
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.0.0
4
+ version: 6.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pablo Carranza