Many updates

This commit is contained in:
Dan Milne
2025-11-13 14:42:43 +11:00
parent 5e5198f113
commit df94ac9720
41 changed files with 4760 additions and 516 deletions

View File

@@ -2,28 +2,35 @@
class EventsController < ApplicationController
def show
@event = Event.find(params[:id])
@network_range = NetworkRange.contains_ip(@event.ip_address.to_s).first
@event = Event.includes(:network_range).find(params[:id])
# Auto-generate network range if no match found
# Use denormalized network_range_id if available (much faster)
@network_range = @event.network_range
# Fallback to IP lookup if network_range_id is missing
unless @network_range
@network_range = NetworkRangeGenerator.find_or_create_for_ip(@event.ip_address)
Rails.logger.debug "Auto-generated network range #{@network_range&.cidr} for IP #{@event.ip_address}" if @network_range
@network_range = NetworkRange.contains_ip(@event.ip_address.to_s).first
# Auto-generate network range if no match found
unless @network_range
@network_range = NetworkRangeGenerator.find_or_create_for_ip(@event.ip_address)
Rails.logger.debug "Auto-generated network range #{@network_range&.cidr} for IP #{@event.ip_address}" if @network_range
end
end
end
def index
@events = Event.order(timestamp: :desc)
@events = Event.includes(:network_range, :rule).order(timestamp: :desc)
Rails.logger.debug "Found #{@events.count} total events"
Rails.logger.debug "Action: #{params[:waf_action]}"
# Apply filters
@events = @events.by_ip(params[:ip]) if params[:ip].present?
@events = @events.by_waf_action(params[:waf_action]) if params[:waf_action].present?
@events = @events.joins("JOIN network_ranges ON events.ip_address <<= network_ranges.network")
.where("network_ranges.country = ?", params[:country]) if params[:country].present?
@events = @events.by_country(params[:country]) if params[:country].present?
@events = @events.where(rule_id: params[:rule_id]) if params[:rule_id].present?
# Network-based filters
# Network-based filters (now using denormalized columns)
@events = @events.by_company(params[:company]) if params[:company].present?
@events = @events.by_network_type(params[:network_type]) if params[:network_type].present?
@events = @events.by_asn(params[:asn]) if params[:asn].present?
@@ -37,24 +44,10 @@ class EventsController < ApplicationController
# Paginate
@pagy, @events = pagy(@events, items: 50)
# Preload network ranges for all unique IPs to avoid N+1 queries
unique_ips = @events.pluck(:ip_address).uniq.compact
@network_ranges_by_ip = {}
unique_ips.each do |ip|
ip_string = ip.to_s # IPAddr objects can be converted to string
range = NetworkRange.contains_ip(ip_string).first
# Auto-generate network range if no match found
unless range
range = NetworkRangeGenerator.find_or_create_for_ip(ip)
Rails.logger.debug "Auto-generated network range #{range&.cidr} for IP #{ip_string}" if range
end
@network_ranges_by_ip[ip_string] = range if range
end
# Network ranges are now preloaded via includes(:network_range)
# The denormalized network_range_id makes this much faster than IP containment lookups
Rails.logger.debug "Events count after pagination: #{@events.count}"
Rails.logger.debug "Pagy info: #{@pagy.count} total, #{@pagy.pages} pages"
Rails.logger.debug "Preloaded network ranges for #{@network_ranges_by_ip.count} unique IPs"
end
end