diff options
Diffstat (limited to 'lib/gitlab/metrics/subscribers/ldap.rb')
-rw-r--r-- | lib/gitlab/metrics/subscribers/ldap.rb | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/lib/gitlab/metrics/subscribers/ldap.rb b/lib/gitlab/metrics/subscribers/ldap.rb new file mode 100644 index 00000000000..9cac5f41090 --- /dev/null +++ b/lib/gitlab/metrics/subscribers/ldap.rb @@ -0,0 +1,103 @@ +# frozen_string_literal: true + +module Gitlab + module Metrics + module Subscribers + class Ldap < ActiveSupport::Subscriber + # This namespace is configured in the Net::LDAP library, and appears + # at the end of the event key, e.g. `open.net_ldap` + attach_to :net_ldap + + COUNTER = :net_ldap_count + DURATION = :net_ldap_duration_s + + # Assembled from methods that are instrumented inside Net::LDAP + OBSERVABLE_EVENTS = %i[ + open + bind + add + modify + modify_password + rename + delete + search + ].freeze + + class << self + # @return [Integer] the total number of LDAP requests + def count + Gitlab::SafeRequestStore[COUNTER].to_i + end + + # @return [Float] the total duration spent on LDAP requests + def duration + Gitlab::SafeRequestStore[DURATION].to_f + end + + # Used in Gitlab::InstrumentationHelper to merge the LDAP stats + # into the log output + # + # @return [Hash<Integer, Float>] a hash of the stored statistics + def payload + { + net_ldap_count: count, + net_ldap_duration_s: duration + } + end + end + + # Called when an event is triggered in ActiveSupport::Notifications + # + # This method is aliased to the various events triggered by the + # Net::LDAP library, as the method will be called by those names + # when triggered. + # + # It stores statistics in the request for output to logs, and also + # resubmits the event data into Prometheus for monitoring purposes. + def observe_event(event) + add_to_request_store(event) + expose_metrics(event) + end + + OBSERVABLE_EVENTS.each do |event| + alias_method event, :observe_event + end + + private + + def current_transaction + ::Gitlab::Metrics::WebTransaction.current || ::Gitlab::Metrics::BackgroundTransaction.current + end + + # Track these events as statistics for the current requests, for logging purposes + def add_to_request_store(event) + return unless Gitlab::SafeRequestStore.active? + + Gitlab::SafeRequestStore[COUNTER] = Gitlab::SafeRequestStore[COUNTER].to_i + 1 + Gitlab::SafeRequestStore[DURATION] = Gitlab::SafeRequestStore[DURATION].to_f + event.duration.to_f + end + + # Converts the observed events into Prometheus metrics + def expose_metrics(event) + return unless current_transaction + + # event.name will be, for example, `search.net_ldap` + # and so we only want the first part, which is the + # true name of the event + labels = { name: event.name.split(".").first } + + current_transaction.increment(:gitlab_net_ldap_total, 1, labels) do + docstring 'Net::LDAP calls' + label_keys labels.keys + end + + current_transaction.observe(:gitlab_net_ldap_duration_seconds, event.duration, labels) do + docstring 'Net::LDAP time' + buckets [0.001, 0.01, 0.1, 1.0, 2.0, 5.0] + label_keys labels.keys + end + end + end + end + end +end |