Class: Aikido::Zen::Collector::Stats Private

Inherits:
Object
  • Object
show all
Defined in:
lib/aikido/zen/collector/stats.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Tracks information about how the Aikido Agent is used in the app.

Instance Method Summary collapse

Constructor Details

#initialize(config = Aikido::Zen.config) ⇒ Stats

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of Stats.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/aikido/zen/collector/stats.rb', line 16

def initialize(config = Aikido::Zen.config)
  super()
  @config = config

  @started_at = @ended_at = nil
  @requests = 0
  @aborted_requests = 0
  @rate_limited_requests = 0
  @user_agents = Hash.new { |h, k| h[k] = 0 }
  @ip_lists = Hash.new { |h, k| h[k] = 0 }
  @attack_waves = 0
  @blocked_attack_waves = 0
  @sinks = Hash.new { |h, k| h[k] = Collector::SinkStats.new(k, @config) }
end

Instance Method Details

#add_attack(sink_name, being_blocked:) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Parameters:

  • sink_name (String)

    the name of the sink

  • being_blocked (Boolean)

    whether the Agent blocked the request



110
111
112
113
114
# File 'lib/aikido/zen/collector/stats.rb', line 110

def add_attack(sink_name, being_blocked:)
  stats = @sinks[sink_name]
  stats.attacks += 1
  stats.blocked_attacks += 1 if being_blocked
end

#add_attack_wave(being_blocked:) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Parameters:

  • being_blocked (Boolean)

    whether the Agent blocked the request



91
92
93
94
# File 'lib/aikido/zen/collector/stats.rb', line 91

def add_attack_wave(being_blocked:)
  @attack_waves += 1
  @blocked_attack_waves += 1 if being_blocked
end

#add_ip_list(ip_list_keys) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Parameters:

  • user_agent_keys (Array<String>)

    the user agent keys



85
86
87
# File 'lib/aikido/zen/collector/stats.rb', line 85

def add_ip_list(ip_list_keys)
  ip_list_keys&.each { |ip_list_key| @ip_lists[ip_list_key] += 1 }
end

#add_rate_limited_requestvoid

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.



73
74
75
# File 'lib/aikido/zen/collector/stats.rb', line 73

def add_rate_limited_request
  @rate_limited_requests += 1
end

#add_requestvoid

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.



68
69
70
# File 'lib/aikido/zen/collector/stats.rb', line 68

def add_request
  @requests += 1
end

#add_scan(sink_name, duration, has_errors:) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Parameters:

  • sink_name (String)

    the name of the sink

  • duration (Float)

    the length the scan in seconds

  • has_errors (Boolean)

    whether errors occurred during the scan



100
101
102
103
104
105
# File 'lib/aikido/zen/collector/stats.rb', line 100

def add_scan(sink_name, duration, has_errors:)
  stats = @sinks[sink_name]
  stats.scans += 1
  stats.errors += 1 if has_errors
  stats.add_timing(duration)
end

#add_user_agent(user_agent_keys) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Parameters:

  • user_agent_keys (Array<String>)

    the user agent keys



79
80
81
# File 'lib/aikido/zen/collector/stats.rb', line 79

def add_user_agent(user_agent_keys)
  user_agent_keys&.each { |user_agent_key| @user_agents[user_agent_key] += 1 }
end

#any?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Boolean)


40
41
42
# File 'lib/aikido/zen/collector/stats.rb', line 40

def any?
  !empty?
end

#as_jsonObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/aikido/zen/collector/stats.rb', line 116

def as_json
  total_attacks, total_blocked = aggregate_attacks_from_sinks
  {
    startedAt: @started_at.to_i * 1000,
    endedAt: (@ended_at.to_i * 1000 if @ended_at),
    operations: @sinks.transform_values(&:as_json),
    requests: {
      total: @requests,
      aborted: @aborted_requests,
      rateLimited: @rate_limited_requests,
      attacksDetected: {
        total: total_attacks,
        blocked: total_blocked
      },
      attackWaves: {
        total: @attack_waves,
        blocked: @blocked_attack_waves
      }
    },
    userAgents: {
      breakdown: @user_agents
    },
    ipAddresses: {
      breakdown: @ip_lists
    }
  }
end

#empty?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Boolean)


32
33
34
35
36
37
# File 'lib/aikido/zen/collector/stats.rb', line 32

def empty?
  @requests.zero? &&
    @user_agents.empty? &&
    @attack_waves.zero? &&
    @sinks.empty?
end

#flush(at: Time.now.utc) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Sets the end time for these stats block, freezes it to avoid any more writing to them, and compresses the timing stats in anticipation of sending these to the Aikido servers.

Parameters:

  • at (Time) (defaults to: Time.now.utc)

    the time at which we’re resetting, which is set as the ending time for the returned copy.



59
60
61
62
63
64
65
# File 'lib/aikido/zen/collector/stats.rb', line 59

def flush(at: Time.now.utc)
  # Make sure the timing stats are compressed before copying, since we
  # need these compressed when we serialize this for the API.
  @sinks.each_value { |sink| sink.compress_timings(at: at) }
  @ended_at = at
  freeze
end

#start(at = Time.now.utc) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Track the timestamp we start tracking this series of stats.

Parameters:

  • at (Time) (defaults to: Time.now.utc)


48
49
50
# File 'lib/aikido/zen/collector/stats.rb', line 48

def start(at = Time.now.utc)
  @started_at = at
end