Ubuntu
1. Create a monitoring user
CREATE USER 'watchlog_monitor'@'%' IDENTIFIED BY 'your_password';
GRANT PROCESS, REPLICATION CLIENT ON *.* TO 'watchlog_monitor'@'%';
GRANT SELECT ON performance_schema.* TO 'watchlog_monitor'@'%';
GRANT SELECT ON information_schema.* TO 'watchlog_monitor'@'%';
FLUSH PRIVILEGES;
If the agent connects over the loopback interface, use @'localhost' instead of @'%' — MySQL treats them as different accounts, and a mismatch is the most common Access denied cause.
2. Confirm performance_schema is on
SHOW VARIABLES LIKE 'performance_schema';
ON unlocks the Queries, Indexes and Locks tabs. If it is OFF, add this to /etc/mysql/mysql.conf.d/mysqld.cnf and restart:
[mysqld]
performance_schema = ON
The integration works without it — you keep connections, InnoDB, schema sizes and replication — but query-level analysis needs it.
3. Configure the agent
- Navigate to the agent config directory:
cd /opt/watchlog-agent sudo vim integration.json - Locate the MySQL object:
{ "service": "mysql", "monitor": false, "host": "localhost", "port": "3306", "username": "", "password": "", "database": [] }
3. Change `"monitor"` from `false` to `true`:
```diff
- "monitor": false
+ "monitor": true
Populate the fields:
host,port,username,passworddatabase: only the legacy collector needs this list. The advanced collector discovers every schema itself, so you can leave it as[].
{ "service": "mysql", "monitor": true, "host": "localhost", "port": "3306", "username": "watchlog_monitor", "password": "your_password", "database": [] }Save the file and reload the agent:
sudo pm2 reload watchlog-agent
Verify
Check the connection and the three capability probes the agent makes:
mysql -h 127.0.0.1 -u watchlog_monitor -p'your_password' -e "
SELECT VERSION() AS version;
SELECT @@performance_schema AS performance_schema;
SELECT COUNT(*) AS digests FROM performance_schema.events_statements_summary_by_digest;
SELECT COUNT(*) AS index_stats FROM performance_schema.table_io_waits_summary_by_index_usage;
"
Each query that succeeds corresponds to a tab that will appear. One that fails with Access denied or Table doesn't exist disables that section only.
TLS
Set "ssl": true:
{
"service": "mysql",
"monitor": true,
"host": "mysql.internal",
"port": "3306",
"username": "watchlog_monitor",
"password": "your_password",
"database": [],
"ssl": true
}
To require it server-side for this account:
ALTER USER 'watchlog_monitor'@'%' REQUIRE SSL;
MariaDB
The same configuration works. The agent detects MariaDB from the version string and adjusts:
- Lock waits come from
information_schema.innodb_lock_waitsrather thanperformance_schema.data_lock_waits, which MariaDB never adopted. - Replication uses the original
SHOW SLAVE STATUSterminology, which MariaDB kept. Innodb_deadlocksis a MariaDB status variable with no MySQL equivalent — Watchlog reads it where present.
Slow queries
There is nothing to enable. Watchlog reads performance_schema.events_statements_summary_by_digest, not the slow query log file — so you get query-level detail without the file, without a threshold to configure, and without the write cost.
slowQuery.thresholdMs only decides what the dashboard labels slow:
"slowQuery": {
"thresholdMs": 100
}
MySQL normalizes the digest text itself, so literals are already ? before Watchlog sees them. Parameter values never leave your host.
