log_sense 1.0.11 → 1.2.0

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.
@@ -0,0 +1,351 @@
1
+ <!doctype html>
2
+ <html class="no-js" lang="en">
3
+ <head>
4
+ <title><%= options[:title] || "Log Sense: #{data[:log_file]}" %></title>
5
+
6
+ <meta charset="utf-8" />
7
+ <meta http-equiv="x-ua-compatible" content="ie=edge">
8
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
9
+ <meta name="author" content="Log Sense">
10
+ <meta name="description" content="Analysis of <%= data[:log_file] %>">
11
+
12
+ <link rel="preconnect" href="https://fonts.googleapis.com">
13
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
14
+ <link href="https://fonts.googleapis.com/css2?family=PT+Sans&display=swap" rel="stylesheet">
15
+
16
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/foundicons/3.0.0/foundation-icons.min.css">
17
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/foundation-sites@6.7.4/dist/css/foundation.min.css">
18
+ <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/zf/dt-1.11.3/datatables.min.css"/>
19
+
20
+
21
+ <script src="https://cdn.jsdelivr.net/npm/vega@5.21.0"></script>
22
+ <script src="https://cdn.jsdelivr.net/npm/vega-lite@5.2.0"></script>
23
+ <script src="https://cdn.jsdelivr.net/npm/vega-embed@6.20.2"></script>
24
+
25
+ <style>
26
+ body {
27
+ font-family: 'PT Sans', sans-serif;
28
+ font-size: 80%;
29
+ }
30
+
31
+ #offCanvas {
32
+ color: white;
33
+ background: #0D0630;
34
+ border-right: none;
35
+ box-shadow: none;
36
+ padding: 0.5rem;
37
+ }
38
+ #offCanvas a {
39
+ color: #E6F9AF;
40
+ }
41
+
42
+ .contents-button {
43
+ font-size: xx-large;
44
+ }
45
+
46
+ .main-section {
47
+ margin-left: 45px;
48
+ }
49
+
50
+ h1 {
51
+ font-size: 1.8rem;
52
+ }
53
+
54
+ h2 {
55
+ font-size: 1.2rem;
56
+ }
57
+
58
+ th {
59
+ padding: 0.2rem 1.2rem 0.2rem 0.2rem !important
60
+ }
61
+
62
+ td {
63
+ padding: 0.2rem 1rem 0.2rem 0.2rem !important;
64
+ }
65
+
66
+ .hits, .visits, .size, .count, .s2xx, .s3xx, .so4xx, .total-hits, .total-visits {
67
+ text-align: right !important;
68
+ }
69
+
70
+ .card-divider {
71
+ padding: 0.2rem 0.4rem 0.2rem 0.4rem;
72
+ background: #D30001;
73
+ color: white;
74
+ }
75
+
76
+ input, select {
77
+ font-size: 0.8rem !important;
78
+ height: 1.5rem !important;
79
+ padding: 0.2rem 0.4rem 0.2rem 0.4rem !important;
80
+ }
81
+
82
+ .dataTables_info {
83
+ font-size: small;
84
+ color: rgb(202, 202, 202);
85
+ }
86
+
87
+ ul.pagination, li.paginate_button {
88
+ font-size: small;
89
+ margin-top: 0px !important;
90
+ margin-bottom: 0px !important;
91
+ padding-top: 0px !important;
92
+ padding-bottom: 0px !important;
93
+ }
94
+
95
+ .stats-list {
96
+ list-style-type: none;
97
+ clear: left;
98
+ margin: 0;
99
+ padding: 0;
100
+ text-align: center;
101
+ margin-bottom: 30px;
102
+ }
103
+
104
+ .stats-list .stats-list-positive {
105
+ color: #228b22;
106
+ }
107
+
108
+ .stats-list .stats-list-negative {
109
+ color: #a52a2a;
110
+ }
111
+
112
+ .stats-list > li {
113
+ display: inline-block;
114
+ margin-right: 10px;
115
+ padding-right: 10px;
116
+ border-right: 1px solid #cacaca;
117
+ text-align: center;
118
+ font-size: 1.1em;
119
+ font-weight: bold;
120
+ }
121
+
122
+ .stats-list > li:last-child {
123
+ border: none;
124
+ margin: 0;
125
+ padding: 0;
126
+ }
127
+
128
+ .stats-list > li .stats-list-label {
129
+ display: block;
130
+ margin-top: 2px;
131
+ font-size: 0.9em;
132
+ font-weight: normal;
133
+ }
134
+
135
+ #streaks-table .ip {
136
+ vertical-align: top;
137
+ }
138
+ #streaks-table .date {
139
+ font-weight: bold;
140
+ }
141
+ #streaks-table .res-title {
142
+ font-decoration: underline;
143
+ }
144
+ </style>
145
+
146
+ </head>
147
+
148
+ <body>
149
+ <div class="off-canvas-wrapper">
150
+ <div class="off-canvas position-left" id="offCanvas" data-off-canvas>
151
+ <nav>
152
+ <h2>Navigation</h2>
153
+ <ul class="no-bullet">
154
+ <% [
155
+ "Summary",
156
+ "Log Structure",
157
+ "Daily Distribution",
158
+ "Time Distribution",
159
+ "Statuses",
160
+ "Rails Performance",
161
+ "Fatal Events",
162
+ "IPs",
163
+ "Command Invocation",
164
+ "Performance"
165
+ ].each do |item| %>
166
+ <li class="nav-item">
167
+ <a href="#<%= item.downcase.gsub(' ', '-') %>" data-close><%= item %></a>
168
+ </li>
169
+ <% end %>
170
+ </ul>
171
+
172
+ <p>
173
+ Generated by
174
+ <a href="https://github.com/avillafiorita/log_sense">LogSense</a> <br />
175
+ on <%= DateTime.now.strftime("%Y-%m-%d %H:%M") %>.<br />
176
+ <a href='https://db-ip.com'>IP Geolocation by DB-IP</a>
177
+ </p>
178
+ </nav>
179
+ </div>
180
+ <div class="off-canvas-content grid-container grid-x fluid" data-off-canvas-content>
181
+ <div data-sticky-container>
182
+ <div class="sticky" data-sticky data-margin-top="0">
183
+ <div class="contents-button">
184
+ <i id="hamburger" class="fi-list" data-toggle="offCanvas"></i>
185
+ </div>
186
+ </div>
187
+ </div>
188
+
189
+ <section class="main-section">
190
+ <h1><%= options[:title] || "Log Sense: #{data[:log_file]}" %></h1>
191
+
192
+ <p><b>Input File:</b> <%= (data[:log_file] || "stdin") %></p>
193
+
194
+ <div class="grid-x grid-margin-x">
195
+ <article class="card small-12 large-6 cell">
196
+ <div class="card-divider">
197
+ <h2 id="summary">Summary</h2>
198
+ </div>
199
+ <div class="card-section">
200
+ <%= render "summary.html.erb", data: data %>
201
+ </div>
202
+ </article>
203
+
204
+ <article class="card cell small-12 large-6">
205
+ <div class="card-divider">
206
+ <h2 id="log-structure">Log Structure</h2>
207
+ </div>
208
+ <div class="card-section">
209
+ <%= render "log_structure.html.erb", data: data %>
210
+ </div>
211
+ </article>
212
+ </div>
213
+
214
+ <% @reports = [
215
+ { title: "Daily Distribution",
216
+ header: ["Day", "DOW", "Hits"],
217
+ rows: data[:daily_distribution],
218
+ vega_spec: {
219
+ "mark": {
220
+ "type": "line",
221
+ "point": {
222
+ "filled": false,
223
+ "fill": "white"
224
+ }
225
+ },
226
+ "encoding": {
227
+ "x": {"field": "Day", "type": "temporal"},
228
+ "y": {"field": "Hits", "type": "quantitative"}
229
+ }
230
+ }
231
+ },
232
+ { title: "Time Distribution",
233
+ header: ["Hour", "Hits"],
234
+ rows: data[:time_distribution],
235
+ vega_spec: {
236
+ "mark": "bar",
237
+ "encoding": {
238
+ "x": {"field": "Hour", "type": "nominal"},
239
+ "y": {"field": "Hits", "type": "quantitative"}
240
+ }
241
+ }
242
+ },
243
+ { title: "Statuses",
244
+ header: ["Status", "Count"],
245
+ rows: data[:statuses],
246
+ vega_spec: {
247
+ "mark": "bar",
248
+ "encoding": {
249
+ "x": {"field": "Status", "type": "nominal"},
250
+ "y": {"field": "Count", "type": "quantitative"}
251
+ }
252
+ }
253
+ },
254
+ { title: "Rails Performance",
255
+ header: ['Controller', 'Hits', 'Min', 'Avg', 'Max'],
256
+ rows: @data[:performance]
257
+ },
258
+ { title: "Fatal Events",
259
+ header: ['Date', 'IP', 'URL', 'Description', 'Log ID'], rows: @data[:fatal],
260
+ col: "small-12 cell"
261
+ },
262
+ { title: "Internal Server Errors",
263
+ header: ['Date', 'Status', 'IP', 'URL', 'Description', 'Log ID'], rows: @data[:internal_server_error],
264
+ col: "small-12 cell"
265
+ },
266
+ { title: "Errors",
267
+ header: ['Log ID', 'Context', 'Description', 'Count'], rows: @data[:error],
268
+ col: "small-12 cell"
269
+ },
270
+ { title: "IPs",
271
+ header: ["IPs", "Hits", "Country"],
272
+ rows: data[:ips]
273
+ },
274
+ ]
275
+ %>
276
+ <div class="grid-x grid-margin-x">
277
+ <% @reports.each_with_index do |report, index| %>
278
+ <article class="card cell <%= report[:col] || "small-12 large-6" %>" >
279
+ <div class="card-divider">
280
+ <h2>
281
+ <%= report[:title] %>
282
+ </h2>
283
+ </div>
284
+
285
+ <% if report[:vega_spec] %>
286
+ <div id="<%= "plot-#{index}" %>"></div>
287
+ <script>
288
+ plot_spec_<%= index %> = Object.assign(
289
+ <%= report[:vega_spec].to_json %>,
290
+ { "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
291
+ width: "container",
292
+ description: "<%= report[:title] %>",
293
+ data: {
294
+ values: [
295
+ <% report[:rows].each do |row| %>
296
+ {
297
+ <% report[:header].each_with_index do |h, i| %>
298
+ "<%= h %>": <%= (row[i].class == Integer or row[i].class == Float) ? row[i] : "\"#{row[i]}\"" %>,
299
+ <% end %>
300
+ },
301
+ <% end %>
302
+ ]
303
+ },
304
+ });
305
+ vegaEmbed('#<%= "plot-#{index}"%>', plot_spec_<%= index %>);
306
+ </script>
307
+ <% end %>
308
+ <div class="card-section">
309
+ <%= render "output_table.html.erb", report %>
310
+ </div>
311
+ </article>
312
+ <% end %>
313
+ </div>
314
+
315
+ <div class="grid-x grid-margin-x">
316
+ <div class="cell small-12 large-6">
317
+ <article>
318
+ <h2 id="command-invocation">Command Invocation</h2>
319
+
320
+ <%= render "command_invocation.html.erb", data: data, options: options %>
321
+ </article>
322
+ </div>
323
+
324
+ <div class="small-12 large-6 cell">
325
+ <article>
326
+ <h2 id="performance"> Performance</h2>
327
+
328
+ <%= render "performance.html.erb", data: data %>
329
+ </article>
330
+ </div>
331
+ </div>
332
+ </section>
333
+ </div>
334
+
335
+ <script type="text/javascript" src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
336
+ <script type="text/javascript" src="js/vendor/what-input.js"></script>
337
+ <script type="text/javascript" src="https://cdn.datatables.net/v/zf/dt-1.11.3/datatables.min.js"></script>
338
+ <script src="https://cdn.jsdelivr.net/npm/vega@5"></script>
339
+ <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/foundation-sites@6.7.4/dist/js/foundation.min.js" crossorigin="anonymous"></script>
340
+ <script>
341
+ $(document).foundation();
342
+
343
+ $(document).ready(function () {
344
+ $('.data-table').each(function () {
345
+ $(this).DataTable();
346
+ });
347
+ });
348
+ </script>
349
+ </div>
350
+ </body>
351
+ </html>
@@ -26,14 +26,6 @@ table.align_column(2, :right)
26
26
  table
27
27
  %>
28
28
 
29
- ** IP and Country
30
-
31
- <%=
32
- table = Terminal::Table.new headings: ['IP', 'Events', 'Country'], rows: @data[:ips]
33
- table.align_column(1, :right)
34
- table
35
- %>
36
-
37
29
  ** Rails Performance
38
30
 
39
31
  <%= table = Terminal::Table.new headings: ['Controller', 'Hits', 'Min', 'Avg', 'Max'], rows: @data[:performance]
@@ -46,7 +38,27 @@ table
46
38
 
47
39
  ** Fatal Events
48
40
 
49
- <%= table = Terminal::Table.new headings: ['Date', 'IP', 'URL', 'Log ID'], rows: @data[:fatal]
41
+ <%= table = Terminal::Table.new headings: ['Date', 'IP', 'URL', 'Description', 'Log ID'], rows: @data[:fatal]
42
+ table
43
+ %>
44
+
45
+ ** Internal Server Errors
46
+
47
+ <%= table = Terminal::Table.new headings: ['Date', 'Status', 'IP', 'URL', 'Description', 'Log ID'], rows: @data[:internal_server_error]
48
+ table
49
+ %>
50
+
51
+ ** Errors
52
+
53
+ <%= table = Terminal::Table.new headings: ['Log ID', 'Context', 'Description', 'Count'], rows: @data[:error]
54
+ table
55
+ %>
56
+
57
+ ** IPs
58
+
59
+ <%=
60
+ table = Terminal::Table.new headings: ['IP', 'Hits', 'Country'], rows: @data[:ips]
61
+ table.align_column(1, :right)
50
62
  table
51
63
  %>
52
64
 
@@ -1,3 +1,3 @@
1
1
  module LogSense
2
- VERSION = "1.0.11"
2
+ VERSION = "1.2.0"
3
3
  end
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.0.11
4
+ version: 1.2.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: 2021-12-15 00:00:00.000000000 Z
11
+ date: 2021-12-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: apache_log-parser
@@ -152,13 +152,14 @@ files:
152
152
  - lib/log_sense/rails_log_parser.rb
153
153
  - lib/log_sense/templates/_command_invocation.html.erb
154
154
  - lib/log_sense/templates/_command_invocation.txt.erb
155
+ - lib/log_sense/templates/_log_structure.html.erb
155
156
  - lib/log_sense/templates/_output_table.html.erb
156
157
  - lib/log_sense/templates/_performance.html.erb
157
158
  - lib/log_sense/templates/_performance.txt.erb
158
159
  - lib/log_sense/templates/_summary.html.erb
159
160
  - lib/log_sense/templates/_summary.txt.erb
160
- - lib/log_sense/templates/_total_hits.html.erb
161
161
  - lib/log_sense/templates/apache.html.erb
162
+ - lib/log_sense/templates/rails.html.erb
162
163
  - lib/log_sense/templates/rails.txt.erb
163
164
  - lib/log_sense/version.rb
164
165
  - log_sense.gemspec
@@ -1,32 +0,0 @@
1
- <table class="table unstriped log-structure">
2
- <tbody>
3
- <tr>
4
- <th>Input file</th>
5
- <td><b><%= (data[:log_file] || "stdin") %></b></td>
6
- </tr>
7
- <tr>
8
- <th>Period in Log</th>
9
- <td><%= data[:first_day] %> -- <%= data[:last_day] %></td>
10
- </tr>
11
- <tr>
12
- <th>Total days</th>
13
- <td><%= data[:total_days] %></td>
14
- </tr>
15
- <tr>
16
- <th>Log size</th>
17
- <td><%= data[:log_size] %></td>
18
- </tr>
19
- <tr>
20
- <th>Self poll entries</th>
21
- <td><%= data[:selfpolls_size] %></td>
22
- </tr>
23
- <tr>
24
- <th>Crawlers</th>
25
- <td><%= data[:crawlers_size] %></td>
26
- </tr>
27
- <tr>
28
- <th>Entries considered</th>
29
- <td><%= data[:total_hits] %></td>
30
- </tr>
31
- </tbody>
32
- </table>