# Copyright (c) 2023 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details. # frozen_string_literal: true require 'contrast/utils/metrics_hash' require 'contrast/agent/telemetry/metric_event' require 'contrast/agent/version' require 'contrast/components/logger' module Contrast module Agent module Telemetry # Event to report all gather information from the Input Analysis metrics. class InputAnalysisEvent < Contrast::Agent::Telemetry::MetricEvent include Contrast::Components::Logger::InstanceMethods NOT_APPLICABLE = 'n/a' attr_reader :fields # Override the name for any derived classes NAME = 'InputAnalysis event' # Override the path for any derived classes PATH = '/protect_input_analysis' # @param rule_id [String] the rule name. # @param rates [Contrast::Agent::Protect::Rule::InputClassification::Rates] base class for all rates. def initialize rule_id, rates super() @fields = MetricsHash.new(Integer) add_tags(rule_id, rates) generate_fields(rates) end # Returns the name of the event. # # @return [String] def name cs__class::NAME end # Returns the path to report the event. # # @return [String] def path cs__class::PATH end # Override the empty check for any derived classes if needed. def empty? super && Contrast::Utils::DuckUtils.empty_duck?(@tags) end private # Creates the tags for the event. Overrides the base class to add the rule_id and match_rate. # # @param rule_id [String, nil] # @param rates [Contrast::Agent::Protect::Rule::InputClassification::Rates] def add_tags rule_id, rates return if Contrast::Utils::DuckUtils.empty_duck?(rates) return unless rates.cs__is_a?(Contrast::Agent::Protect::Rule::InputClassification::Rates) @tags['event_type'] = name # rubocop:disable Security/Module/Name @tags['test_environment'] = ENV['CONTRAST_AGENT_TELEMETRY_TEST'] == '1' ? 'true' : 'false' @tags['rule_id'] = rule_id if rule_id @tags['input_type'] = rates&.input_type.dup&.to_s || NOT_APPLICABLE add_system_tags end # Creates the fields for the event. # Override if needed. # # @param rates [Contrast::Agent::Protect::Rule::InputClassification::Rates] base class for all rates. def generate_fields rates return if Contrast::Utils::DuckUtils.empty_duck?(rates) return unless rates.cs__is_a?(Contrast::Agent::Protect::Rule::InputClassification::Rates) rates.to_fields.each { |field, value| @fields[field] = value.dup } end # Adds the system tags to the event. def add_system_tags @tags['agent_version'] = VERSION @tags['ruby_version'] = RUBY_VERSION @tags['os_type'] = sys_info['os_type'] == 'Darwin' ? 'MacOS' : 'Linux' @tags['os_arch'] = sys_info['os_arch'] @tags['os_version'] = sys_info['os_version'] end end end end end