namespace :ci do namespace :prometheus do desc 'Set up Prometheus' task :setup do require 'highline/import' @metrics = [] ENV['PROMETHEUS_PUSHGATEWAY'] ||= ask('Prometheus pushgateway (host:port): ') ENV['PROMETHEUS_PUSHGATEWAY'] = nil if ENV['PROMETHEUS_PUSHGATEWAY'] == '' ENV['PROMETHEUS_PROJECTNAME'] ||= ask('Prometheus project name: ') ENV['PROMETHEUS_PROJECTNAME'] = nil if ENV['PROMETHEUS_PROJECTNAME'] == '' end desc 'Push Prometheus stats' task publish: :setup do gateway = ENV['PROMETHEUS_PUSHGATEWAY'] project = ENV['PROMETHEUS_PROJECTNAME'] next if @metrics.empty? || gateway.nil? require 'prometheus/client' require 'prometheus/client/push' # returns a default registry prometheus = Prometheus::Client.registry @metrics.each do |metric| name = "ci_#{metric[:name]}".to_sym # TODO: Add :docstring where required docstring = metric[:docstring] || 'TODO' label_set = metric[:label_set] || {} value = metric[:value] case metric[:type] when :gauge gauge = if prometheus.exist?(name) prometheus.get(name) else prometheus.gauge(name, docstring, project: project) end gauge.set(label_set, value) else raise "Unknown metric type (#{metric.inspect})" end end client = Prometheus::Client::Push.new("rake-ci-#{project}", nil, gateway) begin client.add(prometheus) rescue Errno::ECONNREFUSED => exception warn "Failed to push metrics to Prometheus: #{exception.message}" @attachments ||= [] @attachments << { color: 'danger', title: 'Publishing Error', text: 'Build metrics could not be pushed - the Prometheus gateway was uncontactable', footer: 'bundle exec rake ci:prometheus:publish' } end end end end