lib/fluent/plugin/monitoring.rb in fluent-plugin-google-cloud-0.7.21 vs lib/fluent/plugin/monitoring.rb in fluent-plugin-google-cloud-0.7.22

- old
+ new

@@ -29,25 +29,48 @@ def increment(by: 1, labels: {}) @counter.increment(labels, by) end end + # OpenCensus implementation of counters. + class OpenCensusCounter < BaseCounter + def initialize(recorder, measure) + raise ArgumentError, 'measure must not be nil' if measure.nil? + @recorder = recorder + @measure = measure + end + + def increment(by: 1, labels: {}) + tag_map = OpenCensus::Tags::TagMap.new( + labels.map { |k, v| [k.to_s, v.to_s] }.to_h) + @recorder.record(@measure.create_measurement(value: by, tags: tag_map)) + end + end + # Base class for the monitoring registry. class BaseMonitoringRegistry + def initialize(_project_id, _monitored_resource) + end + def counter(_name, _labels, _docstring) nil end + + def export + nil + end end # Prometheus implementation of the monitoring registry, that uses the default # registry in the official Prometheus client library. class PrometheusMonitoringRegistry < BaseMonitoringRegistry def self.name 'prometheus' end - def initialize + def initialize(_project_id, _monitored_resource) + super require 'prometheus/client' @registry = Prometheus::Client.registry end # Exception-driven behavior to avoid synchronization errors. @@ -56,22 +79,93 @@ rescue Prometheus::Client::Registry::AlreadyRegisteredError return PrometheusCounter.new(@registry.get(name)) end end + # OpenCensus implementation of the monitoring registry. + class OpenCensusMonitoringRegistry < BaseMonitoringRegistry + def self.name + 'opencensus' + end + + def initialize(project_id, monitored_resource) + super + require 'opencensus' + require 'opencensus-stackdriver' + @log = $log # rubocop:disable Style/GlobalVars + @recorder = OpenCensus::Stats.ensure_recorder + @exporter = OpenCensus::Stats::Exporters::Stackdriver.new( + project_id: project_id, + metric_prefix: 'agent.googleapis.com/agent', + resource_type: monitored_resource.type, + resource_labels: monitored_resource.labels) + OpenCensus.configure do |c| + c.stats.exporter = @exporter + end + @log.debug "OpenCensus config=#{OpenCensus.config}" + end + + def counter(name, labels, docstring) + name = OpenCensusMonitoringRegistry.translate_metric_name(name) + measure = OpenCensus::Stats::MeasureRegistry.get(name) + if measure.nil? + measure = OpenCensus::Stats.create_measure_int( + name: name, + unit: OpenCensus::Stats::Measure::UNIT_NONE, + description: docstring + ) + end + OpenCensus::Stats.create_and_register_view( + name: name, + measure: measure, + aggregation: OpenCensus::Stats.create_sum_aggregation, + description: docstring, + columns: labels.map(&:to_s) + ) + OpenCensusCounter.new(@recorder, measure) + end + + def export + @exporter.export @recorder.views_data + end + + class << self + # Translate the internal metrics to the curated metrics in Stackdriver. + # The Prometheus metrics are collected by Google Kubernetes Engine's + # monitoring, so we can't redefine them. + def translate_metric_name(name) + case name + when :stackdriver_successful_requests_count, + :stackdriver_failed_requests_count + :request_count + when :stackdriver_ingested_entries_count, + :stackdriver_dropped_entries_count + :log_entry_count + when :stackdriver_retried_entries_count + :log_entry_retry_count + else + name + end + end + end + end + # Factory that is used to create a monitoring registry based on # the monitoring solution name. class MonitoringRegistryFactory @known_registry_types = { PrometheusMonitoringRegistry.name => - PrometheusMonitoringRegistry + PrometheusMonitoringRegistry, + OpenCensusMonitoringRegistry.name => + OpenCensusMonitoringRegistry } def self.supports_monitoring_type(name) @known_registry_types.key?(name) end - def self.create(name) - (@known_registry_types[name] || BaseMonitoringRegistry).new + def self.create(name, project_id, monitored_resource) + registry = @known_registry_types[name] || BaseMonitoringRegistry + registry.new(project_id, monitored_resource) end end end