Updated article from 2019.
When debugging any complex application, log files are your best friends. However, navigating through thousands of log entries can quickly become overwhelming. This is where lnav (Log Navigator) comes in. This powerful command-line utility transforms the log analysis experience, making it easier to identify problems and troubleshoot issues in various applications and systems.
In this comprehensive guide, we’ll explore how to use lnav for efficient log file debugging, from basic usage to advanced log analysis techniques. We’ll use WordPress as one example, but the techniques apply to any application that generates log files.
What is lnav?
Lnav is a sophisticated log file navigator designed to enhance the way developers and system administrators interact with log files. Unlike traditional tools like tail
, grep
, or less
, lnav offers a feature-rich environment specifically designed for log analysis.
Key Features:
- Consolidated View: View multiple log files simultaneously in a single, chronologically ordered display
- Syntax Highlighting: Automatic colorization of log levels, timestamps, and other elements
- Real-time Monitoring: Watch logs update in real-time with automatic refreshing
- Powerful Filtering: Filter log entries using regular expressions
- SQL Queries: Run SQL queries against your logs to extract specific information
- Timestamps Navigation: Easily jump to specific time periods
- Customizable Formats: Support for custom log formats, including WordPress
- Bookmarking: Mark important log entries for later reference
Installing lnav
Before diving into WordPress debugging, let’s get lnav installed on your system.
Linux
Debian/Ubuntu:
1 2 3 4 |
sudo apt update sudo apt install lnav |
Fedora:
1 2 3 |
sudo dnf install lnav |
CentOS/RHEL:
1 2 3 |
sudo yum install lnav |
Arch Linux:
1 2 3 |
sudo pacman -S lnav |
macOS
Using Homebrew:
1 2 3 |
brew install lnav |
Windows
Using Chocolatey:
1 2 3 |
choco install lnav |
Alternatively, download binaries from the lnav GitHub releases page.
Configuring Applications for Logging
Before using lnav, you need to ensure your applications are configured to generate detailed logs. Here’s an example of setting up WordPress for logging, which demonstrates a typical configuration process:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// Enable debugging define('WP_DEBUG', true); // Enable debug logging to wp-content/debug.log define('WP_DEBUG_LOG', true); // Display errors on page (set to false in production) define('WP_DEBUG_DISPLAY', false); // For development: Disable JavaScript concatenation define('SCRIPT_DEBUG', true); |
This WordPress configuration creates a debug.log
file that captures PHP errors, warnings, and notices. Other applications will have their own logging configuration methods, but the general principle is to enable detailed logging to files that lnav can read.
Other Common Logging Configurations
Different applications and systems have their own logging mechanisms:
- Apache/Nginx: These web servers typically log to access.log and error.log files
- MySQL/MariaDB: Database logs can be configured to capture slow queries and errors
- System logs: Linux systems log to /var/log/syslog or through journald
- Application frameworks: Most frameworks like Laravel, Django, and Spring have configurable logging systems
Basic lnav Usage
Let’s start with the basics of using lnav to analyze WordPress logs.
Opening Log Files
To open any log file with lnav, simply run:
1 2 3 |
lnav /path/to/logfile.log |
One of lnav’s greatest strengths is the ability to monitor multiple log files simultaneously:
1 2 3 |
lnav /var/log/apache2/access.log /var/log/apache2/error.log /var/log/mysql/error.log |
For example, with a WordPress site, you might monitor:
1 2 3 |
lnav /path/to/wp-content/debug.log /var/log/apache2/error.log /var/log/php/errors.log |
This combined view helps you correlate events across different components of your application stack, making it easier to track issues that span multiple systems.
Essential lnav Commands
Once inside lnav, you’ll need these basic commands:
Key | Action |
---|---|
? | View help |
q | Quit |
e | Examine current line in text editor |
i | Enter interactive command mode |
/ | Search forwards |
n | Move to next search hit |
N | Move to previous search hit |
f | Filter lines using a regular expression |
F | Clear active filters |
r | Toggle between relative/absolute timestamps |
; | Enter SQL query mode |
Practical Examples for Log Debugging
Let’s look at some practical examples of using lnav for various debugging scenarios.
Example 1: Filtering Specific Components
If you suspect a particular component is causing issues, you can filter the logs to show only relevant entries:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# Start lnav with your log files lnav /path/to/application.log # Once inside lnav, press 'f' and type a filter: f database # Filter for a specific component f authentication # In a WordPress context, filter for a specific plugin: f wp-content/plugins/specific-plugin-name # Clear filter by pressing 'F' |
Example 2: Using SQL Queries for Log Analysis
Lnav’s SQL capabilities are extremely powerful for extracting insights from your logs:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# Press ';' to enter SQL mode, then type queries like: # Count errors by type ;SELECT log_level, COUNT(*) FROM access_log GROUP BY log_level # Find the most frequent errors ;SELECT message, COUNT(*) AS count FROM error_log GROUP BY message ORDER BY count DESC LIMIT 10 # Find events during a specific time period ;SELECT * FROM syslog WHERE log_time BETWEEN '2023-04-01 00:00:00' AND '2023-04-01 23:59:59' # For WordPress logs, you could look for errors in specific plugin files: ;SELECT * FROM debug_log WHERE file_path LIKE '%plugin-name%' |
Example 3: Advanced Filtering Techniques
You can use regular expressions for more sophisticated filtering:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# Multiple conditions with regex f (ERROR|FATAL) # Finding database errors f database error # Finding specific error types (PHP example) f PHP (Fatal|Parse) error # Finding errors after a certain time f '2023-04-01 14:00:00' # For WordPress, finding specific hooks: f 'apply_filters|do_action' |
Example 4: Monitoring During Critical Operations
System updates, deployments, and other critical operations can be risky. Set up monitoring before performing them:
1 2 3 4 5 6 7 8 9 10 11 |
# Set up monitoring before performing operations lnav /var/log/syslog /var/log/auth.log /var/log/application.log # For a web application like WordPress: lnav /path/to/wp-content/debug.log /var/log/apache2/error.log # Keep lnav running during the operation # Press 'r' to toggle between relative and absolute timestamps # Press 'p' to pause automatic tailing if needed |
Customizing lnav for Different Log Formats
Most applications produce logs in specific formats. You can enhance lnav’s capabilities by creating custom format definitions for your applications.
Example: WordPress Custom Format
Here’s an example of creating a custom format for WordPress logs. Create or edit ~/.lnav/formats/wordpress.json
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
{ "wordpress_debug": { "title": "WordPress Debug Log", "description": "Format for WordPress debug.log", "url": "https://developer.wordpress.org/", "regex": { "standard": { "pattern": "\\[(\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2})\\] PHP (\\w+): (.+) in (.+) on line (\\d+)" } }, "timestamp-format": [ "%Y-%m-%d %H:%M:%S" ], "level-field": "level", "level": { "error": "Fatal error|Parse error", "warning": "Warning|Notice", "info": "Deprecated" }, "value": { "timestamp": { "kind": "string", "identifier": true }, "level": { "kind": "string", "identifier": true }, "message": { "kind": "string" }, "file": { "kind": "string" }, "line": { "kind": "integer" } }, "sample": [ "[2023-04-01 12:34:56] PHP Warning: file_get_contents(): failed to open stream in /var/www/html/wp-content/plugins/example/file.php on line 123" ] } } |
Custom format definitions like this help lnav properly parse and display application-specific logs, enabling better filtering and SQL queries.
Creating Custom Formats for Other Applications
The same approach can be used for any application with a consistent log format. The key elements to define are:
- The regex pattern that matches log lines
- The timestamp format for proper time-based navigation
- Log levels for proper coloring and filtering
- Named capturing groups for SQL access
Common Error Patterns in Different Applications
Understanding common error patterns helps you create effective filters in lnav. Here are some examples from various applications:
PHP/WordPress Errors
- Undefined Variables:
1 2 3 |
PHP Notice: Undefined variable: variable_name |
- Memory Exhaustion:
1 2 3 |
PHP Fatal error: Allowed memory size of X bytes exhausted |
Web Server Errors
- Apache 404 Errors:
1 2 3 |
GET /missing-page HTTP/1.1" 404 |
- Permission Issues:
1 2 3 |
AH00035: access to /protected denied (filesystem path '/var/www/html/protected') |
Database Errors
- Connection Failures:
1 2 3 |
ERROR 1040 (HY000): Too many connections |
- Query Errors:
1 2 3 |
ERROR 1054 (42S22): Unknown column in field list |
Advanced Debugging Workflows
Here are some advanced workflows for debugging application issues with lnav:
Workflow 1: Tracing a User Experience Issue
- Enable detailed logging in your application
- Reproduce the issue while monitoring logs across multiple systems:
1 2 3 |
lnav /var/log/application.log /var/log/web-server/access.log /var/log/web-server/error.log |
Thoughts
Lnav transforms the often tedious task of log analysis into a more efficient and insightful process. For WordPress developers and administrators, it provides a powerful way to debug issues, monitor performance, and understand the inner workings of their sites.
By mastering lnav’s filtering, SQL capabilities, and navigation features, you can dramatically reduce the time needed to troubleshoot problems and gain deeper insights into your WordPress installation’s behavior.
Whether you’re dealing with plugin conflicts, performance issues, or mysterious errors, lnav equips you with the tools needed to cut through the noise and find the answers hidden in your logs.