Features

On this page

Features

BxLens has two parts. The bar is a snapshot of one request, shown to developers on the page itself. The console is a password protected page for one running server. Clusters, long history and alerting belong to BX Insights, not here.

Free means no BoxLang+ subscription is needed. Plus means a BoxLang+ license or trial. The split is the current state and may change, see Licensing.

The debug bar

The bar is off by default and only shows to allowed callers (loopback by default). It says what happened in this request and nothing more. Analysis lives in the console.

FeatureWhat it doesTier
StripStatus, total time, query count and time, exception count, request id, a Console button, theme toggle. Red only for a 5xx or an uncaught exceptionFree
TimelineOne waterfall of templates, functions (opt in), queries, HTTP calls and transactions, nested the way they ran. Zoom, pan, filter, search with /, click a span for detail and an open in editor linkFree
Interrupted spansA span whose closing event never fired ends at the exception (or last activity) and is marked interrupted, with its own markerFree
QueriesEvery statement with SQL, rows, time, datasource and the line that ran it. Bound values only when includeParams is on. ORM statements carry an ORM labelFree
ExceptionsCaught and uncaught, with BoxLang location and the Java stack. The panel can open itself on a caught exceptionFree
HTTPOutgoing HTTP calls with status, size and timeFree
Messages and TimersWhat your code sends with lensMessage(), lensDump(), lensMeasure(), lensStart() and lensStop()Free
RequestRequest and response headers, status and the request costFree, cost is Plus
Request costCPU time and memory allocated by the request threadPlus
ScopesRedacted copy of url and form (others opt in). Off by default because it costs timeFree
BIFsCalls, total, average and slowest time and errors per built in function. Off by defaultFree
RuntimeA cached snapshot: BoxLang and Java versions, OS, uptime, heap, server and app name, cache names, and the main boxlang.json settings. Secrets hiddenFree
Your panelsApplications and modules add panels with lensPanel() or the onLensCollect interception pointFree
Bar designerShow, hide and reorder the bar tabs from the consoleLook Free, save Plus
Request idEvery tracked request gets a short id, sent as X-BxLens-Id, shown in the bar and the console, and set as request.bxlens.id and lensRequestId()Free

How the bar stays light: the page gets a block of about 1 KB. The CSS, JavaScript and icons are separate files, hashed and cached by the browser. The bar data is built only when the page renders for an allowed caller.

The console

One page at /~bxlens/index.bxm, with its own password, an optional second viewer password, lockout after failed logins, CSRF tokens and a strict content security policy. It makes no request to any other site.

Inspect

PageWhat it doesTier
OverviewRequests, errors, p95 and what needs attentionFree
RequestsEvery request in memory, including JSON and SSE. Click one for its timeline, issues (N+1, slow query, slow template, failed HTTP, security notes), headers and cost. Copy as JSON or cURL. Unfinished and interrupted requests are markedFree, last 25 kept. Plus keeps the configured size
In flightRequests running now, longest first, with a live stack of what each one is doingFree
ErrorsErrors grouped by cause with counts, where, and a stack and request context per sample. Redacted prompt copy for an AI chatFree in memory, saved to disk with Plus
ReportsTotals, error rate, p95 and p99, status codes, busiest and slowest URLs, a minute seriesFree for 60 minutes, longer and saved with Plus
QueriesStatements ranked by slowest, total time, count and failures, across every requestFree
Ask LensAsk about this server in plain words. Copy prompt, Ask ChatGPT and Ask Claude buttons are free. With BoxLang+ it is the full page of the LensyFree copy, Plus assistant

Runtime

PageWhat it doesTier
ExecutorsPool, thread and queue use against thresholds, a 60 second chart, health notes, and the tasks bound to each scheduler executorFree
TasksScheduled tasks with status, schedule, next and last run, runs and failures. Run now, pause, resume, reloadView Free, actions Plus
DatasourcesPool size, active and idle connections, waits and timeouts. Test connectionFree
ORMOpt in integration with bx-orm. Event totals, flushes, failures and Hibernate statistics, with a switch to turn statistics onPage is Plus, the ORM SQL in Queries is Free
MailMessages sent through bx-mail with a locked preview, delivery steps, servers, the spool and its bouncesCounters and ten messages Free, viewer and queue Plus
CachesHit rate and counts per cache, a capped key list. Read a value, evict, reap, clearStatistics Free, actions Plus
LogsEvery file in the logs directory. Search, level filter, live tailFree (admin), download Plus
ModulesLoaded modules, versions and settings, plus the Integrations section with a switch per integrationFree
EnvironmentThe effective configuration, JVM arguments, variables and properties, secrets hidden. Diagnostic bundleFree (admin), bundle Plus
ConfigurationThe effective BoxLang settings by area with the value and its source (default, boxlang.json or environment variable), and a filter boxFree
SystemCPU, heap, memory pools, GC, disks and runtime details. Run GC. Deadlock detection. Heap dumpFree, heap dump Plus and off until console.allowHeapDump
ThreadsEvery thread with state, CPU and stack. BoxLang frames highlighted. Copy or download a thread dumpFree (admin)

Config

PageWhat it doesTier
Bar designerChoose and order the bar tabsSave Plus
AIStatus, requirements, live settings and a connection test for Lensy. The key is never typed in: an environment variable name or a bxsecret: valueView Free, change Plus
SettingsChange thresholds, collectors, interface and limits live, with a reset, saved to a small overrides file. Passwords, access rules, console.*, store.* and the AI key stay in boxlang.jsonFree

Lensy

A chat in a drawer on every console page (and the full page of Ask Lens) that answers by calling tools: overview, requests, errors, queries, executors with concrete pool recommendations, threads, blocked threads and deadlocks, garbage collection pressure, datasources, logs, database metadata and a diagnose health sweep, plus a search of these docs. Actions (tasks, caches, run GC, integrations, a live setting) wait for an Approve click. Default model: Ollama on this machine. Admins can also let it ask MCP servers, such as the Ortus documentation, which are all off until turned on. BoxLang+. See the AI page, the tool list and the threat model.

Roles and control

  • Admin and viewer roles. A viewer sees overview, requests, in flight, queries, errors, reports, executors, tasks, datasources, cache statistics and modules. Logs, thread stacks, environment, system details and a few sensitive setting values are admin only.
  • Read only mode refuses every change from the console.
  • Audit log (bxlens-audit.log) records every change, download and denied attempt. No secrets.
  • Access rules per surface: loopback, an IP list, allowed hosts (DNS rebinding guard), a required header, and proxy header trust only from trusted peers.

Server identity

Multi server observability is BoxLang+. Free shows one server only.

Every record says which machine produced it, so the data of many servers can end up in one database and still be told apart. This is built in and free. It is a name and an address, never a lookup while a request runs.

WhatWhere the identity appears
A requestThe serverHost, serverIp and serverId of the summary and the detail, the Request tab of the bar, the console request detail, the Requests table (a Server column shows when the history holds more than one server id), the JSON and cURL exports
ErrorsThe group and every sample, and a top level server on the list
Reports and queriesA top level server on the totals and on the query statistics, and the server id of each statement
In flightEach running request
Audit logEvery line has server=<id>
Disk storeerrors.json and reports.json have a top level server, every error group and sample has its own serverId
BIFslensServer(), and the server key of lensReport() and lensDiagnostics(). The rows of lensErrors(), lensQueries() and lensInflight() carry serverId
Response headerX-BxLens-Server, only next to X-BxLens-Id and only with history.serverHeader
ConsoleThe host name and address in the header and on the Overview

The identity is detected once at start and looked at again every five minutes. Set server.name, server.address and server.id (or the environment variables LENS_SERVER_NAME, LENS_SERVER_ADDRESS and LENS_SERVER_ID) behind containers or NAT. See server.

Integrations

An integration reads another module's events. It is off by default, and it is only offered when that module is installed. Until both are true Lens registers no listener.

IntegrationNeedsWhat you get
Mailbx-mail with the onMail events, collectors.mail.enabledThe Mail page
ORMbx-orm 1.7.2 or later, collectors.orm.enabledORM SQL in the bar and console queries with an ORM label, flush counts, failed statements, startup DDL, and (Plus) the statistics page

How to add one: Integrations.

BIFs for your code

lensMessage(), lensDump(), lensMeasure(), lensStart(), lensStop(), lensException(), lensPanel(), lensEnable(), lensDisable(), lensIsEnabled(), lensRender(), lensRequestId(), and for tools and dashboards lensReport(), lensErrors(), lensQueries(), lensInflight(), lensLicense(), lensDiagnostics() and lensServer(). The tracking BIFs do nothing when the request is not tracked.

Safe by default

SettingDefaultWhy
bar.enabled, console.enabledoffNothing runs until you ask
bar.access, console.accesslocalLoopback only
collect.levellightNo bound values, scopes, request headers, caller lookups or stack frames beyond what is cheap
collectors.queries.includeParamsoffValues can be personal data
collectors.functions, bifs, logs, scopes, ormoffThey cost time or copy data
console.allowHeapDumpoffA dump holds every secret in memory
ai.enabledoffWhen on, prompts and what the assistant reads leave the server (a local model keeps them in your network)
  • Redaction happens before storing. Statement text is stored with literals masked, never parameter values.
  • Every in-memory store has a hard cap and drops the oldest entry.
  • A tracked request that never finishes is closed after request.maxMinutes (10) and kept as unfinished.
  • Heavy aggregation (query statistics, error groups, reports, history, audit) runs on one bounded background worker. When its queue is full new work is dropped and counted, and a request never waits.

Speed

Measured on /index.bxm with the MiniServer and 8 clients (requests per second): installed with bar and console off about 2770, console on at light about 2190, bar shown about 1650. The full table is in Performance.

What it does not do

  • Clusters, shared history and alerting: use BX Insights.
  • Capture bound query values by default.
  • Add a request id to outgoing HTTP calls. collectors.http.propagateId is reserved: core gives Lens a read only HTTP request, so it cannot add a header yet.
  • Record request timeouts or client disconnects. Core does not announce them, so only the unfinished request sweep covers those.