summaryrefslogtreecommitdiff
path: root/lib/gitlab/metrics/transaction.rb
diff options
context:
space:
mode:
authorPawel Chojnacki <pawel@chojnacki.ws>2017-09-06 11:36:29 +0200
committerPawel Chojnacki <pawel@chojnacki.ws>2017-11-02 18:11:43 +0100
commita8a5c337c1d6914a0f9bdd17fb9fe1453c21a067 (patch)
tree84172d4d0f0f565b4d60d1b1f8d3713ad98b22ac /lib/gitlab/metrics/transaction.rb
parent29a1ad16467123c5d6a11e5c7bf0ebacc4e79438 (diff)
downloadgitlab-ce-a8a5c337c1d6914a0f9bdd17fb9fe1453c21a067.tar.gz
Transaction needs to be able to describe controller action by itself
Diffstat (limited to 'lib/gitlab/metrics/transaction.rb')
-rw-r--r--lib/gitlab/metrics/transaction.rb93
1 files changed, 72 insertions, 21 deletions
diff --git a/lib/gitlab/metrics/transaction.rb b/lib/gitlab/metrics/transaction.rb
index 322111b63dc..0b15d73a237 100644
--- a/lib/gitlab/metrics/transaction.rb
+++ b/lib/gitlab/metrics/transaction.rb
@@ -2,6 +2,21 @@ module Gitlab
module Metrics
# Class for storing metrics information of a single transaction.
class Transaction
+ CONTROLLER_KEY = 'action_controller.instance'.freeze
+ ENDPOINT_KEY = 'api.endpoint'.freeze
+
+ CONTENT_TYPES = {
+ 'text/html' => :html,
+ 'text/plain' => :txt,
+ 'application/json' => :json,
+ 'text/js' => :js,
+ 'application/atom+xml' => :atom,
+ 'image/png' => :png,
+ 'image/jpeg' => :jpeg,
+ 'image/gif' => :gif,
+ 'image/svg+xml' => :svg
+ }.freeze
+
THREAD_KEY = :_gitlab_metrics_transaction
# The series to store events (e.g. Git pushes) in.
@@ -9,15 +24,13 @@ module Gitlab
attr_reader :tags, :values, :method, :metrics
- attr_accessor :action
-
def self.current
Thread.current[THREAD_KEY]
end
# action - A String describing the action performed, usually the class
# plus method name.
- def initialize(action = nil)
+ def initialize(env)
@metrics = []
@methods = {}
@@ -26,7 +39,7 @@ module Gitlab
@values = Hash.new(0)
@tags = {}
- @action = action
+ @env = env
@memory_before = 0
@memory_after = 0
@@ -40,22 +53,12 @@ module Gitlab
@memory_after - @memory_before
end
- def self.metric_transaction_duration_seconds
- @metric_transaction_duration_seconds ||= Gitlab::Metrics.histogram(
- :gitlab_transaction_duration_seconds,
- 'Transaction duration',
- { action: nil },
- [0.001, 0.002, 0.005, 0.01, 0.02, 0.05, 0.1, 0.500, 2.0, 10.0]
- )
- end
-
- def self.metric_transaction_allocated_memory_bytes
- @metric_transaction_allocated_memory_bytes ||= Gitlab::Metrics.histogram(
- :gitlab_transaction_allocated_memory_bytes,
- 'Transaction allocated memory bytes',
- { action: nil },
- [1000, 10000, 20000, 500000, 1000000, 2000000, 5000000, 10000000, 20000000, 100000000]
- )
+ def action
+ @action ||= if @env[CONTROLLER_KEY]
+ action_from_controller(@env) || ''
+ elsif @env[ENDPOINT_KEY]
+ action_from_endpoint(@env) || ''
+ end
end
def run
@@ -135,7 +138,7 @@ module Gitlab
submit_hashes = submit.map do |metric|
hash = metric.to_hash
- hash[:tags][:action] ||= @action if @action && !metric.event?
+ hash[:tags][:action] ||= action if action && !metric.event?
hash
end
@@ -145,6 +148,24 @@ module Gitlab
private
+ def self.metric_transaction_duration_seconds
+ @metric_transaction_duration_seconds ||= Gitlab::Metrics.histogram(
+ :gitlab_transaction_duration_seconds,
+ 'Transaction duration',
+ { action: nil },
+ [0.001, 0.002, 0.005, 0.01, 0.02, 0.05, 0.1, 0.500, 2.0, 10.0]
+ )
+ end
+
+ def self.metric_transaction_allocated_memory_bytes
+ @metric_transaction_allocated_memory_bytes ||= Gitlab::Metrics.histogram(
+ :gitlab_transaction_allocated_memory_bytes,
+ 'Transaction allocated memory bytes',
+ { action: nil },
+ [1000, 10000, 20000, 500000, 1000000, 2000000, 5000000, 10000000, 20000000, 100000000]
+ )
+ end
+
def self.metric_event_counter(event_name, tags)
@metric_event_counters ||= {}
@metric_event_counters[event_name] ||= Gitlab::Metrics.counter(
@@ -167,6 +188,36 @@ module Gitlab
"gitlab_transaction_#{name}".to_sym, "Transaction gauge #{name}", { action: nil }, :livesum
)
end
+
+ def action_from_controller(env)
+ controller = env[CONTROLLER_KEY]
+
+ action = "#{controller.class.name}##{controller.action_name}"
+ suffix = CONTENT_TYPES[controller.content_type]
+
+ if suffix && suffix != :html
+ action += ".#{suffix}"
+ end
+
+ action
+ end
+
+ def action_from_endpoint(env)
+ endpoint = env[ENDPOINT_KEY]
+
+ begin
+ route = endpoint.route
+ rescue
+ # endpoint.route is calling env[Grape::Env::GRAPE_ROUTING_ARGS][:route_info]
+ # but env[Grape::Env::GRAPE_ROUTING_ARGS] is nil in the case of a 405 response
+ # so we're rescuing exceptions and bailing out
+ end
+
+ if route
+ path = endpoint_paths_cache[route.request_method][route.path]
+ "Grape##{route.request_method} #{path}"
+ end
+ end
end
end
end