log_sense 1.4.1 → 1.5.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.org +45 -0
- data/Gemfile.lock +15 -8
- data/LICENSE.txt +9 -2
- data/README.org +33 -16
- data/Rakefile +17 -3
- data/exe/log_sense +22 -5
- data/ip_locations/dbip-country-lite.sqlite3 +0 -0
- data/lib/log_sense/apache_data_cruncher.rb +23 -19
- data/lib/log_sense/apache_log_line_parser.rb +1 -1
- data/lib/log_sense/apache_log_parser.rb +1 -1
- data/lib/log_sense/emitter.rb +199 -67
- data/lib/log_sense/ip_locator.rb +26 -19
- data/lib/log_sense/options_parser.rb +16 -2
- data/lib/log_sense/rails_data_cruncher.rb +3 -0
- data/lib/log_sense/templates/_command_invocation.html.erb +4 -0
- data/lib/log_sense/templates/_command_invocation.txt.erb +1 -0
- data/lib/log_sense/templates/_log_structure.html.erb +6 -3
- data/lib/log_sense/templates/_navigation.html.erb +22 -0
- data/lib/log_sense/templates/_output_table.html.erb +49 -1
- data/lib/log_sense/templates/_output_table.txt.erb +6 -3
- data/lib/log_sense/templates/_report_data.html.erb +4 -4
- data/lib/log_sense/templates/_stylesheet.css +144 -0
- data/lib/log_sense/templates/_summary.html.erb +11 -4
- data/lib/log_sense/templates/_summary.txt.erb +1 -1
- data/lib/log_sense/templates/_warning.txt.erb +1 -0
- data/lib/log_sense/templates/apache.html.erb +51 -316
- data/lib/log_sense/templates/apache.txt.erb +2 -15
- data/lib/log_sense/templates/rails.html.erb +56 -216
- data/lib/log_sense/templates/rails.txt.erb +5 -6
- data/lib/log_sense/version.rb +1 -1
- data/log_sense.gemspec +21 -21
- metadata +9 -7
- data/sample_logs/empty_log.log +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5f37b2247014af9bccfb8bdd205b54eb51cbef35495904444765648a96e0b9ac
|
4
|
+
data.tar.gz: a9cd03afb6770bf854791b8ec93e87d09532828d894b28f5dde670f1af1b1b1d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 62981216e38b92e1c3ea227726dccd592c441de32519a4df6f39bac127f55da32e82b4a1a14897b09b7032c7b3f9506a14e80e49dc43bfe8c9d86bfaa340da82
|
7
|
+
data.tar.gz: e5e6180008a12561d688668cffb2ef3d885d7733cf877aafaed0397b9fa0e91dd12a2998b19006dad4fe6b202bd203a00757f86d5d37efee777dbc7be43e5ab1
|
data/CHANGELOG.org
CHANGED
@@ -2,6 +2,51 @@
|
|
2
2
|
#+AUTHOR: Adolfo Villafiorita
|
3
3
|
#+STARTUP: showall
|
4
4
|
|
5
|
+
* 1.5.2
|
6
|
+
|
7
|
+
- [User] Updated DB-IP country file.
|
8
|
+
- [User] Added reports "Missed Pages by IP" and "Missed Resources by
|
9
|
+
IP". It can help pinpoint attack sources.
|
10
|
+
- [User] Added report "Combined Platform", which puts together
|
11
|
+
Browser, OS, and IP.
|
12
|
+
- [User] Summary now shows total size transferred.
|
13
|
+
- [User] Added link to DB-IP page for IPs in some tables.
|
14
|
+
- [User] Added count of IPs by Country.
|
15
|
+
- [User] Improved textual report: values in cells holding multiple
|
16
|
+
values (e.g. IPs) are now shown in distinct lines in the cell. A new
|
17
|
+
option -r limits the number of lines shown per cell.
|
18
|
+
- [Default] The number of rows initially shown in HTML reports is now 25.
|
19
|
+
- [Default] Default for number of entries in textual report is now
|
20
|
+
100 (used to be 900).
|
21
|
+
- [Fixed] The size column in HTML reports is now sorted numerically.
|
22
|
+
- [Code] Improved performances of DataTable rendering, using the
|
23
|
+
dataRender flag.
|
24
|
+
- [Code] Use trim_mode in ERB to avoid empty lines in HTML output.
|
25
|
+
- [Code] Moved to the debug gem.
|
26
|
+
- [Gem] Updated email and author's name.
|
27
|
+
|
28
|
+
* 1.5.1
|
29
|
+
|
30
|
+
- [User] Option --input-files allows to specify input files
|
31
|
+
in addition to passing filenames to the command line
|
32
|
+
- [User] Minor changes to the layout of HTML reports
|
33
|
+
- [User] Add version number in reports
|
34
|
+
- [Fixed] Duplicated entries in navigation
|
35
|
+
- [Code] Updated and added minitest(s)
|
36
|
+
|
37
|
+
* 1.5.0
|
38
|
+
|
39
|
+
- [User] Present Unique Visits / day as integer
|
40
|
+
- [User] Added Country and Streaks report for rails
|
41
|
+
- [User] Changed Streak report in Apache
|
42
|
+
- [Gem] Updated DB-IP
|
43
|
+
- [Gem] Updated Bundle
|
44
|
+
- [Code] Refactored all reports, so that they are specified
|
45
|
+
in the same way
|
46
|
+
- [Code] Refactor warning message in textual reports
|
47
|
+
- [Code] Build HTML menu for report specification
|
48
|
+
- [Code] Various refactoring passes on the code
|
49
|
+
|
5
50
|
* 1.4.1
|
6
51
|
|
7
52
|
- [User] New textual report for Apache
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
log_sense (1.
|
4
|
+
log_sense (1.5.2)
|
5
5
|
browser
|
6
6
|
ipaddr
|
7
7
|
iso_country_codes
|
@@ -12,24 +12,31 @@ GEM
|
|
12
12
|
remote: https://rubygems.org/
|
13
13
|
specs:
|
14
14
|
browser (5.3.1)
|
15
|
-
|
16
|
-
|
15
|
+
debug (1.6.2)
|
16
|
+
irb (>= 1.3.6)
|
17
|
+
reline (>= 0.3.1)
|
18
|
+
io-console (0.5.11)
|
19
|
+
ipaddr (1.2.4)
|
20
|
+
irb (1.4.1)
|
21
|
+
reline (>= 0.3.0)
|
17
22
|
iso_country_codes (0.7.8)
|
18
|
-
minitest (5.
|
23
|
+
minitest (5.15.0)
|
19
24
|
rake (12.3.3)
|
20
|
-
|
25
|
+
reline (0.3.1)
|
26
|
+
io-console (~> 0.5)
|
27
|
+
sqlite3 (1.4.4)
|
21
28
|
terminal-table (3.0.2)
|
22
29
|
unicode-display_width (>= 1.1.1, < 3)
|
23
|
-
unicode-display_width (2.
|
30
|
+
unicode-display_width (2.2.0)
|
24
31
|
|
25
32
|
PLATFORMS
|
26
33
|
ruby
|
27
34
|
|
28
35
|
DEPENDENCIES
|
29
|
-
|
36
|
+
debug
|
30
37
|
log_sense!
|
31
38
|
minitest
|
32
39
|
rake (~> 12.0)
|
33
40
|
|
34
41
|
BUNDLED WITH
|
35
|
-
2.
|
42
|
+
2.3.3
|
data/LICENSE.txt
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
The MIT License (MIT)
|
2
|
-
|
1
|
+
The source code is distributed under the terms of the MIT License (MIT)
|
3
2
|
Copyright (c) 2021 Shair.Tech
|
4
3
|
|
5
4
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
@@ -19,3 +18,11 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
18
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
19
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
20
|
THE SOFTWARE.
|
21
|
+
|
22
|
+
==============================================================================
|
23
|
+
LogSense uses data from The free DB-IP Lite database for geolocation purposes.
|
24
|
+
|
25
|
+
The DB-IP Lite Database is licensed under a Creative Commons Attribution 4.0
|
26
|
+
International License.
|
27
|
+
|
28
|
+
For more information: https://db-ip.com
|
data/README.org
CHANGED
@@ -14,13 +14,13 @@ LogSense reports the following data:
|
|
14
14
|
- Visitors, hits, unique visitors, bandwidth used
|
15
15
|
- Most accessed HTML pages
|
16
16
|
- Most accessed resources
|
17
|
+
- Missed resources (also by IP) which helps highlight
|
18
|
+
potential attacks
|
17
19
|
- Response statuses
|
18
20
|
- Referers
|
19
21
|
- OS, browsers, and devices
|
20
|
-
- IP Country location, thanks to the
|
22
|
+
- IP Country location, thanks to the DP-IP lite country DB
|
21
23
|
- Streaks: resources accessed by a given IP over time
|
22
|
-
- Potential attacks: access to resources which are not meant to be
|
23
|
-
served by a web server serving static websites
|
24
24
|
- Performance of Rails requests
|
25
25
|
|
26
26
|
Filters from the command line allow to analyze specific periods and
|
@@ -33,6 +33,18 @@ And, of course, the compulsory screenshot:
|
|
33
33
|
#+ATTR_HTML: :width 80%
|
34
34
|
[[file:./apache-screenshot.png]]
|
35
35
|
|
36
|
+
|
37
|
+
* An important word of warning
|
38
|
+
|
39
|
+
[[https://owasp.org/www-community/attacks/Log_Injection][Log poisoning]] is a technique whereby attackers send requests with invalidated
|
40
|
+
user input to forge log entries or inject malicious content into the logs.
|
41
|
+
|
42
|
+
log_sense sanitizes entries of HTML reports, to try and protect from log
|
43
|
+
poisoning. *Log entries and URLs in SQLite3, however, are not sanitized*:
|
44
|
+
they are stored and read from the log. This is not, in general, an issue,
|
45
|
+
unless you use the data from SQLite in environments in which URLs can be
|
46
|
+
opened or code executed.
|
47
|
+
|
36
48
|
* Motivation
|
37
49
|
|
38
50
|
LogSense moves along the lines of tools such as [[https://goaccess.io/][GoAccess]] (which
|
@@ -54,6 +66,7 @@ generated files are then made available on a private area on the web.
|
|
54
66
|
gem install log_sense
|
55
67
|
#+end_src
|
56
68
|
|
69
|
+
|
57
70
|
* Usage
|
58
71
|
|
59
72
|
#+begin_src bash :results raw output :wrap example
|
@@ -65,37 +78,41 @@ generated files are then made available on a private area on the web.
|
|
65
78
|
Usage: log_sense [options] [logfile ...]
|
66
79
|
--title=TITLE Title to use in the report
|
67
80
|
-f, --input-format=FORMAT Input format (either rails or apache)
|
81
|
+
-i, --input-files=file,file, Input files (can also be passed directly)
|
68
82
|
-t, --output-format=FORMAT Output format: html, org, txt, sqlite. See below for available formats
|
69
83
|
-o, --output-file=OUTPUT_FILE Output file
|
70
84
|
-b, --begin=DATE Consider entries after or on DATE
|
71
85
|
-e, --end=DATE Consider entries before or on DATE
|
72
|
-
-l, --limit=N Limit to the N most requested resources (defaults to
|
73
|
-
-w, --width=WIDTH Maximum width of
|
86
|
+
-l, --limit=N Limit to the N most requested resources (defaults to 100)
|
87
|
+
-w, --width=WIDTH Maximum width of long columns in textual reports
|
88
|
+
-r, --rows=ROWS Maximum number of rows for columns with multiple entries in textual reports
|
74
89
|
-c, --crawlers=POLICY Decide what to do with crawlers (applies to Apache Logs)
|
75
90
|
-n, --no-selfpolls Ignore self poll entries (requests from ::1; applies to Apache Logs)
|
91
|
+
--verbose Inform about progress (prints to STDERR)
|
76
92
|
-v, --version Prints version information
|
77
93
|
-h, --help Prints this help
|
78
94
|
|
79
|
-
This is version 1.
|
95
|
+
This is version 1.5.2
|
80
96
|
|
81
97
|
Output formats
|
82
|
-
rails parsing can produce the following outputs:
|
83
|
-
- sqlite
|
84
|
-
- txt
|
85
|
-
- html
|
86
98
|
apache parsing can produce the following outputs:
|
87
99
|
- sqlite
|
100
|
+
- html
|
88
101
|
- txt
|
102
|
+
rails parsing can produce the following outputs:
|
103
|
+
- sqlite
|
89
104
|
- html
|
105
|
+
- txt
|
90
106
|
#+end_example
|
91
107
|
|
92
108
|
Examples:
|
93
109
|
|
94
110
|
#+begin_example sh
|
95
111
|
log_sense -f apache -i access.log -t txt > access-data.txt
|
96
|
-
log_sense -f rails -i production.log -t html -o performance.
|
112
|
+
log_sense -f rails -i production.log -t html -o performance.html
|
97
113
|
#+end_example
|
98
114
|
|
115
|
+
|
99
116
|
* Change Log
|
100
117
|
|
101
118
|
See the [[file:CHANGELOG.org][CHANGELOG]] file.
|
@@ -110,8 +127,8 @@ Concerning the outputs:
|
|
110
127
|
- HTML reports use [[https://get.foundation/][Zurb Foundation]], [[https://www.datatables.net/][Data Tables]], and [[https://vega.github.io/vega-lite/][Vega Light]], which
|
111
128
|
are all downloaded from a CDN
|
112
129
|
- The textual format is compatible with [[https://orgmode.org/][Org Mode]] and can be further
|
113
|
-
processed to any format [[https://orgmode.org/][Org Mode]] can be exported to
|
114
|
-
and PDF
|
130
|
+
processed to any format [[https://orgmode.org/][Org Mode]] can be exported to, including HTML
|
131
|
+
and PDF, with the word of warning in the section above.
|
115
132
|
|
116
133
|
* Author and Contributors
|
117
134
|
|
@@ -119,12 +136,12 @@ Concerning the outputs:
|
|
119
136
|
|
120
137
|
* Known Bugs
|
121
138
|
|
122
|
-
No known bugs; an unknown number of unknown bugs.
|
123
|
-
|
139
|
+
No known bugs; an unknown number of unknown bugs. (See the open issues for
|
140
|
+
the known bugs.)
|
124
141
|
|
125
142
|
* License
|
126
143
|
|
127
|
-
|
144
|
+
Source code distributed under the terms of the [[http://opensource.org/licenses/MIT][MIT License]].
|
128
145
|
|
129
146
|
Geolocation is made possible by the DB-IP.com IP to City database,
|
130
147
|
released under a CC license.
|
data/Rakefile
CHANGED
@@ -9,7 +9,21 @@ end
|
|
9
9
|
require_relative './lib/log_sense/ip_locator.rb'
|
10
10
|
|
11
11
|
desc "Convert Geolocation DB to sqlite"
|
12
|
-
task :dbip_to_sqlite3, [:
|
13
|
-
filename = args[:
|
14
|
-
|
12
|
+
task :dbip_to_sqlite3, [:year_month] do |tasks, args|
|
13
|
+
filename = "./ip_locations/dbip-country-lite-#{args[:year_month]}.csv"
|
14
|
+
|
15
|
+
if !File.exist? filename
|
16
|
+
puts "Error. Could not find: #{filename}"
|
17
|
+
puts
|
18
|
+
puts 'I see the following files:'
|
19
|
+
puts Dir.glob("ip_locations/dbip-country-lite*").map { |x| "- #{x}\n" }
|
20
|
+
puts ''
|
21
|
+
puts '1. Download (if necessary) a more recent version from: https://db-ip.com/db/download/ip-to-country-lite'
|
22
|
+
puts '2. Save downloaded file to ip_locations/'
|
23
|
+
puts '3. Relaunch with YYYY-MM'
|
24
|
+
|
25
|
+
exit
|
26
|
+
else
|
27
|
+
LogSense::IpLocator::dbip_to_sqlite filename
|
28
|
+
end
|
15
29
|
end
|
data/exe/log_sense
CHANGED
@@ -11,11 +11,18 @@ require 'log_sense.rb'
|
|
11
11
|
@options = LogSense::OptionsParser.parse ARGV
|
12
12
|
@output_file = @options[:output_file]
|
13
13
|
|
14
|
-
|
15
|
-
|
14
|
+
#
|
15
|
+
# Input files can be gotten from an option and from what remains in
|
16
|
+
# ARGV
|
17
|
+
#
|
18
|
+
@input_filenames = @options[:input_filenames] + ARGV
|
19
|
+
@non_existing = @input_filenames.reject { |x| File.exist?(x) }
|
20
|
+
|
21
|
+
unless @non_existing.empty?
|
22
|
+
$stderr.puts "Error: input file(s) '#{@non_existing.join(', ')}' do not exist"
|
16
23
|
exit 1
|
17
24
|
end
|
18
|
-
@input_files =
|
25
|
+
@input_files = @input_filenames.empty? ? [$stdin] : @input_filenames.map { |x| File.open(x, 'r') }
|
19
26
|
|
20
27
|
#
|
21
28
|
# Parse Log and Track Statistics
|
@@ -31,35 +38,45 @@ when 'rails'
|
|
31
38
|
parser_klass = LogSense::RailsLogParser
|
32
39
|
cruncher_klass = LogSense::RailsDataCruncher
|
33
40
|
else
|
34
|
-
|
41
|
+
$stderr.puts "Error: input format #{@options[:input_format]} not understood."
|
35
42
|
exit 1
|
36
43
|
end
|
37
44
|
|
45
|
+
$stderr.puts "Parsing input files..." if @options[:verbose]
|
38
46
|
@db = parser_klass.parse @input_files
|
39
47
|
|
40
48
|
if @options[:output_format] == 'sqlite'
|
49
|
+
$stderr.puts "Saving to SQLite3..." if @options[:verbose]
|
41
50
|
ddb = SQLite3::Database.new(@output_file || 'db.sqlite3')
|
42
51
|
b = SQLite3::Backup.new(ddb, 'main', @db, 'main')
|
43
52
|
b.step(-1) #=> DONE
|
44
53
|
b.finish
|
45
54
|
else
|
55
|
+
$stderr.puts "Aggregating data..." if @options[:verbose]
|
46
56
|
@data = cruncher_klass.crunch @db, @options
|
57
|
+
|
58
|
+
$stderr.puts "Geolocating..." if @options[:verbose]
|
47
59
|
@data = LogSense::IpLocator.geolocate @data
|
48
60
|
|
61
|
+
$stderr.puts "Grouping by country..." if @options[:verbose]
|
62
|
+
country_col = @data[:ips][0].size - 1
|
63
|
+
@data[:countries] = @data[:ips].group_by { |x| x[country_col] }
|
64
|
+
|
49
65
|
@ended_at = Time.now
|
50
66
|
@duration = @ended_at - @started_at
|
51
67
|
|
52
68
|
@data = @data.merge({
|
53
69
|
command: @command_line,
|
70
|
+
filenames: ARGV,
|
54
71
|
log_files: @input_files,
|
55
72
|
started_at: @started_at,
|
56
73
|
ended_at: @ended_at,
|
57
74
|
duration: @duration,
|
58
75
|
width: @options[:width]
|
59
76
|
})
|
60
|
-
|
61
77
|
#
|
62
78
|
# Emit Output
|
63
79
|
#
|
80
|
+
$stderr.puts "Emitting..." if @options[:verbose]
|
64
81
|
puts LogSense::Emitter.emit @data, @options
|
65
82
|
end
|
Binary file
|
@@ -17,15 +17,15 @@ module LogSense
|
|
17
17
|
@total_days = 0
|
18
18
|
@total_days = (@last_day - @first_day).to_i if @first_day && @last_day
|
19
19
|
|
20
|
-
@source_files = db.execute
|
20
|
+
@source_files = db.execute 'SELECT distinct(source_file) from LogLine'
|
21
21
|
|
22
|
-
@log_size = db.execute
|
22
|
+
@log_size = db.execute 'SELECT count(datetime) from LogLine'
|
23
23
|
@log_size = @log_size[0][0]
|
24
24
|
|
25
25
|
@selfpolls_size = db.execute "SELECT count(datetime) from LogLine where ip == '::1'"
|
26
26
|
@selfpolls_size = @selfpolls_size[0][0]
|
27
27
|
|
28
|
-
@crawlers_size = db.execute
|
28
|
+
@crawlers_size = db.execute 'SELECT count(datetime) from LogLine where bot == 1'
|
29
29
|
@crawlers_size = @crawlers_size[0][0]
|
30
30
|
|
31
31
|
@first_day_requested = options[:from_date]
|
@@ -35,7 +35,7 @@ module LogSense
|
|
35
35
|
@last_day_in_analysis = date_intersect options[:to_date], @last_day, :min
|
36
36
|
|
37
37
|
@total_days_in_analysis = 0
|
38
|
-
if @first_day_in_analysis
|
38
|
+
if @first_day_in_analysis && @last_day_in_analysis
|
39
39
|
@total_days_in_analysis = (@last_day_in_analysis - @first_day_in_analysis).to_i
|
40
40
|
end
|
41
41
|
|
@@ -45,24 +45,24 @@ module LogSense
|
|
45
45
|
filter = [
|
46
46
|
(options[:from_date] ? "date(datetime) >= '#{options[:from_date]}'" : nil),
|
47
47
|
(options[:to_date] ? "date(datetime) <= '#{options[:to_date]}'" : nil),
|
48
|
-
(options[:only_crawlers] ?
|
49
|
-
(options[:ignore_crawlers] ?
|
48
|
+
(options[:only_crawlers] ? 'bot == 1' : nil),
|
49
|
+
(options[:ignore_crawlers] ? 'bot == 0' : nil),
|
50
50
|
(options[:no_selfpolls] ? "ip != '::1'" : nil),
|
51
|
-
|
51
|
+
'true'
|
52
52
|
].compact.join " and "
|
53
53
|
|
54
54
|
mega = 1024 * 1024
|
55
55
|
giga = mega * 1024
|
56
56
|
tera = giga * 1024
|
57
|
-
|
57
|
+
|
58
58
|
# in alternative to sum(size)
|
59
59
|
human_readable_size = <<-EOS
|
60
|
-
CASE
|
60
|
+
CASE
|
61
61
|
WHEN sum(size) < 1024 THEN sum(size) || ' B'
|
62
62
|
WHEN sum(size) >= 1024 AND sum(size) < (#{mega}) THEN ROUND((CAST(sum(size) AS REAL) / 1024), 2) || ' KB'
|
63
63
|
WHEN sum(size) >= (#{mega}) AND sum(size) < (#{giga}) THEN ROUND((CAST(sum(size) AS REAL) / (#{mega})), 2) || ' MB'
|
64
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'
|
65
|
+
WHEN sum(size) >= (#{tera}) THEN ROUND((CAST(sum(size) AS REAL) / (#{tera})), 2) || ' TB'
|
66
66
|
END AS size
|
67
67
|
EOS
|
68
68
|
|
@@ -101,6 +101,9 @@ module LogSense
|
|
101
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
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
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
|
+
|
104
107
|
@statuses = db.execute "SELECT status, count(status) from LogLine where #{filter} group by status order by status"
|
105
108
|
|
106
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)"
|
@@ -113,24 +116,26 @@ module LogSense
|
|
113
116
|
|
114
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"
|
115
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
|
+
|
116
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]}"
|
117
123
|
|
118
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]}"
|
119
125
|
|
120
|
-
@streaks = db.execute
|
126
|
+
@streaks = db.execute 'SELECT ip, substr(datetime, 1, 10), path from LogLine order by ip, datetime'
|
121
127
|
data = {}
|
122
128
|
|
123
|
-
|
124
|
-
var_as_symbol = variable.to_s[1
|
125
|
-
data[var_as_symbol] =
|
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)
|
126
132
|
end
|
133
|
+
|
127
134
|
data
|
128
135
|
end
|
129
136
|
|
130
|
-
|
131
|
-
|
132
|
-
def self.date_intersect date1, date2, method
|
133
|
-
if date1 and date2
|
137
|
+
def self.date_intersect(date1, date2, method)
|
138
|
+
if date1 && date2
|
134
139
|
[date1, date2].send(method)
|
135
140
|
elsif date1
|
136
141
|
date1
|
@@ -140,4 +145,3 @@ module LogSense
|
|
140
145
|
end
|
141
146
|
end
|
142
147
|
end
|
143
|
-
|