# Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details. # frozen_string_literal: true module Contrast module Logger # Our decorator for the Ougai logger allowing for the logging of the # application environment, used to provide context during troubleshooting. module Application ENV_KEYS = %w[HOME PWD RACK_ENV RAILS_ENV RUBY_VERSION GEM_HOME GEM_PATH].cs__freeze # Utility method to log some current ruby and rails information from environment def application_environment return unless info? info('Process environment information', p_id: Process.pid, pp_id: Process.ppid, agent_version: Contrast::Agent::VERSION, ruby_version: RUBY_VERSION) ENV.each do |env_key, env_value| env_key = env_key.to_s next unless ENV_KEYS.include?(env_key) || (env_key.start_with?(Contrast::Components::Config::CONTRAST_ENV_MARKER) && !env_key.start_with?("#{ Contrast::Components::Config::CONTRAST_ENV_MARKER }API")) info('Environment settings', key: env_key, value: env_value) end end def application_configuration return unless info? loggable = ::Contrast::CONFIG.loggable info('Current configuration', configuration: loggable) env_keys = ENV.keys.select do |env_key| env_key&.to_s&.start_with?(Contrast::Components::Config::CONTRAST_ENV_MARKER) end env_items = env_keys.map { |env_key| Contrast::Utils::EnvConfigurationItem.new(env_key, nil) } env_translations = env_items.each_with_object({}) do |conversion, hash| hash[conversion.key] = conversion.dot_path_array.join('.') end info('Set by environment', overrides: env_translations) end def application_libraries if debug? log_all_libraries elsif info? log_specific_libraries end end FRAMEWORKS = %w[rails sinatra grape].cs__freeze WEB_SERVERS = %w[ agoo falcon hoof iodine mongrel mongrel2 passenger puma rack skinny thin trinidad unicorn webrick yarn ].cs__freeze LIBRARIES = %w[excon json mongo moped mysql nokogiri oga ox pg psych sqlite3 typhoeus yaml].cs__freeze def log_specific_libraries FRAMEWORKS.each(&cs__method(:log_gem_data)) WEB_SERVERS.each(&cs__method(:log_gem_data)) LIBRARIES.each(&cs__method(:log_gem_data)) end private def log_all_libraries return unless debug? Gem.loaded_specs.each_pair do |_name, gem_spec| debug('Gem loaded', # rubocop:disable Security/Module/Name -- gems builtin. gem_name: gem_spec.name, gem_version: gem_spec.version.to_s) end end def log_gem_data gem_name gem_spec = Gem.loaded_specs[gem_name] return unless gem_spec info('Gem loaded', gem_name: gem_spec.name, gem_version: gem_spec.version.to_s) # rubocop:enable Security/Module/Name end end end end