Browser RUM Deployment & Configuration
vuSmartMaps Configuration: Enabling Browser RUM
Enabling Browser RUM O11ySource
- Navigate to O11ySources:
- vuSmartMaps O11ySources can be accessed by navigating from the left navigation menu (Data Ingestion > O11ySources).
- Locate Browser RUM O11ySource on the landing page.


- Enable Browser RUM O11ySources:
- Click the Enable button to activate Browser RUM O11ySource.

Data Collection and Processing
Browser RUM collects real user monitoring data through VuNet’s JavaScript RUM agent, which runs within users' web browsers. For secure data collection, it is recommended to deploy a proxy server in the DMZ (Demilitarized Zone). This proxy acts as a secure intermediary, forwarding telemetry data from end-user browsers to the internal RUM data collector hosted within the observability platform. This setup ensures both data security and reliable monitoring without exposing internal systems directly to the internet. The RUM script can be downloaded from the following URL: https://cdn.vunet.ai/rum/vunet-rum-v0.1.23.js. Save the file as vunet-rum.js.
Prerequisites
To configure the data source, you need the following parameters:
| Parameter | Description |
|---|---|
| Application Name | The name of the application you want to monitor. |
| SSL | Select Yes to enable TLS (SSL) for secure data transmission. Select No if secure communication is not required. |
| Traces Sampling Percentage | Specify a value between 0 and 100 to control the percentage of trace data collected by the RUM agent: - 0%: No trace data will be collected. - 100%: All trace data will be collected. - 1–99%: A random sampling mechanism will collect traces accordingly. |
| Session Replay Sampling Percentage | Specify a value between 0 and 100 to control how many sessions are recorded for replay: - 0%: Session replay is disabled. - 100%: All sessions will be recorded. - 1–99%: Sessions are selected using a normalized sampling algorithm (explained below). |
Session Replay Sampling Logic
When a sampling value between 1 and 99 is configured, the RUM agent uses the following logic to decide whether to record a session for replay:
percentage(base + replayPercentage * RandomJitter) < replayPercentage
- base: A numeric value derived by hashing the session ID.
- RandomJitter: A randomized factor that varies by ±25% to avoid skewed sampling.
- percentage(): A normalization function that ensures the result falls between 0 and 100.
If the final computed value is less than the configured
replayPercentage, the session is selected for replay.
- Values above 100% are capped at 100.
- Values below 0% are raised to 0.
Disabling Options
- To disable trace collection, set Traces Sampling Percentage to
0. - To disable session replay, set Session Replay Sampling Percentage to
0. - To disable both, set both values to
0.
Firewall Requirements
To ensure seamless data collection, the following firewall configurations must be in place:
- Allow inbound traffic on TCP port 443 (HTTPS) to the proxy server.
- Allow inbound traffic on TCP port 80 (HTTP) for automatic redirection to HTTPS (optional).
- Allow outbound traffic from the proxy server to the OTEL Collector on port 4319 (or a custom port, depending on the environment).
- Allow connection from proxy server to vuInterface node of vuSmartMaps on port 443
Certificate
-
Browser-to-Proxy SSL Certificate
- Used to establish a secure connection between the browser and the proxy server.
- Ensures that data transmitted from the JavaScript RUM agent running in the browser is encrypted and trusted.
-
OTEL Collector Certificate
- Required for secure communication between the proxy server and the OpenTelemetry (OTEL) collector.
- Ensures encrypted and authenticated data transfer from the proxy to the OTEL collector.
Configuring Data Sources
- Navigate to the Sources tab and click the + button to add new services to be monitored.
- Fill up the Following Details in the Wizard:
- Applications Group: Select or enter the name of the application group to which the monitored application belongs.
- SSL Required: Choose Yes to enable TLS (SSL) for secure communication, or No if it's not required.
- Traces Sampling Percentage – Specify the percentage of trace data to be collected.
- Session Replay Percentage – Specify the percentage of sessions to be recorded for replay.

- Download the client instrumentation package from the agent configuration wizard.

- Follow the instructions provided in the Client Side Browser RUM Instrumentation.
Client Side Browser RUM Instrumentation
Instrumenting JavaScript Applications
This section guides you through tracing JavaScript applications using Browser RUM.
Prerequisite
Before you begin, ensure the following:
- Configure your web server as a reverse proxy to serve the RUM script and forward trace data, or use a dedicated proxy server to receive and relay RUM traces.
- The RUM script should send data to the proxy at the following endpoint (e.g.,
https://<proxy_address>/rum/v1/traces), which then forwards it to the OpenTelemetry Collector (e.g.,https://<RUM-collector-host>:4319/v1/traces). - Instrumentation requires JavaScript to be added to HTML pages by editing or updating the pages to include the
<script>tag. - The method for editing or updating HTML files depends on the technology used in the web application (e.g., JavaScript, React, Angular, PHP, ASP.NET, etc.). There are two cases:
- For JavaScript-based applications (JS, Angular, React):
- If it is a Single Page Application (SPA), the main HTML file (typically
index.html) must be edited to include the<script>tag. - For Multi-page Applications, all main HTML pages of the application must be updated with the
<script>tag.
- If it is a Single Page Application (SPA), the main HTML file (typically
- For server-side rendered applications (e.g., PHP, JSP, ASP.NET):
- HTML files are generated dynamically from the server.
- In this case, the
<script>tag should be added by the server-side code into the dynamically generated HTML files (typically by modifying files likeheader.php,_Layout.chtml, etc.).
- For JavaScript-based applications (JS, Angular, React):
- The application and environment must allow externally loaded or inline scripts to be executed, since the RUM SDK is loaded as a script.
Host / Virtual Machine (VM)
- Copy the RUM Script
- Add the file
/public/js/vunet-rum.js(absolute path) to your application’s codebase, preferably inside thejsfolder.
- Add the file

- Add the RUM Script to the Page Header
- Insert the following script in the
<head>section of your HTML file:
- Insert the following script in the
<script>
(function (w, s, d, r, e, n) {
(w[s] = w[s] || {
readyListeners: [],
onReady: function (e) {
w[s].readyListeners.push(e);
},
}),
((e = d.createElement('script')).async = 1),
(e.src = r),(n = d.getElementsByTagName('script')[0]).parentNode.insertBefore(e, n);
})( window, 'vunetRum', document, '/public/js/vunet-rum.js');
window.vunetRum.onReady(function () {
window.vunetRum.initialize({
collectionSourceUrl: "<VUNET_TELEMETRY_RECEIVER_URL>", //mention the urlwhere the otel collector is running
serviceName: '<SERVICE_NAME>',// mention the service name of the application
applicationName: '<APPLICATION_NAME>', // mention the name of the application
decideApiEndpoint: "<DECIDE_API_ENDPOINT_URL>",
collectErrors: true,
dropShortTracesMs: 100,//drop traces shorter than 100 milliseconds
authorizationToken: "ef7ae8b1fa097092a66a56882fd8366cfbdb1b6848ae0d529a21a68a94e245020"
ignoreUrls:[/\/rum\/v1\/.*/i, /\/vusmartmaps\/.*/i]
});
});
</script>
-
Update the Variables
Replace the placeholder values in the script as follows:
- VUNET_TELEMETRY_RECEIVER_URL: URL of the reverse proxy
- Example:
"http://10.1.1.1/rum/v1/traces"
- Example:
- SERVICE_NAME: Service name for the application
- Example:
'vubank-frontend'
- Example:
- APPLICATION_NAME: Name of the application
- Example:
'IBMB'
- Example:
- decideApiEndpoint: URL of reverse proxy with path as “/vuSmartMaps/api/rum”. The proxy will forward this request to Cairo to invoke Decide API
- Example: "https://10.1.1.1/vuSmartMaps/api/rum/"
- dropShortTracesMs: Filters out short, low-value traces
- If the total duration of a trace (from its root span’s start to its end) is less than the value of
dropShortTracesMs, the entire trace will be discarded. - All spans within such short traces will also be excluded.
- This is useful for filtering out fast, low-impact user interactions.
- Value is specified in milliseconds.
- Example:
dropShortTracesMs: 100
- Example:
- If the total duration of a trace (from its root span’s start to its end) is less than the value of
- authorizationToken: Token used for authenticating requests
- Generate a token on a Linux host using:
openssl rand -hex 32- Include this token in the RUM script on the application side.
- The same token must also be configured on the proxy server to validate incoming requests.
- VUNET_TELEMETRY_RECEIVER_URL: URL of the reverse proxy
-
Restart the Web Server
- Apply the changes by restarting your web server.
Cloud Machine Setup (Using CDN)
For cloud environments, the JavaScript file can be loaded directly from VuNet's Content Delivery Network (CDN).
-
Insert the Script in the HTML
<head>SectionUse the following script:
<script>
(function (w, s, d, r, e, n) {
(w[s] = w[s] || {
readyListeners: [],
onReady: function (e) {
w[s].readyListeners.push(e);
},
}),
((e = d.createElement('script')).async = 1),
(e.src = r),(n = d.getElementsByTagName('script')[0]).parentNode.insertBefore(e, n);
})( window, 'vunetRum', document, 'https://cdn.vunet.ai/rum/vunet-rum-v0.1.23.js');
window.vunetRum.onReady(function () {
window.vunetRum.initialize({
collectionSourceUrl: "<VUNET_TELEMETRY_RECEIVER_URL>", //mention the urlwhere the otel collector is running
serviceName: '<SERVICE_NAME>',// mention the service name of the application
applicationName: '<APPLICATION_NAME>', // mention the name of the application
decideApiEndpoint: "<DECIDE_API_ENDPOINT_URL>",
collectErrors: true,
dropShortTracesMs: 100,//drop traces shorter than 100 milliseconds
authorizationToken: "ef7ae8b1fa097092a66a56882fd8366cfbdb1b6848ae0d529a21a68a94e245020"
ignoreUrls:[/\/rum\/v1\/.*/i, /\/vusmartmaps\/.*/i]
});
});
</script>
-
Update the Variables
Replace the placeholders in the script:
-
VUNET_TELEMETRY_RECEIVER_URL: URL of the reverse proxy
- Example:
"http://10.1.1.1/rum/v1/traces"
- Example:
-
SERVICE_NAME: The name of the service
- Example:
'vubank-frontend'
- Example:
-
APPLICATION_NAME: The name of the application
- Example:
'IBMB'
- Example:
-
decideApiEndpoint: URL of reverse proxy with path as
/vuSmartMaps/api/rum, The proxy will forward this request to Cairo to invoke Decide API- Example:
http://10.1.1.1/vuSmartMaps/api/rum/
- Example:
-
dropShortTracesMs: Filters out short, low-value traces
- If the total duration of a trace (from its root span’s start to its end) is less than the value of
dropShortTracesMs, the entire trace will be discarded. - All spans within such short traces will also be excluded.
- This is useful for filtering out fast, low-impact user interactions.
- Value is specified in milliseconds.
- Example:
dropShortTracesMs: 1
- Example:
- If the total duration of a trace (from its root span’s start to its end) is less than the value of
-
authorizationToken: Token used for authenticating requests
- Generate a token on a Linux host using:
-
openssl rand -hex 32
- Include this token in the RUM script on the application side.
- The same token must also be configured on the proxy server to validate incoming requests.
- Ensure that the CSP is configured to allow loading files from our CDN (http://cdn.vunet.ai).
- If the JS file is loaded correctly, then it should function as expected. If there are difficulties in receiving data, verify that the JS file is properly loaded and that the collectionSourceUrl is correct and accessible.
Container
For containerized environments, follow these steps:
- Add the RUM script to your page header as shown above.
- Rebuild the Docker container with the updated codebase to ensure the script is included.
Kubernetes
For Kubernetes environments, follow these steps:
- Add the RUM script to your page header as shown above.
- Rebuild the Docker container and deploy it in your Kubernetes environment to include the updated script.
CORS Prerequisites
To ensure successful communication between the application and the proxy server, the following CORS-related requirements must be met:
- Restrict Origins
- Only trusted application domains should be allowed to send data.
- The proxy server must be configured to whitelist specific origins using the following headers:
Access-Control-Allow-Origin: https://<App-name.com>
Access-Control-Allow-Methods: POST, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization, logcategory
- Replace
https://<App-name.com>with the actual domain(s) of your frontend application.
- Security Mechanism Compatibility
- If the application uses security mechanisms such as:
- CSP (Content Security Policy)
- Firewalls
- Then these must be configured to allow communication with the proxy.
- The CSP headers must permit the proxy domain in the
connect-srcdirective. For example:
- If the application uses security mechanisms such as:
Content-Security-Policy: script-src 'self'; connect-src 'self' https://<proxy_address>;
- Ensure the proxy’s hostname (e.g.,
https://otelproxy.com) is included in theconnect-srcdirective.
- Preflight Request Support
- Browsers automatically send OPTIONS (preflight) requests before
POSTrequests to check CORS permissions. - The proxy must correctly handle these preflight requests.
- Ensure your NGINX or proxy server is configured to return appropriate CORS headers for
OPTIONSrequests.
- Browsers automatically send OPTIONS (preflight) requests before
Additional Configuration Details
RUM Proxy Server Configuration Guide
This section outlines the prerequisites and configuration guidelines for setting up a Reverse Proxy for Real User Monitoring (RUM) data, in alignment with organizational standards. While NGINX is used as an example in this guide, it is recommended to use the proxy server approved by your organization.
The configuration includes support for:
- SSL termination
- Cross-Origin Resource Sharing (CORS)
- API key authentication
- Backend proxying to an internal RUM collector
Prerequisites
- A Linux-based server with NGINX installed
- NGINX version >= 1.18
- SSL certificate and key (PEM format)
- Domain/subdomain pointing to your NGINX proxy server
- Approved Origin Domains (used in CORS)
- Firewall rules allowing port 443 (HTTPS) (External Port)
- Firewall rules allowing port 4319/4320 from Proxy to RUM OTEL Collector
Configuration Summary
SSL Configuration
- Ensure your NGINX server has a valid SSL certificate.
- Place your certificate and key files in the appropriate directory, typically:
/etc/ssl/certs/proxy-cert.crt
/etc/ssl/private/proxy-key.key
CORS Mapping
- Allows requests only from specified origins.
- Use the following configuration for handling CORS:
# For handling Cors
map $http_origin $cors_allow_origin {
default "";
"~^https?://myapp\.domain\.com$" "$http_origin";
"~^https?://192.\.168\.1\.1$" "$http_origin";
}
- Add the following line inside the specific
locationblock:
add_header 'Access-Control-Allow-Origin' "$cors_allow_origin" always;
API Key Mapping
- Maps a valid
Authorizationheader to a flag used for access control. - Add the following configuration:
map $http_authorization $is_valid_api_key {
default 0;
"ef7ae8b1fa097092a66a56882fd8366cfbdb1b6848ae0d529a21a68a94e245020" 1;
}
- To generate the key using
openssl:
$ openssl rand -hex 32
ef7ae8b1fa097092a66a56882fd8366cfbdb1b6848ae0d529a21a68a94e245020
HTTPS Server Block
Handles SSL, routes requests, and enforces security headers.
server {
listen 443 ssl;
# Replace with actual domain or IP address
server_name myproxydomain.com;
ssl_certificate /etc/ssl/certs/proxy-cert.crt;
ssl_certificate_key /etc/ssl/private/proxy-key.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
location /vuSmartMaps/api/rum {
proxy_pass https://vuSmartMapsIP;
proxy_set_header Host vuSmartMapsIP;
}
location /rum/ {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' "$cors_allow_origin" always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, logcategory' always;
return 204;
}
if ($is_valid_api_key = 0) {
return 401 "Unauthorized";
}
add_header 'Access-Control-Allow-Origin' "$cors_allow_origin" always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, logcategory' always;
proxy_pass http://rum-backend/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
}
}
HTTP Redirect Block
Redirects HTTP to HTTPS.
server {
listen 80;
server_name otelcollector.com;
return 301 https://$host$request_uri;
}
Upstream Block
Defines backend servers for the RUM collector.
upstream rum-backend {
# server 172.16.124.188:4319; # Example sandbox backend
}
Consolidated NGINX Configuration
Create the below configuration under:
/etc/nginx/conf.d/rumsslproxy.conf
This file will define reverse proxy and CORS logic for RUM service integration. Replace all highlighted placeholders with appropriate values to be updated as per the end state environment
# =========================
# Map CORS-Allowed Origins
# =========================
# This maps the Origin header to itself only if it matches approved domains,
# which are then used in the 'Access-Control-Allow-Origin' header.
map $http_origin $cors_allow_origin {
default "";
"~^https?://<ALLOWED_ORIGIN>$" "$http_origin";
#######EXAMPLE####################################
##"~^https?://myapp\.com$" "$http_origin";
##"~^https?://192\.168\.1\.1$" "$http_origin";
}
# =============================
# Map Authorization API Key
# =============================
# This maps the incoming Authorization header to a flag (1 if valid, 0 otherwise),
# enabling simple conditional checks in the server block.
map $http_authorization $is_valid_api_key {
default 0;
"ef7ae8b1fa097092a66a56882fd8366cfbdb1b6848ae0d529a21a68a94e245020" 1;
}
# ===========================
# HTTPS Server for RUM Proxy
# ===========================
server {
listen 443 ssl;
# --------------------------
# Domain name of the proxy for example rum.vunetsystems.com
# --------------------------
Server_name <SERVER_NAME>;
# SSL certificate and private key
ssl_certificate <SSL_CERT_PATH>;
ssl_certificate_key <SSL_CERT_KEY_PATH>;
###EXAMPLE##########################################
# ssl_certificate /etc/ssl/certs/vusmartmaps.crt;
# ssl_certificate_key /etc/ssl/private/vusmartmaps.key;
# Enforce modern TLS protocols and secure cipher suites
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# Security headers for HTTPS best practices
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# ============================================================
# Proxy to vuSmartMaps decide API EndPoint. Specify vuSmartMapsIP
# ============================================================
# Basic reverse proxy for internal API calls
location /vuSmartMaps/api/rum {
proxy_pass https://vuSmartMapsIP;
proxy_set_header Host vuSmartMapsIP;
}
# ===============================
# Main RUM Beacon Proxy Endpoint
# ===============================
location /rum/ {
# --------------------------
# Handle CORS Preflight
# --------------------------
# If this is an OPTIONS request, return allowed headers & methods
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' "$cors_allow_origin" always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, logcategory' always;
return 204;
}
# --------------------------
# Enforce API Key Auth
# --------------------------
# If API key is not valid, reject the request
if ($is_valid_api_key = 0) {
return 401 "Unauthorized";
}
# --------------------------
# Add CORS headers to real requests
# --------------------------
add_header 'Access-Control-Allow-Origin' "$cors_allow_origin" always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, logcategory' always;
# --------------------------
# Proxy to internal RUM collector use http or https based on requirement
# --------------------------
###for http://
proxy_pass http://rum-backend/;
### for https://
#proxy_pass https://rum-backend/;
# Optional SSL configuration for backend (commented out)
# proxy_ssl_name rum.vunetsystems.com;
# proxy_ssl_server_name on;
# proxy_ssl_verify on;
# proxy_ssl_verify_depth 2;
# proxy_ssl_trusted_certificate /etc/nginx/certs/ca_chain.pem;
# Forward client headers to backend
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Disable buffering for low-latency small POSTs
proxy_buffering off;
}
}
# ================================
# Redirect HTTP to HTTPS
# ================================
server {
listen 80;
server_name otelcollector.com;
# Redirect all HTTP requests to HTTPS
return 301 https://$host$request_uri;
}
# ================================
# Define Backend RUM Collector
# ================================
# You can define one or more backend servers here.
# Useful for load balancing or failover.
upstream rum-backend {
# Example backend:
# Replace this with RUM Otel Collector IP
server <OTEL_COLL_IP>:4319
### EXAMPLE
##server 172.16.124.188:4319;
}
Validate and Restart NGINX: Use the following commands to validate the NGINX configuration and restart the server:
$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
$ sudo service nginx restart
Proxy Sizing
To handle 40,000 RUM events per second with 1 KB payloads through an NGINX proxy, a single well-tuned node with 8 vCPU, 16 GB RAM, 100 GB SSD (if logging is enabled) would be required. For high availability and redundancy, deploy 2 such nodes behind an external load balancer.
Input Parameters
- Events per Second (EPS): 40,000
- Payload Size per Event: 2 KB
Per Node Sizing Recommendation
| Resource | Size |
|---|---|
| vCPU | 8 |
| RAM | 16 |
| Disk SSD | 100 GB if logging is enabled |
