Collecting custom logs
The browser agent exposes a logger interface so your web application can collect arbitrary log messages directly. Attach a level, context, and error to each message, then search and filter them in the WhaTap console. Collecting custom events captures the duration and result of an event; custom logs record level-based messages emitted while the application runs.
Custom logs work only with browser agent 3.0 or later. If you are on an earlier version, upgrade the agent before using this feature.
Log monitoring is a billable feature. A 15-day free trial begins on the activation date, after which charges apply based on the collected logs.
Prerequisites
Obtain the following values from the WhaTap console.
| Item | Description |
|---|---|
| Access key | Project access key (projectAccessKey) |
| Project code | Numeric project code (pcode) |
| Collector URL | The collector URL that receives data (proxyBaseUrl) |
If proxyBaseUrl is empty, all logs are silently discarded. Be sure to set it.
Enabling
To use custom logs, configure the following two settings.
- Log settings: Turn on the Activate log monitoring toggle on the Log Configuration screen. Logs are collected only while log monitoring is on; turning the toggle off stops storing logs.
- Custom log option: The browser agent loads asynchronously by default. Use the standard installation snippet from the WhaTap console, and add
enableCustomLog: trueto theconfigobject.
<script>
(function (w, h, _a, t, a, b) {
w = w[a] = w[a] || {
config: {
projectAccessKey: 'YOUR_ACCESS_KEY',
pcode: 12345,
sampleRate: 100,
proxyBaseUrl: 'https://your-collector.example.com/',
enableCustomLog: true, // Enable custom logs
env: 'prod',
version: '1.0.0'
}
};
a = h.createElement(_a);
a.async = 1;
a.src = t;
t = h.getElementsByTagName(_a)[0];
t.parentNode.insertBefore(a, t);
})(window, document, 'script',
'https://repo.whatap-browser-agent.io/rum/v3/whatap-browser-agent.js',
'WhatapBrowserAgent', '');
</script>
Configuration options
| Option | Type | Required | Description |
|---|---|---|---|
projectAccessKey | string | Required | Access key issued by the WhaTap console |
pcode | number | Required | Project code |
proxyBaseUrl | string | Required | Collector base URL. Logs are not sent if unset |
enableCustomLog | boolean | Required | Must be set to true to enable (default false) |
env | string | Optional | Environment label (e.g., prod, staging, dev). Default default_env |
version | string | Optional | Application version. Used to distinguish logs per deployment. Default default_version |
The logger interface is exposed only after the agent script has been downloaded and executed. Calls made very early in page load may be ignored. For a safe calling approach, see Asynchronous load and safe calls.
Custom logs follow the session's sampling decision. If sampleRate excludes the current session from collection, the custom logs of that session are also not sent. To collect logs from all sessions, keep sampleRate: 100 (the default).
Interface
The logger interface is included in the WhatapBrowserAgent object on window.
window.WhatapBrowserAgent.logger.debug(message, context, error);
window.WhatapBrowserAgent.logger.info (message, context, error);
window.WhatapBrowserAgent.logger.warn (message, context, error);
window.WhatapBrowserAgent.logger.error(message, context, error);
window.WhatapBrowserAgent.logger.log (message, context, status, error);
| Argument | Type | Required | Description |
|---|---|---|---|
message | string | Required | Log body. Up to 8KB |
context | object | Optional | Additional metadata. Used for search and filtering |
error | Error or similar object | Optional | Used when sending with a stack trace |
- All methods are synchronous and return nothing.
- Each call is buffered immediately and flushed together after about 1 second.
- A bad argument never throws, so it cannot break your application.
logger.log()takesstatus('debug' | 'info' | 'warn' | 'error') as its third argument; an invalid value falls back to'info'.
Usage
Basic call
window.WhatapBrowserAgent.logger.info('checkout button clicked');
Sending with context
Pass an object as the second argument to make the log searchable and filterable in the WhaTap console.
window.WhatapBrowserAgent.logger.info('checkout step', {
step: 'shipping',
cartItems: 3,
isPremiumUser: true
});
Only strings, numbers, and booleans in context are sent as is. Objects, arrays, null, undefined, and functions are automatically excluded, so flatten nested values or serialize them to strings.
// Ignored: user is an object
window.WhatapBrowserAgent.logger.info('login', {
user: { id: 42, name: 'jihoon' }
});
// Flattened
window.WhatapBrowserAgent.logger.info('login', {
userId: 42,
userName: 'jihoon'
});
// Serialized
window.WhatapBrowserAgent.logger.info('login', {
userJson: JSON.stringify({ id: 42, name: 'jihoon' })
});
Sending with errors
Pass an Error object or a caught value directly as the third argument, and name, message, and stack are sent together.
try {
riskyOperation();
} catch (e) {
window.WhatapBrowserAgent.logger.error(
'riskyOperation failed',
{ feature: 'checkout' },
e
);
}
Errorinstance:name,message, andstackare extracted as is.- Plain object: the
name/message/stackproperties are used if present. - Otherwise (string, number, etc.): converted to a string and placed in
message.
Log levels
| Level | Recommended use |
|---|---|
debug | Detailed tracing during development. Avoid in production |
info | Normal flow events (page entry, business milestones) |
warn | Recovered abnormal situations (retry success, fallback used) |
error | Failures that affect user experience (payment failure, data loss) |
The WhaTap console color-codes each level.
Usage patterns
Tracking the checkout flow
const log = window.WhatapBrowserAgent.logger;
log.info('checkout:start', { cartId, items: cartItems.length, total });
try {
const result = await pay(cartId);
log.info('checkout:success', { cartId, paymentId: result.id });
} catch (e) {
log.error('checkout:fail', { cartId, gateway: 'PG_X' }, e);
}
Augmenting global errors
Attach extra business context on top of the agent's automatic error collection.
window.addEventListener('error', (event) => {
window.WhatapBrowserAgent.logger.error(
'uncaught: ' + event.message,
{ filename: event.filename, line: event.lineno },
event.error
);
});
Send timing
- Logs are flushed together when no new call arrives for about 1 second.
- They are flushed at the latest 5 seconds after the first call.
- They are flushed immediately once 500 entries or about 512KB accumulate in a short time.
- A single message is sent up to 8KB; anything beyond that is truncated.
The defaults are enough in most cases and need no tuning.
Cautions
| Caution | Reason |
|---|---|
| Do not send personal data directly | Mask values such as resident registration numbers, card numbers, and phone numbers in your code before sending |
| Do not call unconditionally inside loops | Calling too frequently can add network overhead |
| Messages over 8KB | Automatically truncated. Split large payloads into the context field |
Do not pass objects or arrays directly in context | They are ignored. Flatten them or serialize them to strings |
Asynchronous load and safe calls
If you need to call logger.* the moment the page opens, check that logger exists first.
function safeLog(level, message, context, error) {
const agent = window.WhatapBrowserAgent;
if (agent && agent.logger && typeof agent.logger[level] === 'function') {
agent.logger[level](message, context, error);
}
// Ignored if before load.
}
safeLog('info', 'app boot', { route: location.pathname });
Calls triggered by user events (clicks, form submissions, etc.) usually run after the agent has loaded, so they need no guard. Use the pattern above only in page boot code.
Troubleshooting
| Symptom | Cause / action |
|---|---|
window.WhatapBrowserAgent.logger is undefined | (1) Agent is below version 3.0 (2) Asynchronous load is not finished yet (3) Script blocked by CSP or ad blocker |
Custom log call was dropped warning in the console | enableCustomLog is false. Add enableCustomLog: true to the config. This warning is printed only once |
| No network request even after calling | Missing enableCustomLog: true, unset proxyBaseUrl, or the call ran before the configuration |
| 401 / 403 response | Access key or pcode error |
| All logs of a specific session are missing | sampleRate excluded that session from collection. Set sampleRate: 100 to collect all sessions |
| Only some logs are missing | Entries beyond 500 or about 512KB in a short time are sent immediately (normal behavior) |
| Message arrives truncated | Single message limit of 8KB. Excess is truncated automatically |
Sent logs can be checked in the WhaTap console under Analysis > User Session Log Search. Search and filter by status, message, context keys, error.message, and more.