@@ -2,22 +2,35 @@ module Gitlab
2
2
module Metrics
3
3
# Class for storing metrics information of a single transaction.
4
4
class Transaction
5
+ CONTROLLER_KEY = 'action_controller.instance' . freeze
6
+ ENDPOINT_KEY = 'api.endpoint' . freeze
7
+
8
+ CONTENT_TYPES = {
9
+ 'text/html' => :html ,
10
+ 'text/plain' => :txt ,
11
+ 'application/json' => :json ,
12
+ 'text/js' => :js ,
13
+ 'application/atom+xml' => :atom ,
14
+ 'image/png' => :png ,
15
+ 'image/jpeg' => :jpeg ,
16
+ 'image/gif' => :gif ,
17
+ 'image/svg+xml' => :svg
18
+ } . freeze
19
+
5
20
THREAD_KEY = :_gitlab_metrics_transaction
6
21
7
22
# The series to store events (e.g. Git pushes) in.
8
23
EVENT_SERIES = 'events' . freeze
9
24
10
25
attr_reader :tags , :values , :method , :metrics
11
26
12
- attr_accessor :action
13
-
14
27
def self . current
15
28
Thread . current [ THREAD_KEY ]
16
29
end
17
30
18
31
# action - A String describing the action performed, usually the class
19
32
# plus method name.
20
- def initialize ( action = nil )
33
+ def initialize ( env )
21
34
@metrics = [ ]
22
35
@methods = { }
23
36
@@ -26,7 +39,7 @@ def initialize(action = nil)
26
39
27
40
@values = Hash . new ( 0 )
28
41
@tags = { }
29
- @action = action
42
+ @env = env
30
43
31
44
@memory_before = 0
32
45
@memory_after = 0
@@ -40,22 +53,12 @@ def allocated_memory
40
53
@memory_after - @memory_before
41
54
end
42
55
43
- def self . metric_transaction_duration_seconds
44
- @metric_transaction_duration_seconds ||= Gitlab ::Metrics . histogram (
45
- :gitlab_transaction_duration_seconds ,
46
- 'Transaction duration' ,
47
- { action : nil } ,
48
- [ 0.001 , 0.002 , 0.005 , 0.01 , 0.02 , 0.05 , 0.1 , 0.500 , 2.0 , 10.0 ]
49
- )
50
- end
51
-
52
- def self . metric_transaction_allocated_memory_bytes
53
- @metric_transaction_allocated_memory_bytes ||= Gitlab ::Metrics . histogram (
54
- :gitlab_transaction_allocated_memory_bytes ,
55
- 'Transaction allocated memory bytes' ,
56
- { action : nil } ,
57
- [ 1000 , 10000 , 20000 , 500000 , 1000000 , 2000000 , 5000000 , 10000000 , 20000000 , 100000000 ]
58
- )
56
+ def action
57
+ @action ||= if @env [ CONTROLLER_KEY ]
58
+ action_from_controller ( @env ) || ''
59
+ elsif @env [ ENDPOINT_KEY ]
60
+ action_from_endpoint ( @env ) || ''
61
+ end
59
62
end
60
63
61
64
def run
@@ -135,7 +138,7 @@ def submit
135
138
submit_hashes = submit . map do |metric |
136
139
hash = metric . to_hash
137
140
138
- hash [ :tags ] [ :action ] ||= @ action if @ action && !metric . event?
141
+ hash [ :tags ] [ :action ] ||= action if action && !metric . event?
139
142
140
143
hash
141
144
end
@@ -145,6 +148,24 @@ def submit
145
148
146
149
private
147
150
151
+ def self . metric_transaction_duration_seconds
152
+ @metric_transaction_duration_seconds ||= Gitlab ::Metrics . histogram (
153
+ :gitlab_transaction_duration_seconds ,
154
+ 'Transaction duration' ,
155
+ { action : nil } ,
156
+ [ 0.001 , 0.002 , 0.005 , 0.01 , 0.02 , 0.05 , 0.1 , 0.500 , 2.0 , 10.0 ]
157
+ )
158
+ end
159
+
160
+ def self . metric_transaction_allocated_memory_bytes
161
+ @metric_transaction_allocated_memory_bytes ||= Gitlab ::Metrics . histogram (
162
+ :gitlab_transaction_allocated_memory_bytes ,
163
+ 'Transaction allocated memory bytes' ,
164
+ { action : nil } ,
165
+ [ 1000 , 10000 , 20000 , 500000 , 1000000 , 2000000 , 5000000 , 10000000 , 20000000 , 100000000 ]
166
+ )
167
+ end
168
+
148
169
def self . metric_event_counter ( event_name , tags )
149
170
@metric_event_counters ||= { }
150
171
@metric_event_counters [ event_name ] ||= Gitlab ::Metrics . counter (
@@ -167,6 +188,36 @@ def self.metric_transaction_gauge(name)
167
188
"gitlab_transaction_#{ name } " . to_sym , "Transaction gauge #{ name } " , { action : nil } , :livesum
168
189
)
169
190
end
191
+
192
+ def action_from_controller ( env )
193
+ controller = env [ CONTROLLER_KEY ]
194
+
195
+ action = "#{ controller . class . name } ##{ controller . action_name } "
196
+ suffix = CONTENT_TYPES [ controller . content_type ]
197
+
198
+ if suffix && suffix != :html
199
+ action += ".#{ suffix } "
200
+ end
201
+
202
+ action
203
+ end
204
+
205
+ def action_from_endpoint ( env )
206
+ endpoint = env [ ENDPOINT_KEY ]
207
+
208
+ begin
209
+ route = endpoint . route
210
+ rescue
211
+ # endpoint.route is calling env[Grape::Env::GRAPE_ROUTING_ARGS][:route_info]
212
+ # but env[Grape::Env::GRAPE_ROUTING_ARGS] is nil in the case of a 405 response
213
+ # so we're rescuing exceptions and bailing out
214
+ end
215
+
216
+ if route
217
+ path = endpoint_paths_cache [ route . request_method ] [ route . path ]
218
+ "Grape##{ route . request_method } #{ path } "
219
+ end
220
+ end
170
221
end
171
222
end
172
223
end
0 commit comments