RAN Monitor Runtime Configuration Guide
Understanding config/runtime.exs
Table of Contents
- Overview
- Database Configuration
- Web Endpoints
- Logger Configuration
- Nokia Integration
- InfluxDB Configuration
- Configuration Best Practices
Overview
The config/runtime.exs file is the primary configuration file for RAN Monitor. It's evaluated at runtime (when the application starts), allowing you to configure all aspects of the system's behavior.
What Gets Configured:
- Database connections (MySQL)
- Web server endpoints and ports
- Nokia base station details
- InfluxDB time-series database
- Logging behavior
- Security credentials
File Location:
config/runtime.exs
Who Should Use This Guide
Important: All RAN Monitor configuration is performed by Omnitouch as part of the initial deployment and ongoing support. This guide is provided for:
- Advanced users who want to understand the system configuration
- Self-managed deployments where customers maintain their own configuration
- Troubleshooting and understanding how the system is configured
- Custom deployments with specific requirements
If you are an Omnitouch-managed customer, contact Omnitouch support for any configuration changes.
For understanding what data is being collected, see Nokia Counter Reference. For dashboard creation, see Grafana Integration.
Database Configuration
MySQL/MariaDB Connection
config :ran_monitor, RanMonitor.Repo,
username: "omnitouch",
password: "omnitouch2024",
hostname: "localhost",
database: "ran_monitor",
stacktrace: true,
show_sensitive_data_on_connection_error: true,
pool_size: 10
Purpose: Configures the connection to the MySQL database used for session state management and operational data.
Parameters Explained
username (String)
- Database user account
- Current value:
"omnitouch" - Usage: Must have CREATE, SELECT, INSERT, UPDATE, DELETE privileges
- Security: Consider using a dedicated user with minimum required privileges
password (String)
- Database password for authentication
- Current value:
"omnitouch2024" - Security: Should be stored in environment variables in production
- Recommendation: Use strong, unique passwords
hostname (String)
- Database server address
- Current value:
"localhost" - Options:
"localhost"- Database on same machine"127.0.0.1"- TCP connection to local machine"10.179.2.135"- Remote database server IP"db.example.com"- Remote database hostname
database (String)
- Database name to use
- Current value:
"ran_monitor" - Note: Database must exist before starting RAN Monitor
- Creation:
CREATE DATABASE ran_monitor CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
stacktrace (Boolean)
- Include stacktraces in error messages
- Current value:
true - Development:
true- Helps with debugging - Production:
false- Reduces log noise
show_sensitive_data_on_connection_error (Boolean)
- Show credentials in connection error messages
- Current value:
true - Development:
true- Easier troubleshooting - Production:
false- Prevents credential exposure in logs
pool_size (Integer)
- Number of database connections to maintain
- Current value:
10 - Sizing Guide:
- 1-5 devices:
pool_size: 5 - 6-20 devices:
pool_size: 10 - 21-50 devices:
pool_size: 15 - 50+ devices:
pool_size: 20
- 1-5 devices:
- Formula: Roughly 2 connections per base station + 5 for web UI
Web Endpoints
RAN Monitor runs multiple web servers for different purposes.
Main SOAP/API Endpoint
config :ran_monitor, RanMonitor.Web.Endpoint,
http: [ip: {0, 0, 0, 0}, port: 8080],
check_origin: false,
secret_key_base: "v5tOS1/QRonjwOky7adGGfkBbrJmiJyXhpesJy/jvSZhqLZkREV+rlo1/pR8lkbu",
server: true
Purpose: Main endpoint for base station communication (SOAP interface for Nokia NE3S protocol).
ip (Tuple)
- Interface to bind to
- Current value:
{0, 0, 0, 0}(all interfaces) - Options:
{0, 0, 0, 0}- Listen on all network interfaces{127, 0, 0, 1}- Listen only on localhost{10, 179, 2, 135}- Listen on specific IP address
port (Integer)
- TCP port number
- Current value:
8080 - Note: Base stations must be configured to send data to this port
- Firewall: Ensure port is open for base station IPs
check_origin (Boolean)
- Validate WebSocket/HTTP origin headers
- Current value:
false - Explanation: Set to
falsefor SOAP API (not user-facing web UI)
secret_key_base (String)
- Cryptographic signing key for sessions
- Current value: 64-character random string
- Generation:
mix phx.gen.secret - Security: Keep this secret, never commit to public repositories
- Impact: Changing this invalidates all existing sessions
server (Boolean)
- Start the endpoint when application starts
- Current value:
true - Always: Should be
truein runtime.exs
Control Panel Web UI
# Get HTTPS port from environment variable, default to 9443
https_port = String.to_integer(System.get_env("CONTROL_PANEL_HTTPS_PORT") || "9443")
config :control_panel, ControlPanelWeb.Endpoint,
url: [host: "0.0.0.0", port: https_port, scheme: "https"],
https: [
ip: {0, 0, 0, 0},
port: https_port,
keyfile: "priv/cert/omnitouch.pem",
certfile: "priv/cert/omnitouch.crt"
]
Purpose: HTTPS endpoint for the web-based control panel UI.
Environment Variables:
- CONTROL_PANEL_HTTPS_PORT - HTTPS port number (default: 9443)
- Set this environment variable to change the HTTPS port at runtime
- Example:
export CONTROL_PANEL_HTTPS_PORT=8443
url (Keyword list)
- External URL configuration
- host:
"0.0.0.0"- Accept connections from any host - port: Uses
https_portvariable (configurable via CONTROL_PANEL_HTTPS_PORT) - scheme:
"https"- Use HTTPS protocol
https (Keyword list)
- HTTPS server configuration
- ip:
{0, 0, 0, 0}- Bind to all interfaces - port: Uses
https_portvariable (must match url port) - keyfile: Path to SSL private key
- certfile: Path to SSL certificate
SSL Certificate Files:
- Must be valid SSL/TLS certificates
- Self-signed certificates work for lab environments
- Production should use CA-signed certificates
- Generate self-signed:
openssl req -newkey rsa:2048 -nodes -keyout omnitouch.pem -x509 -days 365 -out omnitouch.crt
Nokia AirScale Webhook Endpoint
config :ran_monitor, RanMonitor.Web.Nokia.Airscale.Endpoint,
url: [host: "0.0.0.0"],
http: [ip: {0, 0, 0, 0}, port: 9076],
server: true
Purpose: Receives real-time performance data from Nokia AirScale base stations.
port (Integer)
- Current value:
9076 - Note: Must match the port configured in base station PMCADM (rTpmCollEntityPortNum)
- Coordination: This port must match what you configured in the Nokia WebLM Parameter Editor
Logger Configuration
config :logger,
level: :info
config :logger, :console,
format: "$time $metadata[$level] $message\n",
metadata: [:request_id]
Log Level
level (Atom)
- Controls verbosity of logging
- Current value:
:info - Options:
:debug- Extremely verbose, all details:info- Normal operations, recommended for production:warning- Only warnings and errors:error- Only errors
When to Use Each Level:
- Development:
:debug- See all internal operations - Production:
:info- Balance between visibility and noise - Troubleshooting: Temporarily set to
:debug, then revert - Quiet Production:
:warning- Only alert on issues
Console Format
format (String)
- How log messages appear
- Current value:
"$time $metadata[$level] $message\n" - Variables:
$time- Timestamp$metadata- Contextual information$level- Log level (info, error, etc.)$message- Actual log message
metadata (List of atoms)
- Additional context to include
- Current value:
[:request_id] - request_id: Tracks individual HTTP requests through the system
Nokia Integration
This section configures how RAN Monitor communicates with Nokia base stations.
config :ran_monitor,
general: %{
mcc: "505",
mnc: "57"
},
nokia: %{
ne3s: %{
webhook_url: "http://10.5.198.200:9076/webhook",
private_key: Path.join(Application.app_dir(:ran_monitor, "priv"), "external/nokia/ne.key.pem"),
public_key: Path.join(Application.app_dir(:ran_monitor, "priv"), "external/nokia/ne.cert.der"),
reregister_interval: 30
},
airscales: [
%{
address: "10.7.15.67",
name: "ONS-Lab-Airscale",
port: "8080",
web_username: "Nemuadmin",
web_password: "nemuuser"
}
]
}
General Settings
mcc (String)
- Mobile Country Code
- Current value:
"505" - Usage: Identifies the country for 3GPP networks
- Format: 3 digits
- Reference: ITU-T E.212
mnc (String)
- Mobile Network Code
- Current value:
"57" - Usage: Identifies the specific network operator
- Format: 2 or 3 digits
NE3S Configuration (Nokia NE3S Protocol)
webhook_url (String)
- URL where base stations send notifications
- Current value:
"http://10.5.198.200:9076/webhook" - Format:
http://<ran-monitor-ip>:<port>/webhook - IP Address: Must be IP address where RAN Monitor is running
- Port: Must match
RanMonitor.Web.Nokia.Airscale.Endpointport (9076) - Path: Always
/webhook
private_key (String - File path)
- Private key for manager authentication
- Current value:
priv/external/nokia/ne.key.pem - Format: PEM encoded private key
- Security: Keep this file secure, never share
- Generation: Provided by Nokia or generated with OpenSSL
public_key (String - File path)
- Public certificate for manager identity
- Current value:
priv/external/nokia/ne.cert.der - Format: DER encoded certificate
- Usage: Sent to base station during registration
- Pair: Must correspond to private_key
reregister_interval (Integer)
- How often to re-register with base stations (seconds)
- Current value:
30 - Explanation: Sessions expire, periodic re-registration maintains connection
- Range: 30-300 seconds
- Recommendation: 30 seconds for reliable monitoring
AirScale Base Stations
airscales (List of maps)
- List of Nokia AirScale base stations to monitor
- Current value: One base station configured
Each base station entry requires:
address (String)
- IP address of the base station
- Current value:
"10.7.15.66" - Format: IPv4 address as string
- Network: Must be reachable from RAN Monitor server
- Verification:
ping 10.7.15.66should succeed
name (String)
- Friendly name for identification
- Current value:
"ONS-Lab-Airscale" - Usage: Appears in Web UI, logs, and InfluxDB tags
- Recommendation: Use descriptive names (site codes, locations, etc.)
- Examples:
"NYC-Site-A-BS1""LAX-Tower-Main""TestLab-Airscale-01"
port (String)
- Management interface port on base station
- Current value:
"8080" - Standard: Nokia AirScale typically uses 8080
- Verification: Check base station documentation
- Note: Value is a string, not integer
web_username (String)
- Username for WebLM authentication
- Current value:
"Nemuadmin" - Usage: Used for API calls to manage base station
- Privileges: Should have configuration read/write access
- Note: Case-sensitive
web_password (String)
- Password for WebLM authentication
- Current value:
"nemuuser" - Security: Should be stored in environment variables in production
- Rotation: Change regularly according to security policy
Adding Multiple Base Stations
To monitor multiple base stations, add additional entries to the airscales list:
airscales: [
%{
address: "10.7.15.66",
name: "ONS-Lab-Airscale",
port: "8080",
web_username: "Nemuadmin",
web_password: "nemuuser"
},
%{
address: "10.7.15.67",
name: "Site-A-Tower-1",
port: "8080",
web_username: "admin",
web_password: "password123"
},
%{
address: "192.168.100.50",
name: "Site-B-Indoor",
port: "8080",
web_username: "admin",
web_password: "different_password"
}
]
InfluxDB Configuration
config :ran_monitor, RanMonitor.InfluxDbConnection,
auth: [
username: "monitor",
password: "sideunderTexasgalaxyview_61"
],
database: "nokia-monitor",
host: "10.179.2.135"
Purpose: Configures connection to InfluxDB time-series database for storing metrics, alarms, and configuration data.
Parameters Explained
auth (Keyword list)
- Authentication credentials for InfluxDB
- username: InfluxDB user account (
"monitor") - password: InfluxDB password (
"sideunderTexasgalaxyview_61") - Note: For InfluxDB 2.x, this might be an API token instead
database (String)
- Bucket/database name in InfluxDB
- Current value:
"nokia-monitor" - InfluxDB 1.x: Database name
- InfluxDB 2.x: Bucket name
- Creation: Must be created before starting RAN Monitor
# InfluxDB 1.x
influx -execute 'CREATE DATABASE "nokia-monitor"'
# InfluxDB 2.x
influx bucket create -n nokia-monitor -o your-org
host (String)
- InfluxDB server address
- Current value:
"10.179.2.135" - Format: IP address or hostname
- Port: Default InfluxDB port (8086) is assumed
- Examples:
"localhost"- Same server as RAN Monitor"10.179.2.135"- Remote InfluxDB server"influxdb.example.com"- Hostname
InfluxDB Connection Notes
Network Access:
- RAN Monitor must be able to reach InfluxDB server on port 8086
- Verify:
curl http://10.179.2.135:8086/ping
Retention Policies:
- Set via Web UI Data Retention page
- Default: 30 days (720 hours)
- Can be customized per base station

Write Performance:
- InfluxDB receives writes every collection interval (60s default)
- Each base station generates hundreds of data points per interval
- Monitor InfluxDB disk space regularly
Configuration Best Practices
Security
1. Protect Sensitive Data
# Instead of hardcoded passwords:
password: "omnitouch2024"
# Use environment variables:
password: System.get_env("DB_PASSWORD") || "default_password"
2. Restrict File Permissions
chmod 600 config/runtime.exs
chown ran_monitor:ran_monitor config/runtime.exs
3. Never Commit Secrets
- Use
.gitignorefor runtime.exs if it contains secrets - Use environment variables or secret management systems
- Rotate passwords regularly
Performance
1. Database Pool Sizing
- Monitor connection usage
- Increase pool_size if seeing connection timeout errors
- Each device needs ~2 connections during active polling
2. Collection Intervals
- Balance between data granularity and system load
- 60 second intervals work well for most deployments
- Shorter intervals (15s) for troubleshooting
3. InfluxDB Optimization
- Use retention policies to manage disk usage
- Monitor InfluxDB write performance
- Consider separate InfluxDB server for large deployments
Reliability
1. Network Configuration
- Use static IP addresses for all components
- Verify network routes between RAN Monitor and base stations
- Test connectivity before adding devices
- Configure firewall rules appropriately
2. Logging Strategy
- Development:
:debugfor detailed troubleshooting - Production:
:infofor operational visibility - Critical systems: Consider external log aggregation
3. Monitoring RAN Monitor
- Monitor the monitor (meta-monitoring)
- Watch for database connection errors
- Track InfluxDB write success rates
- Alert on base station disconnections
Maintenance
1. Configuration Changes
- Always backup runtime.exs before changes
- Test configuration in development first
- Document changes with comments
- Restart RAN Monitor after configuration changes
2. Adding Base Stations
# 1. Edit runtime.exs
vim config/runtime.exs
# 2. Validate Elixir syntax
elixir -c config/runtime.exs
# 3. Restart application
systemctl restart ran_monitor
3. Scaling Considerations
- Monitor resource usage (CPU, memory, network)
- Increase database pool size as device count grows
- Consider separate InfluxDB instance at 50+ devices
- Monitor disk space for both MySQL and InfluxDB
Example: Complete Configuration
Here's a complete example with multiple base stations and best practices applied:
import Config
# =============================================================================
# Database Configuration
# =============================================================================
config :ran_monitor, RanMonitor.Repo,
username: System.get_env("DB_USERNAME") || "ran_monitor_user",
password: System.get_env("DB_PASSWORD") || "change_this_password",
hostname: System.get_env("DB_HOST") || "localhost",
database: "ran_monitor",
stacktrace: false, # Production: hide stacktraces
show_sensitive_data_on_connection_error: false, # Production: hide credentials
pool_size: 15 # 6 base stations * 2 + 3 overhead
# =============================================================================
# Web Endpoints
# =============================================================================
config :ran_monitor, RanMonitor.Web.Endpoint,
http: [ip: {0, 0, 0, 0}, port: 8080],
check_origin: false,
secret_key_base: System.get_env("SECRET_KEY_BASE") || "generate_with_mix_phx_gen_secret",
server: true
config :control_panel, ControlPanelWeb.Endpoint,
url: [host: "0.0.0.0", port: 9443, scheme: "https"],
https: [
ip: {0, 0, 0, 0},
port: 9443,
keyfile: "priv/cert/server.key",
certfile: "priv/cert/server.crt"
]
config :ran_monitor, RanMonitor.Web.Nokia.Airscale.Endpoint,
url: [host: "0.0.0.0"],
http: [ip: {0, 0, 0, 0}, port: 9076],
server: true
# =============================================================================
# Logger Configuration
# =============================================================================
config :logger,
level: :info # Production setting
config :logger, :console,
format: "$time $metadata[$level] $message\n",
metadata: [:request_id]
# =============================================================================
# Nokia Configuration
# =============================================================================
config :ran_monitor,
general: %{
mcc: "001",
mnc: "001"
},
nokia: %{
ne3s: %{
webhook_url: "http://10.179.2.135:9076/webhook",
private_key: Path.join(Application.app_dir(:ran_monitor, "priv"), "external/nokia/ne.key.pem"),
public_key: Path.join(Application.app_dir(:ran_monitor, "priv"), "external/nokia/ne.cert.der"),
reregister_interval: 30
},
airscales: [
# Site A - Main Tower
%{
address: "10.7.15.66",
name: "Site-A-Main-Tower",
port: "8080",
web_username: "admin",
web_password: System.get_env("BS_SITE_A_PASSWORD") || "password1"
},
# Site A - Backup Tower
%{
address: "10.7.15.67",
name: "Site-A-Backup-Tower",
port: "8080",
web_username: "admin",
web_password: System.get_env("BS_SITE_A_PASSWORD") || "password1"
},
# Site B - Indoor
%{
address: "10.7.16.10",
name: "Site-B-Indoor-DAS",
port: "8080",
web_username: "admin",
web_password: System.get_env("BS_SITE_B_PASSWORD") || "password2"
},
# Site C - Rooftop
%{
address: "192.168.100.50",
name: "Site-C-Rooftop",
port: "8080",
web_username: "admin",
web_password: System.get_env("BS_SITE_C_PASSWORD") || "password3"
},
# Lab - Test Equipment
%{
address: "10.5.198.100",
name: "Lab-Test-Airscale-01",
port: "8080",
web_username: "Nemuadmin",
web_password: "nemuuser"
},
# Lab - Development
%{
address: "10.5.198.101",
name: "Lab-Dev-Airscale-02",
port: "8080",
web_username: "Nemuadmin",
web_password: "nemuuser"
}
]
}
# =============================================================================
# InfluxDB Configuration
# =============================================================================
config :ran_monitor, RanMonitor.InfluxDbConnection,
auth: [
username: System.get_env("INFLUX_USERNAME") || "monitor",
password: System.get_env("INFLUX_PASSWORD") || "change_this_password"
],
database: "nokia-monitor",
host: System.get_env("INFLUX_HOST") || "10.179.2.135"
Related Documentation
- Operations Guide - Day-to-day operations
- AirScale Configuration Guide - Configuring base stations
- Nokia Counter Reference - Performance counter definitions
- Grafana Integration - Building dashboards and alerts
- API Endpoints - REST API reference
- Data Retention Policy - Managing data lifecycle