Add monthly visitors functionality #1

Merged
miguel456 merged 6 commits from feat/monthly-visitors into main 2024-05-20 13:31:19 +00:00
2 changed files with 46 additions and 17 deletions
Showing only changes of commit e49e90f91e - Show all commits

View File

@ -10,21 +10,21 @@
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/.bundle" />
</content>
<orderEntry type="jdk" jdkName="ruby-3.3.1-p55" jdkType="RUBY_SDK" />
<orderEntry type="jdk" jdkName="ruby-3.2.3-p157" jdkType="RUBY_SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" scope="PROVIDED" name="ast (v2.4.2, ruby-3.3.1-p55) [gem]" level="application" />
<orderEntry type="library" scope="PROVIDED" name="bundler (v2.5.9, ruby-3.3.1-p55) [gem]" level="application" />
<orderEntry type="library" scope="PROVIDED" name="json (v2.7.2, ruby-3.3.1-p55) [gem]" level="application" />
<orderEntry type="library" scope="PROVIDED" name="language_server-protocol (v3.17.0.3, ruby-3.3.1-p55) [gem]" level="application" />
<orderEntry type="library" scope="PROVIDED" name="parallel (v1.24.0, ruby-3.3.1-p55) [gem]" level="application" />
<orderEntry type="library" scope="PROVIDED" name="parser (v3.3.1.0, ruby-3.3.1-p55) [gem]" level="application" />
<orderEntry type="library" scope="PROVIDED" name="racc (v1.7.3, ruby-3.3.1-p55) [gem]" level="application" />
<orderEntry type="library" scope="PROVIDED" name="rainbow (v3.1.1, ruby-3.3.1-p55) [gem]" level="application" />
<orderEntry type="library" scope="PROVIDED" name="regexp_parser (v2.9.0, ruby-3.3.1-p55) [gem]" level="application" />
<orderEntry type="library" scope="PROVIDED" name="rexml (v3.2.6, ruby-3.3.1-p55) [gem]" level="application" />
<orderEntry type="library" scope="PROVIDED" name="rubocop (v1.63.4, ruby-3.3.1-p55) [gem]" level="application" />
<orderEntry type="library" scope="PROVIDED" name="rubocop-ast (v1.31.3, ruby-3.3.1-p55) [gem]" level="application" />
<orderEntry type="library" scope="PROVIDED" name="ruby-progressbar (v1.13.0, ruby-3.3.1-p55) [gem]" level="application" />
<orderEntry type="library" scope="PROVIDED" name="unicode-display_width (v2.5.0, ruby-3.3.1-p55) [gem]" level="application" />
<orderEntry type="library" scope="PROVIDED" name="ast (v2.4.2, ruby-3.2.3-p157) [gem]" level="application" />
<orderEntry type="library" scope="PROVIDED" name="bundler (v2.5.9, ruby-3.2.3-p157) [gem]" level="application" />
<orderEntry type="library" scope="PROVIDED" name="json (v2.7.2, ruby-3.2.3-p157) [gem]" level="application" />
<orderEntry type="library" scope="PROVIDED" name="language_server-protocol (v3.17.0.3, ruby-3.2.3-p157) [gem]" level="application" />
<orderEntry type="library" scope="PROVIDED" name="parallel (v1.24.0, ruby-3.2.3-p157) [gem]" level="application" />
<orderEntry type="library" scope="PROVIDED" name="parser (v3.3.1.0, ruby-3.2.3-p157) [gem]" level="application" />
<orderEntry type="library" scope="PROVIDED" name="racc (v1.7.3, ruby-3.2.3-p157) [gem]" level="application" />
<orderEntry type="library" scope="PROVIDED" name="rainbow (v3.1.1, ruby-3.2.3-p157) [gem]" level="application" />
<orderEntry type="library" scope="PROVIDED" name="regexp_parser (v2.9.0, ruby-3.2.3-p157) [gem]" level="application" />
<orderEntry type="library" scope="PROVIDED" name="rexml (v3.2.6, ruby-3.2.3-p157) [gem]" level="application" />
<orderEntry type="library" scope="PROVIDED" name="rubocop (v1.63.4, ruby-3.2.3-p157) [gem]" level="application" />
<orderEntry type="library" scope="PROVIDED" name="rubocop-ast (v1.31.3, ruby-3.2.3-p157) [gem]" level="application" />
<orderEntry type="library" scope="PROVIDED" name="ruby-progressbar (v1.13.0, ruby-3.2.3-p157) [gem]" level="application" />
<orderEntry type="library" scope="PROVIDED" name="unicode-display_width (v2.5.0, ruby-3.2.3-p157) [gem]" level="application" />
</component>
</module>

33
main.rb
View File

@ -44,8 +44,8 @@ def get_line_date(line)
pattern = /\[(.*?)\]/
match = line.match(pattern)[0] if line.match(pattern)
# [12/Apr/2023:13:56:41 +0100] -> 12/Apr/2023:13:56:41 +0100
Date.parse(match.gsub('[', '').gsub(']', ''))
# [12/Apr/2023:13:56:41 +0100] -> 12/Apr/2023:13:56:41 +0100 -> Apr/2023
Date.parse(match.gsub('[', '').gsub(']', '')).strftime('%b/%Y')
end
# Gets the HTTP status code of the given log line
@ -87,6 +87,8 @@ def sort_unique_ip(ips)
end
visit_counter = {}
monthly_visits = {}
client_errors = {}
user_agents = {}
all_ips = []
@ -108,6 +110,7 @@ lines.each do |line|
ip = get_line_ip(line).to_s
code = get_line_code(line)
ua = get_line_ua(line)
date = get_line_date(line)
if is_client_err?(code.to_i)
if client_errors[ip]
@ -123,6 +126,16 @@ lines.each do |line|
user_agents[ua] = 1
end
if monthly_visits[ip]
if monthly_visits[ip][date]
monthly_visits[ip][date] += 1
else
monthly_visits[ip][date] = 1
end
else
monthly_visits[ip] = { date => 1 }
end
end
top_user_agents = user_agents.sort_by { |_ua, count| -count }.first(5)
@ -136,3 +149,19 @@ puts 'Top 5 IPs with most client errors (400-499):'
top_client_errors.each do |ip, count|
puts "#{ip}: #{count} errors"
end
top_monthly_visits = monthly_visits.sort_by { |_ip, dates| -dates.values.sum }.first(5)
top_monthly_visits.each do |ip, dates|
puts "IP #{ip} had the most visits in the following months:"
dates.each do |date, count|
puts " #{date}: #{count} visits"
end
end
monthly_visits.each do |ip, visits|
puts "IP #{ip} had the following visits:"
visits.each do |date, count|
puts " #{date}: #{count} visits"
end
end