Edit: Skip to my reply below to see the fixed SQL report that will show real uptime. Keep reading for an explanation of why the uptime reported by SolarWinds can be horribly wrong.
The issue is that the "up time" queried and presented by SolarWinds appears to be from OID 1.3.6.1.2.1.1.3 (sysUpTime), which is a 32-bit INTEGER for the amount of time the SNMP agent has been running on the device, presented in centiseconds (1/100th of a second), and stored in the database under Nodes.SystemUpTime as seconds. On Windows and Unix servers this is problematic because the SNMP service can restart for a number of reasons without the OS rebooting, which results in SolarWinds showing the wrong up time. It is also problematic for devices that stay up for a long time as the counter will flip every ~497 days. We have Cisco devices with uptimes of ~1900 days that are reporting <400 days.
For our Unix and Windows servers, we added a custom poller for OID 1.3.6.1.2.1.25.1.1 (hrSystemUpTime) to get up time. It doesn't appear to work on any of our other equipment, but works servers. Unfortunately Windows 2003-2008 reports through it in milliseconds while Unix/Linux/Windows 2008 R2 all report in centiseconds (1/100th of a second.)
For network devices, we added a custom poller for OID 1.3.6.1.6.3.10.2.1.3 (snmpEngineTime). It is a 64-bit INTEGER for the SNMP agent up time in seconds. Unfortunately not all network devices support this OID.
I've managed to put together a query that will compare SystemUpTime to hrSystemUpTime (if it exists) and use the larger value. I use variations of this query in Advanced Sql Reports which I then display in parts of the the Orion web interface. I feel like there is a better way to do this, possibly using variables, but I lack the skill to refine it further and include the snmpEngineTime OID.
I cast the numbers as BIGINT everywhere because they kept exceeding the default 32-bit size. The names of the custom pollers are what Solarwinds says is the name of the OID. Most of my queries include the full days/hours/minutes/seconds of uptime. I'd like to even factor in the Nodes.LastSystemUpTimePollUtc column to give potentially even more accurate data. I exclude "down" nodes as their uptime can't be considered accurate.
SELECT Top 10<br />Nodes.NodeID,<br />Nodes.Caption,<br /><br />CASE <br />WHEN CustomNodePollers_CustomPollers.UniqueName = 'hrSystemUpTime'<br />THEN CASE<br />WHEN (Nodes.MachineType LIKE 'Windows 2003%' OR Nodes.MachineType = 'Windows 2008 Server')<br />AND CAST(CustomNodePollerStatus_CustomPollerStatus.Status AS BIGINT) > (CAST(Nodes.SystemUpTime AS BIGINT) * 100)<br />THEN (CAST(CustomNodePollerStatus_CustomPollerStatus.Status AS BIGINT)/86400000)<br />WHEN CAST(CustomNodePollerStatus_CustomPollerStatus.Status AS BIGINT) > (CAST(Nodes.SystemUpTime AS BIGINT) * 100)<br />THEN (CAST(CustomNodePollerStatus_CustomPollerStatus.Status AS BIGINT)/8640000)<br />ELSE (CAST(Nodes.SystemUpTime AS BIGINT)/86400)<br />END<br />ELSE (CAST(Nodes.SystemUpTime AS BIGINT)/86400)<br />END AS Days,<br /><br />CASE <br />WHEN CustomNodePollers_CustomPollers.UniqueName = 'hrSystemUpTime'<br />THEN CASE<br />WHEN (Nodes.MachineType LIKE 'Windows 2003%' OR Nodes.MachineType = 'Windows 2008 Server')<br />AND CAST(CustomNodePollerStatus_CustomPollerStatus.Status AS BIGINT) > (CAST(Nodes.SystemUpTime AS BIGINT) * 100)<br />THEN (CAST(CustomNodePollerStatus_CustomPollerStatus.Status AS BIGINT)/3600000 % 24)<br />WHEN CAST(CustomNodePollerStatus_CustomPollerStatus.Status AS BIGINT) > (CAST(Nodes.SystemUpTime AS BIGINT) * 100)<br />THEN (CAST(CustomNodePollerStatus_CustomPollerStatus.Status AS BIGINT)/360000 % 24)<br />ELSE (CAST(Nodes.SystemUpTime AS BIGINT)/3600 % 24)<br />END<br />ELSE (CAST(Nodes.SystemUpTime AS BIGINT)/3600 % 24)<br />END AS Hours,<br /><br />CASE <br />WHEN CustomNodePollers_CustomPollers.UniqueName = 'hrSystemUpTime'<br />THEN CASE<br />WHEN (Nodes.MachineType LIKE 'Windows 2003%' OR Nodes.MachineType = 'Windows 2008 Server')<br />AND CAST(CustomNodePollerStatus_CustomPollerStatus.Status AS BIGINT) > (CAST(Nodes.SystemUpTime AS BIGINT) * 100)<br />THEN (CAST(CustomNodePollerStatus_CustomPollerStatus.Status AS BIGINT)/1000)<br />WHEN CAST(CustomNodePollerStatus_CustomPollerStatus.Status AS BIGINT) > (CAST(Nodes.SystemUpTime AS BIGINT) * 100)<br />THEN (CAST(CustomNodePollerStatus_CustomPollerStatus.Status AS BIGINT)/100)<br />ELSE (CAST(Nodes.SystemUpTime AS BIGINT))<br />END<br />ELSE (CAST(Nodes.SystemUpTime AS BIGINT))<br />END AS Seconds<br /><br /><br />FROM <br />((Nodes<br />LEFT JOIN CustomPollerAssignment CustomNodePollerAssignment_CustomPollerAssignment <br />ON (Nodes.NodeID = CustomNodePollerAssignment_CustomPollerAssignment.NodeID <br />AND CustomNodePollerAssignment_CustomPollerAssignment.AssignmentName LIKE 'hrSystemUptime%')) <br />LEFT JOIN CustomPollers CustomNodePollers_CustomPollers <br />ON (CustomNodePollerAssignment_CustomPollerAssignment.CustomPollerID = CustomNodePollers_CustomPollers.CustomPollerID)) <br />LEFT JOIN CustomPollerStatus CustomNodePollerStatus_CustomPollerStatus <br />ON (CustomNodePollerAssignment_CustomPollerAssignment.CustomPollerAssignmentID = CustomNodePollerStatus_CustomPollerStatus.CustomPollerAssignmentID)<br /><br /><br />WHERE ((CustomNodePollers_CustomPollers.UniqueName = 'hrSystemUpTime')<br />OR CAST(Nodes.SystemUpTime AS BIGINT) >0)<br />AND (Nodes.Status <> 2)<br /><br /><br />ORDER BY Seconds DESC