Watchlog DocsWatchlog Docs
Home
Get Started
Gen AI Monitoring
Integrations
Log Watchlist
Home
Get Started
Gen AI Monitoring
Integrations
Log Watchlist
  • All Integrations
  • NGINX

    • Nginx Integration
    • Connect NGINX to Watchlog
    • Docker
    • Windows
    • Kubernetes
    • Source Code
  • IIS

    • IIS Integration
    • Ubuntu
    • Docker Container
    • Windows
    • Kubernetes
    • Source Code
  • REDIS

    • Redis Integration
    • Ubuntu
    • Docker Container
    • Windows
    • Kubernetes
    • Source Code
  • POSTGRESQL

    • PostgreSQL Integration
    • Ubuntu
    • Docker Container
    • Windows
    • Kubernetes
    • Source Code
  • MONGODB

    • MongoDB Integration
    • Ubuntu
    • Docker Container
    • Windows
    • Kubernetes
    • Source Code
  • MYSQL

    • MySQL Integration
    • Ubuntu
    • Docker Container
    • Windows
    • Kubernetes
    • Source Code
  • PM2

    • PM2 Integration
    • Ubuntu
    • Docker Container
    • Windows
    • Kubernetes
    • Source Code
  • DOCKER

    • Docker Integration
    • Ubuntu
    • Docker Container
    • Windows
    • Kubernetes
    • Source Code
  • GITLAB

    • Gitlab Integration
    • Ubuntu
    • Docker
    • Windows
    • Kubernetes
    • Source
  • ELASTICSEARCH

    • Elasticsearch Integration
    • Ubuntu
    • Docker Container
    • Windows
    • Kubernetes
    • Source Code

Source Code

  1. Go to your cloned repository:
    cd /path/to/watchlog-agent
    vim integration.json
    
  2. Locate the MySQL config:

{ "service": "mysql", "monitor": false, "host": "localhost", "port": "3306", "username": "root", "password": "", "database": [] }

3. Set `"monitor"` to `true` and fill in the credentials:
```diff
-  "monitor": false
+  "monitor": true

database is only read by the legacy collector. The advanced collector discovers every schema itself, so leaving it [] is correct for new setups. 4. Restart the agent:

pm2 restart watchlog-agent

Run the collector directly

Useful for checking what a given server actually exposes without waiting for the 60s tick:

node -e "
const list = require('./integration.json');
const cfg = list.find(i => i.service === 'mysql');
require('./app/integrations/mysql/index').collect(cfg, (err, res) => {
  if (err) return console.error('failed:', err.message);
  const a = res.advanced;
  console.log('version      :', a.server.version, '(' + a.server.flavour + ')');
  console.log('capabilities :', JSON.stringify(a.capabilities));
  console.log('notes        :', JSON.stringify(a.capabilityNotes || []));
  console.log('digests      :', (a.queries || []).length);
  console.log('tables       :', (a.tables || []).length);
});
"

The capabilityNotes array is the useful part when a tab is missing — it names the exact reason, e.g. performance_schema is disabled; query, index and lock detail are unavailable.

Running the tests

The MySQL parsers, query normalizer and collector derivations are covered by the agent's test suite, which needs no live server:

npm test

Fixtures deliberately cover what a live server cannot show you on demand: a MariaDB row shape, a 5.7 lock table, a counter reset after restart, and a permission-denied path.

Development notes

  • The advanced collector is app/integrations/mysql/index.js; the legacy one is app/integrations/mysql.js beside it. Require the advanced one by full path.
  • performance_schema timings are picoseconds. Divide by 1e9 for milliseconds. This is the opposite of PostgreSQL, whose pg_stat_statements timings are already milliseconds.
  • Queries are ranked by impact — executions in the interval × interval mean latency — not by average latency. Sorting by average hides the 2 ms query running 50 000 times.
  • An unused index is reads === 0, not reads === 0 && writes === 0. The second form excludes every index on a write-heavy table. UNIQUE and PRIMARY are protected via information_schema.statistics and are never removal candidates.
  • CARDINALITY is an InfluxQL reserved word and appears naturally in index queries — every alias in mysqlAdvanced.js must stay quoted, or the endpoint returns a runtime-only 500.
  • Version gates live in parsers.js: supportsDataLocks (MySQL 8+, never MariaDB) and supportsReplicaTerminology (MySQL 8.0.22+). Nothing downstream branches on version — the queries alias everything to one stable shape.
  • Never log query text from a driver error. Driver errors echo the failing statement, and statements carry literals.
Last Updated:: 8/13/26, 12:54 AM
Contributors: mohammad
Prev
Kubernetes