Merv-Logs — live console & MervLogger
Introduction
Merv-Logs is a live log viewer for Merv-Local runs. Call
MervLogger from Java (merv-client-api) or
JavaScript / TypeScript (merv-client). Lines go to the console (optional) and to
{reportRoot}/log/ as rolling NDJSON. Open Merv-Logs from the dashboard to filter,
search, and scroll history.
- How to log with
info/debug/warn/error(and named loggers) - How Java and npm packages write the same
log/*.ndjsonlayout - Which properties control level and file output
- How to open
merv-logs.htmlfrom the local dashboard - How
doctor setup-log,set console, andunset consolescaffold logging-only projects
io.github.techelliiptica:merv-client-api (Maven).
JS/TS — npm install merv-client (4.0.22+).
Both write under merv.report.folder (default ./merv-reports/).
Quick start
Add the Maven dependency, then:
import org.teche.merv.client.logging.MervLogger;
import org.teche.merv.client.logging.MervLoggerFactory;
MervLogger log = MervLoggerFactory.getLogger(MyClass.class);
log.info("Starting checks");
log.debug("Detail only when level is DEBUG");
log.warn("Retrying request…");
log.info("Cart total={}", 42);
Place merv.properties at the project root with
merv.local=true and merv.report.folder=./merv-reports/.
After a Cucumber / TestNG / JUnit run (or any code that calls MervReportsIndexHtmlWriter.write),
open merv-reports/index.html and click Merv-Logs, or open
merv-reports/merv-logs.html with a local static server (Live Server can load
log/manifest.json + NDJSON).
npm install merv-client
npx merv-client doctor setup-log
import { MervLogger, console } from 'merv-client';
MervLogger.info('Starting checks');
console.log('Also mirrors to Merv-Logs');
MervLogger.debug('Detail only when level is DEBUG');
MervLogger.warn('Retrying request…');
const log = MervLogger.getLogger('Checkout');
log.info('Cart total={}', 42);
node my-check.js
npx merv show-logs
doctor setup-log adds only Merv-Logs files (merv.properties, scripts) —
no jsconfig.json or custom-report sample.
Use npx merv-client doctor set console to wire
import { console } from 'merv-client' (or require) into files that already call
console.log; doctor unset console removes those doctor-managed lines.
Prefer npx merv show-logs for live polling
(http://127.0.0.1:6174/merv-logs.html). Live Server alone does not expose
/api/logs/query, but can still load static log/*.ndjson via the page fallback.
Doctor commands (JS/TS)
Use doctor when you want Merv-Logs without a full custom-report scaffold. These commands only touch logging-related files — not Playwright or Cucumber adapters.
| Command | Purpose |
|---|---|
npx merv-client doctor setup-log |
Merv-Logs only: merv.properties, show-logs / show-report scripts,
merv-client dependency. No jsconfig.json or custom-report sample.
|
npx merv-client doctor set console |
Scan project sources; on files that call console.*, add (or toggle off) a doctor-managed
merv-client console import so lines mirror to Merv-Logs.
|
npx merv-client doctor unset console |
Remove only doctor-managed console imports (lines marked
// merv-doctor-console). Manual imports are left alone.
|
npx merv-client doctor setup |
Full core setup — includes setup-log pieces plus
jsconfig.json / tsconfig.json and a sample scripts/custom-report.*.
|
doctor setup-log
Run from your project root (where package.json lives):
npx merv-client doctor setup-log
npm install
npx merv show-logs
Creates or heals:
merv.properties—merv.report.folder,merv.logger.file,merv.logger.levelpackage.jsonscripts —show-logs,show-reportmerv-clientindependencieswhen missing
Does not create: jsconfig.json, tsconfig.json, scripts/custom-report.mjs.
--force rewrites merv.properties;
--suite-title <name> sets merv.regression_suite on a fresh file.
doctor set console / unset console
Node can use import { console } from 'merv-client' (or require) so every
console.log / info / warn / error / debug / trace
also writes to Merv-Logs. Doctor can wire that import across your app automatically.
npx merv-client doctor set console
# run again to toggle off (remove doctor lines)
npx merv-client doctor set console
# remove all doctor-managed imports
npx merv-client doctor unset console
What gets inserted (marked with // merv-doctor-console so unset is safe):
ESM — Node backend / scripts
import { console } from 'merv-client'; // merv-doctor-console
ESM — Vite / React (browser)
import { console } from 'merv-client/browser'; // merv-doctor-console
CommonJS (.cjs or require-style projects)
const { console } = require('merv-client'); // merv-doctor-console
Behavior:
- Scans
.js,.jsx,.ts,.tsx,.mjs,.cjsunder the project - Skips
node_modules,dist,build,merv-reports, and similar folders set consoleadds the import when a file usesconsole.*and does not already have a doctor lineset consoleremoves the doctor import when you run it again on the same file (toggle)unset consoleremoves every line tagged// merv-doctor-console(bothmerv-clientandmerv-client/browser)- Vite / React projects:
.jsx/.tsxand files withimport.metagetmerv-client/browser; Node backends getmerv-client - Files with a hand-written
merv-clientconsole import (no doctor marker) are skipped
import { console } from 'merv-client/browser'
(with VITE_MERV_LOG_SERVER in .env).
Node backends and scripts still use merv-client.
Typical workflow
npx merv-client doctor setup-log
npm install
npx merv-client doctor set console
node src/server.js
npx merv show-logs
MervLogger API
Factory API (SLF4J-style). Package:
org.teche.merv.client.logging.
| API | Purpose |
|---|---|
MervLoggerFactory.getLogger(Class) |
Named logger (recommended). |
MervLoggerFactory.getLogger(String) |
Logger by name string. |
log.info / debug / warn / error / trace |
Levels; overloads take {} args or a Throwable. |
MervLoggerFactory.setGlobalLogLevel(LogLevel.DEBUG) |
Runtime minimum level. |
MervLogContext.setSuite / setTestcase |
Optional labels on NDJSON lines (see below). |
log.info("User {} logged in", username);
log.error("Request failed", exception);
When SLF4J is on the classpath and merv.logger.use.slf4j=true, console routing uses SLF4J;
NDJSON file lines are still written when merv.logger.file=true.
Import from merv-client (same package as Playwright/Cucumber reporters and MervReport).
| API | Purpose |
|---|---|
MervLogger.info(msg, …) |
Default level for progress and outcomes. |
MervLogger.debug(msg, …) |
Verbose detail (hidden when level is INFO or higher). |
MervLogger.warn / error / trace |
Standard severity levels with color when TTY. |
MervLogger.getLogger('Name') |
Named logger; name column in Merv-Logs. |
MervLogger.setLevel('DEBUG') |
Runtime level (overrides file/env until process exit). |
MervLogger.configure({ … }) |
Color, prefix, timestamps, file/console sinks. |
import { console } from 'merv-client' |
Drop-in replacement for global console — same API, mirrors to Merv-Logs.
Wire automatically with doctor set console (Node).
|
Use {} placeholders. Optional last-arg meta (e.g. Playwright screenshot) shows thumbnails in Merv-Logs:
MervLogger.info('After click', { screenshot: await page.screenshot() });
Configuration
Shared keys (project merv.properties and/or classpath
mervlogger.properties on Java):
| Property | Description |
|---|---|
merv.logger.level |
Minimum level for console and file (default INFO). Values: TRACE, DEBUG, INFO, WARN, ERROR. |
merv.logger.file |
true (default) — append NDJSON under {reportRoot}/log/ in ~5-minute UTC files.
Set false for console/SLF4J only (unless merv.log.server is set).
|
merv.log.server |
Optional. Base URL of another project’s running report server
(e.g. http://127.0.0.1:6174). When set, each log line is also POSTed to
/api/logs/ingest on that server so you can open one Merv-Logs page
and see combined output from multiple projects. Env override: MERV_LOG_SERVER.
|
merv.log.source |
Project name stamped on each line when forwarding to a shared server
(shown in Merv-Logs). If omitted, JS uses package.json name
(or folder name); Java uses the project folder name.
Env override: MERV_LOG_SOURCE.
|
merv.report.folder |
Report root (e.g. ./merv-reports/) — log files and merv-logs.html live here. |
merv.logger.use.slf4j (Java) |
Route console output through SLF4J when available (default true). |
MERV_LOG_LEVEL (JS) |
Env override for level (also MERV_LOGGER_LEVEL). |
merv.local=true
merv.report.folder=./merv-reports/
merv.logger.level=INFO
merv.logger.file=true
# Optional: send this project's logs to another show-report (combined view)
# merv.log.server=http://127.0.0.1:6174
# merv.log.source=checkout-api
merv.log.server, Log server URL popup, npx merv show-logs).
Merv-Logs UI
- Live tail — new lines while your process runs (best with
npx merv show-report) - Load older — scroll up / load previous chunks
- Filter — search text, level, logger name
- Timezone — display timestamps in local or selected zone
- Static fallback — without the Node API, the page can still read
log/manifest.json+ NDJSON (Java dashboard / Live Server)
On disk:
{merv.report.folder}/log/merv-….ndjson,
log/manifest.json,
merv-logs.html.
Java refreshes the HTML page when the local index is rewritten; JS does the same via show-report / report writers.
With frameworks
Java
Use MervLoggerFactory.getLogger(…) from step definitions, listeners, or helpers alongside
Cucumber,
TestNG, or
JUnit 5.
No extra dependency beyond merv-client-api.
JavaScript / TypeScript
Install merv-client (plus playwright/cucumber packages as usual). Call
MervLogger from hooks, fixtures, or plugin helpers.
See
Playwright and
Cucumber-js.
Suite / testcase labels (Java)
Attach suite and testcase names to NDJSON lines for filtering in Merv-Logs:
import org.teche.merv.client.logging.MervLogContext;
MervLogContext.setSuite("Smoke Suite");
MervLogContext.setTestcase("Login works");
log.info("Navigating to home");
MervLogContext.clear();
On JS, optional { suite, testcase } meta on a log call (or reporter context) fills the same fields.
Hand-built MervReport sessions can also attach logger lines to the active testcase — see
Custom report.
Troubleshooting
| Issue | What to check |
|---|---|
| Merv-Logs page is empty |
Confirm MervLogger ran and merv.logger.file is not false.
Check {reportRoot}/log/ for merv-*.ndjson. For live poll on JS, use
npx merv show-report.
|
| DEBUG lines missing |
Set merv.logger.level=DEBUG, or Java
MervLoggerFactory.setGlobalLogLevel(LogLevel.DEBUG), or JS
MervLogger.setLevel('DEBUG') / MERV_LOG_LEVEL=DEBUG.
|
| Wrong report folder |
Run from the project root that contains merv.properties.
Java uses user.dir; JS resolves via MERV_PROJECT_ROOT / cwd.
|
No merv-logs.html (Java) |
Open after a local run that refreshes the dashboard index, or call
MervLogSink.ensureMervLogsPage(reportRoot).
|
What’s next
- Centralized logs — combine several projects on one Merv-Logs page
- Cucumber (Java) / TestNG / JUnit 5
- Merv-Tutor — JS/TS step debugger
- Custom report
- Open the dashboard
MERV