Giter Club home page Giter Club logo

tailspin's Introduction

A log file highlighter

Features

  • 🪵 View (or tail) any log file of any format
  • 🍰 No setup or config required
  • 🌈 Highlights numbers, dates, IP-addresses, UUIDs, URLs and more
  • ⚙️ All highlight groups are customizable
  • 🧬 Easy to integrate with other commands
  • 🔍 Uses less under the hood for scrollback, search and filtering

Table of Contents


Overview

tailspin works by reading through a log file line by line, running a series of regexes against each line. The regexes recognize patterns you expect to find in a logfile, like dates, numbers, severity keywords and more.

tailspin does not make any assumptions on the format or position of the items it wants to highlight. For this reason, it requires no configuration and the highlighting will work consistently across different logfiles.

Usage

The binary name for tailspin is tspin.

# Read from file and view in `less`
tspin application.log

# Read from file and print to stdout
tspin application.log --print

# Read from stdin and print to stdout
echo "2021-01-01 12:00:00 [INFO] This is a log message" | tspin 

# Read from another command and print to stdout
kubectl logs [pod name] --follow | tspin

Installing

Package Managers

# Homebrew
brew install tailspin

# Cargo
cargo install tailspin

# Archlinux
pacman -S tailspin

# Nix
nix-shell -p tailspin

# NetBSD
pkgin install tailspin

# FreeBSD
pkg install tailspin

From Source

cargo install --path .

Binary will be placed in ~/.cargo/bin, make sure you add the folder to your PATH environment variable.

Important

When building from source, make sure that you are using the latest version of less.

Highlight Groups

Dates

Keywords

URLs

Numbers

IP Addresses

Quotes

Unix file paths

HTTP methods

UUIDs

Key-value pairs

Pointer addresses

Unix processes

Watching folders

tailspin can listen for newline entries in a given folder. Watching folders is useful for monitoring log files that are rotated.

When watching folders, tailspin will start in follow mode (abort with Ctrl + C) and will only print newline entries which arrive after the initial start.

Customizing Highlight Groups

Overview

Create config.toml in ~/.config/tailspin to customize highlight groups.

Styles have the following shape:

style = { fg = "color", bg = "color", italic = false, bold = false, underline = false }

To edit the different highlight groups, include them in your config.toml file. For example, to edit the date highlight group, add the following to your config.toml:

[date]
style = { fg = "green" }

Expand the section below to see the default config for the highlight groups:

Default highlight groups settings
[date]
number = { fg = "magenta" }
separator = { faint = true }

[date_word] # e.g. "Jan 01", "Mon Feb 28"
day = { fg = "magenta" }
month = { fg = "magenta" }
number = { fg = "magenta" }

[time]
time = { fg = "blue" }
zone = { fg = "red" }
separator = { faint = true }

[[keywords]]
words = ['null', 'true', 'false']
style = { fg = "red", italic = true }

[[keywords]]
words = ['GET']
style = { fg = "black", bg = "green" }
border = true

[url]
http = { fg = "red", faint = true }
https = { fg = "green", faint = true }
host = { fg = "blue", faint = true }
path = { fg = "blue" }
query_params_key = { fg = "magenta" }
query_params_value = { fg = "cyan" }
symbols = { fg = "red" }

[number]
style = { fg = "cyan" }

[ip]
number = { fg = "blue", italic = true }
letter = { fg = "magenta", italic = true }
separator = { fg = "red" }

[quotes]
style = { fg = "yellow" }
token = '"'

[path]
segment = { fg = "green", italic = true }
separator = { fg = "yellow" }

[uuid]
number = { fg = "blue", italic = true }
letter = { fg = "magenta", italic = true }
separator = { fg = "red" }

[pointer]
number = { fg = "blue", italic = true }
letter = { fg = "magenta", italic = true }
separator = { fg = "red" }

[key_value]
key = { faint = true }
separator = { fg = "white" }

[process]
name = { fg = "green" }
separator = { fg = "red" }
id = { fg = "yellow" }

Disabling Highlight Groups

To disable a highlight group, set the disabled field for that group to true:

[date]
disabled = true

Adding Keywords via config.toml

To add custom keywords, either include them in the list of keywords or add new entries:

[[keywords]]
words = ['MyCustomKeyword']
style = { fg = "green" }

[[keywords]]
words = ['null', 'true', 'false']
style = { fg = "red", italic = true }

Adding Keywords from the command line

Sometimes it is more convenient to add highlight groups on the fly without having to edit a TOML. To add highlights from the command line, use the --words-[red|green|yellow|blue|magenta|cyan] flag followed by a comma separated list of words to be highlighted.

Custom regex highlighters

When you need more control over the highlighting, you can use the regex highlighter. This highlighter allows you to specify a regex and a style to be applied to the matched text.

It supports one capture group (). When found, it will apply the style to the captured text.

[[regexps]]
regular_expression = 'Started (.*)\.'
style = { fg = "red" }

Working with stdin and stdout

By default, tailspin will open a file in the pager less. However, if you pipe something into tailspin, it will print the highlighted output directly to stdout. This is similar to running tspin [file] --print.

To let tailspin highlight the logs of different commands, you can pipe the output of those commands into tailspin like so:

journalctl -f | tspin
cat /var/log/syslog | tspin
kubectl logs -f pod_name | tspin

Using the pager less

Overview

tailspin uses less as its pager to view the highlighted log files. You can get more info on less via the man command (man less) or by hitting the h button to access the help screen.

Navigating

Navigating within less uses a set of keybindings that may be familiar to users of vim or other vi-like editors. Here's a brief overview of the most useful navigation commands:

  • j/k: Scroll one line up / down
  • d/u: Scroll one half-page up / down
  • g/G: Go to the top / bottom of the file

Follow mode

When you run tailspin with the -f or --follow flag, it will scroll to the bottom and print new lines to the screen as they're added to the file.

To stop following the file, interrupt with Ctrl + C. This will stop the tailing, but keep the file open, allowing you to review the existing content.

To resume following the file from within less, press Shift + F.

Search

Use / followed by your search query. For example, /ERROR finds the first occurrence of ERROR.

After the search, n finds the next instance, and N finds the previous instance.

Filtering

less allows filtering lines by a keyword, using & followed by the pattern. For instance, &ERROR shows only lines with ERROR.

To only show lines containing either ERROR or WARN, use a regular expression: &\(ERROR\|WARN\).

To clear the filter, use & with no pattern.

Settings

-f, --follow                     Follow the contents of the file
-e, --start-at-end               Start at the end of the file
-p, --print                      Print the output to stdout
-c, --listen-command [CMD]       Listen the output (stdout) of the provided command
    --config-path [PATH]         Use the configuration file from the provided path
    --words-[COLOR] [WORDS]      Highlight the provided words with the given color
    --disable-builtin-keywords   Disable the highlighting of all builtin groups
    --disable-booleans           Disable the highlighting of booleans and nulls
    --disable-severity           Disable the highlighting of severity levels
    --disable-rest               Disable the highlighting of REST verbs

tailspin's People

Contributors

0323pin avatar bensadeh avatar bsdlme avatar dependabot[bot] avatar ecarrara avatar jscarrott avatar just1602 avatar laurentfough avatar mkogan1 avatar snpefk avatar supleed2 avatar tornaxo7 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tailspin's Issues

less is passed path as a regular option

It is safer to tell less that the path must not be accidentally parsed as an option, by using "--" as delimiter.

I.e. instead of "less +F somefile" it is safer to call it as "less +F -- somefile".

Filter based on log level

I want to only see ERROR, or WARN, or INFO logs.

Press 1 = only show ERROR
Press 2 = show > WARN
Press 3 = show > INFO
Press 4 = show all

Crash on latin1 character

Welcome to the rude world of character encoding:

~ ❯ echo "é" | iconv -f utf8 -t latin1 | /tmp/tailspin/spin 
Error reading from stdin: stream did not contain valid UTF-8
thread 'main' panicked at 'Could not receive EOF signal from oneshot channel: RecvError(())', /home/compil/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tailspin-1.2.1/src/main.rs:107:10
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Here, the error message is clear, but I have logs with Latin1 encoded value, and the application crashes. It shouldn't :)
I suspect other encoding not compatible with UTF-8 generate the same crash.

IsTerminal requires rustc 1.70

Recently introduced std::io::IsTerminal was stabilized only since rustc v0.70. You might want to add rust-version = "1.70.0" to your Cargo.toml, or switch to using atty.

Options for dealing with original colors

For now spin sometimes works nicely with grep:

$ echo 12345 | grep --color=always 34 | tspin
<magenta>12</magenta><red>34</red>5
$ echo '123"4"56' | grep --color=always '3"4' | tspin
<magenta>12</magenta><red>3</red><yellow>"4</yellow>"56

Not sure whether it's expected or not but I believe it might be helpful to have the following options:

  • (current behavior?) to preserve colors from the source file;
  • to remove colors from the source file;
  • to prioritize original colors over produced by tspin.

Unable to disable `Date` group in log output?

Hi!

I'm struggling to disable the highlight group for Date, i.e., hide the Date column in log output

From README:

To disable a highlight group, either comment it out or delete it.

I've attempted:

# 1) comment out
#[groups.date]

# 2) set disabled = true
[groups.date]
disabled = true

It looks like I can set disabled on Date and it should work? I may be missing something obvious here 😅

pub struct Date {
pub date: Style,
pub time: Style,
pub zone: Style,
#[serde(default)]
pub disabled: bool,
}

support processing stdin

tailspin claims to be a drop-in replacement for tail -f, yet it does not support data from stdin.

This works: "echo foobar | tail -f"

This fails: "echo foobar | tailspin -f"

The more interesting use case is this: "journalctl -f | tailspin -f"

Crashes on alpine linux, due to unrecognized less option on busybox

Crashes on a simple file, due to alpine using the busybox version of less.
Installation was via cargo:

nightly-x86_64-unknown-linux-musl (default)
rustc 1.76.0-nightly (1e9dda77b 2023-11-22)
localhost:/var/log/nginx# tspin -f error.log
less: unrecognized option: ignore-case
BusyBox v1.36.1 (2023-11-06 11:32:24 UTC) multi-call binary.

Usage: less [-EFIMmNSRh~] [FILE]...

View FILE (or stdin) one screenful at a time

        -E      Quit once the end of a file is reached
        -F      Quit if entire file fits on first screen
        -I      Ignore case in all searches
        -M,-m   Display status line with line numbers
                and percentage through the file
        -N      Prefix line number to each line
        -S      Truncate long lines
        -R      Remove color escape codes in input
        -~      Suppress ~s displayed past EOF
The application panicked (crashed).
Message:  called `Result::unwrap()` on an `Err` value: Custom { kind: Other, error: "background task failed" }
Location: /root/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tailspin-2.2.0/src/main.rs:61

Backtrace omitted. Run with RUST_BACKTRACE=1 environment variable to display it.
Run with RUST_BACKTRACE=full to include source snippets.

With full backtrace:

localhost:/var/log/nginx# RUST_BACKTRACE=1 tspin -f error.log
less: unrecognized option: ignore-case
BusyBox v1.36.1 (2023-11-06 11:32:24 UTC) multi-call binary.

Usage: less [-EFIMmNSRh~] [FILE]...

View FILE (or stdin) one screenful at a time

        -E      Quit once the end of a file is reached
        -F      Quit if entire file fits on first screen
        -I      Ignore case in all searches
        -M,-m   Display status line with line numbers
                and percentage through the file
        -N      Prefix line number to each line
        -S      Truncate long lines
        -R      Remove color escape codes in input
        -~      Suppress ~s displayed past EOF
The application panicked (crashed).
Message:  called `Result::unwrap()` on an `Err` value: Custom { kind: Other, error: "background task failed" }
Location: /root/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tailspin-2.2.0/src/main.rs:61

  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ BACKTRACE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
                                ⋮ 9 frames hidden ⋮
  10: tspin::process_lines::{{closure}}::h989036fa9c27e244
      at <unknown source file>:<unknown line>
  11: tokio::runtime::task::core::Core<T,S>::poll::h0a8230ff4d14ff3a
      at <unknown source file>:<unknown line>
  12: tokio::runtime::task::raw::poll::hc3dd1119f6f12f69
      at <unknown source file>:<unknown line>
  13: tokio::runtime::scheduler::multi_thread::worker::Context::run_task::h5d0e9fc330ceb7c3
      at <unknown source file>:<unknown line>
  14: tokio::runtime::scheduler::multi_thread::worker::Context::run::h33a108d097c8f023
      at <unknown source file>:<unknown line>
  15: tokio::runtime::context::scoped::Scoped<T>::set::h44e407490c6ddb0e
      at <unknown source file>:<unknown line>
  16: tokio::runtime::context::runtime::enter_runtime::h453fa88dbaa438f8
      at <unknown source file>:<unknown line>
  17: tokio::runtime::scheduler::multi_thread::worker::run::h1b17132e983f4d16
      at <unknown source file>:<unknown line>
  18: <tokio::runtime::blocking::task::BlockingTask<T> as core::future::future::Future>::poll::hf82f57bab33c7896
      at <unknown source file>:<unknown line>
  19: tokio::runtime::task::core::Core<T,S>::poll::haac949cf21fb3699
      at <unknown source file>:<unknown line>
  20: tokio::runtime::task::harness::Harness<T,S>::poll::h108e9b04e86acd01
      at <unknown source file>:<unknown line>
  21: tokio::runtime::blocking::pool::Inner::run::h8360b594cf7221b8
      at <unknown source file>:<unknown line>
  22: std::sys_common::backtrace::__rust_begin_short_backtrace::h3f48898d763cdb34
      at <unknown source file>:<unknown line>
  23: core::ops::function::FnOnce::call_once{{vtable.shim}}::hc50d5f34188abc7a
      at <unknown source file>:<unknown line>
  24: <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once::hc347b84c4e72a07c
      at /rustc/1e9dda77b5b8e690c7e21871bbd2dcf182e1a841/library/alloc/src/boxed.rs:2007
  25: <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once::he567d8d07a5ab38b
      at /rustc/1e9dda77b5b8e690c7e21871bbd2dcf182e1a841/library/alloc/src/boxed.rs:2007
  26: std::sys::unix::thread::Thread::new::thread_start::h6824dd6ac9aad219
      at /rustc/1e9dda77b5b8e690c7e21871bbd2dcf182e1a841/library/std/src/sys/unix/thread.rs:108

Run with COLORBT_SHOW_HIDDEN=1 environment variable to disable frame filtering.
Run with RUST_BACKTRACE=full to include source snippets.

Accessed file:

localhost:/var/log/nginx# cat access.log
10.0.1.26 - - [23/Nov/2023:10:24:31 +0100] "GET / HTTP/1.1" 404 146 "-" "insomnia/2023.5.8" "-"
10.0.1.26 - - [23/Nov/2023:10:24:59 +0100] "GET / HTTP/1.1" 404 146 "-" "insomnia/2023.5.8" "-"
10.0.1.26 - - [23/Nov/2023:10:25:10 +0100] "GET / HTTP/1.1" 404 146 "-" "insomnia/2023.5.8" "-"
10.0.1.26 - - [23/Nov/2023:10:25:55 +0100] "GET / HTTP/1.1" 404 146 "-" "curl/8.0.1" "-"
10.0.1.26 - - [23/Nov/2023:10:29:16 +0100] "GET / HTTP/1.1" 502 150 "-" "curl/8.0.1" "-"
10.0.1.26 - - [23/Nov/2023:10:29:43 +0100] "GET / HTTP/1.1" 502 150 "-" "curl/8.0.1" "-"
10.0.1.26 - - [23/Nov/2023:10:30:00 +0100] "GET / HTTP/1.1" 502 150 "-" "curl/8.0.1" "-"
10.0.1.26 - - [23/Nov/2023:10:30:46 +0100] "GET / HTTP/1.1" 502 150 "-" "curl/8.0.1" "-"
10.0.1.26 - - [23/Nov/2023:10:32:04 +0100] "GET / HTTP/1.1" 502 150 "-" "curl/8.0.1" "-"
10.0.1.26 - - [23/Nov/2023:10:33:15 +0100] "GET / HTTP/1.1" 502 150 "-" "curl/8.0.1" "-"
10.0.1.26 - - [23/Nov/2023:10:33:48 +0100] "GET / HTTP/1.1" 502 150 "-" "curl/8.0.1" "-"
10.0.1.26 - - [23/Nov/2023:10:33:55 +0100] "GET / HTTP/1.1" 502 150 "-" "curl/8.0.1" "-"
10.0.1.26 - - [23/Nov/2023:10:34:23 +0100] "GET / HTTP/1.1" 502 150 "-" "curl/8.0.1" "-"
10.0.1.26 - - [23/Nov/2023:10:34:53 +0100] "GET / HTTP/1.1" 502 150 "-" "curl/8.0.1" "-"
10.0.1.26 - - [23/Nov/2023:10:35:42 +0100] "GET / HTTP/1.1" 502 150 "-" "curl/8.0.1" "-"
10.0.1.26 - - [23/Nov/2023:10:36:13 +0100] "GET / HTTP/1.1" 502 150 "-" "curl/8.0.1" "-"
10.0.1.26 - - [23/Nov/2023:10:36:53 +0100] "GET / HTTP/1.1" 502 150 "-" "curl/8.0.1" "-"
10.0.1.26 - - [23/Nov/2023:10:38:23 +0100] "GET / HTTP/1.1" 502 150 "-" "curl/8.0.1" "-"
10.0.1.26 - - [23/Nov/2023:10:38:40 +0100] "GET / HTTP/1.1" 502 150 "-" "curl/8.0.1" "-"
10.0.1.26 - - [23/Nov/2023:10:39:07 +0100] "GET / HTTP/1.1" 502 150 "-" "curl/8.0.1" "-"
10.0.1.26 - - [23/Nov/2023:10:39:36 +0100] "GET / HTTP/1.1" 502 150 "-" "curl/8.0.1" "-"
10.0.1.26 - - [23/Nov/2023:10:40:01 +0100] "GET / HTTP/1.1" 502 150 "-" "curl/8.0.1" "-"
10.0.1.26 - - [23/Nov/2023:10:40:52 +0100] "GET / HTTP/1.1" 502 150 "-" "curl/8.0.1" "-"
10.0.1.26 - - [23/Nov/2023:10:42:27 +0100] "GET / HTTP/1.1" 502 150 "-" "curl/8.0.1" "-"
10.0.1.26 - - [23/Nov/2023:10:43:10 +0100] "GET / HTTP/1.1" 502 150 "-" "curl/8.0.1" "-"
10.0.1.26 - - [23/Nov/2023:10:46:06 +0100] "GET / HTTP/1.1" 200 2716 "-" "curl/8.0.1" "-"

Stops following

spin -f logfile compared to less +F logfile just stops following on one and the same file.

Date interpretted as Unix File Path

On MacOS 13.1, using iTerm.
tailspin version 1.6.1

I use a black background in my terminal window and the blue in the time format was hard to read. I changed it to yellow in my ~/.config/tailspin/config.toml file as such:

...
[time]
time = { fg = "yellow" }
zone = { fg = "red" }
# To shorten the time, uncomment the line below
# shorten = { to = "␣", style = { fg = "blue" } }

Anyway, when I tried to view this log file, part of the date appears to be interpretted as a unix file path.
Also, I think the logic expects a . after the time but instead is seeing a : and interpretting it as something else.

image
$cat "com.flexibits.fantastical2.mac 2023-10-02--15-42-31-759.log"
2023/10/02 11:42:31:738  Location manager failed: Error Domain=kCLErrorDomain Code=0 "(null)"
2023/10/02 11:43:27:698  Location manager error: Error Domain=kCLErrorDomain Code=0 "(null)"
2023/10/02 11:47:39:850  Location manager failed: Error Domain=kCLErrorDomain Code=0 "(null)"

Use relative dates

I don’t want to waste terminal space on todays date. It is today. I know that. Give me back 10 charactes (i.e. 15%) of my terminal area.

Panic when passing `-p` flag on macOS

Hi!

Running the following command panics at the end of the file:

> cargo run example-logs/example2 -p
// ... the rest of the file ...
2022-09-10 02:37:29,743 [Worker-63: Building] INFO // ...
The application panicked (crashed).
Message:  called `Result::unwrap()` on an `Err` value: Custom { kind: Other, error: "task was cancelled" }
Location: src/main.rs:60

And on the offending line, we find ourselves with a gift! (an unwra- like u-unwrapping a gift, opening a present, etc. etc.)

tailspin/src/main.rs

Lines 53 to 61 in c6ed6ab

async fn process_lines<T: AsyncLineReader + AsyncLineWriter + Unpin + Send>(
mut io: T,
highlight_processor: HighlightProcessor,
) {
while let Ok(Some(line)) = io.next_line().await {
let highlighted_line = highlight_processor.apply(&line);
io.write_line(&highlighted_line).await.unwrap();
}
}

assumes less is configured to interpret ANSI escape codes

On my Debian system, running tailspin on a logfile warns that output "may be a binary file", and if I accept to see it anyway it shows the logfile with lots of escape codes where coloring was expected.

If I instead run tailspin with environment variable LESS="R" then it displays colors as expected.

I suspect your test environment is configured to have less parse escape sequences, which is not the default behaviour of less, as far as I can see in the less decoumentation.

I guess the proper thing to do is to add option -R to lines 7 and 9 of src/less/mod.rs, to ensure that ANSI escape code parsing is enabled regardless of environment setup.

'tspin -p empty.log' waits until file has content, which may never happen

Thanks for this project, it's great!

One unexpected behavior I've noticed (in 2.0.0) is:

$ rm -f empty.log
$ touch empty.log
$ tspin -p empty.log  # hangs indefinitely

If I leave that hanging, and in a separate Zsh session run:

$ print -rl -- one two three >empty.log

then the first session with the hanging tspin command prints

one
two
three

and exits.

I wouldn't expect tspin -p to wait for any/more input -- is that intentional? I would expect instead for it to print nothing and exit immediately, in the case of an empty file.

Statically-linked binaries on GitHub Release

Consider adding statically-linked binaries for Mac OS X, Linux, and OpenBSD. This would make it super convenient for users to download and use the executable via HTTPS, quickly and securely.

Automatically open compressed log files

I have a feature request that would benefit my workflow.

I have a directory with a bunch of compressed log files in them, so I end up doing something like this:

gunzip some_info.log.gz
tspin some_info.log

It would be nice if there was an option to automatically decompress the file and store it in the same location without the .gz extension, or in the case of a small file, just decompress it in memory so no extra file is created.

Not sure if this is something you would want to implement, but it would make viewing log files easier for me.

Readling large log files

Hi, gave tailspin a spin :) and while it works on smaller logfiles and tailing others (or even folders which is great) it seems to have problems with large (>100mb) files. So I think there may be something off with the less pager.

Support for highlighting pointers

Hey! I love this tool! One thing that would be really useful for low level developers is highlighting pointers/memory addresses, potentially also splitting them up into 32bit chunks so they're easier to read :)

Incorrect formatting

On MacOS 13.1, using iTerm.

When viewing a log file in nano, it displays correcly:

image

However when viewing it through spin, it looks messed up:

image

Similarly when piping the output of cat:

image

Support more keywords

Here are some logging definitions from loguru in Python.

Level name Severity value Logger method
TRACE 5 logger.trace()
DEBUG 10 logger.debug()
INFO 20 logger.info()
SUCCESS 25 logger.success()
WARNING 30 logger.warning()
ERROR 40 logger.error()
CRITICAL 50 logger.critical()

How to use in windows?

I use tspin -f 2023-12-30.log command, and prompt "'less' command not found. Please ensure it is installed and on your PATH."
what should I do?

Default `bucket_size` in piped mode to 0

Problem

I have debugged my setup for 2 hours because tailspin did not show my logs in piped mode. Only once I looked at the source code I realized, I have to set the bucket size to zero in order to show realtime log output.

I expected this to be the default when using tspin in piped mode because with a bucket_size of 10,000, the output is delayed af.

Fix

Set the bucket size to zero by default when used in piped mode. This would prevent any future users from having the same problem. The tspin process runs in parallel anyway when used in pipes, so the performance loss should be neglectable. If more performance at the cost of "up-to-dateness" is required, then one could just manually increase the bucket size.

Performance issues with large files (slow to open)

I tested tailspin on a 868M log file (one I routinely check on my system) and it took 2 minutes and 45 seconds to open in tailspin, pegging a core the entire time. This same file opens instantly with less.

I'd love to use tailspin when this is resolved!

How to use with vscode

Since many developers use vscode and vscode outputs log information to the debug console or terminal output panel, it would be good to be able to pipe that log into through tailspin.

Any idea how to achive this? Perhaps some clever vscode launch config?

e.g.
image

Binary name conflict

Hi,

I was asked to package tailspin for pkgsrc/NetBSD yesterday.
I'll be working on getting this done in an hour or so, but I've noticed that renaming the binary and seding the new name into the manpage will be required, as there's already a spin binary in the package tree.

Considering the existence of spin, it would probably be better to call the binary tailspin and avoid conflicts.

I'm open to other suggestions if you have other preferences.

Regards

Simple output (i.e. no call to `less`)

This is an incredible valuable project, thanks!

But to be honest, sometimes, I much prefer the behavior of a simple tail -f, where I can "put" separator by hitting Enter key.
Is it possible to add a mode where tailspin or tailspin -f completely skip the less part?

Handle quote escapes inside strings

Strings such as the following are not appropriately highlighted.

"Hello \"World\""

Steps to reproduce

echo "\"Hello \\\"Mars\\\"\"" | spin

Cant install in Ubuntu 22.04

Ubuntu 22.04 is on rustc 1.66.1 not able to upgrade to 1.67 due to dependencies.

rustc 1.66.1+dfsg0ubuntu1-0ubuntu0.22.04.1 [Ubuntu/jammy main]

If I install tailspin via Cargo I end up in missing dependency toml v0.8.6 because it require rustc 1.67 which is unavailable.

error: failed to compile `tailspin v2.1.0`, intermediate artifacts can be found at `/tmp/cargo-installyKblhI`

Caused by:
  package `toml v0.8.6` cannot be built because it requires rustc 1.67 or newer, while the currently active rustc version is 1.66.1

For Others come by the same issue, maybe can be statet somewhere, you need to manually upgrade rsutc on your ubuntu.

First uninstall rustc apt remove rustc then install the latest rust from rustup

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

suggestion: document use as systemd journalctl pager

You might want to add a note to documentation that this is how to make tailspin your pager for systemd journalctl:

SYSTEMD_PAGERSECURE=true PAGER=/usr/bin/tailspin journalctl

...but you might wanna first implement #27 since currently your pager isn't secure.

Also, the above does not actually work - adding option -f or -e works but calling bare journalctl just hangs with nothing output to screen. :-(

Better error message when `less` binary not found

I recently ran tspin on a system without less installed, and I got this error:

lavender@pi:~$ tspin -f /opt/my/path/log_info.log
Failed to run less: No such file or directory (os error 2)
The application panicked (crashed).
Message:  called `Result::unwrap()` on an `Err` value: Custom { kind: Other, error: "background task failed" }
Location: /home/lavender/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tailspin-2.0.0/src/main.rs:59

Backtrace omitted. Run with RUST_BACKTRACE=1 environment variable to display it.
Run with RUST_BACKTRACE=full to include source snippets

I think having a nicer error message would really help people understand what they need to do (install less) in order to get it working.

Custom regex patterns?

Discussed in #102

Originally posted by seqizz December 29, 2023
Hi 👋

First of all, cool project. Tried on few places and liking it.

A small question is: Do you plan to support custom patterns? Something like:

[our_special_fqdn]
segment = { fg = "cyan", italic = true }
separator = { fg = "red" }
regexp = ' [a-z0-9-]+.[a-z0-9]+\.business\.local '

Here is an example I see on latest release:

image

As far as I understand, this is the "process" but can't catch udev-worker due to parentheses.

Considering weird logs we see every day, I thought this might be a nice addition for ones who'd like to lose some sanity via regex and gain amazing customization powers.

generate-config writes to hardcoded path

I think it would be better if subcommand generate-config would not create default config file, but simply spew config data to stdout. That way, the user is free to either create default or custom config file, or to use the output to make a diff against an existing config file.

Additionally, I think it would be better if a) instead of a hardcoded default path XDG evironment variables was consulted (which leads to same default path as now, so no surprises for the millions of existing users of the tool), and b) not only a user-specific path is used but (when that is missing) system-shared paths are consulted too.
All of this seems possible with the crate microxdg using Xdg::search_config_file().
(the more popular crate Directories unfortunately does not support system-wide lookups).

name of executable clashes with existing tool

Hi,

Nice tool. I am now looking into packaging it for Debian.

One little nit, though: The executable is called "spin" which clashes with another tool.

Please consider renaming this tool. I suggest same name as the project: "tailspin".
In fact, for now I am preparing the Debian package with name changed to "tailspin" because it is not permitted for multiple packages in Debian to provide same name (unless they provide same ABI which clearly this name clash is not an example of).

Add homebrew package

It would be lovely to have a homebrew-core package to just run: brew install tailspin.

Alternatively a tailpsin tap would be a nice solution, then a bensadeh/homebrew-tap repo is needed and to install would need:

brew tap bensadeh/tap
brew install tailspin

Piping output of tailspin to another pager can results in panic

The following uses case.

$ cat large_log_file.log | tspin | less

Do not scroll till EOF in less, but quit at some point before. This results in crash due to broken pipe.

The application panicked (crashed).
Message:  failed printing to stdout: Broken pipe (os error 32)
Location: library/std/src/io/stdio.rs:1019

Backtrace omitted. Run with RUST_BACKTRACE=1 environment variable to display it.
Run with RUST_BACKTRACE=full to include source snippets.
The application panicked (crashed).
Message:  Could not receive EOF signal from oneshot channel: RecvError(())
Location: /home/XXX/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tailspin-2.0.0/src/main.rs:48

Backtrace omitted. Run with RUST_BACKTRACE=1 environment variable to display it.
Run with RUST_BACKTRACE=full to include source snippets.

This is probably an unconventional use case, but I noticed that feeding large (>10MB) file directly to tspin gets slow, while in the above case it is pretty much instant.

tspin version 2.0.0

Where is default config file location?

I want to add new custom keywords but I want them to match the colors used by default for INFO, WARN, ERROR etc
I have created my own ~/.config/tailspin/config.toml file but don't want to guess what those color values are.

So what does tailspin use to decide what those colors should be by default? Is it embedded in the code or is there some config file I can look at?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.