https://github.com/suda/leno
🌲️ Command-line log viewer with a web UI
https://github.com/suda/leno
logging logs webui
Last synced: 4 months ago
JSON representation
🌲️ Command-line log viewer with a web UI
- Host: GitHub
- URL: https://github.com/suda/leno
- Owner: suda
- License: mit
- Created: 2020-12-03T18:24:27.000Z (over 5 years ago)
- Default Branch: main
- Last Pushed: 2024-08-30T16:54:14.000Z (almost 2 years ago)
- Last Synced: 2026-01-17T06:26:18.155Z (5 months ago)
- Topics: logging, logs, webui
- Language: Svelte
- Homepage:
- Size: 704 KB
- Stars: 6
- Watchers: 1
- Forks: 0
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
Leño is a [JSON lines](https://jsonlines.org/) log viewer with a web UI. Think of it as local Kibana/Sumo Logic for development. Works great with [Pino](https://getpino.io/) logging library, any other app that logs into JSON, or nginx/nginx-ingress access logs.

## Installation
Download the latest binary for your platform from the [releases page](https://github.com/suda/leno/releases) and place it somewhere on your `$PATH`.
Or build from source (requires Go 1.21+ and Node.js for the Svelte build step):
```sh
git clone https://github.com/suda/leno
cd leno
npm install
make build
```
This produces a single `./leno` binary with the web UI embedded — no runtime dependencies.
## Usage
Pipe your app's output to `leno`:
```sh
$ ./myapp | leno
Leno running on http://localhost:3000
```
Now open [http://localhost:3000](http://localhost:3000) to see logs stream in real time.
### Custom port
```sh
$ LENO_PORT=8080 ./myapp | leno
Leno running on http://localhost:8080
```
### Example with Pino
```sh
$ node server.js | leno
```
### Nginx / nginx-ingress access logs
Use `--log-format=nginx` to parse nginx access logs (both the standard [combined log format](https://nginx.org/en/docs/http/ngx_http_log_module.html) and the extended [nginx-ingress format](https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/log-format/)). Each line is converted to a JSON object before display.
```sh
# Local nginx
$ tail -f /var/log/nginx/access.log | leno --log-format=nginx
# Kubernetes nginx-ingress
$ kubectl logs -n nginx -l app.kubernetes.io/name=ingress-nginx \
--all-containers=true -f | leno --log-format=nginx
```
The following fields are extracted:
| Field | Type | Description |
|---|---|---|
| `remote_addr` | string | Client IP address |
| `remote_user` | string | Authenticated user (`-` if none) |
| `time` | string | Request time in RFC 3339 UTC |
| `method` | string | HTTP method |
| `path` | string | Request path |
| `http_version` | string | HTTP version |
| `status` | number | HTTP response status code |
| `body_bytes` | number | Bytes sent to client |
| `http_referer` | string | `Referer` header |
| `http_user_agent` | string | `User-Agent` header |
| `request_length` | number | *(nginx-ingress)* Request size in bytes |
| `request_time` | number | *(nginx-ingress)* Request processing time in seconds |
| `upstream_name` | string | *(nginx-ingress)* Upstream service name |
| `upstream_addr` | string | *(nginx-ingress)* Upstream pod address |
| `upstream_response_time` | string | *(nginx-ingress)* Upstream response time(s) |
| `upstream_status` | number | *(nginx-ingress)* Upstream response status code |
| `request_id` | string | *(nginx-ingress)* Unique request ID |
Lines that don't match either format are passed through as-is, so mixed log streams (e.g. nginx error lines alongside access lines) are handled gracefully.
### Generate fake logs for testing
```sh
$ ./scripts/generate-fake-logs.sh | leno
```
## Building from source
Requirements: Go 1.21+, Node.js (build only)
```sh
# Install JS build dependencies
npm install
# Build Svelte app and compile Go binary
make build # produces ./leno
# Development (Svelte hot-reload)
make dev # runs rollup in watch mode; run ./leno separately
# Clean build artifacts
make clean
```
## Credits
Leño's logo is based on [log by Smalllike](https://thenounproject.com/term/log/2784204) from the Noun Project.