require 'logger' require 'fileutils' require 'colorize' module Soaspec # Custom class for logging API traffic class ApiLogger < Logger # # Rewrite << to use info logger with formatting # def <<(msg) info msg end end # Handles logs of API requests and responses class SpecLogger # Folder to put API traffic logs @traffic_folder = 'logs' # Whether to output api traffic to terminal @output_to_terminal = false # Whether to output API traffic to log file @output_to_file = true # Time test run. Will only be calculated once once called @time_test_run = Time.now.strftime('%Y-%m-%d_%H_%M_%S') class << self # Folder to put API traffic logs attr_accessor :traffic_folder # Readers for log parameters attr_reader :output_to_terminal, :output_to_file, :time_test_run # Whether to log all API traffic def log_api_traffic=(set) @log_api_traffic = set RestClient.log = nil unless set end # @return [Boolean] Whether to log all API traffic def log_api_traffic? @log_api_traffic.nil? ? true : @log_api_traffic end # @param [Symbol, Boolean] value # Whether to output API traffic to log file def output_to_file=(value) @output_to_file = value RestClient.log = Soaspec::SpecLogger.create end # @param [Symbol, Boolean] value # Whether to output API traffic to STDOUT def output_to_terminal=(value) @output_to_terminal = value RestClient.log = Soaspec::SpecLogger.create end # @return [String] Traffic file to create logs at def traffic_file filename = "traffic_#{time_test_run}.log" File.join(traffic_folder, filename) end # Create new log file if necessary and setup logging level # @return [Logger] Logger class to record API traffic def create create_log_file @logger = ApiLogger.new(traffic_file) # Where request and responses of APIs are stored @logger.formatter = proc do |severity, datetime, _progname, msg| message = "SpecLog, [#{datetime.strftime('%Y-%m-%d_%H:%M:%S')}] #{severity} -- : #{msg}\n" print message.colorize(:light_blue) if @output_to_terminal message if @output_to_file end @logger end # Log a message using Soaspec logger # @param [String] message The message to add to the logger def info(message) return unless log_api_traffic? if message.respond_to? :each message.each do |message_item| @logger.info(message_item) end else @logger.info(message) end end private # Create folder and file to store logs def create_log_file return if File.exist?(traffic_file) FileUtils.mkdir_p traffic_folder FileUtils.touch traffic_file end end end end