logviewer 1.0.0 → 1.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5af89372bbff4a9d1a87c53c87be966b685532e5734cddaca3d1f338ecca806d
4
- data.tar.gz: 04acdaa2c421345747cdfdaf0445aa139252bac918b74df4d41fa34b0a6451b2
3
+ metadata.gz: e840049796961dbaec340da1cd042cd84b6a6f03e460d3fe7f186654d69fe6de
4
+ data.tar.gz: d6a800844d7b1deda1c8f3cf890bbcffeca9d6e7c746b38bb535b8b922b707ab
5
5
  SHA512:
6
- metadata.gz: 7d55746ec6dddde8279deb41c50429acb38f6e3c9bd55350388aa8cda585a33c482b64e6d84acd31b45708e9f84aa239b02a6e6494a82d4f65e992b724e5417b
7
- data.tar.gz: b895f2d31c99001de43836e96c3dacd092b87c1e16fd761baf93321b2fee5a2300228614281266d07dc90926f79031fa7b2547ad647b7efa645aee01bdea8115
6
+ metadata.gz: 2fc6f9364df619503be26dddfe2ca170a3446bf1f6e7b518cd52c305e3cf30f41f128f425de598f51bec005a21ddb3da260e347066338231a9cfa5de9145ec78
7
+ data.tar.gz: a05e13067b1ef5e3a97412a9ea7239bdcf5121f7c27b9c6033bce80e570aac2dc5fc2b68e186b21d11f422f7f5898eaf14d16d973f72d04b5be41e3069e4e364
data/README.md CHANGED
@@ -6,8 +6,11 @@ A Ruby gem that converts NDJSON log files into a readable HTML format for easy v
6
6
 
7
7
  - Converts NDJSON log files to HTML tables
8
8
  - Filters logs by minimum level (trace, debug, info, warning, error, fatal)
9
- - Displays key fields: level, text, file, and method
9
+ - Displays key fields: timestamp, level, tag, text, file, line, and method
10
+ - Human-readable timestamp formatting (MM/DD HH:MM:SS)
11
+ - Simplified file paths (shows only filename, not full path)
10
12
  - Color-coded log levels for easy identification
13
+ - Large, readable fonts throughout the interface (18px base size)
11
14
  - Responsive design that works well in any browser
12
15
  - Automatically opens the generated HTML file in your default browser
13
16
 
@@ -67,25 +70,33 @@ logviewer --version
67
70
 
68
71
  The tool expects NDJSON (newline-delimited JSON) files where each line contains a JSON object with these fields:
69
72
 
73
+ - `timestamp`: ISO 8601 timestamp (e.g., "2025-06-02T18:22:48.855-07:00")
70
74
  - `level`: Log level (trace, debug, info, warning, error, fatal)
75
+ - `tag`: Category or module tag (e.g., "Play/manager")
71
76
  - `text`: The log message
72
- - `file`: Source file name
77
+ - `file`: Source file path (displayed as filename only)
78
+ - `line`: Line number in the source file
73
79
  - `method`: Function/method name
74
80
 
75
81
  Example log entry:
76
82
  ```json
77
- {"level":"info","text":"User logged in successfully","file":"auth.rb","method":"login"}
83
+ {"timestamp":"2025-06-02T18:22:48.855-07:00","level":"info","tag":"Auth/manager","text":"User logged in successfully","file":"auth.rb","line":42,"method":"login"}
78
84
  ```
79
85
 
80
86
  ## Output
81
87
 
82
88
  The generated HTML file will be saved in `/tmp/` with a timestamp and automatically opened in your browser. The HTML includes:
83
89
 
84
- - A responsive table layout
90
+ - A wide, responsive table layout (1800px max width) with timestamp, level, tag, text, file, line, and method columns
91
+ - Human-readable timestamps (MM/DD HH:MM:SS format)
85
92
  - Color-coded log levels
86
93
  - Sticky header for easy navigation
87
94
  - Hover effects for better readability
88
- - File and method names in monospace font
95
+ - Large fonts (18px base size) for excellent readability
96
+ - Simplified file display (filename only, not full paths)
97
+ - Optimized column widths with expanded text area for log messages
98
+ - Timestamp, file, line, and method names in monospace font
99
+ - Color-coded tags for easy categorization
89
100
 
90
101
  ## Development
91
102
 
@@ -1,3 +1,3 @@
1
1
  module LogViewer
2
- VERSION = "1.0.0"
2
+ VERSION = "1.4.0"
3
3
  end
data/lib/logviewer.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'json'
2
2
  require 'optparse'
3
3
  require 'fileutils'
4
+ require 'time'
4
5
  require_relative 'logviewer/version'
5
6
 
6
7
  module LogViewer
@@ -74,9 +75,12 @@ module LogViewer
74
75
 
75
76
  if should_include_log?(log_entry['level'])
76
77
  logs << {
78
+ timestamp: log_entry['timestamp'] || '',
77
79
  level: log_entry['level'] || 'unknown',
80
+ tag: log_entry['tag'] || '',
78
81
  text: log_entry['text'] || '',
79
82
  file: log_entry['file'] || '',
83
+ line: log_entry['line'],
80
84
  method: log_entry['method'] || ''
81
85
  }
82
86
  end
@@ -107,6 +111,22 @@ module LogViewer
107
111
  end
108
112
  end
109
113
 
114
+ def format_timestamp(timestamp_str)
115
+ return '' if timestamp_str.nil? || timestamp_str.empty?
116
+
117
+ begin
118
+ time = Time.parse(timestamp_str)
119
+ time.strftime('%m/%d %H:%M:%S')
120
+ rescue => e
121
+ timestamp_str # fallback to original if parsing fails
122
+ end
123
+ end
124
+
125
+ def extract_filename(file_path)
126
+ return '' if file_path.nil? || file_path.empty?
127
+ File.basename(file_path)
128
+ end
129
+
110
130
  def generate_html(logs)
111
131
  html = <<~HTML
112
132
  <!DOCTYPE html>
@@ -123,7 +143,7 @@ module LogViewer
123
143
  background-color: #f8f9fa;
124
144
  }
125
145
  .container {
126
- max-width: 1400px;
146
+ max-width: 1800px;
127
147
  margin: 0 auto;
128
148
  background: white;
129
149
  border-radius: 8px;
@@ -150,11 +170,11 @@ module LogViewer
150
170
  table {
151
171
  width: 100%;
152
172
  border-collapse: collapse;
153
- font-size: 14px;
173
+ font-size: 18px;
154
174
  }
155
175
  th {
156
176
  background: #e9ecef;
157
- padding: 12px;
177
+ padding: 18px;
158
178
  text-align: left;
159
179
  font-weight: 600;
160
180
  border-bottom: 2px solid #dee2e6;
@@ -162,7 +182,7 @@ module LogViewer
162
182
  top: 0;
163
183
  }
164
184
  td {
165
- padding: 10px 12px;
185
+ padding: 15px 18px;
166
186
  border-bottom: 1px solid #dee2e6;
167
187
  vertical-align: top;
168
188
  }
@@ -172,27 +192,45 @@ module LogViewer
172
192
  .level {
173
193
  font-weight: bold;
174
194
  text-transform: uppercase;
175
- font-size: 12px;
195
+ font-size: 16px;
176
196
  white-space: nowrap;
177
197
  }
178
198
  .text {
179
- max-width: 600px;
199
+ min-width: 600px;
180
200
  word-wrap: break-word;
181
201
  white-space: pre-wrap;
182
202
  }
183
203
  .file {
184
204
  font-family: 'Monaco', 'Menlo', monospace;
185
- font-size: 12px;
205
+ font-size: 16px;
186
206
  color: #666;
187
207
  max-width: 200px;
188
208
  word-wrap: break-word;
189
209
  }
190
210
  .method {
191
211
  font-family: 'Monaco', 'Menlo', monospace;
192
- font-size: 12px;
212
+ font-size: 16px;
193
213
  color: #333;
194
214
  font-weight: 500;
195
215
  }
216
+ .timestamp {
217
+ font-family: 'Monaco', 'Menlo', monospace;
218
+ font-size: 15px;
219
+ color: #666;
220
+ white-space: nowrap;
221
+ }
222
+ .tag {
223
+ font-family: 'Monaco', 'Menlo', monospace;
224
+ font-size: 16px;
225
+ color: #007acc;
226
+ font-weight: 500;
227
+ }
228
+ .line {
229
+ font-family: 'Monaco', 'Menlo', monospace;
230
+ font-size: 16px;
231
+ color: #999;
232
+ text-align: right;
233
+ }
196
234
  .empty {
197
235
  color: #999;
198
236
  font-style: italic;
@@ -209,10 +247,13 @@ module LogViewer
209
247
  <table>
210
248
  <thead>
211
249
  <tr>
250
+ <th style="width: 120px;">Timestamp</th>
212
251
  <th style="width: 80px;">Level</th>
252
+ <th style="width: 120px;">Tag</th>
213
253
  <th>Text</th>
214
- <th style="width: 200px;">File</th>
215
- <th style="width: 150px;">Method</th>
254
+ <th style="width: 180px;">File</th>
255
+ <th style="width: 50px;">Line</th>
256
+ <th style="width: 100px;">Method</th>
216
257
  </tr>
217
258
  </thead>
218
259
  <tbody>
@@ -220,15 +261,23 @@ module LogViewer
220
261
 
221
262
  logs.each do |log|
222
263
  level_style = "color: #{level_color(log[:level])}"
264
+ formatted_timestamp = format_timestamp(log[:timestamp])
265
+ timestamp_content = formatted_timestamp.empty? ? '<span class="empty">-</span>' : formatted_timestamp
266
+ tag_content = log[:tag].empty? ? '<span class="empty">-</span>' : log[:tag]
223
267
  text_content = log[:text].empty? ? '<span class="empty">-</span>' : log[:text]
224
- file_content = log[:file].empty? ? '<span class="empty">-</span>' : log[:file]
268
+ filename = extract_filename(log[:file])
269
+ file_content = filename.empty? ? '<span class="empty">-</span>' : filename
270
+ line_content = log[:line].nil? ? '<span class="empty">-</span>' : log[:line]
225
271
  method_content = log[:method].empty? ? '<span class="empty">-</span>' : log[:method]
226
272
 
227
273
  html += <<~HTML
228
274
  <tr>
275
+ <td class="timestamp">#{timestamp_content}</td>
229
276
  <td class="level" style="#{level_style}">#{log[:level]}</td>
277
+ <td class="tag">#{tag_content}</td>
230
278
  <td class="text">#{text_content}</td>
231
279
  <td class="file">#{file_content}</td>
280
+ <td class="line">#{line_content}</td>
232
281
  <td class="method">#{method_content}</td>
233
282
  </tr>
234
283
  HTML
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logviewer
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Bishop