logviewer 1.7.1 → 2.1.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 +4 -4
- data/README.md +15 -13
- data/lib/logviewer/version.rb +1 -1
- data/lib/logviewer.rb +31 -20
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fac69fee4a6d38227b055f96c78477b9baa3a40cceef07a291b59b184dce88b6
|
4
|
+
data.tar.gz: 9c4dac6e68e9dad2753d9300a601e7582e4827f17fb35aeccbf231c1c235aa2b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bbb6b8f5cbbf1ec4bb61a33dc342e71eb4833c0f9a058d1f5bedc63a7f4d1c7cdf298967dc98b96054d69347af7307a92d957a7167c8dad1ca57fcd7cbe859ee
|
7
|
+
data.tar.gz: 8ac8b3b96a0aaf5bd2a418b014275cd1405402656891cfc1d4f74aa816356d6974e89bc6a381d10077a115b44c5d26b6af15368e62f7f5d6be53a804882aa9ba
|
data/README.md
CHANGED
@@ -5,7 +5,7 @@ A Ruby gem that converts NDJSON log files into a readable HTML format for easy v
|
|
5
5
|
## Features
|
6
6
|
|
7
7
|
- Converts NDJSON log files to HTML tables
|
8
|
-
- Filters logs by minimum level (trace, debug, info, warning, error,
|
8
|
+
- Filters logs by minimum level (trace, debug, info, notice, warning, error, critical)
|
9
9
|
- Displays key fields: date, level, tag, file, function, and text
|
10
10
|
- Human-readable timestamp formatting (MM/DD HH:MM:SS)
|
11
11
|
- Simplified file paths (shows only filename, not full path)
|
@@ -37,10 +37,10 @@ logviewer
|
|
37
37
|
```
|
38
38
|
|
39
39
|
This will:
|
40
|
-
1. Parse the NDJSON file
|
41
|
-
2. Include all log levels (
|
40
|
+
1. Parse the NDJSON file
|
41
|
+
2. Include all log levels (trace and above by default)
|
42
42
|
3. Generate an HTML file in `/tmp/`
|
43
|
-
4. Open the HTML file in your default browser
|
43
|
+
4. Open the HTML file in your default browser (initially filtered to debug+)
|
44
44
|
|
45
45
|
### Filter by Log Level
|
46
46
|
|
@@ -48,7 +48,7 @@ This will:
|
|
48
48
|
logviewer --level info example.ndjson
|
49
49
|
```
|
50
50
|
|
51
|
-
Only includes log entries with level "info" and above in the HTML file. You can then use the interactive dropdown in the browser to filter
|
51
|
+
Only includes log entries with level "info" and above in the HTML file. You can then use the interactive dropdown in the browser to filter within those entries.
|
52
52
|
|
53
53
|
### Auto-Detection of Log Files
|
54
54
|
|
@@ -62,7 +62,7 @@ This will find the most recent `.ndjson` file in the current directory and apply
|
|
62
62
|
|
63
63
|
### Command Line Options
|
64
64
|
|
65
|
-
- `-l, --level LEVEL`: Set minimum log level (trace, debug, info, warning, error,
|
65
|
+
- `-l, --level LEVEL`: Set minimum log level (trace, debug, info, notice, warning, error, critical)
|
66
66
|
- `-v, --version`: Show version
|
67
67
|
- `-h, --help`: Show help message
|
68
68
|
|
@@ -89,16 +89,16 @@ logviewer --version
|
|
89
89
|
|
90
90
|
The tool expects NDJSON (newline-delimited JSON) files where each line contains a JSON object with these fields:
|
91
91
|
|
92
|
-
- `timestamp`:
|
93
|
-
- `
|
94
|
-
- `
|
95
|
-
- `
|
92
|
+
- `timestamp`: Unix timestamp in milliseconds since epoch (displayed as MM/DD HH:MM:SS)
|
93
|
+
- `levelName`: Log level (trace, debug, info, notice, warning, error, critical)
|
94
|
+
- `subsystem` and `category`: Combined to create tag display (e.g., "Play/avPlayer")
|
95
|
+
- `message`: The log message
|
96
96
|
- `file`: Source file path (displayed as filename only)
|
97
|
-
- `
|
97
|
+
- `function`: Function/method name
|
98
98
|
|
99
99
|
Example log entry:
|
100
100
|
```json
|
101
|
-
{"timestamp":"
|
101
|
+
{"timestamp":1749926447359,"levelName":"debug","subsystem":"Play","category":"avPlayer","message":"pausing","file":"PodHaven/PodAVPlayer.swift","function":"pause(overwritePreSeekStatus:)","line":136}
|
102
102
|
```
|
103
103
|
|
104
104
|
## Output
|
@@ -124,7 +124,9 @@ Once the HTML file opens in your browser, you can:
|
|
124
124
|
- Use the dropdown in the header to dynamically filter log entries by minimum level
|
125
125
|
- Filter changes are applied instantly without page reload
|
126
126
|
- Entry counts update automatically to show how many entries match the current filter
|
127
|
-
- Command line level
|
127
|
+
- Command line level controls what entries are included in the HTML file
|
128
|
+
- Browser initially shows debug+ level by default, regardless of command line level
|
129
|
+
- Browser filtering works within the entries included from the command line
|
128
130
|
|
129
131
|
## Development
|
130
132
|
|
data/lib/logviewer/version.rb
CHANGED
data/lib/logviewer.rb
CHANGED
@@ -10,14 +10,15 @@ module LogViewer
|
|
10
10
|
'trace' => 0,
|
11
11
|
'debug' => 1,
|
12
12
|
'info' => 2,
|
13
|
-
'
|
14
|
-
'
|
15
|
-
'
|
13
|
+
'notice' => 3,
|
14
|
+
'warning' => 4,
|
15
|
+
'error' => 5,
|
16
|
+
'critical' => 6
|
16
17
|
}
|
17
18
|
|
18
19
|
def initialize(args = ARGV)
|
19
20
|
@args = args
|
20
|
-
@min_level = '
|
21
|
+
@min_level = 'trace'
|
21
22
|
@input_file = nil
|
22
23
|
end
|
23
24
|
|
@@ -25,7 +26,7 @@ module LogViewer
|
|
25
26
|
OptionParser.new do |opts|
|
26
27
|
opts.banner = "Usage: logviewer [options] [ndjson_file]"
|
27
28
|
|
28
|
-
opts.on('-l', '--level LEVEL', 'Minimum log level (trace, debug, info, warning, error,
|
29
|
+
opts.on('-l', '--level LEVEL', 'Minimum log level (trace, debug, info, notice, warning, error, critical)') do |level|
|
29
30
|
level = level.downcase
|
30
31
|
if LOG_LEVELS.key?(level)
|
31
32
|
@min_level = level
|
@@ -85,14 +86,20 @@ module LogViewer
|
|
85
86
|
begin
|
86
87
|
log_entry = JSON.parse(line.strip)
|
87
88
|
|
88
|
-
if should_include_log?(log_entry['
|
89
|
+
if should_include_log?(log_entry['levelName'])
|
90
|
+
# Build tag from subsystem/category
|
91
|
+
tag = []
|
92
|
+
tag << log_entry['subsystem'] if log_entry['subsystem']
|
93
|
+
tag << log_entry['category'] if log_entry['category']
|
94
|
+
tag_string = tag.join('/')
|
95
|
+
|
89
96
|
logs << {
|
90
97
|
timestamp: log_entry['timestamp'] || '',
|
91
|
-
level: log_entry['
|
92
|
-
tag:
|
93
|
-
text: log_entry['
|
98
|
+
level: log_entry['levelName'] || 'unknown',
|
99
|
+
tag: tag_string,
|
100
|
+
text: log_entry['message'] || '',
|
94
101
|
file: log_entry['file'] || '',
|
95
|
-
method: log_entry['
|
102
|
+
method: log_entry['function'] || ''
|
96
103
|
}
|
97
104
|
end
|
98
105
|
rescue JSON::ParserError => e
|
@@ -111,25 +118,28 @@ module LogViewer
|
|
111
118
|
'#adb5bd'
|
112
119
|
when 'info'
|
113
120
|
'#6ea8fe'
|
121
|
+
when 'notice'
|
122
|
+
'#ffc107'
|
114
123
|
when 'warning'
|
115
124
|
'#fd9843'
|
116
125
|
when 'error'
|
117
126
|
'#ea868f'
|
118
|
-
when '
|
127
|
+
when 'critical'
|
119
128
|
'#c29ffa'
|
120
129
|
else
|
121
130
|
'#e0e0e0'
|
122
131
|
end
|
123
132
|
end
|
124
133
|
|
125
|
-
def format_timestamp(
|
126
|
-
return '' if
|
134
|
+
def format_timestamp(timestamp)
|
135
|
+
return '' if timestamp.nil? || timestamp == ''
|
127
136
|
|
128
137
|
begin
|
129
|
-
|
138
|
+
# Convert milliseconds to seconds for Time.at
|
139
|
+
time = Time.at(timestamp / 1000.0)
|
130
140
|
time.strftime('%m/%d %H:%M:%S')
|
131
141
|
rescue => e
|
132
|
-
|
142
|
+
timestamp.to_s # fallback to original if parsing fails
|
133
143
|
end
|
134
144
|
end
|
135
145
|
|
@@ -324,16 +334,17 @@ module LogViewer
|
|
324
334
|
'trace': 0,
|
325
335
|
'debug': 1,
|
326
336
|
'info': 2,
|
327
|
-
'
|
328
|
-
'
|
329
|
-
'
|
337
|
+
'notice': 3,
|
338
|
+
'warning': 4,
|
339
|
+
'error': 5,
|
340
|
+
'critical': 6
|
330
341
|
};
|
331
342
|
|
332
343
|
const levelFilter = document.getElementById('levelFilter');
|
333
344
|
const tableRows = document.querySelectorAll('tbody tr');
|
334
345
|
|
335
|
-
// Set initial filter to
|
336
|
-
levelFilter.value = '
|
346
|
+
// Set initial filter to debug (default UI filter)
|
347
|
+
levelFilter.value = 'debug';
|
337
348
|
|
338
349
|
function filterByLevel() {
|
339
350
|
const selectedLevel = levelFilter.value;
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logviewer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Bishop
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: bundler
|
@@ -70,7 +70,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
70
70
|
- !ruby/object:Gem::Version
|
71
71
|
version: '0'
|
72
72
|
requirements: []
|
73
|
-
rubygems_version: 3.6.
|
73
|
+
rubygems_version: 3.6.9
|
74
74
|
specification_version: 4
|
75
75
|
summary: Convert NDJSON log files to HTML for easy viewing
|
76
76
|
test_files: []
|