Module: Datadog::AppSec::Event
- Defined in:
- lib/datadog/appsec/event.rb
Overview
AppSec event
Constant Summary collapse
- ALLOWED_REQUEST_HEADERS =
%w[ X-Forwarded-For X-Client-IP X-Real-IP X-Forwarded X-Cluster-Client-IP Forwarded-For Forwarded Via True-Client-IP Content-Length Content-Type Content-Encoding Content-Language Host User-Agent Accept Accept-Encoding Accept-Language ].map!(&:downcase).freeze
- ALLOWED_RESPONSE_HEADERS =
%w[ Content-Length Content-Type Content-Encoding Content-Language ].map!(&:downcase).freeze
Class Method Summary collapse
-
.record(*events) ⇒ Object
Record events for a trace.
-
.record_via_span(*events) ⇒ Object
rubocop:disable Metrics/MethodLength.
Class Method Details
.record(*events) ⇒ Object
Record events for a trace
This is expected to be called only once per trace for the rate limiter to properly apply
41 42 43 44 45 46 47 48 |
# File 'lib/datadog/appsec/event.rb', line 41 def self.record(*events) # ensure rate limiter is called only when there are events to record return if events.empty? Datadog::AppSec::RateLimiter.limit(:traces) do record_via_span(*events) end end |
.record_via_span(*events) ⇒ Object
rubocop:disable Metrics/MethodLength
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/datadog/appsec/event.rb', line 51 def self.record_via_span(*events) events.group_by { |e| e[:trace] }.each do |trace, event_group| unless trace Datadog.logger.debug { "{ error: 'no trace: cannot record', event_group: #{event_group.inspect}}" } next end trace.keep! trace.set_tag( Datadog::Tracing::Metadata::Ext::Distributed::TAG_DECISION_MAKER, Datadog::Tracing::Sampling::Ext::Decision::ASM ) # prepare and gather tags to apply = event_group.each_with_object({}) do |event, | # TODO: assume HTTP request context for now if (request = event[:request]) request_headers = request.headers.select do |k, _| ALLOWED_REQUEST_HEADERS.include?(k.downcase) end request_headers.each do |header, value| ["http.request.headers.#{header}"] = value end ['http.host'] = request.host ['http.useragent'] = request.user_agent ['network.client.ip'] = request.remote_addr end if (response = event[:response]) response_headers = response.headers.select do |k, _| ALLOWED_RESPONSE_HEADERS.include?(k.downcase) end response_headers.each do |header, value| ["http.response.headers.#{header}"] = value end end ['_dd.origin'] = 'appsec' # accumulate triggers ['_dd.appsec.triggers'] ||= [] ['_dd.appsec.triggers'] += event[:waf_result].data end # apply tags to root span # complex types are unsupported, we need to serialize to a string triggers = .delete('_dd.appsec.triggers') trace.set_tag('_dd.appsec.json', JSON.dump({ triggers: triggers })) .each do |key, value| trace.set_tag(key, value) end end end |