debian-mirror-gitlab/lib/gitlab/metrics/exporter/base_exporter.rb

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

124 lines
3.8 KiB
Ruby
Raw Normal View History

2019-12-21 20:55:43 +05:30
# frozen_string_literal: true
2021-09-30 23:02:18 +05:30
require 'webrick'
require 'prometheus/client/rack/exporter'
2019-12-21 20:55:43 +05:30
module Gitlab
module Metrics
module Exporter
class BaseExporter < Daemon
2022-08-13 15:12:31 +05:30
CERT_REGEX = /-----BEGIN CERTIFICATE-----(?:.|\n)+?-----END CERTIFICATE-----/.freeze
2019-12-21 20:55:43 +05:30
attr_reader :server
2022-04-04 11:22:00 +05:30
# @param settings [Hash] SettingsLogic hash containing the `*_exporter` config
# @param log_enabled [Boolean] whether to log HTTP requests
# @param log_file [String] path to where the server log should be located
# @param gc_requests [Boolean] whether to run a major GC after each scraper request
2022-03-02 08:16:31 +05:30
def initialize(settings, log_enabled:, log_file:, gc_requests: false, **options)
2022-01-26 12:08:38 +05:30
super(**options)
@settings = settings
2022-03-02 08:16:31 +05:30
@gc_requests = gc_requests
# log_enabled does not exist for all exporters
log_sink = log_enabled ? File.join(Rails.root, 'log', log_file) : File::NULL
@logger = WEBrick::Log.new(log_sink)
@logger.time_format = "[%Y-%m-%dT%H:%M:%S.%L%z]"
2019-12-21 20:55:43 +05:30
end
2022-01-26 12:08:38 +05:30
def enabled?
settings.enabled
2019-12-21 20:55:43 +05:30
end
private
2022-03-02 08:16:31 +05:30
attr_reader :settings, :logger
2022-01-26 12:08:38 +05:30
2019-12-21 20:55:43 +05:30
def start_working
access_log = [
[logger, WEBrick::AccessLog::COMBINED_LOG_FORMAT]
]
2022-08-13 15:12:31 +05:30
server_config = {
Port: settings.port,
BindAddress: settings.address,
Logger: logger,
AccessLog: access_log
}
server_config.merge!(ssl_config) if settings['tls_enabled']
@server = ::WEBrick::HTTPServer.new(server_config)
2019-12-21 20:55:43 +05:30
server.mount '/', Rack::Handler::WEBrick, rack_app
true
2022-03-02 08:16:31 +05:30
rescue StandardError => e
logger.error(e)
false
2019-12-21 20:55:43 +05:30
end
def run_thread
server&.start
rescue IOError
# ignore forcibily closed servers
end
def stop_working
if server
# we close sockets if thread is not longer running
# this happens, when the process forks
if thread.alive?
server.shutdown
else
server.listeners.each(&:close)
end
end
@server = nil
end
def rack_app
2022-03-02 08:16:31 +05:30
pid = thread_name
gc_requests = @gc_requests
2019-12-21 20:55:43 +05:30
Rack::Builder.app do
use Rack::Deflater
2022-03-02 08:16:31 +05:30
use Gitlab::Metrics::Exporter::MetricsMiddleware, pid
use Gitlab::Metrics::Exporter::GcRequestMiddleware if gc_requests
2019-12-21 20:55:43 +05:30
use ::Prometheus::Client::Rack::Exporter if ::Gitlab::Metrics.metrics_folder_present?
run -> (env) { [404, {}, ['']] }
end
end
2022-08-13 15:12:31 +05:30
def ssl_config
# This monkey-patches WEBrick::GenericServer, so never require this unless TLS is enabled.
require 'webrick/ssl'
certs = load_ca_certs_bundle(File.binread(settings['tls_cert_path']))
{
SSLEnable: true,
SSLCertificate: certs.shift,
SSLPrivateKey: OpenSSL::PKey.read(File.binread(settings['tls_key_path'])),
# SSLStartImmediately is true by default according to the docs, but when WEBrick creates the
# SSLServer internally, the switch was always nil for some reason. Setting this explicitly fixes this.
SSLStartImmediately: true,
SSLExtraChainCert: certs
}
end
# In Ruby OpenSSL v3.0.0, this can be replaced by OpenSSL::X509::Certificate.load
# https://github.com/ruby/openssl/issues/254
def load_ca_certs_bundle(ca_certs_string)
return [] unless ca_certs_string
ca_certs_string.scan(CERT_REGEX).map do |ca_cert_string|
OpenSSL::X509::Certificate.new(ca_cert_string)
end
end
2019-12-21 20:55:43 +05:30
end
end
end
end