log_sense 1.4.1 → 1.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
-
|