2

I have log file of multi threaded application. Each line has a well know format (e.g. 3rd field is thread id). while one of fields is thread id. I hope that I'm not trying to reinvent the wheel :)

Any way, to easy reading of the file, I thought of two options that could help:

  1. Highlight all lines with the same thread id as current line.

  2. If some keystroke is pressed, all lines with other thread id are folded, pressing again the keystroke unfold the lines.

A skeleton for both items is welcomed.

dimba
  • 26,717
  • 34
  • 141
  • 196

2 Answers2

4

Highlighting by pattern

Here is a function to highlight (and another to clear) all lines that contain a given pattern, with an accent highlight on the pattern itself. The "last search" register @/ is also set to the requested pattern so n/N, in normal mode, jumps forwards/backwards through matching lines. <Leader>l (equivalent to \l on most installs) is a shortcut to highlight lines that contain the WORD under your cursor.

highlight def link xHiLine Special
highlight def link xHiPatt String

function! ClearHighlight()
    syn clear xHiLine
    syn clear xHiPatt
    let @/ = ''
endfunction

function! HighlightPattern(patt)
    call ClearHighlight()
    if a:patt != ''
        echo "Highlighting pattern: ".a:patt
        exec "syn match xHiPatt \"".a:patt."\" contained"
        exec "syn match xHiLine \".*".a:patt.".*\" contains=xHiPatt"
        let @/ = a:patt
    endif
endfunction

map <Leader>l :call HighlightPattern(expand("<cWORD>"))<CR>
map <Leader>c :call ClearHighlight()<CR>

Folding by pattern

For an example of folding based on patterns, check out the Show-Hide Vim plug-in. It provides two commands, SHOW and HIDE, and a few shortcut maps. For example, :SHOW thread=1234 will fold all lines except those that contain thread=1234, while zs in normal mode will show lines containing the word under your cursor. [You may want to create an alternate map, such as zS, to use <cWORD> instead of <cword>.]

Building patterns

If neither <cword> nor <cWORD> extract a sufficiently unique filter pattern (or to avoid moving the cursor to the proper field), create another function like the one below and call it from a map.

function! GetField(num)
    let toks = split(getline('.'))
    if len(toks) >= a:num
        return toks[a:num-1]
    endif
    return ''
endfunction

map <Leader>hl :call HighlightPattern(GetField(3))<CR>
map <Leader>fl :exec "SHOW ".GetField(3)<CR>
Garrett
  • 47,045
  • 6
  • 61
  • 50
1

What you are basically looking for is an external mechanisem to be built on top of your log file. Chainsaw is doing exactly that for log4j based logs: http://logging.apache.org/chainsaw/index.html

Not sure what is your logging application, but you should probbaly look at that direction.

JAR.JAR.beans
  • 9,668
  • 4
  • 45
  • 57
  • Looks interesting, however it's GUI based. Our support works many times over slow remote connections, so I'm interesting in a console based solution too. – dimba Apr 10 '11 at 17:03