# frozen_string_literal: true # # Copyright 2021- MahithaB # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. require 'concurrent' require 'rest-client' require 'fluent/plugin/input' require_relative 'base_metrics_parser' require_relative 'metrics_helper' require_relative 'newrelic_metrics_parser' require_relative 'splunk_metrics_parser' require_relative 'datadog_metrics_parser' module Fluent module Plugin class JfrogMetricsInput < Fluent::Plugin::Input Fluent::Plugin.register_input('jfrog_metrics', self) helpers :timer # `config_param` defines a parameter. # You can refer to a parameter like an instance variable e.g. @port. # `:default` means that the parameter is optional. config_param :tag, :string, default: '' config_param :jpd_url, :string, default: '' config_param :username, :string, default: '' config_param :apikey, :string, default: '', :secret => true config_param :token, :string, default: '', :secret => true config_param :execution_interval, :time, default: 60 config_param :request_timeout, :time, default: 20 config_param :metric_prefix, :string, default: '' config_param :target_platform, :string, default: 'SPLUNK' config_param :common_jpd, :bool, default: false config_param :verify_ssl, :bool, default: true $logger = nil # `configure` is called before `start`. # 'conf' is a `Hash` that includes the configuration parameters. # If the configuration is invalid, raise `Fluent::ConfigError`. def configure(conf) super raise Fluent::ConfigError, 'Must define the tag for metrics data.' if @tag == '' raise Fluent::ConfigError, 'Must define the jpd_url to scrape metrics.' if @jpd_url == '' raise Fluent::ConfigError, 'Must define the username for authentication.' if @username == '' raise Fluent::ConfigError, 'Must define the apikey or token for authentication.' if @token == '' && @apikey == '' raise Fluent::ConfigError, 'Must define the metric_prefix to use for getting the metrics.' if @metric_prefix == '' raise Fluent::ConfigError, 'Must define the target_platform to use for getting the metrics.' if @target_platform == '' raise Fluent::ConfigError, 'Must define the target_platform to be fone of the following (DATADOG, NEWRELIC, SPLUNK).' if !(['DATADOG', 'NEWRELIC', 'SPLUNK'].include?(@target_platform)) end def initialize super end # `start` is called when starting and after `configure` is successfully completed. def start super @running = true $logger = log @thread = Thread.new do run end end def shutdown @running = false @thread.join super end def run $logger.info("Preparing metrics collection, creating timer task") timer_task = Concurrent::TimerTask.new(execution_interval: @execution_interval, run_now: true) do begin $logger.info("Timer task execution started") do_execute next "Timer task execution finished successfully" rescue => e $logger.error("Error occurred when running Timer task: #{e.message}") raise e end end timer_task.add_observer(TaskObserver.new) timer_task.execute sleep 100 end def do_execute begin $logger.info("Metrics collection started") metrics_helper = MetricsHelper.new($logger, @metric_prefix, @jpd_url, @username, @apikey, @token, @common_jpd, @verify_ssl, @request_timeout) platform_metrics = metrics_helper.get_metrics additional_metrics = metrics_helper.get_additional_metrics if !additional_metrics.nil? && additional_metrics != '' platform_metrics += additional_metrics.to_s end $logger.info("Metrics collection finished") if @target_platform == 'SPLUNK' parser = SplunkMetricsParser.new(@metric_prefix, router, @tag) elsif @target_platform == 'NEWRELIC' parser = NewRelicMetricsParser.new(@metric_prefix, router, @tag) elsif @target_platform == 'DATADOG' parser = DatadogMetricsParser.new(@metric_prefix, router, @tag) else raise 'Parser Type is not valid. target_platform Should be SPLUNK or NEWRELIC or DATADOG' end $logger.debug("Emitting collected metrics started") parser.emit_parsed_metrics(platform_metrics) $logger.debug("Emitting collected metrics finished") rescue RestClient::Exceptions::OpenTimeout $logger.info("The request timed out while trying to open a connection. The configured request timeout is: #{@request_timeout}") rescue RestClient::Exceptions::ReadTimeout $logger.info("The request timed out while waiting for a response. The configured request timeout is: #{@request_timeout}") rescue RestClient::Exceptions::RequestTimeout $logger.info("The request timed out. The configured request timeout is: #{@request_timeout}") rescue RestClient::ExceptionWithResponse => e $logger.info("HTTP request failed: #{e.response}") rescue StandardError => e $logger.info("An unexpected error occurred during metrics collection: #{e.message}") else $logger.debug("Metrics collection and emission do_execute finished with no errors") end end class TaskObserver def update(time, result, e) if result $logger.info("Timer task Execution successfully returned: '#{result}' at: #{time}") else $logger.error("Timer task Execution failed with error: #{e} at: #{time}") end end end end end end