module Sqreen::Signals::Conversions
Public Class Methods
@param [Sqreen::Attack] attack XXX: not used because we don't use Sqreen::Attack
# File lib/sqreen/signals/conversions.rb, line 45 def convert_attack(attack) # no need to set actor/context as we only include them in request records/traces location_h = {} location_h.merge!(stack_trace: attack.backtrace) if attack.backtrace location_h.merge!(datadog_trace_id: datadog_trace_id) if attack.datadog_trace_id location_h.merge!(datadog_span_id: datadog_span_id) if attack.datadog_span_id location = Kit::Signals::Location.new(location_h) unless location_h.empty? Kit::Signals::Specialized::Attack.new( signal_name: "sq.agent.attack.#{attack.attack_type}", source: "sqreen:rule:#{attack.rulespack_id}:#{attack.rule_name}", time: attack.time, location: location, payload: Kit::Signals::Specialized::Attack::Payload.new( test: attack.test?, block: attack.block?, infos: attack.infos ) ) end
@return [Array<Sqreen::Kit::Signals::Signal|Sqreen::Kit::Signals::Trace>]
# File lib/sqreen/signals/conversions.rb, line 159 def convert_batch(batch) batch.map do |evt| case evt when RemoteException convert_exception(evt) when AggregatedMetric convert_metric_sample(evt) when RequestRecord convert_req_record(evt) when Sqreen::Kit::Signals::Signal evt when Sqreen::Kit::Signals::Trace evt else raise NotImplementedError, "Unknown type of event in batch: #{evt}" end end end
@param [Sqreen::RemoteException] exception @return [Sqreen::Kit::Signals::Specialized::SqreenException]
# File lib/sqreen/signals/conversions.rb, line 89 def convert_exception(exception) payload = exception.payload infos = payload['client_ip'] ? { client_ip: payload['client_ip'] } : {} infos.merge!(payload['infos'] || {}) Kit::Signals::Specialized::SqreenException.new( source: if payload['rule_name'] "sqreen:rule:#{payload['rulespack_id']}:#{payload['rule_name']}" else agent_gen_source end, time: exception.time, ruby_exception: payload['exception'], infos: infos ) end
@param [Sqreen::AggregatedMetric] agg @return [Sqreen::Kit::Signals::Metric]
# File lib/sqreen/signals/conversions.rb, line 25 def convert_metric_sample(agg) attrs = { signal_name: "sq.agent.metric.#{agg.name}", source: if agg.rule "sqreen:rules:#{agg.rule.rulespack_id}:#{agg.rule.rule_name}" else agent_gen_source end, time: agg.finish, } if agg.metric.is_a?(Sqreen::Metric::Binning) conv_binning_metric(agg, attrs) else conv_generic_metric(agg, attrs) end end
@param [Sqreen::RequestRecord] req_rec @return [Sqreen::Kit::Signals::Specialized::HttpTrace]
# File lib/sqreen/signals/conversions.rb, line 121 def convert_req_record(req_rec) payload = req_rec.payload request_p = payload['request'] id_args = req_rec.last_identify_args identifiers = id_args[0] if id_args traits = id_args[1] if id_args observed = payload[:observed] || {} signals = [] signals += (observed[:attacks] || []) .map { |att| convert_unstructured_attack(att) } signals += (observed[:sqreen_exceptions] || []) .map { |sq_exc| convert_unstructured_exception(sq_exc) } signals += req_rec.processed_sdk_calls .select { |h| h[:name] == :track } .map { |h| convert_track(h) } signals += (observed[:signals] || []) trace = Kit::Signals::Specialized::HttpTrace.new( actor: Kit::Signals::Actor.new( ip_addresses: [request_p[:client_ip]].compact, user_agent: request_p[:user_agent], identifiers: identifiers, traits: traits, ), location_infra: location_infra, context: convert_request(request_p, payload['response'], payload['headers'], payload['params']), data: signals ) HttpTraceRedaction.redact_trace!(trace, req_rec.redactor) trace end
see Sqreen::Rules::RuleCB.record_event
# File lib/sqreen/signals/conversions.rb, line 67 def convert_unstructured_attack(payload) location_h = {} location_h.merge!(stack_trace: payload[:backtrace]) if payload[:backtrace] location_h.merge!(datadog_trace_id: payload[:datadog_trace_id]) if payload[:datadog_span_id] location_h.merge!(datadog_span_id: payload[:datadog_span_id]) if payload[:datadog_span_id] location = Kit::Signals::Location.new(location_h) unless location_h.empty? Kit::Signals::Specialized::Attack.new( signal_name: "sq.agent.attack.#{payload[:attack_type]}", source: "sqreen:rule:#{payload[:rulespack_id]}:#{payload[:rule_name]}", time: payload[:time], location: location, payload: Kit::Signals::Specialized::Attack::Payload.new( test: payload[:test], block: payload[:block], infos: payload[:infos] ) ) end
see Sqreen::Rules::RuleCB.record_exception
@param [Hash] payload @return [Sqreen::Kit::Signals::Specialized::SqreenException]
# File lib/sqreen/signals/conversions.rb, line 110 def convert_unstructured_exception(payload) Kit::Signals::Specialized::SqreenException.new( source: "sqreen:rule:#{payload[:rulespack_id]}:#{payload[:rule_name]}", time: payload[:time], ruby_exception: payload[:exception], infos: payload[:infos] ) end
Private Class Methods
# File lib/sqreen/signals/conversions.rb, line 180 def agent_gen_source "sqreen:agent:ruby:#{Sqreen::VERSION}" end
@param [Sqreen::AggregatedMetric] agg @param [Hash] attrs
# File lib/sqreen/signals/conversions.rb, line 287 def conv_binning_metric(agg, attrs) attrs[:payload] = Kit::Signals::Specialized::BinningMetric::Payload.new( capture_interval_s: agg.metric.period, date_started: agg.start, date_ended: agg.finish, base: agg.data['b'], unit: agg.data['u'], max: agg.data['v']['max'], bins: agg.data['v'].reject { |k, _v| k == 'max' } ) Kit::Signals::Specialized::BinningMetric.new(attrs) end
@param [Sqreen::AggregatedMetric] agg @param [Hash] attrs
# File lib/sqreen/signals/conversions.rb, line 273 def conv_generic_metric(agg, attrs) attrs[:payload] = Kit::Signals::Specialized::AggregatedMetric::Payload.new( kind: metric_kind(agg.metric), capture_interval_s: agg.metric.period, date_started: agg.start, date_ended: agg.finish, values: agg.data ) Kit::Signals::Specialized::AggregatedMetric.new(attrs) end
@param [Hash] req_payload @param [Hash] headers_payload @param [Hash] params_payload see the PayloadCreator
abomination for reference TODO: do not convert from the old payload to the new payload Have an intermediate object that gets the data from the framework. (Or convert directly from the framework, but this needs to be done during the request, not just before event is transmitted)
# File lib/sqreen/signals/conversions.rb, line 218 def convert_request(req_payload, resp_payload, headers_payload, params_payload) req_payload ||= {} headers_payload ||= {} resp_payload ||= {} params_payload ||= {} other = params_payload['other'] other = merge_hash_append(other, params_payload['rack']) other = merge_hash_append(other, params_payload['grape_params']) other = merge_hash_append(other, params_payload['rack_routing']) Sqreen::Kit::Signals::Context::HttpContext.new( { rid: req_payload[:rid], headers: headers_payload, user_agent: req_payload[:user_agent], scheme: req_payload[:scheme], verb: req_payload[:verb], host: req_payload[:host], port: req_payload[:port], remote_ip: req_payload[:remote_ip], remote_port: req_payload[:remote_port] || 0, path: req_payload[:path], referer: req_payload[:referer], params_query: params_payload['query'], params_form: params_payload['form'], params_other: other, # endpoint, is_reveal_replayed not set status: resp_payload[:status], content_length: resp_payload[:content_length], content_type: resp_payload[:content_type], # datadog datadog_trace_id: req_payload[:datadog_trace_id], datadog_span_id: req_payload[:datadog_span_id], } ) end
see Sqreen::RequestRecord.processed_sdk_calls
# File lib/sqreen/signals/conversions.rb, line 198 def convert_track(call_info) options = call_info[:args][1] || {} Kit::Signals::Specialized::SdkTrackCall.new( signal_name: "sq.sdk.#{call_info[:args][0]}", time: call_info[:time], payload: Kit::Signals::Specialized::SdkTrackCall::Payload.new( properties: options[:properties], user_identifiers: options[:user_identifiers] ) ) end
# File lib/sqreen/signals/conversions.rb, line 184 def location_infra @location_infra ||= begin Kit::Signals::LocationInfra.new( agent_version: Sqreen::VERSION, os_type: RuntimeInfos.os[:os_type], hostname: RuntimeInfos.hostname, runtime_type: RuntimeInfos.runtime[:runtime_type], runtime_version: RuntimeInfos.runtime[:runtime_version], libsqreen_version: RuntimeInfos.libsqreen_version, ) end end
# File lib/sqreen/signals/conversions.rb, line 256 def merge_hash_append(hash1, hash2) return nil if hash1.nil? && hash2.nil? return hash1 if hash2.nil? || hash2.empty? return hash2 if hash1.nil? || hash1.empty? pairs = (hash1.keys + hash2.keys).map do |key| values1 = hash1[key] values2 = hash2[key] values = [values1, values2].compact values = values.first if values.size == 1 [key, values] end Hash[pairs] end
@param [Sqreen::Metric::Base] metric
# File lib/sqreen/signals/conversions.rb, line 302 def metric_kind(metric) metric.class.name.sub(/.*::/, '').sub(/Metric$/, '') end