A Rust library for parsing and analysing MySQL slow query logs. This library anonymises SQL queries by replacing literal values with placeholders, making it easy to identify and group similar queries for performance analysis.
- Parse MySQL slow query log files
- Anonymise queries by replacing literals with placeholders
- Extract detailed query statistics (query time, lock time, rows examined, etc.)
- Generate fingerprints for normalised queries
cargo add slowloguse slowlog::process_slow_log_file;
fn main() {
process_slow_log_file("path/to/slow.log", |query| {
println!("Original: {}", query.query);
println!("Formatted: {}", query.formatted);
println!("Fingerprint: {}", query.fingerprint);
println!("Query time: {:.2}s", query.stats.query_time);
println!("Rows examined: {}", query.stats.rows_examined);
}).unwrap();
}use slowlog::process_slow_log_reader;
use std::fs::File;
use std::io::BufReader;
fn main() {
let file = File::open("slow.log").unwrap();
let reader = BufReader::new(file);
process_slow_log_reader(reader, |query| {
println!("{:?}", query);
}).unwrap();
}The library replaces all literal values with ? placeholders:
| Original Query | Anonymised Query |
|---|---|
SELECT * FROM users WHERE id = 123 |
SELECT * FROM users WHERE id = ? |
UPDATE users SET name = 'John' WHERE age > 18 |
UPDATE users SET name = ? WHERE age > ? |
INSERT INTO users (name, age) VALUES ('Alice', 25) |
INSERT INTO users (name, age) VALUES (?, ?) |
DELETE FROM users WHERE age BETWEEN 18 AND 65 |
DELETE FROM users WHERE age BETWEEN ? AND ? |
The library extracts the following statistics from slow log entries:
- user: Database user who executed the query
- host: Host from which the query was executed
- time: Timestamp when the query was executed
- query_time: Total query execution time in seconds
- lock_time: Time spent waiting for locks in seconds
- rows_sent: Number of rows returned by the query
- rows_examined: Number of rows examined during query execution
Processes a slow log file and calls the callback for each query found.
Parameters:
path: Path to the slow log filequery_callback: Function called for each parsed query
Example:
use slowlog::process_slow_log_file;
process_slow_log_file("slow.log", |query| {
println!("{:?}", query);
}).unwrap();Processes slow log data from any BufRead source.
Parameters:
reader: Any type implementingBufReadquery_callback: Function called for each parsed query
Example:
use slowlog::process_slow_log_reader;
use std::io::BufReader;
let reader = BufReader::new(file);
process_slow_log_reader(reader, |query| {
println!("{:?}", query);
}).unwrap();pub struct Query {
pub query: String, // Original query
pub formatted: String, // Anonymised query with placeholders
pub fingerprint: String, // SHA1 hash of formatted query
pub stats: QueryStats, // Query execution statistics
}pub struct QueryStats {
pub user: String, // Database user
pub host: String, // Client host
pub time: DateTime<Utc>, // Execution timestamp
pub rows_examined: u64, // Rows scanned
pub rows_sent: u64, // Rows returned
pub query_time: f64, // Execution time (seconds)
pub lock_time: f64, // Lock wait time (seconds)
}pub enum QueryError {
ParseError(String), // SQL parsing failed
InvalidQuery, // No valid SQL statement found
}- Basic SELECT, INSERT, UPDATE, DELETE statements
- WHERE clauses with operators (=, !=, <>, >, <, >=, <=)
- IN and NOT IN lists
- BETWEEN conditions
- LIKE and NOT LIKE patterns
- Subqueries
- CASE expressions
- SQL functions (MAX, MIN, CEIL, FLOOR, etc.)
- GROUPING operations
- Binary and unary operations