Register: Difference between revisions

From VoIPmonitor.org
(Review: opravy formátování (pre->syntaxhighlight, typo, heading hierarchy), zkrácení AI Summary)
(Review: opravy formátování, odstranění nepatřičného obsahu z jiných stránek, vyčištění struktury)
Line 1: Line 1:
The SIP Register section shows three tables - Active registered SIP users, Failed registrations and State changes in SIP registrations. Those tables are filled once you enable sip-register = yes in /etc/voipmonitor.conf.
{{DISPLAYTITLE:SIP Register Monitoring}}
[[Category:GUI manual]]


By default PCAP files are not saved for SIP register messages (it can easily overload file system). If you need to record SIP messages you can control this in capture rules main section and here in all three sections there are gray/red small circles which indicates if SIP messages are being recorded to pcap file so it can be retrieved by clicking on PCAP link. Clicking on the circle enables / disables recording. In the dialog window you can adjust values and set auto remove for the rule at specific date.
The SIP Register section shows three tables - Active registered SIP users, Failed registrations, and State changes in SIP registrations. These tables are populated once you enable <code>sip-register = yes</code> in <code>/etc/voipmonitor.conf</code>.
Note: If you need to record all register packets by the sniffer instance without need to create capture rules in a GUI use sip-register-save-all=yes in its config (/etc/voipmonitor.conf)
 
By default, PCAP files are not saved for SIP register messages (it can easily overload the file system). If you need to record SIP messages, you can control this in capture rules main section. In all three sections, there are gray/red small circles which indicate if SIP messages are being recorded to PCAP file so it can be retrieved by clicking on the PCAP link. Clicking on the circle enables/disables recording. In the dialog window you can adjust values and set auto remove for the rule at a specific date.
 
{{Note|1=If you need to record all register packets by the sniffer instance without creating capture rules in the GUI, use <code>sip-register-save-all=yes</code> in <code>/etc/voipmonitor.conf</code>.}}


[[File:register-recording.png]]
[[File:register-recording.png]]


== Active table ==
== Active Table ==


The active table shows current registered users with this columns:
The Active table shows currently registered users with these columns:


[[File:register-active.png]]
[[File:register-active.png]]


*ID/sensor id shows internal unique ID and if enabled sensor id
* '''ID/sensor id''' - Internal unique ID and sensor id (if enabled)
*datetime is time creation
* '''datetime''' - Registration creation time
*User name / realm shows username and realm from REGISTER message
* '''User name / realm''' - Username and realm from REGISTER message
*Source IP / Destination IP
* '''Source IP / Destination IP'''
*From / To / Contact are values from SIP headers
* '''From / To / Contact''' - Values from SIP headers
*Expires at shows date when the registration expires
* '''Expires at''' - Date when the registration expires
*User agent
* '''User agent'''
*Commands - download PCAP
* '''Commands''' - Download PCAP


On the picture below you can see a detail area where a sub-grid with state changes and failed registrations from the user name is located. This holds quick filters for a particular active user where you can quickly see his history. Once the SIP registration is expired  the history is no longer in the Active table . Each expired registration is stored in the State table.
The picture below shows a detail area with a sub-grid containing state changes and failed registrations for the user name. This provides quick filters for a particular active user where you can quickly see their history. Once the SIP registration expires, the history is no longer in the Active table. Each expired registration is stored in the State table.


[[File:register-activesubstate.png]]
[[File:register-activesubstate.png]]


On the picture below you can see a detail area where a sub-grid with related CDR from the user name is located.
The picture below shows a detail area with a sub-grid containing related CDR for the user name.


[[File:register-activesubcdr.png]]
[[File:register-activesubcdr.png]]


== Failed table ==
== Failed Table ==


The failed table shows failed SIP registrations. If some device fails to register continuously the counter column increases instead of creating a new row. If there is a one-hour gap between two failed registrations from the same user a new row will be created.
The Failed table shows failed SIP registrations. If a device fails to register continuously, the counter column increases instead of creating a new row. If there is a one-hour gap between two failed registrations from the same user, a new row will be created.


[[File:register-failed.png]]
[[File:register-failed.png]]


== State table ==
== State Table ==


The state table retains registration history where REGISTER, UNREGISTER and EXPIRE are saved. In each state row you can click on detail [+] to show all related SIP register messages to the selected user. If device registers in regular intervals it will not save state change in the state table (not true now, see bellow) but keeps the last registration status until the re-registration stops - then UNREGISTER will be the last register state change. If the device do not resend registration in time (register expires + 5 second) the last state will be EXPIRE (with red flag).
The State table retains registration history where REGISTER, UNREGISTER and EXPIRE events are saved. In each state row, you can click on detail [+] to show all related SIP register messages for the selected user.


The same state is periodically saved due to e.g. graphing, etc. The default is 600 seconds. It can be changed by sip-register-state-timeout option in the sensor config.
The same state is periodically saved for graphing purposes. The default interval is 600 seconds. It can be changed with the <code>sip-register-state-timeout</code> option in the sensor config.
 
If the device does not resend registration in time (register expires + 5 seconds), the last state will be EXPIRE (with red flag).


[[File:register-state.png]]
[[File:register-state.png]]


== Configuration Location in Distributed Architecture ==
== Configuration in Distributed Architecture ==


In distributed/client-server deployments, the location where you must enable <code>sip-register = yes</code> depends on your <code>packetbuffer_sender</code> configuration:
In distributed/client-server deployments, the location where you must enable <code>sip-register = yes</code> depends on your <code>packetbuffer_sender</code> configuration:
Line 56: Line 62:
|}
|}


To determine where to configure <code>sip-register</code>:
=== Determining Configuration Location ===


;1. Check the <code>packetbuffer_sender</code> setting on your remote sensors:
;1. Check the <code>packetbuffer_sender</code> setting on your remote sensors:
Line 71: Line 77:
* Restart the voipmonitor service on the remote sensor(s)
* Restart the voipmonitor service on the remote sensor(s)


For detailed information on distributed architectures and configuration locations, see [[Sniffer_distributed_architecture]].
For detailed information on distributed architectures, see [[Sniffer_distributed_architecture]].


== How the Active tab retrieves data ==
== How the Active Tab Retrieves Data ==


The Active table in the GUI displays registration data in two different ways, depending on whether the sip-register feature is enabled:
The Active table in the GUI displays registration data in two different ways, depending on whether the sip-register feature is enabled:


*'''When sip-register is disabled (default):''' The GUI retrieves active registration data directly from the running sniffer processes in real-time. The sniffer maintains an in-memory list of currently registered SIP devices and provides this information to the GUI. In this configuration, the database tables (register, register_state, register_failed) are '''not''' created or used. The Active tab will still function correctly and show live registration data.
* '''When sip-register is disabled (default):''' The GUI retrieves active registration data directly from the running sniffer processes in real-time. The sniffer maintains an in-memory list of currently registered SIP devices. In this configuration, the database tables (<code>register</code>, <code>register_state</code>, <code>register_failed</code>) are '''not''' created or used. The Active tab will still function correctly and show live registration data.


*'''When sip-register = yes:''' Registration data is stored in database tables (register, register_state, register_failed) for persistent storage and historical reporting. The GUI can then query these tables to display both current and historical registration information.
* '''When sip-register = yes:''' Registration data is stored in database tables for persistent storage and historical reporting. The GUI can then query these tables to display both current and historical registration information.


== Displaying Multiple Registrations for the Same Account Independently ==
== Displaying Multiple Registrations for the Same Account ==


By default, multiple registrations for the same SIP account (same username) from different IP addresses or ports may be displayed as a single aggregated record in the GUI Active table. To view all registrations for the same account separately (differentiated by their source and destination IP addresses and ports), enable comparison options in the sniffer configuration file.
By default, multiple registrations for the same SIP account from different IP addresses or ports may be displayed as a single aggregated record. To view all registrations separately, enable comparison options in the sniffer configuration.


Add these lines to <code>/etc/voipmonitor.conf</code> (the configuration that processes <code>sip-register=yes</code>):
Add these lines to <code>/etc/voipmonitor.conf</code>:


<syntaxhighlight lang="ini">
<syntaxhighlight lang="ini">
Line 95: Line 101:


# Optional: Track registration state changes separately by From domain
# Optional: Track registration state changes separately by From domain
# Useful when the same SIP account registers from different domains
sip-register-state-compare-from_domain = yes
sip-register-state-compare-from_domain = yes
</syntaxhighlight>
</syntaxhighlight>


These settings instruct the system to create separate registration entries when the source IP (sipcallerip), source port (sipcallerport), destination IP (sipcalledip), destination port (sipcalledport), or From domain differ. This allows you to see each registration instance independently rather than having them merged into a single record. The <code>sip-register-state-compare-from_domain</code> option is particularly useful for accurate alerting when multiple registrations from the same account should be tracked separately based on their originating domain.
These settings create separate registration entries when the source IP, source port, destination IP, destination port, or From domain differ. This allows you to see each registration instance independently rather than merged into a single record.


After modifying the configuration, reload or restart the voipmonitor service for changes to take effect.
After modifying the configuration, restart the voipmonitor service:
<syntaxhighlight lang="bash">
systemctl restart voipmonitor
</syntaxhighlight>


In distributed architectures, apply these settings to the same location where <code>sip-register = yes</code> is configured (central server for <code>packetbuffer_sender=yes</code>, or remote sensor for <code>packetbuffer_sender=no</code>).
In distributed architectures, apply these settings to the same location where <code>sip-register = yes</code> is configured.


== Error: Table 'voipmonitor.register' doesn't exist ==
== Error: Table 'voipmonitor.register' doesn't exist ==


If you see the error message "Table 'voipmonitor.register' doesn't exist" when viewing the Active tab, this is '''expected and correct behavior''' when the sip-register feature is disabled.
If you see the error message "Table 'voipmonitor.register' doesn't exist" when viewing the Active tab, this is '''expected behavior''' when the sip-register feature is disabled.


The error message typically appears if the GUI attempts to query the database table for historical information while the feature is disabled. However, the Active tab will still display live registration data retrieved directly from the sniffer processes.
The error appears if the GUI attempts to query the database table for historical information while the feature is disabled. However, the Active tab will still display live registration data retrieved directly from the sniffer processes.


'''No action is required to fix this error.''' The system is functioning as intended. The error simply indicates that persistent database storage is not enabled for registration data.
'''No action is required.''' If you want to enable persistent storage of registration history, add <code>sip-register = yes</code> to <code>/etc/voipmonitor.conf</code> and restart the sniffer.


If you want to enable persistent storage of registration history, add sip-register = yes to /etc/voipmonitor.conf and restart the sniffer. This will create the database tables and eliminate the error message, but it is optional for basic registration monitoring.
== Troubleshooting: Missing Registration Data ==


== Troubleshooting: Registration Data Missing Despite Traffic Being Present ==
If SIP registration information is missing from the GUI even though traffic is present on your network, follow these troubleshooting steps:


If SIP registration information is missing from the GUI even though traffic is confirmed present on your network mirror port, the issue is likely with packet capture rather than the sip-register configuration. Follow these troubleshooting steps:
=== Step 1: Verify Packets Are Reaching the Sensor ===


;1. Verify packets are reaching the sensor host:
Run a packet capture directly on the sensor interface:
Run a packet capture directly on the sensor to verify REGISTER packets are arriving at the interface. Use <code>tcpdump</code> or <code>tshark</code> on the correct interface:


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
# Check for REGISTER packets on the sensor interface
# Check for REGISTER packets
tcpdump -i napa0 -s 0 -c 10 "port 5060 and udp"
tcpdump -i eth0 -s 0 -c 10 "port 5060 and udp"


# Or use tshark for more detailed analysis
# Or use tshark for more detailed analysis
tshark -i napa0 -Y "sip.Method == REGISTER" -c 10
tshark -i eth0 -Y "sip.Method == REGISTER" -c 10
</syntaxhighlight>
</syntaxhighlight>


If no packets appear, the problem is with your network mirroring configuration (SPAN/TAP). See [[Sniffer_troubleshooting]] for detailed packet capture troubleshooting.
If no packets appear, the problem is with your network mirroring configuration. See [[Sniffer_troubleshooting]].
 
=== Step 2: Check for Packet Drops ===


;2. Check for packet drops in the GUI:
Navigate to '''Settings → Sensors''' in the GUI and check the '''# packet drops''' counter:
Navigate to '''Settings → Sensors''' in the VoIPmonitor GUI. Expand the sensor details and check the '''# packet drops''' counter.


{| class="wikitable"
{| class="wikitable"
|-
|-
! Packet Drops Value !! Meaning !! Action
! Packet Drops !! Meaning !! Action
|-
|-
| 0 || Normal || No drop issues
| 0 || Normal || No drop issues
|-
|-
| Non-zero value || Sensor is dropping packets || See [[Sniffer_troubleshooting#Check_Sensor_Statistics_in_GUI|Sniffer Troubleshooting: Sensor Statistics]]
| Non-zero || Sensor is dropping packets || See [[Sniffer_troubleshooting#Check_Sensor_Statistics_in_GUI|Sensor Statistics]]
|}
|}


;3. If using Napatech hardware:
=== Step 3: Napatech Hardware Issues ===
Standard capture tools may show no packets if Napatech interfaces are in a DOWN state. This is a common issue with Napatech cards.
 
If using Napatech cards, standard capture tools may show no packets if interfaces are in DOWN state.


Check interface status:
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
# Check interface status
ip link show napa0
ip link show napa0
</syntaxhighlight>
If the interface shows DOWN instead of UP, the solution is to use a custom <code>libpcap</code> library provided by Napatech. See [[Napatech#Troubleshooting:_Napatech_Interfaces_in_DOWN_State|Napatech Troubleshooting]] for detailed steps to:
* Check if Napatech drivers are loaded
* Verify voipmonitor is linked against Napatech libpcap
* Rebuild the sniffer with the correct library


The key command to verify:
# Verify voipmonitor is using Napatech libpcap
<syntaxhighlight lang="bash">
# Check which libpcap voipmonitor is using
ldd /usr/local/sbin/voipmonitor | grep pcap
ldd /usr/local/sbin/voipmonitor | grep pcap
# Should show: /opt/napatech3/lib/libpcap.so.1
# Should show: /opt/napatech3/lib/libpcap.so.1
# NOT: /lib/x86_64-linux-gnu/libpcap.so.1
</syntaxhighlight>
</syntaxhighlight>


;4. Additional troubleshooting resources:
See [[Napatech#Troubleshooting]] for detailed steps.
* [[Sniffer_troubleshooting]] - Comprehensive guide for diagnosing packet capture issues
* [[Sniffer_troubleshooting#Is_Network_Traffic_Reaching_the_Server|Network traffic verification with tshark]]
* [[Sniffer_troubleshooting#Check_the_VoIPmonitor_Configuration]] - Verify interface, sipport, and filter settings


== Slow Queries on register_state Table ==
== Slow Queries on register_state Table ==


If queries on the <code>register_state</code> table are extremely slow or time out when filtering by text fields (Username, Domain, Number), especially for older data, this indicates missing indexes on frequently queried columns.
If queries on the <code>register_state</code> table are slow when filtering by Username, Domain, or Number, this indicates missing indexes.


=== Problem Description ===
=== Symptoms ===
 
The <code>register_state</code> table stores SIP registration history (REGISTER, UNREGISTER, EXPIRE events). Because SIP devices re-register frequently (typically every 30-60 seconds), this table accumulates rows very quickly. Queries filtering by text fields without proper indexes require full table scans, which are extremely slow on large tables.
 
=== Common Symptoms ===


* Queries with filters on Username, Domain, or Number time out
* Queries with filters on Username, Domain, or Number time out
* Searches for specific registration events take 30+ seconds or indefinite
* GUI Register State tab is unresponsive when applying filters
* GUI Register State tab is unresponsive when applying filters
* MySQL shows high CPU usage from register_state queries
* MySQL shows high CPU usage from register_state queries
Line 188: Line 179:
=== Solution: Create Missing Indexes ===
=== Solution: Create Missing Indexes ===


The root cause is almost always missing indexes on columns used in WHERE clauses. Create indexes manually on the most frequently queried columns.
First, verify which indexes exist:
 
First, verify which indexes already exist:


<syntaxhighlight lang="sql">
<syntaxhighlight lang="sql">
-- Show current indexes on register_state
SHOW INDEX FROM register_state;
SHOW INDEX FROM register_state;
</syntaxhighlight>
</syntaxhighlight>


Look for indexes on:
Create indexes on frequently queried columns:
* <code>digestusername</code>
* <code>digest_from_number</code>
* <code>digest_to_number</code>
* <code>digest_to_domain</code>
* <code>digest_realm</code>
 
If these indexes are missing, create them:


<syntaxhighlight lang="sql">
<syntaxhighlight lang="sql">
-- Create index on username (most common query)
CREATE INDEX digestusername ON register_state (digestusername);
CREATE INDEX digestusername ON register_state (digestusername);
-- Create indexes on other frequently queried columns
CREATE INDEX digest_from_number ON register_state (digest_from_number);
CREATE INDEX digest_from_number ON register_state (digest_from_number);
CREATE INDEX digest_to_number ON register_state (digest_to_number);
CREATE INDEX digest_to_number ON register_state (digest_to_number);
Line 217: Line 195:
</syntaxhighlight>
</syntaxhighlight>


{{Warning|
{{Warning|1=<code>CREATE INDEX</code> on large tables can be slow and may block writes. Schedule during maintenance windows.}}
<code>CREATE INDEX</code> operations on large tables can be very slow and may block write operations to the table. Schedule index creation during a maintenance window or low-traffic periods.
}}
 
=== Additional Performance Optimization ===


If performance is still insufficient after adding indexes:
=== Additional Optimization ===


1. Increase <code>innodb_buffer_pool_size</code> in MySQL configuration (see [[Scaling#Memory_Configuration|Scaling Guide]])
* Increase <code>innodb_buffer_pool_size</code> in MySQL configuration (see [[Scaling]])
2. Configure <code>cleandatabaseregister = 7</code> (or 30) in <code>/etc/voipmonitor.conf</code> to limit data retention (see [[Data_Cleaning]])
* Configure <code>cleandatabaseregister = 7</code> in <code>/etc/voipmonitor.conf</code> to limit data retention (see [[Data_Cleaning]])


{{Note|
{{Note|1=For MySQL 5.6+ or MariaDB 10.1+, use online index creation: <code>CREATE INDEX digestusername ON register_state (digestusername) ALGORITHM=INPLACE, LOCK=NONE;</code>}}
For MySQL 5.6+ or MariaDB 10.1+, use online index creation to avoid blocking writes:
<code>CREATE INDEX digestusername ON register_state (digestusername) ALGORITHM=INPLACE, LOCK=NONE;</code>
}}


=== Calculating Required innodb_buffer_pool_size for High-Volume REGISTER Data ===
=== Calculating innodb_buffer_pool_size for High-Volume Data ===


For systems with high REGISTER volume (e.g., 30 million records per day), determining the maximum history you can store without performance degradation requires calculating the correct <code>innodb_buffer_pool_size</code>.
For systems with high REGISTER volume (e.g., 30 million records per day):
 
==== Understanding the Limit ====
 
The "maximum" history you can query efficiently is determined by the amount of data that fits entirely within MySQL's <code>innodb_buffer_pool_size</code>. If the database tables and indexes exceed this memory allocation, queries must read from disk (I/O), which is significantly slower.
 
==== Step-by-Step Calculation ====
 
Follow these steps to calculate the required buffer pool size based on your specific daily volume and query requirements:
 
1. '''Calculate the size of database partitions for a single day:'''


1. '''Calculate daily partition size:'''
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
ls -lat /var/lib/mysql/voipmonitor | grep pYYMMDD | cut -d' ' -f 7 | paste -s -d+ - | bc
ls -lat /var/lib/mysql/voipmonitor | grep pYYMMDD | cut -d' ' -f 7 | paste -s -d+ - | bc
</syntaxhighlight>
</syntaxhighlight>


Replace <code>pYYMMDD</code> with the actual partition date format (e.g., <code>p250101</code> for January 1, 2025).
2. '''Multiply by days needed:''' If each day is 15GB and you need 7 days: 15GB × 7 = 105GB minimum buffer pool
 
2. '''Multiply by the number of days you need to query quickly:'''
 
For example, if each day is 15GB and you need to query last 7 days efficiently:
15GB × 7 days = 105GB minimum buffer pool
 
3. '''Configure MySQL to use this calculated value:'''
 
Edit your MySQL configuration file (e.g., <code>/etc/mysql/my.cnf</code> or <code>/etc/mysql/mariadb.conf.d/50-server.cnf</code>):


3. '''Configure MySQL:'''
<syntaxhighlight lang="ini">
<syntaxhighlight lang="ini">
[mysqld]
[mysqld]
# Set to the calculated value or higher
innodb_buffer_pool_size = 128G
innodb_buffer_pool_size = 128G
</syntaxhighlight>
</syntaxhighlight>


4. '''Ensure sufficient physical RAM:'''
4. '''Ensure sufficient RAM''' to accommodate the buffer pool plus OS and application overhead
 
The server must have enough physical RAM to accommodate the <code>innodb_buffer_pool_size</code> '''plus''' operating system, application, and other MySQL memory allocations. Avoid using swap, as swap usage leads to severe performance degradation.
 
==== Practical Guidelines ====
 
For high-volume REGISTER environments:
 
* '''30+ million records/day:''' Expect 15-20+ GB per day. Require 64GB+ RAM for 3-7 day history.
* '''Partition-based storage:''' VoIPmonitor uses MySQL partitioning by date. Query performance drops sharply when filters span partitions not cached in the buffer pool.
* '''Set aggressive retention policy:''' Use <code>cleandatabaseregister = 3</code> (or lower) to maintain manageable table sizes. See [[Data_Cleaning]] for retention options.


==== Query Timing Warnings ====
==== Query Timing Warnings ====


To avoid performance impact on real-time monitoring:
* Avoid large range reports during peak traffic hours
 
* Avoid reports during the partition maintenance window (1:00 AM - 5:00 AM)
* '''Avoid running large range reports during peak traffic hours.''' History queries spanning multiple days can monopolize I/O resources.
* Schedule large historical queries during off-peak hours
* '''Avoid running reports during the partition maintenance window (1:00 AM - 5:00 AM).''' This is when automatic partition cleanup occurs, competing for database resources.
* '''Schedule large historical queries during maintenance windows or off-peak hours.'''


== AI Summary for RAG ==
== AI Summary for RAG ==


'''Summary:''' The SIP Register section displays Active, Failed, and State tables for monitoring SIP registrations. Enable with <code>sip-register = yes</code> in voipmonitor.conf for persistent database storage; the Active tab works in real-time even when disabled (data retrieved directly from sniffer process). In distributed architectures, configure <code>sip-register</code> on the central server if <code>packetbuffer_sender=yes</code>, or on remote sensors if <code>packetbuffer_sender=no</code>. By default, PCAP files are not saved for REGISTER messages to prevent disk overload; enable via capture rules or <code>sip-register-save-all=yes</code> globally. To display multiple registrations for the same account independently (instead of aggregated), enable comparison options: <code>sip-register-compare-sipcallerip</code>, <code>sip-register-compare-sipcallerport</code>, <code>sip-register-compare-sipcalledip</code>, <code>sip-register-compare-sipcalledport</code>, and optionally <code>sip-register-state-compare-from_domain</code>. For slow queries on register_state table, create indexes on digestusername, digest_from_number, digest_to_number, digest_to_domain, digest_realm. For high-volume environments (30M+ records/day), calculate required <code>innodb_buffer_pool_size</code> based on daily partition size × days to retain. Avoid large reports during partition maintenance window (1:00-5:00 AM).
'''Summary:''' The SIP Register section displays Active, Failed, and State tables for monitoring SIP registrations. Enable with <code>sip-register = yes</code> in voipmonitor.conf for persistent database storage; the Active tab works in real-time even when disabled (data retrieved directly from sniffer process). In distributed architectures, configure <code>sip-register</code> on the central server if <code>packetbuffer_sender=yes</code>, or on remote sensors if <code>packetbuffer_sender=no</code>. By default, PCAP files are not saved for REGISTER messages; enable via capture rules or <code>sip-register-save-all=yes</code>. To display multiple registrations for the same account independently, enable comparison options: <code>sip-register-compare-sipcallerip</code>, <code>sip-register-compare-sipcallerport</code>, <code>sip-register-compare-sipcalledip</code>, <code>sip-register-compare-sipcalledport</code>, and <code>sip-register-state-compare-from_domain</code>. For slow queries on register_state table, create indexes on digestusername, digest_from_number, digest_to_number, digest_to_domain, digest_realm. For high-volume environments, calculate required <code>innodb_buffer_pool_size</code> based on daily partition size × retention days.


'''Keywords:''' SIP Register, Active, Failed, State, sip-register, packetbuffer_sender, distributed architecture, central server, remote sensor, multiple registrations, aggregated registrations, sip-register-compare-sipcallerip, sip-register-compare-sipcallerport, sip-register-compare-sipcalledip, sip-register-compare-sipcalledport, sip-register-state-compare-from_domain, register_state, slow query, index, digestusername, innodb_buffer_pool_size, cleandatabaseregister, PCAP recording, sip-register-save-all, Napatech, packet drops, tcpdump, tshark
'''Keywords:''' SIP Register, Active, Failed, State, sip-register, packetbuffer_sender, distributed architecture, multiple registrations, sip-register-compare-sipcallerip, register_state, slow query, index, digestusername, innodb_buffer_pool_size, cleandatabaseregister, PCAP recording, sip-register-save-all, Napatech, packet drops


'''Key Questions:'''
'''Key Questions:'''
Line 299: Line 240:
* Why does the Active tab show "Table 'voipmonitor.register' doesn't exist"?
* Why does the Active tab show "Table 'voipmonitor.register' doesn't exist"?
* How to display multiple registrations for the same account separately?
* How to display multiple registrations for the same account separately?
* Why are fewer SIP trunks shown in the Registered client list than actually registered?
* How to fix aggregated registrations showing as single record?
* Why are queries on register_state table so slow?
* Why are queries on register_state table so slow?
* How to create indexes on register_state columns?
* How to create indexes on register_state columns?
* How to calculate innodb_buffer_pool_size for high-volume REGISTER data?
* How to calculate innodb_buffer_pool_size for high-volume REGISTER data?
* What is the partition maintenance window time?
* How to verify packets are reaching the sensor interface?
* How to verify packets are reaching the sensor interface?
* How to troubleshoot Napatech interfaces in DOWN state?
* How to troubleshoot Napatech interfaces in DOWN state?
upgrade on a development/staging system first if possible
* Major version upgrades (e.g., 5.7 to 8.0) require additional planning and testing
* Review the MySQL upgrade documentation for your version for any breaking changes
=== Which Recovery Method to Use ===
'''Use Table-Level Repair (First Attempt when MySQL is running):'''
* MySQL/MariaDB service is running and accessible
* Only specific tables are corrupted (not entire database)
* You want to preserve CDR data as much as possible
* Corruption appears mild and detected early
* System is experiencing poor performance but still accessible
This method uses <code>mysqlcheck --repair</code> or <code>REPAIR TABLE</code> to fix individual tables without dropping the database. See the <code>Solution: Table-Level Repair</code> section above.
'''Use Drop and Recreate Database (Simplest, when MySQL is running):'''
* MySQL/MariaDB service is running and accessible
* Only the voipmonitor database is corrupted
* You do not need to preserve CDR data (historical call records are acceptable to lose)
* You want to restore service quickly with minimal downtime
* GUI configuration loss is acceptable or will be reconfigured
'''Use innodb_force_recovery (Recommended for filesystem corruption/InnoDB assertion failures):'''
* MySQL fails to start after a filesystem issue (Read-only file system errors)
* InnoDB assertion failures during startup
* PCAP files may or may not be available in the spool directory
* You need to preserve GUI configuration (users, sensors, settings)
* You are willing to lose all CDR data if it cannot be restored from PCAP
'''Use PCAP restore (Alternative):'''
* PCAP files are definitely available and intact in the spool directory
* You want to restore historical CDR data along with GUI configuration
* The innodb_force_recovery method did not work
* You have time for a lengthy re-processing operation
=== Solution: Drop and Recreate Database (Simplest, When MySQL is Running) ===
If MySQL/MariaDB is running but only the voipmonitor database is corrupted, the fastest recovery method is to drop the corrupted database and let the sensor recreate it automatically.
'''Warning:''' This procedure will result in complete loss of all CDR data, call recordings, and GUI configuration. You will need to reconfigure sensors, users, and settings in the GUI.
==== Step 1: Stop All VoIPmonitor Sensor Processes ====
Stop all VoIPmonitor sensors to prevent further database corruption during the recovery process.
<syntaxhighlight lang="bash">
# Stop all VoIPmonitor sensor services
systemctl stop voipmonitor
# If running distributed (client/server mode), stop all sensor services:
# - On server sensors: systemctl stop voipmonitor-server
# - On client sensors: systemctl stop voipmonitor-client
# - Check all running sensors: ps aux | grep voipmonitor
</syntaxhighlight>
If you are using a client/server architecture, stop ALL sensors first, including both client and server sensors.
==== Step 2: Drop the Corrupted VoIPmonitor Database ====
Delete the corrupted voipmonitor database from MySQL/MariaDB.
<syntaxhighlight lang="bash">
# Connect to MySQL as root
mysql -u root -p
</syntaxhighlight>
Run the following SQL command:
<syntaxhighlight lang="sql">
DROP DATABASE IF EXISTS voipmonitor;
EXIT;
</syntaxhighlight>
Replace the database name <code>voipmonitor</code> if you are using a custom database name in your configuration.
==== Step 3: Restart a Single Sensor to Create Fresh Database ====
Start ONE sensor instance (preferably the server sensor in client/server mode) so it can automatically create a fresh, empty database with all required tables.
<syntaxhighlight lang="bash">
# Start the primary sensor (or server sensor in client/server mode)
systemctl start voipmonitor
# Verify the sensor is running
systemctl status voipmonitor
# Monitor the sensor log for database creation messages
journalctl -u voipmonitor -f
</syntaxhighlight>
The sensor will automatically create the voipmonitor database, all tables, functions, and routines. You should see log messages indicating the database structure is being created.
==== Step 4: Start All Remaining Sensors ====
Once the database is created, start any additional sensors (client sensors in distributed mode).
<syntaxhighlight lang="bash">
# Start any remaining sensors
systemctl start voipmonitor-client1
systemctl start voipmonitor-client2
# ... etc for all sensors
</syntaxhighlight>
==== Step 5: Verify System Functionality ====
Verify that the system is operating correctly.
* Access the VoIPmonitor web GUI and log in
* You may need to reconfigure the GUI (create users, sensors, capture rules, alerts)
* Check that the sniffer service is running and capturing:
  <syntaxhighlight lang="bash">systemctl status voipmonitor</syntaxhighlight>
* Confirm that new calls are being captured and processed
==== Step 6: Prevent Future Corruption with Automatic Database Cleanup ====
To prevent future database corruption due to excessive data accumulation, configure automatic database cleanup using the <code>cleandatabase*</code> options in your sensor configuration file (<code>/etc/voipmonitor.conf</code>).
Edit the configuration file:
<syntaxhighlight lang="bash">
sudo nano /etc/voipmonitor.conf
</syntaxhighlight>
Add or adjust the following parameters based on your requirements:
<syntaxhighlight lang="ini">
# Automatically delete CDR records older than X days
cleandatabase = 90;  # Delete CDRs older than 90 days
# Optionally control per-table cleanup
cleandatabasecdr = 90;      # Delete cdr table records older than 90 days
cleandatabasemsg = 30;        # Delete message table records older than 30 days
cleandatabaseregister = 7;    # Delete register table records older than 7 days
cleandatabasesip = 30;        # Delete sip table records older than 30 days
cleandatabasequeue = 180;    # Delete queue table records older than 180 days
# Optionally control cleanup timing
cleandatabasehour = 3;        # Run cleanup at 3:00 AM daily
cleandatabaseminute = 0;      # At 00 minutes past the hour
</syntaxhighlight>
For more information on data retention and cleanup options, see the [[Data_Cleaning]] page.
Restart the sensor after making configuration changes:
<syntaxhighlight lang="bash">
systemctl restart voipmonitor
</syntaxhighlight>
=== Solution: Using innodb_force_recovery (Recommended for Filesystem Corruption and InnoDB Assertion Failures) ===
If the database is corrupted after a filesystem issue and MySQL/MariaDB fails to start with InnoDB assertion errors, you can attempt to recover using the MySQL <code>innodb_force_recovery</code> parameter. This method starts MySQL in a read-only recovery mode, allowing you to back up and restore the GUI configuration.
'''Warning:''' This procedure will result in complete loss of CDR data. Only the GUI configuration can be preserved.
==== Step 1: Ensure Filesystem Issues Are Resolved ====
Before attempting MySQL recovery, the underlying filesystem issue that caused the corruption must be fixed. MySQL will likely fail again if the disk is still having problems.
===== Detailed Filesystem Check (fsck) Procedure =====
If a partition becomes read-only due to filesystem errors, follow these steps to repair it:
1. '''Identify the problematic partition:'''
<syntaxhighlight lang="bash">
# Check mount points to see which partition is affected
df -h
# Check for read-only mount or I/O errors in dmesg
dmesg | tail -100 | grep -i "read-only\|i/o error\|ext4-fs"
</syntaxhighlight>
2. '''Stop services writing to the partition:'''
Important: You must stop any services (voipmonitor, mariadb, etc.) that are writing to the affected partition before unmounting it.
<syntaxhighlight lang="bash">
# Example: Stop services that write to /home partition
systemctl stop voipmonitor mariadb
# Adjust these services based on which partition is affected
</syntaxhighlight>
3. '''Unmount the partition:'''
<syntaxhighlight lang="bash">
# Unmount the affected partition
umount /home
# Replace /home with your actual mount point from df -h
</syntaxhighlight>
4. '''Run filesystem check:'''
<syntaxhighlight lang="bash">
# Standard partition (e.g., /dev/sda1)
fsck -t ext4 -y /dev/sda1
# LVM partition (e.g., /dev/mapper/vg_northvoipmonitorr630-lv_home)
fsck -t ext4 -y /dev/mapper/vg_northvoipmonitorr630-lv_home
</syntaxhighlight>
The <code>-t ext4</code> flag specifies the filesystem type (ext3, ext4, xfs, etc.). Use <code>df -T</code> to check the filesystem type. The <code>-y</code> flag automatically answers 'yes' to all repair prompts.
5. '''Remount the partition:'''
<syntaxhighlight lang="bash">
mount /home
# Replace with your mount point
</syntaxhighlight>
6. '''Restart the services:'''
<syntaxhighlight lang="bash">
systemctl start mariadb voipmonitor
# Adjust these services based on what you stopped
</syntaxhighlight>
7. '''Verify the filesystem is healthy:'''
<syntaxhighlight lang="bash">
# Check mount status and free space
df -h
# Verify mounted read-write (not read-only)
mount | grep "on /home type"
# Check system logs for filesystem errors
dmesg | grep -i ext4 | tail -20
</syntaxhighlight>
'''Summary Checklist:'''
* Check <code>dmesg</code> or <code>/var/log/syslog</code> for I/O errors
* Ensure the partition is mounted Read-Write (not Read-Only)
* Stop services writing to the partition before unmounting
* Unmount and run <code>fsck</code> on the unmounted device
* Remount and restart services
* Verify filesystem health with <code>df -h</code>, <code>mount</code>, and <code>dmesg</code>
==== Step 2: Enable innodb_force_recovery Mode ====
Add the recovery parameter to MySQL's configuration to start it in read-only mode. This allows MySQL to start despite InnoDB corruption.
Edit the MySQL/MariaDB configuration file:
<syntaxhighlight lang="bash">
sudo nano /etc/my.cnf
# or
sudo nano /etc/mysql/my.cnf
</syntaxhighlight>
Add the following line to the <code>[mysqld]</code> section:
<syntaxhighlight lang="ini">
[mysqld]
innodb_force_recovery=6
</syntaxhighlight>
The <code>innodb_force_recovery=6</code> setting is the most aggressive recovery mode. It allows MySQL to start in read-only mode even with severe InnoDB corruption. See the [[#Understanding innodb_force_recovery Levels|innodb_force_recovery levels]] section below for details on each level.
==== Step 3: Back Up GUI Configuration ====
With MySQL in recovery mode, back up the GUI configuration before proceeding.
<syntaxhighlight lang="bash">
cd /var/www/html
php php/run.php backupGuiTables -t config -f /root/backup.zip
</syntaxhighlight>
This command exports all GUI settings (users, sensors, capture rules, alerts, etc.) to a backup file. For more information on GUI backup and restore, see the [[Backing_Up_GUI_Configuration]] page.
==== Step 4: Stop MySQL and Back Up Corrupted Data ====
Stop the MySQL service and create a backup of the corrupted MySQL data directory.
<syntaxhighlight lang="bash">
# Stop MySQL
systemctl stop mysql
# or
systemctl stop mariadb
# Move the corrupted data directory to a backup location
sudo mv /var/lib/mysql /var/lib/mysql-corrupted
</syntaxhighlight>
==== Step 5: Re-initialize MySQL Data Directory ====
Create a new, empty MySQL data directory.
<syntaxhighlight lang="bash">
# Reinitialize MySQL data directory
sudo mysql_install_db --user=mysql --datadir=/var/lib/mysql
# or on newer systems:
sudo mysqld --initialize --user=mysql
</syntaxhighlight>
==== Step 6: Remove innodb_force_recovery and Start MySQL ====
Remove the recovery parameter from the configuration file and start MySQL normally.
First, edit the configuration file and remove or comment out the line:
<syntaxhighlight lang="ini">
[mysqld]
# innodb_force_recovery=6  <-- Comment out or remove this line
</syntaxhighlight>
Then start MySQL:
<syntaxhighlight lang="bash">
systemctl start mysql
# or
systemctl start mariadb
# Verify MySQL is running
systemctl status mysql
</syntaxhighlight>
MySQL should now be able to start with a fresh, empty database.
==== Step 7: Create VoIPmonitor Database ====
Create a new database for VoIPmonitor:
<syntaxhighlight lang="bash">
mysql -u root -p
</syntaxhighlight>
Run the following SQL commands:
<syntaxhighlight lang="sql">
CREATE DATABASE voipmonitor;
CREATE USER 'voipmonitor'@'localhost' IDENTIFIED BY 'your_password_here';
GRANT ALL PRIVILEGES ON voipmonitor.* TO 'voipmonitor'@'localhost';
FLUSH PRIVILEGES;
EXIT;
</syntaxhighlight>
==== Step 8: Restore GUI Configuration ====
Restore the GUI configuration from the backup file created in Step 3.
<syntaxhighlight lang="bash">
cd /var/www/html
php php/run.php restoreGuiTables -t config -f /root/backup.zip
</syntaxhighlight>
==== Step 9: Verify System Functionality ====
Verify that the GUI and sniffer are working correctly.
* Access the VoIPmonitor web GUI and log in
* Verify that sensors, users, and other settings are present
* Check that the sniffer service is running:
  <syntaxhighlight lang="bash">systemctl status voipmonitor</syntaxhighlight>
* Confirm that new calls are being captured and processed
'''Note:''' All historical CDR data has been lost. Only the GUI configuration was preserved. The system will begin accumulating new CDR data from this point forward.
==== Understanding innodb_force_recovery Levels ====
The <code>innodb_force_recovery</code> parameter accepts values from 1 to 6, each enabling progressively more aggressive recovery options:
{| class="wikitable"
|-
! Value
! Meaning
|-
| 1
| (SRV_FORCE_IGNORE_CORRUPT) Runs the server even if it detects a corrupt page
|-
| 2
| (SRV_FORCE_NO_BACKGROUND) Prevents the master thread from running; prevents crash recovery
|-
| 3
| (SRV_FORCE_NO_TRX_UNDO) Does not run transaction rollbacks after recovery
|-
| 4
| (SRV_FORCE_NO_IBUF_MERGE) Prevents insert buffer merge operations
|-
| 5
| (SRV_FORCE_NO_UNDO_LOG_SCAN) Does not look at undo logs when starting the database
|-
| 6
| (SRV_FORCE_NO_LOG_REDO) Does not apply the redo log from crash recovery (most aggressive)
|}
For maximum recovery capability, use <code>innodb_force_recovery=6</code>. This mode enables all recovery strategies and allows MySQL to start even with severe InnoDB corruption.
=== Solution: Restore from PCAP Files (Alternative) ===
If you have PCAP files available in the spool directory, you can restore CDR data from them instead of using <code>innodb_force_recovery</code>. This preserves your call recordings and metadata by reprocessing the packet captures.
'''When to use PCAP restore:'''
* PCAP files are available in the spool directory
* You want to restore historical CDR data, not just GUI configuration
* <code>innodb_force_recovery</code> method did not work
'''Warning:''' This procedure requires stopping the VoIPmonitor services and may take significant time depending on the amount of data to restore.
The following diagram illustrates the restoration workflow:
<kroki lang="plantuml">
@startuml
skinparam shadowing false
skinparam defaultFontName Arial
skinparam activityFontSize 12
skinparam arrowFontSize 11
title Database Restore from PCAP Files
start
:Stop VoIPmonitor services;
note right: voipmonitor, manager, gui
:Backup corrupted database;
note right: /var/lib/mysql-backup-corrupted
:Remove corrupted database;
note right: /var/lib/mysql/voipmonitor
:Start MySQL/MariaDB;
:Create fresh database;
note right: CREATE DATABASE voipmonitor
:Run sniffer in restore mode;
note right: --readpcapdir /var/spool/voipmonitor
while (All PCAP files processed?) is (no)
  :Process next PCAP file;
  :Generate CDR records;
endwhile (yes)
:Stop restore process;
:Start normal service;
note right: systemctl start voipmonitor
:Verify Web GUI access;
stop
@enduml
</kroki>
==== Step 1: Stop VoIPmonitor Services ====
Stop all VoIPmonitor services to prevent further database corruption:
<syntaxhighlight lang="bash">
# Stop the sniffer service
systemctl stop voipmonitor
# Stop sniffer manager (if running)
systemctl stop voipmonitor-manager
# Stop any other VoIPmonitor services
systemctl stop voipmonitor-gui
</syntaxhighlight>
==== Step 2: Backup the Corrupted Database ====
Although corrupted, create a backup of the existing database for troubleshooting purposes:
<syntaxhighlight lang="bash">
# Stop MySQL/MariaDB service
systemctl stop mysql
# Create a backup of the MySQL data directory
sudo cp -a /var/lib/mysql /var/lib/mysql-backup-corrupted
</syntaxhighlight>
==== Step 3: Remove the Corrupted Database ====
Move or remove the corrupted database files to prepare for a fresh database:
<syntaxhighlight lang="bash">
# Remove the corrupted VoIPmonitor database directory
sudo rm -rf /var/lib/mysql/voipmonitor
# Alternatively, move it instead of deleting:
sudo mv /var/lib/mysql/voipmonitor /var/lib/mysql/voipmonitor.corrupted
</syntaxhighlight>
==== Step 4: Start MySQL/MariaDB Service ====
Restart the MySQL/MariaDB service:
<syntaxhighlight lang="bash">
# Start MySQL/MariaDB
systemctl start mysql
# Verify the service is running
systemctl status mysql
</syntaxhighlight>
==== Step 5: Create a Fresh VoIPmonitor Database ====
Create a new empty database for VoIPmonitor:
<syntaxhighlight lang="bash">
# Log in to MySQL as root
mysql -u root -p
</syntaxhighlight>
Run the following SQL commands:
<syntaxhighlight lang="sql">
CREATE DATABASE voipmonitor;
CREATE USER 'voipmonitor'@'localhost' IDENTIFIED BY 'your_password_here';
GRANT ALL PRIVILEGES ON voipmonitor.* TO 'voipmonitor'@'localhost';
FLUSH PRIVILEGES;
EXIT;
</syntaxhighlight>
Replace <code>your_password_here</code> with a strong password.
==== Step 6: Restore CDRs from PCAP Files ====
Instruct the sniffer to reprocess all PCAP files from the spool directory and populate the new database:
<syntaxhighlight lang="bash">
# 1. Verify your spool directory path
# Check voipmonitor.conf for the spooldir setting (default: /var/spool/voipmonitor)
grep "^spooldir" /etc/voipmonitor.conf
# 2. Clear the sniffer's manager socket for the restore process
# This ensures clean communication with the sniffer
rm -f /tmp/vmsck
# 3. Start the sniffer in restore mode
# The sniffer will read all PCAP files from the spool directory
# and regenerate CDR records in the new database
voipmonitor --config-file /etc/voipmonitor.conf --readpcapdir /var/spool/voipmonitor
</syntaxhighlight>
'''Note:''' The <code>--readpcapdir</code> parameter instructs the sniffer to process all PCAP files in the specified directory. This may take considerable time depending on the amount of historical data.
==== Step 7: Monitor the Restore Process ====
Monitor the restore progress:
<syntaxhighlight lang="bash">
# Monitor sniffer output for progress
journalctl -u voipmonitor -f
# Alternatively, check the database for new CDR records
mysql -u root -p voipmonitor -e "SELECT COUNT(*) FROM cdr;"
</syntaxhighlight>
==== Step 8: Restart Normal Service ====
Once the restore is complete, restart the sniffer in normal operation mode:
<syntaxhighlight lang="bash">
# Stop the restore process (Ctrl+C if running manually)
# Then start the normal sniffer service
systemctl start voipmonitor
# Verify the sniffer is running and capturing
systemctl status voipmonitor
# Test Web GUI access
# Navigate to http://your-server/ in your browser
</syntaxhighlight>
=== Prevention: Database Backup Strategies ===
To avoid future data loss due to database corruption:
==== Automatic Filesystem Backup ====
Configure regular backups of the MySQL data directory:
<syntaxhighlight lang="bash">
# Example: Daily backup using cron
0 2 * * * /usr/bin/rsync -av --delete /var/lib/mysql/ /backup/mysql-$(date +\%Y\%m\%d)/
</syntaxhighlight>
==== MySQL Replication ====
Set up MySQL master-slave replication for redundancy:
* See the [[Mysql_master-slave_replication_hints]] guide for detailed instructions
* This provides a real-time backup database that can be promoted if corruption occurs
==== VoIPmonitor Database Replication ====
Use VoIPmonitor's built-in database backup mode ([[Redundant_database]]):
* This replicates CDR data to a secondary database server
* No traditional MySQL replication required
* Useful for GUI migrations and disaster recovery
== RRD Graph Errors After Hardware Upgrades ==
After a hardware upgrade or system migration, RRD (Round Robin Database) graphs in the VoIPmonitor GUI may display errors indicating that Data Sources (DS) are missing from RRD files. This occurs because RRD files are created with a specific hardware-dependent schema that may become incompatible after system changes.
=== Symptoms ===
* RRD graphs in the Web GUI show display errors instead of rendering data
* Error message: <code>ERROR: No DS called '...' in '/var/spool/voipmonitor/rrd/..."'</code>
* Example: <code>ERROR: No DS called 'SQLq-SM' in '/var/spool/voipmonitor/rrd/3db-SQL.rrd'</code>
* The error appears after hardware upgrades, CPU changes, or system migrations
* Multiple RRD files may be affected, affecting various graph types
=== RRD File Location ===
RRD files are stored in the RRD directory within the VoIPmonitor spool directory:
<code>/var/spool/voipmonitor/rrd/</code>
=== Root Cause ===
RRD (Round Robin Database) files contain time-series data with a schema defined at creation time. Some data sources in RRD files are hardware-specific (e.g., CPU metrics tied to specific CPU identifiers). When hardware changes, the schema information stored in the RRD files may no longer match the current system configuration, resulting in missing Data Source (DS) errors.
=== Solution: Delete Corrupted RRD Files ===
The VoIPmonitor service will automatically recreate RRD files with the correct schema if they are missing. This is a safe operation because:
* New RRD files will be created with the current hardware's correct schema
* Historical RRD data is typically short-term (graph display purposes only)
* CDR data and call recordings are stored separately and are not affected
==== Step 1: Stop the VoIPmonitor Service ====
Stop the voipmonitor service to prevent file access conflicts:
<syntaxhighlight lang="bash">
systemctl stop voipmonitor
</syntaxhighlight>
==== Step 2: Remove Corrupted RRD Files ====
Delete the affected RRD files from the RRD directory. You can remove individual problematic files or the entire RRD directory:
<syntaxhighlight lang="bash">
# Option 1: Remove specific corrupted RRD file (recommended)
rm /var/spool/voipmonitor/rrd/3db-SQL.rrd
# Option 2: Remove all RRD files if multiple errors exist
rm /var/spool/voipmonitor/rrd/*
</syntaxhighlight>
Replace <code>3db-SQL.rrd</code> with the actual filename from the error message.
==== Step 3: Start the VoIPmonitor Service ====
Start the voipmonitor service to recreate the RRD files:
<syntaxhighlight lang="bash">
systemctl start voipmonitor
</syntaxhighlight>
The service will automatically detect the missing RRD files and recreate them with the correct schema based on the current hardware configuration. New graph data will begin accumulating immediately.
==== Step 4: Verify RRD Graphs ====
Check the Web GUI to verify that RRD graphs are now displaying correctly:
* Navigate to the VoIPmonitor Web GUI
* Access dashboard or reporting pages with RRD graphs
* Verify that graphs render without errors
* Note: Historical data in the affected RRD files will be lost, but new data will start appearing
=== Rerunning with Different Hardware ===
If you need to preserve RRD data when moving to different hardware (for example, testing on a different machine), consider these options:
* '''Don't copy RRD files''' - Let the new system create fresh RRD files with appropriate schemas
* '''Use rrdtool dump/restore''' - For advanced users, you can modify RRD file contents using rrdtool export/import tools
* '''Accept data loss''' - RRD data is typically short-term monitoring data, not critical call records
=== Related Information ===
* RRD files are separate from CDR data (cdr table in MySQL) and PCAP recordings
* The VoIPmonitor <code>spooldir</code> location is configurable in /etc/voipmonitor.conf
* RRD files are automatically created by the sniffer service when needed
== Faxes Cannot Be Displayed in the GUI ==
If faxes cannot be displayed in the GUI and an error message appears, the issue is likely that the required package for fax conversion is not installed.
=== Symptoms ===
* Faxes are not displayed in the GUI or a generic error message appears when attempting to view fax contents
* Other GUI features work normally
* No error in browser console related to failed binary execution
=== Root Cause ===
The GUI requires the `tiff2pdf` utility to convert fax TIFF images for display in the web browser. This utility is part of the `libtiff-tools` package on Debian/Ubuntu systems or related packages on other distributions.
=== Solution: Install libtiff-tools Package ===
Install the required package using your system's package manager.
'''For Debian/Ubuntu:'''
<syntaxhighlight lang="bash">
# SSH into the GUI host
sudo apt-get update
sudo apt-get install libtiff-tools
</syntaxhighlight>
'''For CentOS/RHEL/AlmaLinux:'''
<syntaxhighlight lang="bash">
sudo yum install libtiff-tools
# or on newer systems:
sudo dnf install libtiff-tools
</syntaxhighlight>
=== Verifying the Fix ===
Verify that the `tiff2pdf` binary is accessible and executable by the web server user:
<syntaxhighlight lang="bash">
# Check if tiff2pdf is available system-wide
which tiff2pdf
# Verify the web server user can access tiff2pdf
# For Debian/Ubuntu (www-data)
runuser -u www-data -- which tiff2pdf
# For CentOS/RHEL (apache)
runuser -u apache -- which tiff2pdf
</syntaxhighlight>
If the command returns a path (e.g., `/usr/bin/tiff2pdf`), the binary is correctly installed and accessible.
After installing the package, reload the GUI and try to display faxes again. The ability to view faxes in the GUI should now be restored.
=== Related Information ===
* The `tiff2pdf` utility converts TIFF image files to PDF format for web browser display
* Faxes are captured by VoIPmonitor as TIFF images in T.38 fax sessions
* This conversion is required because not all browsers can display TIFF images natively
* Other GUI features (audio playback, graphs, etc.) may have different package requirements
== Incorrect Ownership / Permission Errors ==
If the GUI reports an "incorrect ownership" error even after verifying that the web server user (e.g., apache or www-data) has write permissions to the web root directory, the actual error may be hidden. The web server user needs **execute permissions** on all binary files in the `./bin` directory of the GUI installation.
=== Symptoms ===
* GUI displays "incorrect ownership" or permission errors
* Error persists even after fixing ownership/permissions on the web root directory
* Binary files in the bin directory cannot be executed by the web server
=== Root Cause ===
The GUI requires the web server user to have execute permissions on all binary files in the `bin` directory (e.g., `sox-x86_64`, `ffmpeg`, etc.). These binaries are used by the GUI for audio processing, call playback, and other features. If the binaries lack execute permissions, the GUI cannot run them.
=== Solution: Set Execute Permissions on Binaries ===
Check and fix permissions on all files in the `./bin` directory:
<syntaxhighlight lang="bash">
# Navigate to the GUI installation directory (default is /var/www/html)
cd /var/www/html
# Check the bin directory
ls -la bin/
# Set execute permissions on all files in the bin directory
chmod +x bin/*
# For specific binaries, you can set execute permissions individually
chmod +x bin/sox-x86_64
chmod +x bin/ffmpeg
</syntaxhighlight>
=== Verifying the Fix ===
Test that the binaries can be executed by the web server user:
<syntaxhighlight lang="bash">
# For Debian/Ubuntu (www-data)
su - www-data -s /bin/bash -c "/var/www/html/bin/sox-x86_64 --version"
# or
su - www-data -s /bin/bash -c "ls -x /var/www/html/bin/"
# For CentOS/RHEL (apache)
su - apache -s /bin/bash -c "/var/www/html/bin/sox-x86_64 --version"
# or
su - apache -s /bin/bash -c "ls -x /var/www/html/bin/"
</syntaxhighlight>
If the binaries can now be executed, the GUI should work correctly.
=== Troubleshooting Symlinks ===
Sometimes the `bin` directory contains symlinks to other locations. Check both the symlink and its target:
<syntaxhighlight lang="bash">
# Check if files are symlinks and their targets
ls -lah bin/
# If a symlink cannot be accessed, check permissions on the target
# For example, if bin/sox-x86_64 is a symlink:
ls -l bin/sox-x86_64
ls -l /path/to/real/location/sox-x86_64
# Fix permissions on the target if needed
chmod +x /path/to/real/location/sox-x86_64
</syntaxhighlight>
=== Reproducing the Error ===
To verify that missing execute permissions cause this error, you can temporarily remove execute permissions:
<syntaxhighlight lang="bash">
# Remove execute permissions (reproduces the error)
chmod -x bin/sox-x86_64
# Test the GUI - should show "incorrect ownership" error
# Restore execute permissions
chmod +x bin/sox-x86_64
</syntaxhighlight>
=== Common Binaries in bin/ Directory ===
Typical binaries that require execute permissions include:
* `sox-x86_64` - Audio conversion tool
* `ffmpeg` - Video/audio processing
* `soxr` - Audio resampling library
* Other utility binaries used by the GUI
== IonCube Loader Issues ==
The VoIPmonitor GUI is protected with IonCube, which requires proper PHP configuration. Common issues include permission errors on temporary directories and security module interference.
=== Unable to create lock file / temp directory not writable ===
If you see errors like "Unable to create lock file" or "System temp directory check fails... not writable" from IonCube Loader, follow these troubleshooting steps:
==== Step 1: Update the system and restart ====
First, ensure your system packages are up to date:
<syntaxhighlight lang="bash">
# Debian/Ubuntu
sudo apt update && sudo apt upgrade -y
# RHEL/CentOS/AlmaLinux
sudo yum update -y
# or
sudo dnf update -y
# Then restart the server
sudo reboot
</syntaxhighlight>
==== Step 2: Check SELinux or AppArmor ====
Security modules like SELinux (default on RHEL/CentOS/Red Hat systems) or AppArmor (default on Ubuntu/Debian) can block IonCube from accessing temporary directories.
'''Check if SELinux is enabled:'''
<syntaxhighlight lang="bash">
# Check current status
getenforce
# Common values: Enforcing (active), Permissive (logging only), Disabled
# To temporarily disable SELinux for testing:
sudo setenforce 0
</syntaxhighlight>
If disabling SELinux resolves the issue, you can permanently configure it:
<syntaxhighlight lang="bash">
# Edit the SELinux configuration file
sudo nano /etc/selinux/config
# Change SELINUX= to either:
# SELINUX=permissive
# or
# SELINUX=disabled
# Then reboot the server
sudo reboot
</syntaxhighlight>
'''Check if AppArmor is enabled:'''
<syntaxhighlight lang="bash">
# Check AppArmor status
sudo aa-status
# If AppArmor is running, temporarily disable individual profiles:
sudo aa-disable /etc/apparmor.d/*php*
# Or disable it entirely for testing:
sudo systemctl stop apparmor
sudo systemctl disable apparmor
</syntaxhighlight>
==== Step 3: Check systemd PrivateTmp ====
Some systemd service configurations use <code>PrivateTmp=true</code>, which creates a private temporary directory for each service. This can cause issues if the private tmp directory has restrictive permissions.
Check if your web server is using PrivateTmp:
<syntaxhighlight lang="bash">
# For Apache
systemctl show httpd | grep PrivateTmp
# or
systemctl show apache2 | grep PrivateTmp
# For PHP-FPM
systemctl show php-fpm | grep PrivateTmp
</syntaxhighlight>
If PrivateTmp is enabled (value=1), disable it in the service file:
<syntaxhighlight lang="bash">
# Create override directory if it doesn't exist
sudo mkdir -p /etc/systemd/system/httpd.service.d
# Create override file
sudo nano /etc/systemd/system/httpd.service.d/privatetmp.conf
</syntaxhighlight>
Add the following content:
<syntaxhighlight lang="ini">
[Service]
PrivateTmp=false
</syntaxhighlight>
Then reload and restart:
<syntaxhighlight lang="bash">
# Reload systemd and restart the service
sudo systemctl daemon-reload
sudo systemctl restart httpd
# or
sudo systemctl restart apache2
</syntaxhighlight>
==== Step 4: Verify PHP Temporary Directory Configuration ====
Check which temporary directory PHP is using:
Create a PHP info file:
<syntaxhighlight lang="bash">
echo '<?php phpinfo(); ?>' > /var/www/html/info.php
</syntaxhighlight>
Visit <code>http://your-server-ip/info.php</code> in your browser and search for:
* <code>upload_tmp_dir</code>
* <code>sys_get_temp_dir</code>
* <code>session.save_path</code>
Ensure these directories are writable by the web server user:
<syntaxhighlight lang="bash">
# Check ownership
ls -ld /tmp
# Fix ownership if needed
sudo chown www-data:www-data /tmp  # Debian/Ubuntu
# or
sudo chown apache:apache /tmp      # CentOS/RHEL
# Fix permissions
sudo chmod 1777 /tmp
</syntaxhighlight>
'''Important:''' Clean up after troubleshooting:
<syntaxhighlight lang="bash">
rm /var/www/html/info.php
</syntaxhighlight>
==== Step 5: Check open_basedir restrictions ====
If the above steps don't resolve the issue, check if PHP's <code>open_basedir</code> is restricting access to the temp directory:
<syntaxhighlight lang="bash">
# Check open_basedir in php.ini
grep open_basedir /etc/php/*/apache2/php.ini
# or
grep open_basedir /etc/php.ini
</syntaxhighlight>
Ensure the temp directory is included in the list, e.g.:
<code>open_basedir = /var/www/html:/tmp:/var/tmp</code>
=== Failed check Ioncube.com PHP Loader for php cli ===
If the GUI installation check fails with the error "Failed check Ioncube.com PHP Loader for php cli : no ionCube extension enabled in PHP cli" even though IonCube appears to be correctly installed from the command line, the issue is often a difference between the PHP CLI environment tested by root and the PHP environment used by the web server.
==== Diagnosis: Exact Web Server Environment Test ====
To diagnose the issue, run the exact command the GUI uses as the web server user instead of root:
<syntaxhighlight lang="bash">
# Test IonCube extension as the web server user
sudo -u www-data PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin php -r 'echo extension_loaded("ionCube Loader")?"yes":"no";' 2>&1
# For CentOS/RHEL systems, replace www-data with apache
sudo -u apache PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin php -r 'echo extension_loaded("ionCube Loader")?"yes":"no";' 2>&1
</syntaxhighlight>
If this command returns "no" but the same command as root returns "yes", there is a configuration difference between users.
Note the <code>PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin</code> parameter is critical - it ensures the web server user can find the correct PHP binary.
==== Compare PHP Configuration Files ====
The CLI PHP may use a different configuration file than the web server PHP. Compare the configurations:
<syntaxhighlight lang="bash">
# Check which configuration file CLI PHP uses
php --ini
# Create phpinfo file to check web server configuration
echo '<?php phpinfo(); ?>' > /var/www/html/info.php
# Visit http://your-server-ip/info.php in your browser
# Look for "Loaded Configuration File" and "Additional .ini files parsed"
</syntaxhighlight>
==== Verify zend_extension Directive Placement ====
Ensure the <code>zend_extension</code> directive for IonCube Loader is in the correct PHP configuration file used by the web server, not just in the CLI configuration:
<syntaxhighlight lang="bash">
# Check for IonCube in web server config
grep -r "ioncube_loader" /etc/php/*/apache2/conf.d/
grep -r "ioncube_loader" /etc/php/*/fpm/conf.d/
# or for CentOS/RHEL
grep -r "ioncube_loader" /etc/php.d/
# Check CLI config
grep -r "ioncube_loader" /etc/php/*/cli/conf.d/
</syntaxhighlight>
If the web server config is missing the <code>zend_extension = ioncube_loader_lin_*.so</code> line, add it in the appropriate directory:
<syntaxhighlight lang="bash">
# Example for PHP 8.1 on Debian/Ubuntu (Apache)
echo 'zend_extension = ioncube_loader_lin_8.1.so' | sudo tee /etc/php/8.1/apache2/conf.d/00-ioncube.ini
# Example for PHP 8.1 on Debian/Ubuntu (FPM)
echo 'zend_extension = ioncube_loader_lin_8.1.so' | sudo tee /etc/php/8.1/fpm/conf.d/00-ioncube.ini
# Example for CentOS/RHEL
echo 'zend_extension = ioncube_loader_lin_8.1.so' | sudo tee /etc/php.d/00-ioncube.ini
</syntaxhighlight>
Restart the web server after making changes:
<syntaxhighlight lang="bash">
# Debian/Ubuntu with Apache
sudo systemctl restart apache2
# Debian/Ubuntu with PHP-FPM
sudo systemctl restart php8.1-fpm
# CentOS/RHEL with httpd
sudo systemctl restart httpd
# CentOS/RHEL with PHP-FPM
sudo systemctl restart php-fpm
</syntaxhighlight>
Clean up the test file:
<syntaxhighlight lang="bash">
rm /var/www/html/info.php
</syntaxhighlight>
== /dev/shm Filesystem Capacity Issues ==
After a period of operation, user sessions may start logging out and new logins become impossible. This occurs when the <code>/dev/shm</code> filesystem (tmpfs) reaches its capacity limit. The VoIPmonitor GUI stores PHP session files in <code>/dev/shm</code> by default for performance reasons.
=== Symptoms ===
* Users are frequently logged out from the GUI
* New logins fail or immediately redirect to login screen
* <code>/dev/shm</code> is reported as full (100% capacity)
* GUI behavior improves temporarily after clearing session files
=== Diagnosis ===
Check the current <code>/dev/shm</code> usage:
<syntaxhighlight lang="bash">
# Check /dev/shm usage and available space
df -h /dev/shm
# Check how much space is used by session files
du -sh /dev/shm/php_sessions/*
# Count session files
ls /dev/shm/php_sessions/ | wc -l
</syntaxhighlight>
=== Solution: Increase /dev/shm Size ===
==== Temporary Increase (Until Reboot) ====
To temporarily increase the size of <code>/dev/shm</code> without rebooting:
<syntaxhighlight lang="bash">
# Remount /dev/shm with increased size (example: 1GB)
mount -o remount,size=1G /dev/shm
# Verify the new size
df -h /dev/shm
</syntaxhighlight>
Adjust the size parameter (<code>size=1G</code>) based on your server's RAM and expected number of concurrent users.
==== Permanent Configuration (Persistent After Reboot) ====
To make the size increase permanent, edit the <code>/etc/fstab</code> file:
<syntaxhighlight lang="bash">
# Edit /etc/fstab as root
sudo nano /etc/fstab
</syntaxhighlight>
Find the line for <code>/dev/shm</code>. It typically looks like this:
<pre>tmpfs /dev/shm tmpfs defaults 0 0</pre>
Modify it to include the size parameter:
<pre>tmpfs /dev/shm tmpfs defaults,size=1G 0 0</pre>
Save the file and apply the changes without rebooting:
<syntaxhighlight lang="bash">
# Remount all filesystems from /etc/fstab
mount -a
# Verify the new size
df -h /dev/shm
</syntaxhighlight>
=== Prevention: Session Cleanup Configuration ===
Ensure that PHP is configured to clean up old session files from <code>/dev/shm</code>. Check the following PHP configuration settings:
<syntaxhighlight lang="bash">
# Check session configuration
php -i | grep -i session
# Look for these directives in php.ini:
# session.gc_maxlifetime - Session lifetime in seconds (default: 1440 = 24 minutes)
# session.gc_probability - Probability of garbage collection (default: 0)
# session.gc_divisor - Garbage collection divisor (default: 1000)
</syntaxhighlight>
For automatic cleanup, ensure <code>session.gc_probability</code> is set to a non-zero value. The probability is calculated as <code>gc_probability / gc_divisor</code>. For example:
* <code>session.gc_probability = 1</code> and <code>session.gc_divisor = 100</code> = 1% chance each session start
* <code>session.gc_probability = 1</code> and <code>session.gc_divisor = 10</code> = 10% chance each session start
=== Related Information ===
* <code>/dev/shm</code> is a tmpfs filesystem backed by RAM
* Increasing <code>/dev/shm</code> size consumes physical RAM - monitor total memory usage
* The GUI typically stores session files in <code>/dev/shm/php_sessions/</code> when configured for performance
* Alternative session handlers (memcached, redis) can be considered for very high-traffic deployments
== Alternative: MySQL General Log ==
If you need a persistent server-side log of all database queries (not just from the GUI), you can enable the MySQL general log:
<syntaxhighlight lang="sql">
-- Enable general log
SET GLOBAL general_log = 'ON';
-- Perform actions in the GUI...
-- Disable when done (important for performance)
SET GLOBAL general_log = 'OFF';
</syntaxhighlight>
The log file location is typically <code>/var/lib/mysql/hostname.log</code> or as defined in your MySQL configuration.
'''Warning:''' The general log can grow very quickly on a busy system. Always disable it after debugging.
== AI Summary for RAG ==
'''Summary:''' This page covers GUI troubleshooting techniques including debug mode activation, MySQL/MariaDB database corruption restoration, and filesystem repair procedures. The database corruption section includes FOUR recovery methods with clear decision criteria: (1) Table-Level Repair (FIRST ATTEMPT when MySQL is running and corruption is limited to specific tables - use mysqlcheck --repair or REPAIR TABLE) by stopping voipmonitor, running mysqlcheck --repair voipmonitor, repairing specific InnoDB tables with "REPAIR TABLE cdr; REPAIR TABLE cdr_next_partition;", checking and trimming large tables with DELETE/OPTIMIZE or configuring cleandatabase options, restarting services, and optionally upgrading MySQL to latest version in branch (e.g., 5.7.33 to latest 5.7.x), (2) Drop and recreate database (SIMPLEST AND FASTEST - use when MySQL is running, corruption is widespread, data loss is acceptable, and quick service restoration is needed) by stopping sensors with systemctl stop voipmonitor, dropping the database with DROP DATABASE IF EXISTS voipmonitor, restarting one sensor to auto-recreate the database, then starting remaining sensors, (3) innodb_force_recovery parameter (ONLY for InnoDB assertion failures after filesystem corruption where MySQL fails to start - this is more complex and requires GUI backup/restore) to save GUI configuration when MySQL cannot start normally, and (4) restore from PCAP files (alternative when PCAP files are available and you want to restore historical CDR data). For recovery, ALWAYS try table-level repair first (mysqlcheck) if MySQL is running, then drop/recreate if repair fails or data loss is acceptable, then innodb_force_recovery for severe InnoDB corruption. Corruption indicators in MySQL logs include "semaphore waits", "page corruption detected", "Table is marked as crashed", "InnoDB Assertion failure". Prevention: Configure cleandatabase* options (cleandatabase=90 etc.) in /etc/voipmonitor.conf to prevent future corruption from excessive data accumulation. The filesystem check section provides complete fsck procedure for repairing read-only partitions (stop services, unmount, run fsck -t ext4 -y, remount, restart services, verify). Other topics include browser cache issues after GUI upgrade (clear cache or hard refresh Ctrl+F5/Cmd+Shift+R), faxes not being displayed in the GUI (missing libtiff-tools package with tiff2pdf utility), incorrect ownership errors caused by missing execute permissions on GUI binaries in the ./bin directory, incorrect web root directory ownership causing "Invalid compressed data in update file" error, RRD graph errors after hardware upgrades (delete RRD files, service auto-recreates), upgrade issues (web portal inaccessible after upgrade requiring web server restart, blank screen with JavaScript errors, conflicting constants.php file, blank white screen due to SELinux), apilicensecheck.php fatal error (DO NOT reinstall entire GUI - replace only the patched file), IonCube Loader problems, and /dev/shm filesystem capacity issues.
'''Keywords:''' GUI troubleshooting, debug mode, MySQL corruption, MariaDB corruption, database restore, PCAP restore, CDR restore, drop database, recreate database, drop and recreate, DROP DATABASE, sensor auto-create, database corruption recovery, cleandatabase, cleandatabasecdr, cleandatabasemsg, cleandatabaseregister, cleandatabasesip, cleandatabasequeue, automatic database cleanup, prevent corruption, innodb_force_recovery, InnoDB assertion failure, read-only filesystem, filesystem repair, filesystem check, fsck, partition repair, umount, remount, ext4, filesystem errors, I/O errors, disk check, partition readonly, read-only partition, GUI configuration backup, GUI configuration restore, table-level repair, mysqlcheck, mysqlcheck --repair, REPAIR TABLE, repair corrupted tables, table corruption, semaphore waits, page corruption, InnoDB page corruption, database error log, check MySQL error log, trim large tables, DELETE old data, OPTIMIZE TABLE, upgrade MySQL server, MySQL upgrade, latest MySQL version, MySQL 5.7.33, MySQL 5.7 upgrade, faxes not displaying, cannot display faxes, fax error, FAX, T.38, fax TIFF, TIFF images, PDF conversion, tiff2pdf, missing tiff2pdf, libtiff-tools, install libtiff-tools, fax package, fax conversion, fax preview, fax missing, incorrect ownership, permission errors, bin directory, execute permissions, chmod +x, sox-x86_64, ffmpeg, symlinks, web root ownership, chown -R, Invalid compressed data in update file, web server user, apache, www-data, nginx, directory ownership fix, update fails, RRD graphs, RRD error, Round Robin Database, hardware upgrade, No DS called, delete RRD files, systemctl stop voipmonitor, upgrade issues, web portal inaccessible, restart httpd, restart apache2, restart php-fpm, systemctl restart, IonCube, SELinux, AppArmor, PrivateTmp, temporary directory, permissions, open_basedir, blank screen, blank white screen, JavaScript errors, constants.php, PEAR, ReferenceError, setenforce, /dev/shm, dev shm, tmpfs, session logout, login failed, mount -o remount, fstab, session gc, session.gc_maxlifetime, session.gc_probability, php_sessions, apilicensecheck.php, findExecutableFile, patched file, license check API, Check License, undefined function, call to undefined function, PHP Fatal error, DO NOT reinstall, full reinstall not required, replace single file, backup original file, chown www-data:www-data, chmod 644, browser cache, clear cache, hard refresh, Ctrl+F5, Cmd+Shift+R, cookies, stale assets, GUI upgrade cache issues
'''Key Questions:'''
* How do I enable debug mode in the GUI to see SQL queries?
* IP lookup stopped working after GUI upgrade - what do I do?
* Features stop working immediately after GUI upgrade - how do I fix it?
* How do I clear browser cache and cookies after a GUI upgrade?
* What is a hard refresh and how do I perform it (Ctrl+F5, Cmd+Shift+R)?
* Why should I clear browser cache after upgrading the GUI?
* GUI features broken after upgrade but web server restart doesn't help - what now?
* Icons or styling appear wrong after GUI upgrade - how do I fix it?
* Faxes cannot be displayed in the GUI - what do I do?
* What package do I need to install to view faxes in the GUI?
* How do I fix fax display errors in VoIPmonitor?
* Why are faxes not showing in my VoIPmonitor GUI?
* tiff2pdf command not found - how do I fix fax display?
* How do I verify tiff2pdf is accessible to the web server?
* What is the tiff2pdf utility used for in VoIPmonitor?
* How do I install libtiff-tools for fax display?
* GUI update fails with "Invalid compressed data in update file" - what do I do?
* The GUI reports an incorrect ownership error but web server user has permissions - what do I check?
* My MySQL database is corrupted, data loss is acceptable, and I need to restore service quickly - what do I do?
* What is the FASTEST way to restore service when MySQL database is corrupted?
* How do I quickly fix a corrupted voipmonitor database when MySQL is running?
* Should I use drop and recreate or innodb_force_recovery for database corruption?
* When should I use DROP DATABASE vs innodb_force_recovery?
* What is the simplest way to restore service when the voipmonitor database is corrupted?
* How do I use the sensor to auto-create a fresh database?
* What should I do if the MySQL/MariaDB database is corrupted but the service is running?
* How do I use mysqlcheck --repair to fix corrupted tables?
* What is the table-level repair method for database corruption?
* How do I use REPAIR TABLE to fix InnoDB corruption?
* How do I trim large tables to free disk space?
* How do I upgrade MySQL server after database corruption?
* What are the MySQL error log indicators for database corruption (semaphore waits, page corruption, InnoDB Assertion failure)?
* How do I fix a corrupted voipmonitor database when MySQL is running?
* How do I drop and recreate the voipmonitor database?
* How do I configure cleandatabase options to prevent future database corruption?
* What cleandatabase parameters should I set for automatic database cleanup?
* How do I prevent database corruption due to excessive data accumulation?
* How do I stop sensors and restart them to recreate the database?
* What is the DROP DATABASE command for corrupted voipmonitor database?
* How do I choose between drop/recreate and innodb_force_recovery for database corruption?
* How do I fix incorrect ownership errors related to the bin directory?
* What files need execute permissions in the GUI bin directory?
* How do I use chmod +x on GUI binaries like sox-x86_64?
* Why do GUI binaries need execute permissions?
* How do I verify that the web server user can execute binaries in the bin directory?
* What should I do if the MySQL/MariaDB database is corrupted after a filesystem issue?
* How do I choose between innodb_force_recovery and PCAP restore for database corruption?
* MySQL fails to start after filesystem crash with InnoDB assertion failures - which method should I use?
* How do I use innodb_force_recovery to recover MySQL from InnoDB corruption?
* What is the innodb_force_recovery parameter in MySQL?
* How do I back up and restore GUI configuration using backupGuiTables and restoreGuiTables?
* MySQL fails to start with InnoDB assertion failure - how do I fix it?
* How do I reinitialize MySQL data directory after corruption?
* How do I restore CDR data from PCAP files after database corruption?
* When should I use innodb_force_recovery versus PCAP restore for database corruption?
* RRD graphs show error "No DS called 'SQLq-SM'" after hardware upgrade - how do I fix it?
* How do I fix web portal inaccessible after GUI upgrade?
* Should I restart the web server after upgrading the GUI?
* What web server commands should I use after a GUI upgrade?
* How do I fix RRD graph errors appearing after system migration or CPU change?
* Can I delete RRD files and will voipmonitor recreate them automatically?
* Where are VoIPmonitor RRD files stored?
* How do I fix "Unable to create lock file" errors from IonCube Loader?
* How do I check if SELinux or AppArmor is blocking the GUI?
* What is systemd PrivateTmp and how does it affect the GUI?
* Why is my GUI showing a blank screen with JavaScript ReferenceError after an update?
* How do I fix ReferenceError: _AuditActivity_download_wav is not defined?
* My GUI shows a blank white screen after login without JavaScript errors - is this caused by SELinux?
* How do I disable SELinux to fix blank white screen in the GUI?
* What is the command to temporarily disable SELinux (setenforce 0)?
* How do I permanently disable SELinux in /etc/selinux/config?
* How do I check if SELinux is enabled with getenforce?
* My Check License API call fails with "Call to undefined function findExecutableFile()" - how do I fix it?
* Call to undefined function findExecutableFile in apilicensecheck.php - should I reinstall the entire GUI?
* How do I replace apilicensecheck.php with a patched file from support?
* What is the correct fix for apilicensecheck.php PHP Fatal error?
* How do I fix the apilicensecheck.php fatal error requiring a patched file?
* Users are being logged out and cannot login - /dev/shm is full - what do I do?
* How do I increase /dev/shm size?
* How do I permanently change /dev/shm size in /etc/fstab?
* How do I configure PHP to clean up old session files from /dev/shm?
* A Linux partition becomes read-only due to filesystem errors - how do I fix it?
* How do I run fsck to repair a read-only filesystem?
* What is the procedure for fixing a filesystem that is mounted read-only?
* How do I stop services before running fsck on a partition?
* How do I unmount a partition to run filesystem check?
* What fsck command do I use to repair a read-only partition?
* How do I check the filesystem type before running fsck?
* What should I do after running fsck on a corrupted filesystem?
* How do I verify the filesystem is healthy after running fsck?
* What is the correct order: fsck first or MySQL recovery first?

Revision as of 18:00, 6 January 2026


The SIP Register section shows three tables - Active registered SIP users, Failed registrations, and State changes in SIP registrations. These tables are populated once you enable sip-register = yes in /etc/voipmonitor.conf.

By default, PCAP files are not saved for SIP register messages (it can easily overload the file system). If you need to record SIP messages, you can control this in capture rules main section. In all three sections, there are gray/red small circles which indicate if SIP messages are being recorded to PCAP file so it can be retrieved by clicking on the PCAP link. Clicking on the circle enables/disables recording. In the dialog window you can adjust values and set auto remove for the rule at a specific date.

ℹ️ Note: If you need to record all register packets by the sniffer instance without creating capture rules in the GUI, use sip-register-save-all=yes in /etc/voipmonitor.conf.

Active Table

The Active table shows currently registered users with these columns:

  • ID/sensor id - Internal unique ID and sensor id (if enabled)
  • datetime - Registration creation time
  • User name / realm - Username and realm from REGISTER message
  • Source IP / Destination IP
  • From / To / Contact - Values from SIP headers
  • Expires at - Date when the registration expires
  • User agent
  • Commands - Download PCAP

The picture below shows a detail area with a sub-grid containing state changes and failed registrations for the user name. This provides quick filters for a particular active user where you can quickly see their history. Once the SIP registration expires, the history is no longer in the Active table. Each expired registration is stored in the State table.

The picture below shows a detail area with a sub-grid containing related CDR for the user name.

Failed Table

The Failed table shows failed SIP registrations. If a device fails to register continuously, the counter column increases instead of creating a new row. If there is a one-hour gap between two failed registrations from the same user, a new row will be created.

State Table

The State table retains registration history where REGISTER, UNREGISTER and EXPIRE events are saved. In each state row, you can click on detail [+] to show all related SIP register messages for the selected user.

The same state is periodically saved for graphing purposes. The default interval is 600 seconds. It can be changed with the sip-register-state-timeout option in the sensor config.

If the device does not resend registration in time (register expires + 5 seconds), the last state will be EXPIRE (with red flag).

Configuration in Distributed Architecture

In distributed/client-server deployments, the location where you must enable sip-register = yes depends on your packetbuffer_sender configuration:

Mode Configuration Location Processing Location
packetbuffer_sender = yes (Packet Mirroring) Central server Central server processes raw packets from remote sensors
packetbuffer_sender = no (Local Processing) Remote sensor Each sensor processes packets locally before sending CDRs to central server

Determining Configuration Location

1. Check the packetbuffer_sender setting on your remote sensors
grep packetbuffer_sender /etc/voipmonitor.conf
2. If packetbuffer_sender = yes
  • Configure sip-register = yes on the central server's /etc/voipmonitor.conf
  • Restart the voipmonitor service on the central server
3. If packetbuffer_sender = no (or not set)
  • Configure sip-register = yes on the remote sensor's /etc/voipmonitor.conf
  • Restart the voipmonitor service on the remote sensor(s)

For detailed information on distributed architectures, see Sniffer_distributed_architecture.

How the Active Tab Retrieves Data

The Active table in the GUI displays registration data in two different ways, depending on whether the sip-register feature is enabled:

  • When sip-register is disabled (default): The GUI retrieves active registration data directly from the running sniffer processes in real-time. The sniffer maintains an in-memory list of currently registered SIP devices. In this configuration, the database tables (register, register_state, register_failed) are not created or used. The Active tab will still function correctly and show live registration data.
  • When sip-register = yes: Registration data is stored in database tables for persistent storage and historical reporting. The GUI can then query these tables to display both current and historical registration information.

Displaying Multiple Registrations for the Same Account

By default, multiple registrations for the same SIP account from different IP addresses or ports may be displayed as a single aggregated record. To view all registrations separately, enable comparison options in the sniffer configuration.

Add these lines to /etc/voipmonitor.conf:

# Enable independent display of multiple registrations for the same account
sip-register-compare-sipcallerip = yes
sip-register-compare-sipcallerport = yes
sip-register-compare-sipcalledip = yes
sip-register-compare-sipcalledport = yes

# Optional: Track registration state changes separately by From domain
sip-register-state-compare-from_domain = yes

These settings create separate registration entries when the source IP, source port, destination IP, destination port, or From domain differ. This allows you to see each registration instance independently rather than merged into a single record.

After modifying the configuration, restart the voipmonitor service:

systemctl restart voipmonitor

In distributed architectures, apply these settings to the same location where sip-register = yes is configured.

Error: Table 'voipmonitor.register' doesn't exist

If you see the error message "Table 'voipmonitor.register' doesn't exist" when viewing the Active tab, this is expected behavior when the sip-register feature is disabled.

The error appears if the GUI attempts to query the database table for historical information while the feature is disabled. However, the Active tab will still display live registration data retrieved directly from the sniffer processes.

No action is required. If you want to enable persistent storage of registration history, add sip-register = yes to /etc/voipmonitor.conf and restart the sniffer.

Troubleshooting: Missing Registration Data

If SIP registration information is missing from the GUI even though traffic is present on your network, follow these troubleshooting steps:

Step 1: Verify Packets Are Reaching the Sensor

Run a packet capture directly on the sensor interface:

# Check for REGISTER packets
tcpdump -i eth0 -s 0 -c 10 "port 5060 and udp"

# Or use tshark for more detailed analysis
tshark -i eth0 -Y "sip.Method == REGISTER" -c 10

If no packets appear, the problem is with your network mirroring configuration. See Sniffer_troubleshooting.

Step 2: Check for Packet Drops

Navigate to Settings → Sensors in the GUI and check the # packet drops counter:

Packet Drops Meaning Action
0 Normal No drop issues
Non-zero Sensor is dropping packets See Sensor Statistics

Step 3: Napatech Hardware Issues

If using Napatech cards, standard capture tools may show no packets if interfaces are in DOWN state.

# Check interface status
ip link show napa0

# Verify voipmonitor is using Napatech libpcap
ldd /usr/local/sbin/voipmonitor | grep pcap
# Should show: /opt/napatech3/lib/libpcap.so.1

See Napatech#Troubleshooting for detailed steps.

Slow Queries on register_state Table

If queries on the register_state table are slow when filtering by Username, Domain, or Number, this indicates missing indexes.

Symptoms

  • Queries with filters on Username, Domain, or Number time out
  • GUI Register State tab is unresponsive when applying filters
  • MySQL shows high CPU usage from register_state queries

Solution: Create Missing Indexes

First, verify which indexes exist:

SHOW INDEX FROM register_state;

Create indexes on frequently queried columns:

CREATE INDEX digestusername ON register_state (digestusername);
CREATE INDEX digest_from_number ON register_state (digest_from_number);
CREATE INDEX digest_to_number ON register_state (digest_to_number);
CREATE INDEX digest_to_domain ON register_state (digest_to_domain);
CREATE INDEX digest_realm ON register_state (digest_realm);

⚠️ Warning: CREATE INDEX on large tables can be slow and may block writes. Schedule during maintenance windows.

Additional Optimization

  • Increase innodb_buffer_pool_size in MySQL configuration (see Scaling)
  • Configure cleandatabaseregister = 7 in /etc/voipmonitor.conf to limit data retention (see Data_Cleaning)

ℹ️ Note: For MySQL 5.6+ or MariaDB 10.1+, use online index creation: CREATE INDEX digestusername ON register_state (digestusername) ALGORITHM=INPLACE, LOCK=NONE;

Calculating innodb_buffer_pool_size for High-Volume Data

For systems with high REGISTER volume (e.g., 30 million records per day):

1. Calculate daily partition size:

ls -lat /var/lib/mysql/voipmonitor | grep pYYMMDD | cut -d' ' -f 7 | paste -s -d+ - | bc

2. Multiply by days needed: If each day is 15GB and you need 7 days: 15GB × 7 = 105GB minimum buffer pool

3. Configure MySQL:

[mysqld]
innodb_buffer_pool_size = 128G

4. Ensure sufficient RAM to accommodate the buffer pool plus OS and application overhead

Query Timing Warnings

  • Avoid large range reports during peak traffic hours
  • Avoid reports during the partition maintenance window (1:00 AM - 5:00 AM)
  • Schedule large historical queries during off-peak hours

AI Summary for RAG

Summary: The SIP Register section displays Active, Failed, and State tables for monitoring SIP registrations. Enable with sip-register = yes in voipmonitor.conf for persistent database storage; the Active tab works in real-time even when disabled (data retrieved directly from sniffer process). In distributed architectures, configure sip-register on the central server if packetbuffer_sender=yes, or on remote sensors if packetbuffer_sender=no. By default, PCAP files are not saved for REGISTER messages; enable via capture rules or sip-register-save-all=yes. To display multiple registrations for the same account independently, enable comparison options: sip-register-compare-sipcallerip, sip-register-compare-sipcallerport, sip-register-compare-sipcalledip, sip-register-compare-sipcalledport, and sip-register-state-compare-from_domain. For slow queries on register_state table, create indexes on digestusername, digest_from_number, digest_to_number, digest_to_domain, digest_realm. For high-volume environments, calculate required innodb_buffer_pool_size based on daily partition size × retention days.

Keywords: SIP Register, Active, Failed, State, sip-register, packetbuffer_sender, distributed architecture, multiple registrations, sip-register-compare-sipcallerip, register_state, slow query, index, digestusername, innodb_buffer_pool_size, cleandatabaseregister, PCAP recording, sip-register-save-all, Napatech, packet drops

Key Questions:

  • How do I enable SIP registration monitoring in VoIPmonitor?
  • Where do I configure sip-register in distributed architecture?
  • Why does the Active tab show "Table 'voipmonitor.register' doesn't exist"?
  • How to display multiple registrations for the same account separately?
  • Why are queries on register_state table so slow?
  • How to create indexes on register_state columns?
  • How to calculate innodb_buffer_pool_size for high-volume REGISTER data?
  • How to verify packets are reaching the sensor interface?
  • How to troubleshoot Napatech interfaces in DOWN state?