log4lab 0.1.0__tar.gz
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.
- log4lab-0.1.0/LICENSE +21 -0
- log4lab-0.1.0/PKG-INFO +338 -0
- log4lab-0.1.0/README.md +301 -0
- log4lab-0.1.0/log4lab/__init__.py +1 -0
- log4lab-0.1.0/log4lab/cli.py +64 -0
- log4lab-0.1.0/log4lab/server.py +155 -0
- log4lab-0.1.0/log4lab/tail.py +283 -0
- log4lab-0.1.0/log4lab/templates/index.html +579 -0
- log4lab-0.1.0/log4lab/templates/runs.html +182 -0
- log4lab-0.1.0/log4lab.egg-info/PKG-INFO +338 -0
- log4lab-0.1.0/log4lab.egg-info/SOURCES.txt +17 -0
- log4lab-0.1.0/log4lab.egg-info/dependency_links.txt +1 -0
- log4lab-0.1.0/log4lab.egg-info/entry_points.txt +2 -0
- log4lab-0.1.0/log4lab.egg-info/requires.txt +13 -0
- log4lab-0.1.0/log4lab.egg-info/top_level.txt +4 -0
- log4lab-0.1.0/pyproject.toml +65 -0
- log4lab-0.1.0/setup.cfg +4 -0
- log4lab-0.1.0/tests/__init__.py +1 -0
- log4lab-0.1.0/tests/test_server.py +214 -0
log4lab-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Thibaut Lamadon
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
log4lab-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: log4lab
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A lightweight structured log viewer with live streaming and filters.
|
|
5
|
+
Author: Thibaut Lamadon
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/tlamadon/log4lab
|
|
8
|
+
Project-URL: Repository, https://github.com/tlamadon/log4lab
|
|
9
|
+
Project-URL: Issues, https://github.com/tlamadon/log4lab/issues
|
|
10
|
+
Keywords: logging,log-viewer,structured-logs,jsonl,monitoring,dashboard,live-streaming
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
20
|
+
Classifier: Topic :: System :: Logging
|
|
21
|
+
Classifier: Topic :: System :: Monitoring
|
|
22
|
+
Requires-Python: >=3.8
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: fastapi
|
|
26
|
+
Requires-Dist: uvicorn
|
|
27
|
+
Requires-Dist: jinja2
|
|
28
|
+
Requires-Dist: typer
|
|
29
|
+
Requires-Dist: rich>=13.0.0
|
|
30
|
+
Provides-Extra: test
|
|
31
|
+
Requires-Dist: pytest>=7.0; extra == "test"
|
|
32
|
+
Requires-Dist: pytest-asyncio>=0.21; extra == "test"
|
|
33
|
+
Requires-Dist: httpx>=0.24; extra == "test"
|
|
34
|
+
Provides-Extra: images
|
|
35
|
+
Requires-Dist: term-image>=0.7.0; extra == "images"
|
|
36
|
+
Dynamic: license-file
|
|
37
|
+
|
|
38
|
+
# Log4Lab
|
|
39
|
+
|
|
40
|
+
A powerful, lightweight structured log viewer with live streaming, advanced filtering, and run tracking capabilities.
|
|
41
|
+
|
|
42
|
+
Log4Lab is a web-based dashboard for viewing and analyzing structured JSON logs in real-time. It provides a clean, modern interface for monitoring application logs with live updates, making it easy to track experiments, debug issues, and understand what's happening in your applications.
|
|
43
|
+
|
|
44
|
+
## Features
|
|
45
|
+
|
|
46
|
+
### Core Functionality
|
|
47
|
+
- **Live Log Streaming**: Automatically streams new log entries as they're written to the log file using Server-Sent Events (SSE)
|
|
48
|
+
- **Structured Log Support**: Parses and displays JSONL (JSON Lines) formatted logs
|
|
49
|
+
- **Relative Time Display**: Shows "how long ago" each entry was created with automatic updates
|
|
50
|
+
- **Dark Mode**: Built-in dark mode support with theme persistence in browser local storage
|
|
51
|
+
|
|
52
|
+
### Advanced Filtering
|
|
53
|
+
- **Level Filter**: Dynamically populated dropdown based on actual log levels in your file (case-insensitive)
|
|
54
|
+
- **Section Filter**: Filter by component or section name
|
|
55
|
+
- **Group Filter**: Filter by experiment or job group
|
|
56
|
+
- **Run Name Filter**: Filter by run name to see all runs in a collection
|
|
57
|
+
- **Run ID Filter**: Focus on a specific run instance
|
|
58
|
+
- **Time Range Filter**: View logs from the last 1 minute, 5 minutes, 1 hour, 6 hours, or 24 hours
|
|
59
|
+
- **URL-based Filters**: All filters can be passed as URL query parameters for bookmarking and sharing
|
|
60
|
+
|
|
61
|
+
### Run Management
|
|
62
|
+
- **Runs Index Page**: Hierarchical view showing all run names with their associated run IDs
|
|
63
|
+
- **Run Links**: Each log entry includes a clickable link to filter by its run name or run ID
|
|
64
|
+
- **Run Statistics**: See total log counts per run name and individual run ID
|
|
65
|
+
|
|
66
|
+
### Display & Navigation
|
|
67
|
+
- **Pagination**: Configurable page size (20, 50, 100, or 200 entries per page)
|
|
68
|
+
- **Sort Toggle**: Switch between newest-first and oldest-first ordering (perfect for reviewing run chronology)
|
|
69
|
+
- **Collapsible JSON**: Full JSON view available for each entry, collapsed by default
|
|
70
|
+
- **Smart Message Display**: Renders the `message` field as the main content in fixed-width font
|
|
71
|
+
- **Artifact Rendering**: Automatically displays images, PDFs, and files referenced in the `cache_path` field
|
|
72
|
+
|
|
73
|
+
### User Interface
|
|
74
|
+
- **Modern Design**: Built with Tailwind CSS for a clean, responsive interface
|
|
75
|
+
- **Smooth Navigation**: Scroll to top on page changes, smooth transitions
|
|
76
|
+
- **Keyboard-Friendly**: All filters and controls are easily accessible
|
|
77
|
+
|
|
78
|
+
## Installation
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
pip install log4lab
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Or install from source:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
git clone https://github.com/yourusername/log4lab.git
|
|
88
|
+
cd log4lab
|
|
89
|
+
pip install -e .
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Usage
|
|
93
|
+
|
|
94
|
+
Start the Log4Lab server:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
log4lab serve [LOGFILE]
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Or tail logs in the terminal:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
log4lab tail [LOGFILE]
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Options
|
|
107
|
+
|
|
108
|
+
- `LOGFILE`: Path to the JSONL log file to stream (default: `logs/app.log`)
|
|
109
|
+
- `--host`: Host to bind to (default: `127.0.0.1`)
|
|
110
|
+
- `--port`: Port to listen on (default: `8000`)
|
|
111
|
+
- `--reload`: Enable auto-reload for development
|
|
112
|
+
|
|
113
|
+
### Examples
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
# Web server - Use default log file (logs/app.log)
|
|
117
|
+
log4lab serve
|
|
118
|
+
|
|
119
|
+
# Specify a custom log file
|
|
120
|
+
log4lab serve /path/to/your/app.log
|
|
121
|
+
|
|
122
|
+
# Run on a different port
|
|
123
|
+
log4lab serve myapp.log --port 3000
|
|
124
|
+
|
|
125
|
+
# Bind to all interfaces
|
|
126
|
+
log4lab serve myapp.log --host 0.0.0.0
|
|
127
|
+
|
|
128
|
+
# Development mode with auto-reload
|
|
129
|
+
log4lab serve --reload
|
|
130
|
+
|
|
131
|
+
# Terminal tail - live streaming to terminal
|
|
132
|
+
log4lab tail myapp.log
|
|
133
|
+
|
|
134
|
+
# Tail with filters
|
|
135
|
+
log4lab tail myapp.log --level=ERROR --open-images
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Then open your browser to `http://localhost:8000` to view the dashboard.
|
|
139
|
+
|
|
140
|
+
### Using Filters via URL
|
|
141
|
+
|
|
142
|
+
Share specific filtered views by passing query parameters:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
# View only ERROR logs
|
|
146
|
+
http://localhost:8000/?level=error
|
|
147
|
+
|
|
148
|
+
# View a specific run
|
|
149
|
+
http://localhost:8000/?run_id=abc123
|
|
150
|
+
|
|
151
|
+
# View all runs in a collection
|
|
152
|
+
http://localhost:8000/?run_name=model_training
|
|
153
|
+
|
|
154
|
+
# Combine multiple filters
|
|
155
|
+
http://localhost:8000/?level=error&run_name=experiment1&time=3600
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Log Format
|
|
159
|
+
|
|
160
|
+
Log4Lab expects logs in JSONL format (one JSON object per line). Each log entry should be a JSON object.
|
|
161
|
+
|
|
162
|
+
### Basic Example
|
|
163
|
+
|
|
164
|
+
```json
|
|
165
|
+
{"time": "2025-10-24T10:30:00Z", "level": "INFO", "section": "train", "message": "Training started"}
|
|
166
|
+
{"time": "2025-10-24T10:30:05Z", "level": "WARN", "section": "data", "message": "Missing data point"}
|
|
167
|
+
{"time": "2025-10-24T10:30:10Z", "level": "ERROR", "section": "model", "message": "Model failed to converge"}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Advanced Example with Runs and Artifacts
|
|
171
|
+
|
|
172
|
+
```json
|
|
173
|
+
{
|
|
174
|
+
"time": "2025-10-24T10:30:00Z",
|
|
175
|
+
"level": "INFO",
|
|
176
|
+
"section": "train",
|
|
177
|
+
"message": "Training epoch 1 complete",
|
|
178
|
+
"run_name": "model_training",
|
|
179
|
+
"run_id": "run_001",
|
|
180
|
+
"group": "experiment_1",
|
|
181
|
+
"cache_path": "artifacts/training_plot.png",
|
|
182
|
+
"accuracy": 0.92,
|
|
183
|
+
"loss": 0.15
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Supported Fields
|
|
188
|
+
|
|
189
|
+
#### Core Fields
|
|
190
|
+
- `time`: Timestamp in ISO 8601 format (automatically handles UTC if no timezone specified)
|
|
191
|
+
- `level`: Log level (INFO, WARN, ERROR, DEBUG, etc.) - case-insensitive
|
|
192
|
+
- `section`: Component or section of your application
|
|
193
|
+
- `message` or `msg`: The main log message (displayed prominently in fixed-width font)
|
|
194
|
+
|
|
195
|
+
#### Run Tracking Fields
|
|
196
|
+
- `run_name`: Name of the run collection (e.g., "hyperparameter_search")
|
|
197
|
+
- `run_id`: Unique identifier for a specific run instance
|
|
198
|
+
- `group`: Group or experiment name for organizing related runs
|
|
199
|
+
|
|
200
|
+
#### Artifact Fields
|
|
201
|
+
- `cache_path`: Path to an artifact file (images, PDFs, etc.)
|
|
202
|
+
- Images (PNG, JPG, SVG, etc.) are displayed inline
|
|
203
|
+
- PDFs are embedded with a viewer
|
|
204
|
+
- Other files show as download links
|
|
205
|
+
|
|
206
|
+
#### Additional Fields
|
|
207
|
+
Any additional fields (metrics, parameters, etc.) are displayed in the expandable JSON view.
|
|
208
|
+
|
|
209
|
+
## Features in Detail
|
|
210
|
+
|
|
211
|
+
### Live Streaming
|
|
212
|
+
|
|
213
|
+
Log4Lab monitors the log file for changes and automatically streams new entries to the browser using Server-Sent Events (SSE). New entries appear at the top with smooth animations, and the "time ago" display updates every 5 seconds.
|
|
214
|
+
|
|
215
|
+
### Time Display
|
|
216
|
+
|
|
217
|
+
Each log entry shows:
|
|
218
|
+
- Relative time (e.g., "just now", "5m ago", "2h ago", "3d ago")
|
|
219
|
+
- Absolute timestamp for reference
|
|
220
|
+
- Automatic handling of UTC timestamps
|
|
221
|
+
- Smart future timestamp detection (shows "in 2h" for logs from the future)
|
|
222
|
+
|
|
223
|
+
### Filtering System
|
|
224
|
+
|
|
225
|
+
**Dynamic Level Filter**: Automatically discovers all log levels in your file and populates the dropdown. Supports any level names (INFO, Error, debug, WARN, etc.) with case-insensitive matching.
|
|
226
|
+
|
|
227
|
+
**Text Filters**: Section, Group, Run Name, and Run ID filters support partial matching and are case-insensitive.
|
|
228
|
+
|
|
229
|
+
**Time Range Filter**: Show only recent logs:
|
|
230
|
+
- Last 1 minute
|
|
231
|
+
- Last 5 minutes
|
|
232
|
+
- Last 10 minutes
|
|
233
|
+
- Last 30 minutes
|
|
234
|
+
- Last 1 hour
|
|
235
|
+
- Last 6 hours
|
|
236
|
+
- Last 24 hours
|
|
237
|
+
|
|
238
|
+
**Filter Persistence**: All filters are reflected in the URL, so you can bookmark specific views or share links with teammates.
|
|
239
|
+
|
|
240
|
+
### Run Management
|
|
241
|
+
|
|
242
|
+
The **Runs Index** (`/runs`) provides a bird's-eye view of all your runs:
|
|
243
|
+
- Lists all unique run names
|
|
244
|
+
- Shows total log count per run name
|
|
245
|
+
- Displays all associated run IDs with individual counts
|
|
246
|
+
- Click any run name to see all logs for that collection
|
|
247
|
+
- Click any run ID to see logs for that specific instance
|
|
248
|
+
|
|
249
|
+
Each log entry includes a **run info link** that takes you directly to a filtered view of that run.
|
|
250
|
+
|
|
251
|
+
### Sorting
|
|
252
|
+
|
|
253
|
+
Toggle between two sort orders:
|
|
254
|
+
- **Newest First** (default): Latest logs appear at the top - ideal for monitoring
|
|
255
|
+
- **Oldest First**: Chronological order from the beginning - perfect for understanding run progression
|
|
256
|
+
|
|
257
|
+
### Pagination
|
|
258
|
+
|
|
259
|
+
Control how many logs appear per page (20, 50, 100, or 200) and navigate through pages with Previous/Next buttons. The display shows your current position (e.g., "Showing 1-50 of 153 logs").
|
|
260
|
+
|
|
261
|
+
### Artifact Display
|
|
262
|
+
|
|
263
|
+
If your logs include a `cache_path` field pointing to artifacts:
|
|
264
|
+
|
|
265
|
+
**Images**: Displayed inline with full size
|
|
266
|
+
```json
|
|
267
|
+
{"cache_path": "artifacts/plot.png", "message": "Training loss over time"}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
**PDFs**: Embedded with a document viewer
|
|
271
|
+
```json
|
|
272
|
+
{"cache_path": "artifacts/report.pdf", "message": "Experiment results"}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
**Other Files**: Download link provided
|
|
276
|
+
```json
|
|
277
|
+
{"cache_path": "artifacts/model.pkl", "message": "Model checkpoint saved"}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### Theme Support
|
|
281
|
+
|
|
282
|
+
Toggle between light and dark modes with the theme button in the top-right corner. Your preference is saved in browser local storage and persists across sessions.
|
|
283
|
+
|
|
284
|
+
## Use Cases
|
|
285
|
+
|
|
286
|
+
### Machine Learning Experiments
|
|
287
|
+
|
|
288
|
+
Track training runs with metrics, visualizations, and hyperparameters:
|
|
289
|
+
|
|
290
|
+
```json
|
|
291
|
+
{"time": "2025-10-24T10:30:00Z", "level": "INFO", "run_name": "resnet_training", "run_id": "exp_001", "message": "Epoch 1/100", "loss": 0.45, "accuracy": 0.78, "cache_path": "plots/loss_curve.png"}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
View all runs for a training session, compare metrics across runs, and review training progression chronologically.
|
|
295
|
+
|
|
296
|
+
### Distributed Systems Debugging
|
|
297
|
+
|
|
298
|
+
Monitor services across multiple components:
|
|
299
|
+
|
|
300
|
+
```json
|
|
301
|
+
{"time": "2025-10-24T10:30:00Z", "level": "ERROR", "section": "api", "group": "prod", "message": "Connection timeout to database", "duration_ms": 5000}
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
Filter by section to isolate component issues, use time range to focus on incident windows, and track error patterns.
|
|
305
|
+
|
|
306
|
+
### Research Workflows
|
|
307
|
+
|
|
308
|
+
Document experiments with notes and artifacts:
|
|
309
|
+
|
|
310
|
+
```json
|
|
311
|
+
{"time": "2025-10-24T10:30:00Z", "level": "INFO", "run_name": "parameter_sweep", "run_id": "sweep_042", "message": "Testing learning_rate=0.001", "cache_path": "results/metrics.pdf"}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
Compare results across parameter sweeps, review experimental progression, and access generated reports directly from logs.
|
|
315
|
+
|
|
316
|
+
## Development
|
|
317
|
+
|
|
318
|
+
To run Log4Lab in development mode with auto-reload:
|
|
319
|
+
|
|
320
|
+
```bash
|
|
321
|
+
log4lab serve --reload
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
## Requirements
|
|
325
|
+
|
|
326
|
+
- Python >= 3.8
|
|
327
|
+
- FastAPI
|
|
328
|
+
- Uvicorn
|
|
329
|
+
- Jinja2
|
|
330
|
+
- Typer
|
|
331
|
+
|
|
332
|
+
## License
|
|
333
|
+
|
|
334
|
+
MIT
|
|
335
|
+
|
|
336
|
+
## Author
|
|
337
|
+
|
|
338
|
+
Thibaut Lamadon
|
log4lab-0.1.0/README.md
ADDED
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
# Log4Lab
|
|
2
|
+
|
|
3
|
+
A powerful, lightweight structured log viewer with live streaming, advanced filtering, and run tracking capabilities.
|
|
4
|
+
|
|
5
|
+
Log4Lab is a web-based dashboard for viewing and analyzing structured JSON logs in real-time. It provides a clean, modern interface for monitoring application logs with live updates, making it easy to track experiments, debug issues, and understand what's happening in your applications.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
### Core Functionality
|
|
10
|
+
- **Live Log Streaming**: Automatically streams new log entries as they're written to the log file using Server-Sent Events (SSE)
|
|
11
|
+
- **Structured Log Support**: Parses and displays JSONL (JSON Lines) formatted logs
|
|
12
|
+
- **Relative Time Display**: Shows "how long ago" each entry was created with automatic updates
|
|
13
|
+
- **Dark Mode**: Built-in dark mode support with theme persistence in browser local storage
|
|
14
|
+
|
|
15
|
+
### Advanced Filtering
|
|
16
|
+
- **Level Filter**: Dynamically populated dropdown based on actual log levels in your file (case-insensitive)
|
|
17
|
+
- **Section Filter**: Filter by component or section name
|
|
18
|
+
- **Group Filter**: Filter by experiment or job group
|
|
19
|
+
- **Run Name Filter**: Filter by run name to see all runs in a collection
|
|
20
|
+
- **Run ID Filter**: Focus on a specific run instance
|
|
21
|
+
- **Time Range Filter**: View logs from the last 1 minute, 5 minutes, 1 hour, 6 hours, or 24 hours
|
|
22
|
+
- **URL-based Filters**: All filters can be passed as URL query parameters for bookmarking and sharing
|
|
23
|
+
|
|
24
|
+
### Run Management
|
|
25
|
+
- **Runs Index Page**: Hierarchical view showing all run names with their associated run IDs
|
|
26
|
+
- **Run Links**: Each log entry includes a clickable link to filter by its run name or run ID
|
|
27
|
+
- **Run Statistics**: See total log counts per run name and individual run ID
|
|
28
|
+
|
|
29
|
+
### Display & Navigation
|
|
30
|
+
- **Pagination**: Configurable page size (20, 50, 100, or 200 entries per page)
|
|
31
|
+
- **Sort Toggle**: Switch between newest-first and oldest-first ordering (perfect for reviewing run chronology)
|
|
32
|
+
- **Collapsible JSON**: Full JSON view available for each entry, collapsed by default
|
|
33
|
+
- **Smart Message Display**: Renders the `message` field as the main content in fixed-width font
|
|
34
|
+
- **Artifact Rendering**: Automatically displays images, PDFs, and files referenced in the `cache_path` field
|
|
35
|
+
|
|
36
|
+
### User Interface
|
|
37
|
+
- **Modern Design**: Built with Tailwind CSS for a clean, responsive interface
|
|
38
|
+
- **Smooth Navigation**: Scroll to top on page changes, smooth transitions
|
|
39
|
+
- **Keyboard-Friendly**: All filters and controls are easily accessible
|
|
40
|
+
|
|
41
|
+
## Installation
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
pip install log4lab
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Or install from source:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
git clone https://github.com/yourusername/log4lab.git
|
|
51
|
+
cd log4lab
|
|
52
|
+
pip install -e .
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Usage
|
|
56
|
+
|
|
57
|
+
Start the Log4Lab server:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
log4lab serve [LOGFILE]
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Or tail logs in the terminal:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
log4lab tail [LOGFILE]
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Options
|
|
70
|
+
|
|
71
|
+
- `LOGFILE`: Path to the JSONL log file to stream (default: `logs/app.log`)
|
|
72
|
+
- `--host`: Host to bind to (default: `127.0.0.1`)
|
|
73
|
+
- `--port`: Port to listen on (default: `8000`)
|
|
74
|
+
- `--reload`: Enable auto-reload for development
|
|
75
|
+
|
|
76
|
+
### Examples
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# Web server - Use default log file (logs/app.log)
|
|
80
|
+
log4lab serve
|
|
81
|
+
|
|
82
|
+
# Specify a custom log file
|
|
83
|
+
log4lab serve /path/to/your/app.log
|
|
84
|
+
|
|
85
|
+
# Run on a different port
|
|
86
|
+
log4lab serve myapp.log --port 3000
|
|
87
|
+
|
|
88
|
+
# Bind to all interfaces
|
|
89
|
+
log4lab serve myapp.log --host 0.0.0.0
|
|
90
|
+
|
|
91
|
+
# Development mode with auto-reload
|
|
92
|
+
log4lab serve --reload
|
|
93
|
+
|
|
94
|
+
# Terminal tail - live streaming to terminal
|
|
95
|
+
log4lab tail myapp.log
|
|
96
|
+
|
|
97
|
+
# Tail with filters
|
|
98
|
+
log4lab tail myapp.log --level=ERROR --open-images
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Then open your browser to `http://localhost:8000` to view the dashboard.
|
|
102
|
+
|
|
103
|
+
### Using Filters via URL
|
|
104
|
+
|
|
105
|
+
Share specific filtered views by passing query parameters:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
# View only ERROR logs
|
|
109
|
+
http://localhost:8000/?level=error
|
|
110
|
+
|
|
111
|
+
# View a specific run
|
|
112
|
+
http://localhost:8000/?run_id=abc123
|
|
113
|
+
|
|
114
|
+
# View all runs in a collection
|
|
115
|
+
http://localhost:8000/?run_name=model_training
|
|
116
|
+
|
|
117
|
+
# Combine multiple filters
|
|
118
|
+
http://localhost:8000/?level=error&run_name=experiment1&time=3600
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Log Format
|
|
122
|
+
|
|
123
|
+
Log4Lab expects logs in JSONL format (one JSON object per line). Each log entry should be a JSON object.
|
|
124
|
+
|
|
125
|
+
### Basic Example
|
|
126
|
+
|
|
127
|
+
```json
|
|
128
|
+
{"time": "2025-10-24T10:30:00Z", "level": "INFO", "section": "train", "message": "Training started"}
|
|
129
|
+
{"time": "2025-10-24T10:30:05Z", "level": "WARN", "section": "data", "message": "Missing data point"}
|
|
130
|
+
{"time": "2025-10-24T10:30:10Z", "level": "ERROR", "section": "model", "message": "Model failed to converge"}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Advanced Example with Runs and Artifacts
|
|
134
|
+
|
|
135
|
+
```json
|
|
136
|
+
{
|
|
137
|
+
"time": "2025-10-24T10:30:00Z",
|
|
138
|
+
"level": "INFO",
|
|
139
|
+
"section": "train",
|
|
140
|
+
"message": "Training epoch 1 complete",
|
|
141
|
+
"run_name": "model_training",
|
|
142
|
+
"run_id": "run_001",
|
|
143
|
+
"group": "experiment_1",
|
|
144
|
+
"cache_path": "artifacts/training_plot.png",
|
|
145
|
+
"accuracy": 0.92,
|
|
146
|
+
"loss": 0.15
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Supported Fields
|
|
151
|
+
|
|
152
|
+
#### Core Fields
|
|
153
|
+
- `time`: Timestamp in ISO 8601 format (automatically handles UTC if no timezone specified)
|
|
154
|
+
- `level`: Log level (INFO, WARN, ERROR, DEBUG, etc.) - case-insensitive
|
|
155
|
+
- `section`: Component or section of your application
|
|
156
|
+
- `message` or `msg`: The main log message (displayed prominently in fixed-width font)
|
|
157
|
+
|
|
158
|
+
#### Run Tracking Fields
|
|
159
|
+
- `run_name`: Name of the run collection (e.g., "hyperparameter_search")
|
|
160
|
+
- `run_id`: Unique identifier for a specific run instance
|
|
161
|
+
- `group`: Group or experiment name for organizing related runs
|
|
162
|
+
|
|
163
|
+
#### Artifact Fields
|
|
164
|
+
- `cache_path`: Path to an artifact file (images, PDFs, etc.)
|
|
165
|
+
- Images (PNG, JPG, SVG, etc.) are displayed inline
|
|
166
|
+
- PDFs are embedded with a viewer
|
|
167
|
+
- Other files show as download links
|
|
168
|
+
|
|
169
|
+
#### Additional Fields
|
|
170
|
+
Any additional fields (metrics, parameters, etc.) are displayed in the expandable JSON view.
|
|
171
|
+
|
|
172
|
+
## Features in Detail
|
|
173
|
+
|
|
174
|
+
### Live Streaming
|
|
175
|
+
|
|
176
|
+
Log4Lab monitors the log file for changes and automatically streams new entries to the browser using Server-Sent Events (SSE). New entries appear at the top with smooth animations, and the "time ago" display updates every 5 seconds.
|
|
177
|
+
|
|
178
|
+
### Time Display
|
|
179
|
+
|
|
180
|
+
Each log entry shows:
|
|
181
|
+
- Relative time (e.g., "just now", "5m ago", "2h ago", "3d ago")
|
|
182
|
+
- Absolute timestamp for reference
|
|
183
|
+
- Automatic handling of UTC timestamps
|
|
184
|
+
- Smart future timestamp detection (shows "in 2h" for logs from the future)
|
|
185
|
+
|
|
186
|
+
### Filtering System
|
|
187
|
+
|
|
188
|
+
**Dynamic Level Filter**: Automatically discovers all log levels in your file and populates the dropdown. Supports any level names (INFO, Error, debug, WARN, etc.) with case-insensitive matching.
|
|
189
|
+
|
|
190
|
+
**Text Filters**: Section, Group, Run Name, and Run ID filters support partial matching and are case-insensitive.
|
|
191
|
+
|
|
192
|
+
**Time Range Filter**: Show only recent logs:
|
|
193
|
+
- Last 1 minute
|
|
194
|
+
- Last 5 minutes
|
|
195
|
+
- Last 10 minutes
|
|
196
|
+
- Last 30 minutes
|
|
197
|
+
- Last 1 hour
|
|
198
|
+
- Last 6 hours
|
|
199
|
+
- Last 24 hours
|
|
200
|
+
|
|
201
|
+
**Filter Persistence**: All filters are reflected in the URL, so you can bookmark specific views or share links with teammates.
|
|
202
|
+
|
|
203
|
+
### Run Management
|
|
204
|
+
|
|
205
|
+
The **Runs Index** (`/runs`) provides a bird's-eye view of all your runs:
|
|
206
|
+
- Lists all unique run names
|
|
207
|
+
- Shows total log count per run name
|
|
208
|
+
- Displays all associated run IDs with individual counts
|
|
209
|
+
- Click any run name to see all logs for that collection
|
|
210
|
+
- Click any run ID to see logs for that specific instance
|
|
211
|
+
|
|
212
|
+
Each log entry includes a **run info link** that takes you directly to a filtered view of that run.
|
|
213
|
+
|
|
214
|
+
### Sorting
|
|
215
|
+
|
|
216
|
+
Toggle between two sort orders:
|
|
217
|
+
- **Newest First** (default): Latest logs appear at the top - ideal for monitoring
|
|
218
|
+
- **Oldest First**: Chronological order from the beginning - perfect for understanding run progression
|
|
219
|
+
|
|
220
|
+
### Pagination
|
|
221
|
+
|
|
222
|
+
Control how many logs appear per page (20, 50, 100, or 200) and navigate through pages with Previous/Next buttons. The display shows your current position (e.g., "Showing 1-50 of 153 logs").
|
|
223
|
+
|
|
224
|
+
### Artifact Display
|
|
225
|
+
|
|
226
|
+
If your logs include a `cache_path` field pointing to artifacts:
|
|
227
|
+
|
|
228
|
+
**Images**: Displayed inline with full size
|
|
229
|
+
```json
|
|
230
|
+
{"cache_path": "artifacts/plot.png", "message": "Training loss over time"}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
**PDFs**: Embedded with a document viewer
|
|
234
|
+
```json
|
|
235
|
+
{"cache_path": "artifacts/report.pdf", "message": "Experiment results"}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
**Other Files**: Download link provided
|
|
239
|
+
```json
|
|
240
|
+
{"cache_path": "artifacts/model.pkl", "message": "Model checkpoint saved"}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Theme Support
|
|
244
|
+
|
|
245
|
+
Toggle between light and dark modes with the theme button in the top-right corner. Your preference is saved in browser local storage and persists across sessions.
|
|
246
|
+
|
|
247
|
+
## Use Cases
|
|
248
|
+
|
|
249
|
+
### Machine Learning Experiments
|
|
250
|
+
|
|
251
|
+
Track training runs with metrics, visualizations, and hyperparameters:
|
|
252
|
+
|
|
253
|
+
```json
|
|
254
|
+
{"time": "2025-10-24T10:30:00Z", "level": "INFO", "run_name": "resnet_training", "run_id": "exp_001", "message": "Epoch 1/100", "loss": 0.45, "accuracy": 0.78, "cache_path": "plots/loss_curve.png"}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
View all runs for a training session, compare metrics across runs, and review training progression chronologically.
|
|
258
|
+
|
|
259
|
+
### Distributed Systems Debugging
|
|
260
|
+
|
|
261
|
+
Monitor services across multiple components:
|
|
262
|
+
|
|
263
|
+
```json
|
|
264
|
+
{"time": "2025-10-24T10:30:00Z", "level": "ERROR", "section": "api", "group": "prod", "message": "Connection timeout to database", "duration_ms": 5000}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Filter by section to isolate component issues, use time range to focus on incident windows, and track error patterns.
|
|
268
|
+
|
|
269
|
+
### Research Workflows
|
|
270
|
+
|
|
271
|
+
Document experiments with notes and artifacts:
|
|
272
|
+
|
|
273
|
+
```json
|
|
274
|
+
{"time": "2025-10-24T10:30:00Z", "level": "INFO", "run_name": "parameter_sweep", "run_id": "sweep_042", "message": "Testing learning_rate=0.001", "cache_path": "results/metrics.pdf"}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Compare results across parameter sweeps, review experimental progression, and access generated reports directly from logs.
|
|
278
|
+
|
|
279
|
+
## Development
|
|
280
|
+
|
|
281
|
+
To run Log4Lab in development mode with auto-reload:
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
log4lab serve --reload
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
## Requirements
|
|
288
|
+
|
|
289
|
+
- Python >= 3.8
|
|
290
|
+
- FastAPI
|
|
291
|
+
- Uvicorn
|
|
292
|
+
- Jinja2
|
|
293
|
+
- Typer
|
|
294
|
+
|
|
295
|
+
## License
|
|
296
|
+
|
|
297
|
+
MIT
|
|
298
|
+
|
|
299
|
+
## Author
|
|
300
|
+
|
|
301
|
+
Thibaut Lamadon
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.0"
|