gitlab-exporter 6.0.0 → 6.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +2 -2
- data/config/gitlab-exporter.yml.example +3 -0
- data/lib/gitlab_exporter/database/row_count.rb +69 -10
- data/lib/gitlab_exporter/version.rb +1 -1
- data/spec/database/row_count_spec.rb +23 -5
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 61203f2c5d53c61f05151255076c5004c65a254c2445d632ae8c7262ae0e1f82
|
4
|
+
data.tar.gz: 66b13da650dd0e66b3a4d639bf1738de51474e047e0df878893a5b675d158827
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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.
|
26
|
+
rack (2.2.2)
|
27
27
|
rack-protection (2.0.8.1)
|
28
28
|
rack
|
29
29
|
rainbow (2.1.0)
|
@@ -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
|
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"]
|
154
|
+
result[0]["exists"]
|
118
155
|
end
|
119
156
|
|
120
157
|
def execute(query)
|
121
158
|
with_connection_pool do |conn|
|
122
|
-
|
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(*)
|
131
|
-
|
132
|
-
|
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 |
|
150
|
-
|
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
|
@@ -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(:
|
16
|
-
allow(collector).to receive(:
|
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(
|
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
|