log_sense 1.5.2 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.org +27 -0
  3. data/Gemfile.lock +6 -4
  4. data/README.org +108 -34
  5. data/Rakefile +6 -6
  6. data/exe/log_sense +110 -39
  7. data/ip_locations/dbip-country-lite.sqlite3 +0 -0
  8. data/lib/log_sense/aggregator.rb +191 -0
  9. data/lib/log_sense/apache_aggregator.rb +122 -0
  10. data/lib/log_sense/apache_log_line_parser.rb +23 -21
  11. data/lib/log_sense/apache_log_parser.rb +15 -12
  12. data/lib/log_sense/apache_report_shaper.rb +309 -0
  13. data/lib/log_sense/emitter.rb +55 -553
  14. data/lib/log_sense/ip_locator.rb +24 -12
  15. data/lib/log_sense/options_checker.rb +24 -0
  16. data/lib/log_sense/options_parser.rb +81 -51
  17. data/lib/log_sense/rails_aggregator.rb +69 -0
  18. data/lib/log_sense/rails_log_parser.rb +82 -68
  19. data/lib/log_sense/rails_report_shaper.rb +183 -0
  20. data/lib/log_sense/report_shaper.rb +105 -0
  21. data/lib/log_sense/templates/_cdn_links.html.erb +11 -0
  22. data/lib/log_sense/templates/_command_invocation.html.erb +4 -0
  23. data/lib/log_sense/templates/_log_structure.html.erb +7 -1
  24. data/lib/log_sense/templates/_output_table.html.erb +6 -2
  25. data/lib/log_sense/templates/_rails.css.erb +7 -0
  26. data/lib/log_sense/templates/_summary.html.erb +9 -7
  27. data/lib/log_sense/templates/_summary.txt.erb +2 -2
  28. data/lib/log_sense/templates/{rails.html.erb → report_html.erb} +19 -37
  29. data/lib/log_sense/templates/{apache.txt.erb → report_txt.erb} +1 -1
  30. data/lib/log_sense/version.rb +1 -1
  31. data/lib/log_sense.rb +19 -9
  32. data/log_sense.gemspec +1 -1
  33. data/{apache-screenshot.png → screenshots/apache-screenshot.png} +0 -0
  34. data/screenshots/rails-screenshot.png +0 -0
  35. metadata +17 -11
  36. data/lib/log_sense/apache_data_cruncher.rb +0 -147
  37. data/lib/log_sense/rails_data_cruncher.rb +0 -141
  38. data/lib/log_sense/templates/apache.html.erb +0 -115
  39. data/lib/log_sense/templates/rails.txt.erb +0 -22
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: log_sense
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.2
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adolfo Villafiorita
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-08-18 00:00:00.000000000 Z
11
+ date: 2022-12-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: browser
@@ -124,20 +124,25 @@ files:
124
124
  - LICENSE.txt
125
125
  - README.org
126
126
  - Rakefile
127
- - apache-screenshot.png
128
127
  - bin/console
129
128
  - bin/setup
130
129
  - exe/log_sense
131
130
  - ip_locations/dbip-country-lite.sqlite3
132
131
  - lib/log_sense.rb
133
- - lib/log_sense/apache_data_cruncher.rb
132
+ - lib/log_sense/aggregator.rb
133
+ - lib/log_sense/apache_aggregator.rb
134
134
  - lib/log_sense/apache_log_line_parser.rb
135
135
  - lib/log_sense/apache_log_parser.rb
136
+ - lib/log_sense/apache_report_shaper.rb
136
137
  - lib/log_sense/emitter.rb
137
138
  - lib/log_sense/ip_locator.rb
139
+ - lib/log_sense/options_checker.rb
138
140
  - lib/log_sense/options_parser.rb
139
- - lib/log_sense/rails_data_cruncher.rb
141
+ - lib/log_sense/rails_aggregator.rb
140
142
  - lib/log_sense/rails_log_parser.rb
143
+ - lib/log_sense/rails_report_shaper.rb
144
+ - lib/log_sense/report_shaper.rb
145
+ - lib/log_sense/templates/_cdn_links.html.erb
141
146
  - lib/log_sense/templates/_command_invocation.html.erb
142
147
  - lib/log_sense/templates/_command_invocation.txt.erb
143
148
  - lib/log_sense/templates/_log_structure.html.erb
@@ -146,25 +151,26 @@ files:
146
151
  - lib/log_sense/templates/_output_table.txt.erb
147
152
  - lib/log_sense/templates/_performance.html.erb
148
153
  - lib/log_sense/templates/_performance.txt.erb
154
+ - lib/log_sense/templates/_rails.css.erb
149
155
  - lib/log_sense/templates/_report_data.html.erb
150
156
  - lib/log_sense/templates/_stylesheet.css
151
157
  - lib/log_sense/templates/_summary.html.erb
152
158
  - lib/log_sense/templates/_summary.txt.erb
153
159
  - lib/log_sense/templates/_warning.txt.erb
154
- - lib/log_sense/templates/apache.html.erb
155
- - lib/log_sense/templates/apache.txt.erb
156
- - lib/log_sense/templates/rails.html.erb
157
- - lib/log_sense/templates/rails.txt.erb
160
+ - lib/log_sense/templates/report_html.erb
161
+ - lib/log_sense/templates/report_txt.erb
158
162
  - lib/log_sense/version.rb
159
163
  - log_sense.gemspec
160
164
  - sample_logs/safety-critical_org.log
161
165
  - sample_logs/spmbook_com.log
162
- homepage: https://github.com/shair-tech/log_sense/log_sense
166
+ - screenshots/apache-screenshot.png
167
+ - screenshots/rails-screenshot.png
168
+ homepage: https://github.com/shair-tech/log_sense/
163
169
  licenses:
164
170
  - MIT
165
171
  metadata:
166
172
  allowed_push_host: https://rubygems.org/
167
- homepage_uri: https://github.com/shair-tech/log_sense/log_sense
173
+ homepage_uri: https://github.com/shair-tech/log_sense/
168
174
  source_code_uri: https://github.com/shair-tech/log_sense/
169
175
  changelog_uri: https://github.com/shair-tech/log_sense/blob/main/CHANGELOG.org
170
176
  post_install_message:
@@ -1,147 +0,0 @@
1
- module LogSense
2
- module ApacheDataCruncher
3
- #
4
- # take a sqlite3 database and analyze data
5
- #
6
- # @ variables are automatically put in the returned data
7
- #
8
-
9
- def self.crunch db, options = { limit: 900 }
10
- first_day_s = db.execute "SELECT datetime from LogLine order by datetime limit 1"
11
- last_day_s = db.execute "SELECT datetime from LogLine order by datetime desc limit 1"
12
-
13
- # make first and last day into dates or nil
14
- @first_day = first_day_s&.first&.first ? Date.parse(first_day_s[0][0]) : nil
15
- @last_day = last_day_s&.first&.first ? Date.parse(last_day_s[0][0]) : nil
16
-
17
- @total_days = 0
18
- @total_days = (@last_day - @first_day).to_i if @first_day && @last_day
19
-
20
- @source_files = db.execute 'SELECT distinct(source_file) from LogLine'
21
-
22
- @log_size = db.execute 'SELECT count(datetime) from LogLine'
23
- @log_size = @log_size[0][0]
24
-
25
- @selfpolls_size = db.execute "SELECT count(datetime) from LogLine where ip == '::1'"
26
- @selfpolls_size = @selfpolls_size[0][0]
27
-
28
- @crawlers_size = db.execute 'SELECT count(datetime) from LogLine where bot == 1'
29
- @crawlers_size = @crawlers_size[0][0]
30
-
31
- @first_day_requested = options[:from_date]
32
- @last_day_requested = options[:to_date]
33
-
34
- @first_day_in_analysis = date_intersect options[:from_date], @first_day, :max
35
- @last_day_in_analysis = date_intersect options[:to_date], @last_day, :min
36
-
37
- @total_days_in_analysis = 0
38
- if @first_day_in_analysis && @last_day_in_analysis
39
- @total_days_in_analysis = (@last_day_in_analysis - @first_day_in_analysis).to_i
40
- end
41
-
42
- #
43
- # generate the where clause corresponding to the command line options to filter data
44
- #
45
- filter = [
46
- (options[:from_date] ? "date(datetime) >= '#{options[:from_date]}'" : nil),
47
- (options[:to_date] ? "date(datetime) <= '#{options[:to_date]}'" : nil),
48
- (options[:only_crawlers] ? 'bot == 1' : nil),
49
- (options[:ignore_crawlers] ? 'bot == 0' : nil),
50
- (options[:no_selfpolls] ? "ip != '::1'" : nil),
51
- 'true'
52
- ].compact.join " and "
53
-
54
- mega = 1024 * 1024
55
- giga = mega * 1024
56
- tera = giga * 1024
57
-
58
- # in alternative to sum(size)
59
- human_readable_size = <<-EOS
60
- CASE
61
- WHEN sum(size) < 1024 THEN sum(size) || ' B'
62
- WHEN sum(size) >= 1024 AND sum(size) < (#{mega}) THEN ROUND((CAST(sum(size) AS REAL) / 1024), 2) || ' KB'
63
- WHEN sum(size) >= (#{mega}) AND sum(size) < (#{giga}) THEN ROUND((CAST(sum(size) AS REAL) / (#{mega})), 2) || ' MB'
64
- WHEN sum(size) >= (#{giga}) AND sum(size) < (#{tera}) THEN ROUND((CAST(sum(size) AS REAL) / (#{giga})), 2) || ' GB'
65
- WHEN sum(size) >= (#{tera}) THEN ROUND((CAST(sum(size) AS REAL) / (#{tera})), 2) || ' TB'
66
- END AS size
67
- EOS
68
-
69
- human_readable_day = <<-EOS
70
- case cast (strftime('%w', datetime) as integer)
71
- when 0 then 'Sunday'
72
- when 1 then 'Monday'
73
- when 2 then 'Tuesday'
74
- when 3 then 'Wednesday'
75
- when 4 then 'Thursday'
76
- when 5 then 'Friday'
77
- else 'Saturday'
78
- end as dow
79
- EOS
80
-
81
- @total_hits = db.execute "SELECT count(datetime) from LogLine where #{filter}"
82
- @total_hits = @total_hits[0][0]
83
-
84
- @total_unique_visits = db.execute "SELECT count(distinct(unique_visitor)) from LogLine where #{filter}"
85
- @total_unique_visits = @total_unique_visits[0][0]
86
-
87
- @total_size = db.execute "SELECT #{human_readable_size} from LogLine where #{filter}"
88
- @total_size = @total_size[0][0]
89
-
90
- @daily_distribution = db.execute "SELECT date(datetime), #{human_readable_day}, count(datetime), count(distinct(unique_visitor)), #{human_readable_size} from LogLine where #{filter} group by date(datetime)"
91
- @time_distribution = db.execute "SELECT strftime('%H', datetime), count(datetime), count(distinct(unique_visitor)), #{human_readable_size} from LogLine where #{filter} group by strftime('%H', datetime)"
92
-
93
- good_statuses = "(status like '2%' or status like '3%')"
94
- bad_statuses = "(status like '4%' or status like '5%')"
95
- html_page = "(extension like '.htm%')"
96
- non_html_page = "(extension not like '.htm%')"
97
-
98
- @most_requested_pages = db.execute "SELECT path, count(path), count(distinct(unique_visitor)), #{human_readable_size}, status from LogLine where #{good_statuses} and #{html_page} and #{filter} group by path order by count(path) desc limit #{options[:limit]}"
99
- @most_requested_resources = db.execute "SELECT path, count(path), count(distinct(unique_visitor)), #{human_readable_size}, status from LogLine where #{good_statuses} and #{non_html_page} and #{filter} group by path order by count(path) desc limit #{options[:limit]}"
100
-
101
- @missed_pages = db.execute "SELECT path, count(path), count(distinct(unique_visitor)), status from LogLine where #{bad_statuses} and #{html_page} and #{filter} group by path order by count(path) desc limit #{options[:limit]}"
102
- @missed_resources = db.execute "SELECT path, count(path), count(distinct(unique_visitor)), status from LogLine where #{bad_statuses} and #{filter} group by path order by count(path) desc limit #{options[:limit]}"
103
-
104
- @missed_pages_by_ip = db.execute "SELECT ip, path, status from LogLine where #{bad_statuses} and #{html_page} and #{filter} limit #{options[:limit]}"
105
- @missed_resources_by_ip = db.execute "SELECT ip, path, status from LogLine where #{bad_statuses} and #{filter} limit #{options[:limit]}"
106
-
107
- @statuses = db.execute "SELECT status, count(status) from LogLine where #{filter} group by status order by status"
108
-
109
- @by_day_4xx = db.execute "SELECT date(datetime), count(datetime) from LogLine where substr(status, 1,1) == '4' and #{filter} group by date(datetime)"
110
- @by_day_3xx = db.execute "SELECT date(datetime), count(datetime) from LogLine where substr(status, 1,1) == '3' and #{filter} group by date(datetime)"
111
- @by_day_2xx = db.execute "SELECT date(datetime), count(datetime) from LogLine where substr(status, 1,1) == '2' and #{filter} group by date(datetime)"
112
-
113
- @statuses_by_day = (@by_day_2xx + @by_day_3xx + @by_day_4xx).group_by { |x| x[0] }.to_a.map { |x|
114
- [x[0], x[1].map { |y| y[1] }].flatten
115
- }
116
-
117
- @browsers = db.execute "SELECT browser, count(browser), count(distinct(unique_visitor)), #{human_readable_size} from LogLine where #{filter} group by browser order by count(browser) desc"
118
- @platforms = db.execute "SELECT platform, count(platform), count(distinct(unique_visitor)), #{human_readable_size} from LogLine where #{filter} group by platform order by count(platform) desc"
119
-
120
- @combined_platforms = db.execute "SELECT browser, platform, ip, count(datetime), #{human_readable_size} from LogLine where #{filter} group by browser, platform, ip order by count(datetime) desc limit #{options[:limit]}"
121
-
122
- @referers = db.execute "SELECT referer, count(referer), count(distinct(unique_visitor)), #{human_readable_size} from LogLine where #{filter} group by referer order by count(referer) desc limit #{options[:limit]}"
123
-
124
- @ips = db.execute "SELECT ip, count(ip), count(distinct(unique_visitor)), #{human_readable_size} from LogLine where #{filter} group by ip order by count(ip) desc limit #{options[:limit]}"
125
-
126
- @streaks = db.execute 'SELECT ip, substr(datetime, 1, 10), path from LogLine order by ip, datetime'
127
- data = {}
128
-
129
- instance_variables.each do |variable|
130
- var_as_symbol = variable.to_s[1..].to_sym
131
- data[var_as_symbol] = instance_variable_get(variable)
132
- end
133
-
134
- data
135
- end
136
-
137
- def self.date_intersect(date1, date2, method)
138
- if date1 && date2
139
- [date1, date2].send(method)
140
- elsif date1
141
- date1
142
- else
143
- date2
144
- end
145
- end
146
- end
147
- end
@@ -1,141 +0,0 @@
1
- module LogSense
2
- module RailsDataCruncher
3
-
4
- #
5
- # take a sqlite3 database and analyze data
6
- #
7
- # @ variables are automatically put in the returned data
8
- #
9
-
10
- def self.crunch db, options = { limit: 900 }
11
- first_day_s = db.execute "SELECT started_at from Event where started_at not NULL order by started_at limit 1"
12
- # we could use ended_at to cover the full activity period, but I prefer started_at
13
- # with the meaning that the monitor event initiation
14
- last_day_s = db.execute "SELECT started_at from Event order by started_at desc limit 1"
15
-
16
- # make first and last day into dates or nil
17
- # TODO: bug possible value here: [[nil]], which is not empty
18
- @first_day = first_day_s&.first&.first ? Date.parse(first_day_s[0][0]) : nil
19
- @last_day = last_day_s&.first&.first ? Date.parse(last_day_s[0][0]) : nil
20
-
21
- @total_days = 0
22
- @total_days = (@last_day - @first_day).to_i if @first_day && @last_day
23
-
24
- # TODO should also look into Error
25
- @source_files = db.execute "SELECT distinct(source_file) from Event"
26
-
27
- @log_size = db.execute "SELECT count(started_at) from Event"
28
- @log_size = @log_size[0][0]
29
-
30
- # TODO: I should make the names of events/size/etc uniform betweeen Apache and Rails Logs
31
- # SAME AS ABOVE
32
- @total_hits = @log_size
33
-
34
- # SAME AS ABOVE (but log_size is wrong in the case of Rails
35
- # logs, since an event takes more than one line)
36
- @events = db.execute "SELECT count(started_at) from Event"
37
- @events = @events[0][0]
38
-
39
- @first_day_requested = options[:from_date]
40
- @last_day_requested = options[:to_date]
41
-
42
- @first_day_in_analysis = date_intersect options[:from_date], @first_day, :max
43
- @last_day_in_analysis = date_intersect options[:to_date], @last_day, :min
44
-
45
- @total_days_in_analysis = 0
46
- if @first_day_in_analysis and @last_day_in_analysis
47
- @total_days_in_analysis = (@last_day_in_analysis - @first_day_in_analysis).to_i
48
- end
49
-
50
- #
51
- # generate the where clause corresponding to the command line options to filter data
52
- #
53
- filter = [
54
- (options[:from_date] ? "date(started_at) >= '#{options[:from_date]}'" : nil),
55
- (options[:to_date] ? "date(started_at) <= '#{options[:to_date]}'" : nil),
56
- "true"
57
- ].compact.join " and "
58
-
59
- mega = 1024 * 1024
60
- giga = mega * 1024
61
- tera = giga * 1024
62
-
63
- # in alternative to sum(size)
64
- human_readable_size = <<-EOS
65
- CASE
66
- WHEN sum(size) < 1024 THEN sum(size) || ' B'
67
- WHEN sum(size) >= 1024 AND sum(size) < (#{mega}) THEN ROUND((CAST(sum(size) AS REAL) / 1024), 2) || ' KB'
68
- WHEN sum(size) >= (#{mega}) AND sum(size) < (#{giga}) THEN ROUND((CAST(sum(size) AS REAL) / (#{mega})), 2) || ' MB'
69
- WHEN sum(size) >= (#{giga}) AND sum(size) < (#{tera}) THEN ROUND((CAST(sum(size) AS REAL) / (#{giga})), 2) || ' GB'
70
- WHEN sum(size) >= (#{tera}) THEN ROUND((CAST(sum(size) AS REAL) / (#{tera})), 2) || ' TB'
71
- END AS size
72
- EOS
73
-
74
- human_readable_day = <<-EOS
75
- case cast (strftime('%w', started_at) as integer)
76
- when 0 then 'Sunday'
77
- when 1 then 'Monday'
78
- when 2 then 'Tuesday'
79
- when 3 then 'Wednesday'
80
- when 4 then 'Thursday'
81
- when 5 then 'Friday'
82
- else 'Saturday'
83
- end as dow
84
- EOS
85
-
86
- @total_events = db.execute "SELECT count(started_at) from Event where #{filter}"
87
-
88
- @total_unique_visits = db.execute "SELECT count(distinct(unique_visitor)) from Event where #{filter}"
89
- @total_unique_visits = @total_unique_visits[0][0]
90
-
91
- @daily_distribution = db.execute "SELECT date(started_at), #{human_readable_day}, count(started_at) from Event where #{filter} group by date(started_at)"
92
- @time_distribution = db.execute "SELECT strftime('%H', started_at), count(started_at) from Event where #{filter} group by strftime('%H', started_at)"
93
-
94
- @statuses = db.execute "SELECT status, count(status) from Event where #{filter} group by status order by status"
95
-
96
- @by_day_5xx = db.execute "SELECT date(started_at), count(started_at) from Event where substr(status, 1,1) == '5' and #{filter} group by date(started_at)"
97
- @by_day_4xx = db.execute "SELECT date(started_at), count(started_at) from Event where substr(status, 1,1) == '4' and #{filter} group by date(started_at)"
98
- @by_day_3xx = db.execute "SELECT date(started_at), count(started_at) from Event where substr(status, 1,1) == '3' and #{filter} group by date(started_at)"
99
- @by_day_2xx = db.execute "SELECT date(started_at), count(started_at) from Event where substr(status, 1,1) == '2' and #{filter} group by date(started_at)"
100
-
101
- @statuses_by_day = (@by_day_2xx + @by_day_3xx + @by_day_4xx + @by_day_5xx).group_by { |x| x[0] }.to_a.map { |x|
102
- [x[0], x[1].map { |y| y[1] }].flatten
103
- }
104
-
105
- @ips = db.execute "SELECT ip, count(ip) from Event where #{filter} group by ip order by count(ip) desc limit #{options[:limit]}"
106
-
107
- @streaks = db.execute 'SELECT ip, substr(started_at, 1, 10), url from Event order by ip, started_at'
108
- data = {}
109
-
110
- @performance = db.execute "SELECT distinct(controller), count(controller), printf(\"%.2f\", min(duration_total_ms)), printf(\"%.2f\", avg(duration_total_ms)), printf(\"%.2f\", max(duration_total_ms)) from Event group by controller order by controller"
111
-
112
- @fatal = db.execute ("SELECT strftime(\"%Y-%m-%d %H:%M\", started_at), ip, url, error.description, event.log_id FROM Event JOIN Error ON event.log_id == error.log_id WHERE exit_status == 'F'") || [[]]
113
-
114
- @internal_server_error = (db.execute "SELECT strftime(\"%Y-%m-%d %H:%M\", started_at), status, ip, url, error.description, event.log_id FROM Event JOIN Error ON event.log_id == error.log_id WHERE status is 500") || [[]]
115
-
116
- @error = (db.execute "SELECT log_id, context, description, count(log_id) from Error GROUP BY description") || [[]]
117
-
118
- data = {}
119
- self.instance_variables.each do |variable|
120
- var_as_symbol = variable.to_s[1..-1].to_sym
121
- data[var_as_symbol] = eval(variable.to_s)
122
- end
123
- data
124
- end
125
-
126
- private
127
-
128
- def self.date_intersect date1, date2, method
129
- if date1 and date2
130
- [date1, date2].send(method)
131
- elsif date1
132
- date1
133
- else
134
- date2
135
- end
136
- end
137
-
138
-
139
- end
140
- end
141
-
@@ -1,115 +0,0 @@
1
- <!doctype html>
2
- <html class="no-js" lang="en">
3
- <head>
4
- <title>
5
- <%= options[:title] || "Log Sense: #{data[:filenames].empty? ? "stdin" : data[:filenames].join(", ")}" %>
6
- </title>
7
-
8
- <meta charset="utf-8" />
9
- <meta http-equiv="x-ua-compatible" content="ie=edge">
10
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
11
-
12
- <meta name="author" content="Shair.Tech">
13
- <meta name="description" content="Analysis of <%= data[:filenames].join(', ') %>">
14
-
15
- <link rel="preconnect" href="https://fonts.googleapis.com">
16
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
17
- <link href="https://fonts.googleapis.com/css2?family=Fira+Sans:wght@300;700&display=swap" rel="stylesheet">
18
-
19
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/foundicons/3.0.0/foundation-icons.min.css">
20
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/foundation-sites@6.7.4/dist/css/foundation.min.css">
21
- <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/zf/dt-1.11.3/datatables.min.css"/>
22
-
23
- <script type="text/javascript" src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
24
- <script type="text/javascript" src="https://cdn.datatables.net/v/zf/dt-1.11.3/datatables.min.js"></script>
25
-
26
- <script src="https://cdn.jsdelivr.net/npm/vega@5.21.0"></script>
27
- <script src="https://cdn.jsdelivr.net/npm/vega-lite@5.2.0"></script>
28
- <script src="https://cdn.jsdelivr.net/npm/vega-embed@6.20.2"></script>
29
-
30
- <style>
31
- <%= render "stylesheet.css" %>
32
- </style>
33
- </head>
34
-
35
- <body>
36
- <div class="off-canvas-wrapper">
37
- <div class="off-canvas position-left" id="offCanvas" data-off-canvas>
38
- <%= render "navigation.html.erb",
39
- menus: Emitter::apache_report_specification.map { |x| x[:title] } %>
40
- </div>
41
- <div class="off-canvas-content" data-off-canvas-content>
42
- <button id="toggle-button" type="button" data-toggle="offCanvas">
43
- &#9776;
44
- </button>
45
-
46
- <section class="main-section grid-container fluid">
47
- <h1><%= options[:title] || "Log Sense Apache Log Report" %></h1>
48
-
49
- <p><b>Input File(s):</b> <%= data[:filenames].empty? ? "stdin" : data[:filenames].join(", ") %></p>
50
-
51
- <div class="grid-x grid-padding-x">
52
- <article class="small-12 large-6 cell">
53
- <h2 id="<%= Emitter::slugify "Summary" %>">Summary</h2>
54
- <%= render "summary.html.erb", data: data %>
55
- </article>
56
-
57
- <article class="small-12 large-6 cell">
58
- <h2 id="<%= Emitter::slugify "Summary" %>">Log Structure</h2>
59
- <%= render "log_structure.html.erb", data: data %>
60
- </article>
61
-
62
- <% @reports.each_with_index do |report, index| %>
63
- <article class="<%= report[:col] || "small-12 large-6" %> cell">
64
- <h2 id="<%= Emitter::slugify report[:title] %>"><%= report[:title] %></h2>
65
-
66
- <%= render "report_data.html.erb", report: report, index: index %>
67
- <% if report[:vega_spec] %>
68
- <div id="<%= "plot-#{index}" %>" class="plot-canvas">
69
- </div>
70
- <script>
71
- plot_spec_<%= index %> = Object.assign(
72
- <%= report[:vega_spec].to_json %>,
73
- { "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
74
- width: "container",
75
- description: "<%= report[:title] %>",
76
- data: {
77
- values: data_<%= index %>
78
- },
79
- });
80
- vegaEmbed('#<%= "plot-#{index}"%>', plot_spec_<%= index %>);
81
- </script>
82
- <% end %>
83
-
84
- <%= render "output_table.html.erb", report: report, index: index %>
85
- </article>
86
- <% end %>
87
-
88
- <article class="small-12 large-6 cell">
89
- <h2 id="<%= Emitter::slugify "Command Invocation" %>">Command Invocation</h2>
90
- <%= render "command_invocation.html.erb", data: data, options: options %>
91
- </article>
92
-
93
- <article class="small-12 large-6 cell">
94
- <h2 id="<%= Emitter::slugify "Performance" %>">Performance</h2>
95
- <%= render "performance.html.erb", data: data %>
96
- </article>
97
- </div>
98
- </section>
99
- </div>
100
- </div>
101
-
102
- <script type="text/javascript" src="js/vendor/what-input.js"></script>
103
- <script src="https://cdn.jsdelivr.net/npm/vega@5"></script>
104
- <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/foundation-sites@6.7.4/dist/js/foundation.min.js" crossorigin="anonymous"></script>
105
- <script>
106
- $(document).foundation();
107
-
108
- $(document).ready(function () {
109
- $('.data-table').each(function () {
110
- $(this).DataTable();
111
- });
112
- });
113
- </script>
114
- </body>
115
- </html>
@@ -1,22 +0,0 @@
1
- * Rails Log Analysis
2
-
3
- <%= render "warning.txt.erb" %>
4
-
5
- ** Summary
6
-
7
- <%= render "summary.txt.erb", data: data %>
8
-
9
- <% @reports.reject { |x| x[:report] == :html }.each do |report| %>
10
- ** <%= report[:title] %>
11
-
12
- <%= render "output_table.txt.erb", report: report, data: data %>
13
- <% end %>
14
-
15
- ** Command Invocation
16
-
17
- <%= render 'command_invocation.txt.erb', data: data %>
18
-
19
- ** Performance
20
-
21
- <%= render 'performance.txt.erb', data: data %>
22
-