Commit cb8df09f authored by Yorick Peterse's avatar Yorick Peterse

Merge branch 'add-metrics-initializer-spec-ee' into 'master'

Add metric initializer spec

See merge request !1109
parents 1bf684f7 7e467d1c
if Gitlab::Metrics.enabled?
require 'pathname'
require 'influxdb'
require 'connection_pool'
require 'method_source'
# These are manually require'd so the classes are registered properly with
# ActiveSupport.
require 'gitlab/metrics/subscribers/action_view'
require 'gitlab/metrics/subscribers/active_record'
require 'gitlab/metrics/subscribers/rails_cache'
Gitlab::Application.configure do |config|
config.middleware.use(Gitlab::Metrics::RackMiddleware)
config.middleware.use(Gitlab::Middleware::RailsQueueDuration)
end
Sidekiq.configure_server do |config|
config.server_middleware do |chain|
chain.add Gitlab::Metrics::SidekiqMiddleware
end
end
# This instruments all methods residing in app/models that (appear to) use any
# of the ActiveRecord methods. This has to take place _after_ initializing as
# for some unknown reason calling eager_load! earlier breaks Devise.
Gitlab::Application.config.after_initialize do
Rails.application.eager_load!
models = Rails.root.join('app', 'models').to_s
regex = Regexp.union(
ActiveRecord::Querying.public_instance_methods(false).map(&:to_s)
)
Gitlab::Metrics::Instrumentation.
instrument_class_hierarchy(ActiveRecord::Base) do |klass, method|
# Instrumenting the ApplicationSetting class can lead to an infinite
# loop. Since the data is cached any way we don't really need to
# instrument it.
if klass == ApplicationSetting
false
else
loc = method.source_location
# Autoload all classes that we want to instrument, and instrument the methods we
# need. This takes the Gitlab::Metrics::Instrumentation module as an argument so
# that we can stub it for testing, as it is only called when metrics are
# enabled.
#
# rubocop:disable Metrics/AbcSize
def instrument_classes(instrumentation)
instrumentation.instrument_instance_methods(Gitlab::Shell)
loc && loc[0].start_with?(models) && method.source =~ regex
end
end
end
Gitlab::Metrics::Instrumentation.configure do |config|
config.instrument_instance_methods(Gitlab::Shell)
config.instrument_methods(Gitlab::Git)
instrumentation.instrument_methods(Gitlab::Git)
Gitlab::Git.constants.each do |name|
const = Gitlab::Git.const_get(name)
next unless const.is_a?(Module)
config.instrument_methods(const)
config.instrument_instance_methods(const)
instrumentation.instrument_methods(const)
instrumentation.instrument_instance_methods(const)
end
# Path to search => prefix to strip from constant
......@@ -80,13 +36,13 @@ if Gitlab::Metrics.enabled?
path = Pathname.new(file_path).relative_path_from(prefix)
const = path.to_s.sub('.rb', '').camelize.constantize
config.instrument_methods(const)
config.instrument_instance_methods(const)
instrumentation.instrument_methods(const)
instrumentation.instrument_instance_methods(const)
end
end
config.instrument_methods(Premailer::Adapter::Nokogiri)
config.instrument_instance_methods(Premailer::Adapter::Nokogiri)
instrumentation.instrument_methods(Premailer::Adapter::Nokogiri)
instrumentation.instrument_instance_methods(Premailer::Adapter::Nokogiri)
[
:Blame, :Branch, :BranchCollection, :Blob, :Commit, :Diff, :Repository,
......@@ -94,8 +50,8 @@ if Gitlab::Metrics.enabled?
].each do |name|
const = Rugged.const_get(name)
config.instrument_methods(const)
config.instrument_instance_methods(const)
instrumentation.instrument_methods(const)
instrumentation.instrument_instance_methods(const)
end
# Instruments all Banzai filters and reference parsers
......@@ -107,74 +63,129 @@ if Gitlab::Metrics.enabled?
klass = File.basename(file, File.extname(file)).camelize
const = Banzai.const_get(const_name).const_get(klass)
config.instrument_methods(const)
config.instrument_instance_methods(const)
instrumentation.instrument_methods(const)
instrumentation.instrument_instance_methods(const)
end
end
config.instrument_methods(Banzai::Renderer)
config.instrument_methods(Banzai::Querying)
instrumentation.instrument_methods(Banzai::Renderer)
instrumentation.instrument_methods(Banzai::Querying)
config.instrument_instance_methods(Banzai::ObjectRenderer)
config.instrument_instance_methods(Banzai::Redactor)
config.instrument_methods(Banzai::NoteRenderer)
instrumentation.instrument_instance_methods(Banzai::ObjectRenderer)
instrumentation.instrument_instance_methods(Banzai::Redactor)
instrumentation.instrument_methods(Banzai::NoteRenderer)
[Issuable, Mentionable, Participable].each do |klass|
config.instrument_instance_methods(klass)
config.instrument_instance_methods(klass::ClassMethods)
instrumentation.instrument_instance_methods(klass)
instrumentation.instrument_instance_methods(klass::ClassMethods)
end
config.instrument_methods(Gitlab::ReferenceExtractor)
config.instrument_instance_methods(Gitlab::ReferenceExtractor)
instrumentation.instrument_methods(Gitlab::ReferenceExtractor)
instrumentation.instrument_instance_methods(Gitlab::ReferenceExtractor)
# Instrument the classes used for checking if somebody has push access.
config.instrument_instance_methods(Gitlab::GitAccess)
config.instrument_instance_methods(Gitlab::GitAccessWiki)
instrumentation.instrument_instance_methods(Gitlab::GitAccess)
instrumentation.instrument_instance_methods(Gitlab::GitAccessWiki)
config.instrument_instance_methods(API::Helpers)
instrumentation.instrument_instance_methods(API::Helpers)
config.instrument_instance_methods(RepositoryCheck::SingleRepositoryWorker)
instrumentation.instrument_instance_methods(RepositoryCheck::SingleRepositoryWorker)
config.instrument_instance_methods(Rouge::Plugins::Redcarpet)
config.instrument_instance_methods(Rouge::Formatters::HTMLGitlab)
instrumentation.instrument_instance_methods(Rouge::Plugins::Redcarpet)
instrumentation.instrument_instance_methods(Rouge::Formatters::HTMLGitlab)
[:XML, :HTML].each do |namespace|
namespace_mod = Nokogiri.const_get(namespace)
config.instrument_methods(namespace_mod)
config.instrument_methods(namespace_mod::Document)
instrumentation.instrument_methods(namespace_mod)
instrumentation.instrument_methods(namespace_mod::Document)
end
config.instrument_methods(Rinku)
config.instrument_instance_methods(Repository)
instrumentation.instrument_methods(Rinku)
instrumentation.instrument_instance_methods(Repository)
config.instrument_methods(Gitlab::Highlight)
config.instrument_instance_methods(Gitlab::Highlight)
instrumentation.instrument_methods(Gitlab::Highlight)
instrumentation.instrument_instance_methods(Gitlab::Highlight)
config.instrument_methods(Elasticsearch::Git::Repository)
config.instrument_instance_methods(Elasticsearch::Git::Repository)
instrumentation.instrument_methods(Elasticsearch::Git::Repository)
instrumentation.instrument_instance_methods(Elasticsearch::Git::Repository)
config.instrument_instance_methods(Search::GlobalService)
config.instrument_instance_methods(Search::ProjectService)
instrumentation.instrument_instance_methods(Search::GlobalService)
instrumentation.instrument_instance_methods(Search::ProjectService)
config.instrument_instance_methods(Gitlab::Elastic::SearchResults)
config.instrument_instance_methods(Gitlab::Elastic::ProjectSearchResults)
config.instrument_instance_methods(Gitlab::Elastic::Indexer)
config.instrument_instance_methods(Gitlab::Elastic::SnippetSearchResults)
config.instrument_methods(Gitlab::Elastic::Helper)
instrumentation.instrument_instance_methods(Gitlab::Elastic::SearchResults)
instrumentation.instrument_instance_methods(Gitlab::Elastic::ProjectSearchResults)
instrumentation.instrument_instance_methods(Gitlab::Elastic::Indexer)
instrumentation.instrument_instance_methods(Gitlab::Elastic::SnippetSearchResults)
instrumentation.instrument_methods(Gitlab::Elastic::Helper)
config.instrument_instance_methods(Elastic::ApplicationSearch)
config.instrument_instance_methods(Elastic::IssuesSearch)
config.instrument_instance_methods(Elastic::MergeRequestsSearch)
config.instrument_instance_methods(Elastic::MilestonesSearch)
config.instrument_instance_methods(Elastic::NotesSearch)
config.instrument_instance_methods(Elastic::ProjectsSearch)
config.instrument_instance_methods(Elastic::RepositoriesSearch)
config.instrument_instance_methods(Elastic::SnippetsSearch)
config.instrument_instance_methods(Elastic::WikiRepositoriesSearch)
instrumentation.instrument_instance_methods(Elastic::ApplicationSearch)
instrumentation.instrument_instance_methods(Elastic::IssuesSearch)
instrumentation.instrument_instance_methods(Elastic::MergeRequestsSearch)
instrumentation.instrument_instance_methods(Elastic::MilestonesSearch)
instrumentation.instrument_instance_methods(Elastic::NotesSearch)
instrumentation.instrument_instance_methods(Elastic::ProjectsSearch)
instrumentation.instrument_instance_methods(Elastic::RepositoriesSearch)
instrumentation.instrument_instance_methods(Elastic::SnippetsSearch)
instrumentation.instrument_instance_methods(Elastic::WikiRepositoriesSearch)
# This is a Rails scope so we have to instrument it manually.
config.instrument_method(Project, :visible_to_user)
instrumentation.instrument_method(Project, :visible_to_user)
end
# rubocop:enable Metrics/AbcSize
if Gitlab::Metrics.enabled?
require 'pathname'
require 'influxdb'
require 'connection_pool'
require 'method_source'
# These are manually require'd so the classes are registered properly with
# ActiveSupport.
require 'gitlab/metrics/subscribers/action_view'
require 'gitlab/metrics/subscribers/active_record'
require 'gitlab/metrics/subscribers/rails_cache'
Gitlab::Application.configure do |config|
config.middleware.use(Gitlab::Metrics::RackMiddleware)
config.middleware.use(Gitlab::Middleware::RailsQueueDuration)
end
Sidekiq.configure_server do |config|
config.server_middleware do |chain|
chain.add Gitlab::Metrics::SidekiqMiddleware
end
end
# This instruments all methods residing in app/models that (appear to) use any
# of the ActiveRecord methods. This has to take place _after_ initializing as
# for some unknown reason calling eager_load! earlier breaks Devise.
Gitlab::Application.config.after_initialize do
Rails.application.eager_load!
models = Rails.root.join('app', 'models').to_s
regex = Regexp.union(
ActiveRecord::Querying.public_instance_methods(false).map(&:to_s)
)
Gitlab::Metrics::Instrumentation.
instrument_class_hierarchy(ActiveRecord::Base) do |klass, method|
# Instrumenting the ApplicationSetting class can lead to an infinite
# loop. Since the data is cached any way we don't really need to
# instrument it.
if klass == ApplicationSetting
false
else
loc = method.source_location
loc && loc[0].start_with?(models) && method.source =~ regex
end
end
end
Gitlab::Metrics::Instrumentation.configure do |config|
instrument_classes(config)
end
GC::Profiler.enable
......
require 'spec_helper'
require_relative '../../config/initializers/metrics'
describe 'instrument_classes', lib: true do
let(:config) { double(:config) }
before do
allow(config).to receive(:instrument_method)
allow(config).to receive(:instrument_methods)
allow(config).to receive(:instrument_instance_methods)
end
it 'can autoload and instrument all files' do
expect { instrument_classes(config) }.not_to raise_error
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment