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, sink_kind, 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

  • sink_kind (String)

    the category of operation the sink represents

  • being_blocked (Boolean)

    whether the Agent blocked the request



113
114
115
116
117
118
# File 'lib/aikido/zen/collector/stats.rb', line 113

def add_attack(sink_name, sink_kind, being_blocked:)
  stats = @sinks[sink_name]
  stats.kind = sink_kind
  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, sink_kind, 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

  • sink_kind (String)

    the category of operation the sink represents

  • duration (Float)

    the length the scan in seconds

  • has_errors (Boolean)

    whether errors occurred during the scan



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

def add_scan(sink_name, sink_kind, duration, has_errors:)
  stats = @sinks[sink_name]
  stats.kind = sink_kind
  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.



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

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