1
- require 'prometheus/client'
2
-
3
1
module Gitlab
4
2
module Metrics
5
- extend Gitlab ::CurrentSettings
6
-
7
- RAILS_ROOT = Rails . root . to_s
8
- METRICS_ROOT = Rails . root . join ( 'lib' , 'gitlab' , 'metrics' ) . to_s
9
- PATH_REGEX = /^#{ RAILS_ROOT } \/ ?/
10
-
11
- def self . settings
12
- @settings ||= {
13
- enabled : current_application_settings [ :metrics_enabled ] ,
14
- prometheus_metrics_enabled : current_application_settings [ :prometheus_metrics_enabled ] ,
15
- pool_size : current_application_settings [ :metrics_pool_size ] ,
16
- timeout : current_application_settings [ :metrics_timeout ] ,
17
- method_call_threshold : current_application_settings [ :metrics_method_call_threshold ] ,
18
- host : current_application_settings [ :metrics_host ] ,
19
- port : current_application_settings [ :metrics_port ] ,
20
- sample_interval : current_application_settings [ :metrics_sample_interval ] || 15 ,
21
- packet_size : current_application_settings [ :metrics_packet_size ] || 1
22
- }
23
- end
24
-
25
- def self . prometheus_metrics_enabled?
26
- settings [ :prometheus_metrics_enabled ] || false
27
- end
28
-
29
- def self . influx_metrics_enabled?
30
- settings [ :enabled ] || false
31
- end
3
+ extend Gitlab ::Metrics ::InfluxDb
4
+ extend Gitlab ::Metrics ::Prometheus
32
5
33
6
def self . enabled?
34
7
influx_metrics_enabled? || prometheus_metrics_enabled?
35
8
end
36
-
37
- def self . mri?
38
- RUBY_ENGINE == 'ruby'
39
- end
40
-
41
- def self . method_call_threshold
42
- # This is memoized since this method is called for every instrumented
43
- # method. Loading data from an external cache on every method call slows
44
- # things down too much.
45
- @method_call_threshold ||= settings [ :method_call_threshold ]
46
- end
47
-
48
- def self . pool
49
- @pool
50
- end
51
-
52
- def self . registry
53
- @registry ||= ::Prometheus ::Client . registry
54
- end
55
-
56
- def self . counter ( name , docstring , base_labels = { } )
57
- provide_metric ( name ) || registry . counter ( name , docstring , base_labels )
58
- end
59
-
60
- def self . summary ( name , docstring , base_labels = { } )
61
- provide_metric ( name ) || registry . summary ( name , docstring , base_labels )
62
- end
63
-
64
- def self . gauge ( name , docstring , base_labels = { } )
65
- provide_metric ( name ) || registry . gauge ( name , docstring , base_labels )
66
- end
67
-
68
- def self . histogram ( name , docstring , base_labels = { } , buckets = ::Prometheus ::Client ::Histogram ::DEFAULT_BUCKETS )
69
- provide_metric ( name ) || registry . histogram ( name , docstring , base_labels , buckets )
70
- end
71
-
72
- def self . provide_metric ( name )
73
- if prometheus_metrics_enabled?
74
- registry . get ( name )
75
- else
76
- NullMetric . new
77
- end
78
- end
79
-
80
- def self . submit_metrics ( metrics )
81
- prepared = prepare_metrics ( metrics )
82
-
83
- pool &.with do |connection |
84
- prepared . each_slice ( settings [ :packet_size ] ) do |slice |
85
- begin
86
- connection . write_points ( slice )
87
- rescue StandardError
88
- end
89
- end
90
- end
91
- rescue Errno ::EADDRNOTAVAIL , SocketError => ex
92
- Gitlab ::EnvironmentLogger . error ( 'Cannot resolve InfluxDB address. GitLab Performance Monitoring will not work.' )
93
- Gitlab ::EnvironmentLogger . error ( ex )
94
- end
95
-
96
- def self . prepare_metrics ( metrics )
97
- metrics . map do |hash |
98
- new_hash = hash . symbolize_keys
99
-
100
- new_hash [ :tags ] . each do |key , value |
101
- if value . blank?
102
- new_hash [ :tags ] . delete ( key )
103
- else
104
- new_hash [ :tags ] [ key ] = escape_value ( value )
105
- end
106
- end
107
-
108
- new_hash
109
- end
110
- end
111
-
112
- def self . escape_value ( value )
113
- value . to_s . gsub ( '=' , '\\=' )
114
- end
115
-
116
- # Measures the execution time of a block.
117
- #
118
- # Example:
119
- #
120
- # Gitlab::Metrics.measure(:find_by_username_duration) do
121
- # User.find_by_username(some_username)
122
- # end
123
- #
124
- # name - The name of the field to store the execution time in.
125
- #
126
- # Returns the value yielded by the supplied block.
127
- def self . measure ( name )
128
- trans = current_transaction
129
-
130
- return yield unless trans
131
-
132
- real_start = Time . now . to_f
133
- cpu_start = System . cpu_time
134
-
135
- retval = yield
136
-
137
- cpu_stop = System . cpu_time
138
- real_stop = Time . now . to_f
139
-
140
- real_time = ( real_stop - real_start ) * 1000.0
141
- cpu_time = cpu_stop - cpu_start
142
-
143
- trans . increment ( "#{ name } _real_time" , real_time )
144
- trans . increment ( "#{ name } _cpu_time" , cpu_time )
145
- trans . increment ( "#{ name } _call_count" , 1 )
146
-
147
- retval
148
- end
149
-
150
- # Adds a tag to the current transaction (if any)
151
- #
152
- # name - The name of the tag to add.
153
- # value - The value of the tag.
154
- def self . tag_transaction ( name , value )
155
- trans = current_transaction
156
-
157
- trans &.add_tag ( name , value )
158
- end
159
-
160
- # Sets the action of the current transaction (if any)
161
- #
162
- # action - The name of the action.
163
- def self . action = ( action )
164
- trans = current_transaction
165
-
166
- trans &.action = action
167
- end
168
-
169
- # Tracks an event.
170
- #
171
- # See `Gitlab::Metrics::Transaction#add_event` for more details.
172
- def self . add_event ( *args )
173
- trans = current_transaction
174
-
175
- trans &.add_event ( *args )
176
- end
177
-
178
- # Returns the prefix to use for the name of a series.
179
- def self . series_prefix
180
- @series_prefix ||= Sidekiq . server? ? 'sidekiq_' : 'rails_'
181
- end
182
-
183
- # Allow access from other metrics related middlewares
184
- def self . current_transaction
185
- Transaction . current
186
- end
187
-
188
- # When enabled this should be set before being used as the usual pattern
189
- # "@foo ||= bar" is _not_ thread-safe.
190
- if influx_metrics_enabled?
191
- @pool = ConnectionPool . new ( size : settings [ :pool_size ] , timeout : settings [ :timeout ] ) do
192
- host = settings [ :host ]
193
- port = settings [ :port ]
194
-
195
- InfluxDB ::Client .
196
- new ( udp : { host : host , port : port } )
197
- end
198
- end
199
9
end
200
- end
10
+ end
0 commit comments