Glance over the gifs below for tips.
As with the motivation for my previous post, I often need to read logs in remote machines or containers. Rather than trying to copy the files to my local computer, it’s easier to open and browse them directly in the remote shell using vim.
This article showcases some vanilla vim features (i.e. without custom plugins) that I find useful while navigating logs. The goal is to provide you intuition on how the features work, so that you can adopt them in your own workflows. Before proceeding, I recommend that you first set the 5 configs mentioned in the previous post.
Below is the example log I’ll be using. Feel free to save the content to a file and follow along:
2021-01-02 00:00:01,000 - handlers.py[DEBUG]: start: task 1 2021-01-02 00:00:02,000 - util.py[DEBUG]: Running command ['ip', 'link', 'set', 'dev', 'eth0', 'up'] with allowed return codes  (shell=False, capture=True) 2021-01-02 00:00:04,000 - handlers.py[DEBUG]: finish: task 1, took 3 seconds 2021-01-02 00:00:10,000 - handlers.py[DEBUG]: start: task 2 2021-01-02 00:00:20,000 - handlers.py[DEBUG]: start: task 3 2021-01-02 00:00:21,000 - util.py[DEBUG]: Running command ['/var/tmp/cloud-init/cloud-init-dhcp-x4y__t7z/dhclient', '-1', '-v', '-lf', '/var/tmp/cloud-init/cloud-init-dhcp-x4y__t7z/dhcp.leases', '-pf', '/var/tmp/cloud-init/cloud-init-dhcp-x4y__t7z/dhclient.pid', 'eth0', '-sf', '/bin/true'] with allowed return codes  (shell=False, capture=True) 2021-01-02 00:00:22,000 - util.py[DEBUG]: Running command ['systemd-detect-virt', '--quiet', '--container'] with allowed return codes  (shell=False, capture=True) 2021-01-02 00:00:30,000 - handlers.py[DEBUG]: finish: task 2, took 20 seconds 2021-01-02 00:05:00,000 - handlers.py[DEBUG]: finish: task 3, took 280 seconds
1. Line wrap
Sometimes, log lines are longer than the width of your terminal. You can use
:set wrap to enable line wrap,
:set nowrap to disable it, or
:set wrap! to toggle.
You can search within a file using
/. What makes it more interesting though is that search supports regular expression - just make sure to escape special characters.
The global command,
:g, comes very handy when dealing with verbose or repetitive logs. I use it most often to filter out unneeded log lines:
Or if you want to do the search and filter in one step, put the query between the slashes, e.g.
But be careful to not save! You can run
vim -R to start vim in read-only mode. To save the filtered results, copy them into a new buffer:
Breakdown of commands in the previous gif:
ggto jump to top of the file
Vto visually select entire lines
Gto jump to bottom of the file while in visual mode, thereby selecting all lines
yto copy the selected text
:tabeto open a new blank buffer
pto paste the copied text
gtto navigate to the next (i.e. first) tab
uuto undo the 2
If a lot of information is logged in a delimited format, you can use vim’s search and replace feature to replace the delimiters with new lines, for ease of reading:
Deconstructing the syntax:
%means to perform substitute on all lines (instead of only the current line)
- the “search” and “replace” portions are surrounded by slashes (in the gif, we left “search” blank because we already had search results)
\r(carriage return) represents new line in vim
gmeans to substitute all occurrences in a line (instead of only the first occurrence)
Discuss this post on HN.