Add monthly visitors functionality #1
|
@ -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
33
main.rb
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue