Hot spots

On this page

Hot spots

A slow request has a time, and the question is where it went. Hot spots answers it. While a request runs, BxLens looks at what the request is doing about ten times a second and keeps the looks, then shows them as one picture: your templates and functions, the database, outgoing calls and waits, widest first. The widest bar is where to start.

Hot spots is a BoxLang+ feature and is off until you switch it on. On Free the pages do not show it and the server answers 403 on its routes. It is for the admin role.

The Hot spots picture of a slow request

Switch it on

Open Settings, Collection and switch on the hotspots collector, or set it in boxlang.json:

{
  "modules": { "bxLens": { "settings": { "collectors": { "hotspots": { "enabled": true } } } } }
}

From then on every request that runs longer than 1000 ms is looked at, until it finishes or has been looked at for 60 seconds. A request that finishes sooner costs nothing. The look happens on one thread of its own and reads the stack of every request that is due in one call, so it does not slow the request down much, and the cost has not been measured on a busy server yet. The switch, the start limit, the limits and the rules are live: a change applies at once and survives a restart.

Read the picture

Each row is a place in your code. Its bar is the share of the request's time (the percent and the milliseconds are on the right). Pressing a row folds or opens what it called. The widest branches start open.

  • Your code (blue) is a template, a function or a class of your application. The line is under the name.
  • Database (amber) is a statement that was running, with its text (values hidden, as in Queries).
  • Outgoing calls (purple) is an HTTP call that was running, with its host and path.
  • Waiting (red) is a lock, a sleep or a wait for another thread.
  • BoxLang and server (grey) is the runtime and the web server. They are hidden by default and their time goes to the code that called them. Press All frames to see them.

Below the picture, Where the time went lists the places where the time was spent itself, widest first, with the percent and the milliseconds. It counts wall time: a request that sleeps for a second has a second of waiting.

It is a sample, not a measurement. A request of 5 seconds with a look every 100 ms has about 50 samples, so a place that took 2 percent is one sample and could be luck. Trust the wide bars. A short function that is called very often can fall between two looks, and one that is called at the instant of each look is shown larger than it is. A look is taken at a point where the JVM can stop a thread, which favors loops and calls over straight-line code.

Where you find it

A finished request. Open it in Requests. A request that was looked at has a Hot spots section above the other sections. It says how many looks were taken and why: a slow request, a rule or by hand. The pictures of the last 50 requests stay in memory (collectors.hotspots.keep). A request that was not looked at has no section.

A running request. On In flight pick a request and press Hot spots. Hot spots on a running request The picture builds while the request runs and updates every second and a half. Press Stop hot spots to stop looking. This works on any request, also one that has not reached the start limit. It needs the switch on, and it is read only on the server you are on.

A URL. Open a URL on the Reports page. Hot spots merges the pictures of all the runs of that URL in the range, over every server that shares the store. Ids in the path are one URL, as in the rest of Reports. The picture needs 5 runs to be steady and says so. Under it are the slowest runs, each opens its own request.

The merged Hot spots of a URL

Press Watch this URL for 10 min, 1 h or 24 h to look at every request of that URL for a while, even the fast ones. It adds a rule that ends by itself. The same buttons are on every request in Requests, under the title: look at this URL the next time it runs, for 10 minutes, 1 hour or 24 hours. The rule takes the method and path of that request. Watch the URL of a request When the time is up the rule stops matching and is gone from the list.

Rules

By default only slow requests are looked at. A rule says to look at more. A rule has a path (it starts with /, and a * at the end matches the rest), a method (any, GET, POST, PUT, PATCH or DELETE), start after in milliseconds (0 looks at the request from its first moment) and an optional end (10 minutes, 1 hour or 24 hours, at most 7 days). The first rule that matches a request decides. Rules are in Settings, Collection, Hot spots rules.

The Hot spots rules

A rule that has no end is kept in the settings file. To give the same rules to every server from a deploy, put them in boxlang.json:

{
  "collectors": {
    "hotspots": {
      "rules": [
        { "match": "/api/reports/*", "method": "GET", "startAfterMs": 0 },
        { "match": "/checkout", "method": "POST", "startAfterMs": 300 }
      ]
    }
  }
}

The list in boxlang.json replaces all the rules, also the ones added in the console, the first time it is read and each time you change it in a deploy, as the other lists do (mcp.servers, bar.layout). While it stays the same, rules you add or remove in the console stay. See Several servers that stay in sync.

Limits and safeguards

SettingDefaultWhat it does
enabledfalseThe switch.
slowtrueLook at every request that passes the start limit. Off leaves only the rules.
slowAfterMs1000The start limit, 100 to 60000.
sampleEveryMs100The time between two looks, 20 to 1000.
maxSeconds60The longest a request is looked at. The picture says when it was cut.
maxConcurrent5Requests looked at at the same time, at most 20. Others wait and are not looked at.
keep50Requests whose picture stays in memory.
never/health*, /~bxlens/*Paths that are never looked at, whatever a rule says.
pauseAboveCpuPct85Looking pauses while the server's CPU is above this (0 turns it off) and starts again by itself.
offAfterMinutes0Switch Hot spots off by itself after this long (0 is never).
hideserver and JDK packagesClass prefixes shown as BoxLang and server, not as your code.

The picture of one request holds at most 500 places, the merged picture of a URL 300 for each hour, and the rest is counted in one (other) row. The merged pictures are saved in the disk store as hotspots-rollup-YYYY-MM-DD.json with the other history, for at most 50 URLs an hour, and are removed with the other days.

Every start, stop, rule and automatic switch off is in the audit log (hotspots.start, hotspots.stop, hotspots.rule.add, hotspots.rule.remove, hotspots.off). Texts of statements are shown with their values hidden. Hot spots reads the stacks of the threads and does not change a request.

Routes

All of them are for the admin role, need BoxLang+, and the ones that change something follow the CSRF, console.readOnly and console.actions rules like every other action.

RouteWhat it does
GET hotspots/statusThe state: enabled, paused and why, the requests being looked at now, how many are kept, and the rules.
GET hotspots/rules, POST hotspots/rulesList the rules, or add one (match, method, startAfterMs, forMinutes).
POST hotspots/rules/removeRemove a rule by id.
GET requests/{id}/hotspotsThe picture of a finished request, available: false when there is none.
GET inflight/{id}/hotspotsThe picture of a running request so far.
POST inflight/{id}/hotspots, POST inflight/{id}/hotspots/stopStart or stop looking at a running request.
GET reports/url/hotspots?url=&method=&range=The merged picture of a URL.
POST requests/{id}/hotspots/share, POST reports/url/hotspots/shareShare a report (data has to, channels, parts and note). Needs the notifications feature too.

Ask Lensy and share

Every Hot spots report has Ask Lensy (the request, a running request and a URL). It reads the shares and the widest places, never a statement value, and answers in words with what to change first. It needs BoxLang+ and the assistant.

Ask Lensy about the hot spots of a URL

A request report and a URL report also have Share. It opens the same share sheet as a request or an error issue: your recipients, your chat channels, or any address you type, with a note. It sends the kinds, the 8 widest places and, for a URL, the slowest runs, and the audit log has hotspots.share. The share sheet

A running request cannot be shared, because its picture changes every second. Sharing needs BoxLang+ with the notifications set up.

Lensy has a read only hotSpots tool. Ask "where does /reports/monthly spend its time?" and it reads the merged picture of that URL, or the picture of a request id, and answers in words. See AI tools.

See also