cancel
Showing results for 
Search instead for 
Did you mean: 
Create Post
MVP
MVP

F5 Dashboard

The F5 monitoring is quite detailed in the 2020 version of Solarwinds.  What is lacking, is a way to look at all the F5 data in the once place, and to search for vIPs, Pool members, and so on.

I have built such a dashboard.  I hope to do an export, but for the meantime, below you will find out how to build it yourself.

 

The main screen is as follows, and has the following widgets:

  • F5s
  • Virtual Servers
  • Pools
  • Pool Members
  • (top) Concurrent Connections by Virtual Server
  • Active Alerts
  • (Solarwinds) F5 Audit Events
  • Last 5 Config Changes

F5-dash-1.png 

 

The second page is more a work in progress.  On the left are all the virtual servers.  Clicking on the right will show the Netflow conversations data.

F5-dash-2.png

 

How To Build

As you can see, I have build this as a two page, Summary View.  To get started, make a blank summary view with a couple of columns.  I will show how to create each component in order.

Add this View Limitation by Group of Machine Types.  Add All the device types that have "BIG-IP" in the name.  This allows us to use some standard widgets - which will be filtered to just our F5s.

 

F5s

Object Type:  Custom Table

Rows Per Page: 5

Custom SWQL Query:

 

SELECT d.Caption as F5, d.DetailsUrl as _linkfor_F5
    , '/Orion/images/StatusIcons/Small-' + n.StatusLED as _iconfor_F5
    ,ProductVersion + ' (' + ProductBuild + ')' as Version
    ,FailoverStatusDescription as Failover
    ,'/Orion/F5/images/F5_' + tostring(d.FailOverStatusColor) + '.png' as _iconfor_Failover
    , d.SyncStatusDescription as Sync
    ,'/Orion/F5/images/F5_' + tostring( d.SyncStatusColor ) + '.png' as _iconfor_Sync
    ,'' as Maintenance
    ,case when IsInMaintenanceMode = 'True' then '/Orion/F5/images/Small/Status-Unmanaged.png' else '' end as _iconfor_Maintenance
    --,In_Throughput, Out_Throughput, Connections, ConnectionsNew, ConnectionsSSL
    ,Connections, ConnectionsSSL
    ,mod.Modules
    ,VLANs
FROM Orion.F5.System.Device d
    inner join orion.Nodes n
               on n.nodeID = d.NodeID
    inner join (
            SELECT NodeID --, Name--, Enabled
                ,max( case when Name = 'Global Traffic Manager' then 'GTM ' else '' end ) 
                + max( case when Name = 'Local Traffic Manager' then 'LTM ' else '' end )
                + max( case when Name = 'Advanced Firewall Manager' then 'AFM ' else '' end ) 
                + max( case when Name = 'Access Policy Manager' then 'APM ' else '' end ) 
                + max( case when Name = 'Application Security Manager' then 'ASM ' else '' end ) 
                + max( case when Name = 'Acceleration Manager' then 'AM ' else '' end ) 
                + max( case when Name = 'Application Visibility and Reporting' then 'AVR ' else '' end ) 
                + max( case when Name = 'Link Controller' then 'LC ' else '' end ) 
                + max( case when Name = 'Policy Enforcement Manager' then 'PEM ' else '' end ) 

                + max( case when Name = 'Fraud Protection Service' then 'FPS ' else '' end ) 
                + max( case when Name = 'iRules Language Extensions' then 'ILX ' else '' end )
                + max( case when Name = 'Secure Web Gateway' then 'SWG ' else '' end )
                + max( case when Name = 'Virtual CMP' then 'VCMP ' else '' end )
             as Modules
            FROM Orion.F5.System.Module
            group by NodeID
    ) mod
    on mod.NodeID = d.NodeID
    inner join (
        SELECT NodeID
            ,max(case when vlanIndex = 1 then ShortName   else '' end ) + ' '
            + max(case when vlanIndex = 2 then ShortName  else '' end ) + ' '
            + max(case when vlanIndex = 3 then ShortName  else '' end ) + ' '
            + max(case when vlanIndex = 4 then ShortName  else '' end ) + ' '
            + max(case when vlanIndex = 5 then ShortName  else '' end ) + ' '
            + max(case when vlanIndex = 6 then ShortName  else '' end ) + ' '
            + max(case when vlanIndex = 7 then ShortName  else '' end ) + ' '
            + max(case when vlanIndex = 8 then ShortName  else '' end ) + ' '
            + max(case when vlanIndex = 9 then ShortName  else '' end ) + ' '
            + max(case when vlanIndex = 1 then ShortName  else '' end )
             as VLANs
        FROM Orion.F5.System.VLAN
        group by NodeID
    ) vlan
    on vlan.NodeID = d.NodeID

 

 

Virtual Servers - LTM

Note: I originally planned for these to show LTM and GTM data, but I had problems with the UNION being executed.  It is preferred to also have the GTM data, though for my organisation we do not have GTM F5s.   You will see there is a Type column, that has 'LTM' in it.  I have added the "- LTM" to the end of the heading to as not to mislead.

Adding GTM is an exercise for future improvement - and I will gladly take updates.    

Object Type:  Custom Table

Rows Per Page: 5

Custom SWQL Query:

 

SELECT 'LTM' as Type, '/Orion/F5/F5LTMDetails.aspx?NetObject=F5LTM:' + TOSTRING(n.nodeid) as _linkfor_Type
    , n.Caption as F5, n.DetailsUrl as _linkfor_F5
    , '/Orion/images/StatusIcons/Small-' + n.StatusLED as _iconfor_F5
    ,vs.ShortName as Virtual_Server
    ,'/Orion/F5/F5VirtualServerDetails.aspx?NetObject=F5VS:' + TOSTRING( vs.VirtualServerID) as _linkfor_Virtual_Server
    ,'/Orion/images/StatusIcons/Small-' + case vs.F5Status when 4 then 'UNKNOWN' when 1 then 'UP' when 3 then 'DOWN' end + '.gif' as _iconfor_Virtual_Server
    ,vs.Port
    ,case when vs.F5StatusReason <> 'The virtual server is available' then vs.F5statusReason end as Detail   
FROM Orion.F5.LTM.VirtualServer vs
    inner join Orion.Nodes n
        on vs.NodeID = n.NodeID
order by n.Caption

 

Enable Search: yes

Search SWQL Query:

 

SELECT 'LTM' as Type, '/Orion/F5/F5LTMDetails.aspx?NetObject=F5LTM:' + TOSTRING(n.nodeid) as _linkfor_Type
    , n.Caption as F5, n.DetailsUrl as _linkfor_F5
    , '/Orion/images/StatusIcons/Small-' + n.StatusLED as _iconfor_F5
    ,vs.ShortName as Virtual_Server
    ,'/Orion/F5/F5VirtualServerDetails.aspx?NetObject=F5VS:' + TOSTRING( vs.VirtualServerID) as _linkfor_Virtual_Server
    ,'/Orion/images/StatusIcons/Small-' + case vs.F5Status when 4 then 'UNKNOWN' when 1 then 'UP' when 3 then 'DOWN' end + '.gif' as _iconfor_Virtual_Server
    ,vs.Port
    ,case when vs.F5StatusReason <> 'The virtual server is available' then vs.F5statusReason end as Detail   
FROM Orion.F5.LTM.VirtualServer vs
    inner join Orion.Nodes n
        on vs.NodeID = n.NodeID
where vs.DisplayName like '%${SEARCH_STRING}%' 
    or vs.VirtualIPAddress.IPAddress like '%${SEARCH_STRING}%'
order by n.Caption

 

 

Pools - LTM

Note the same for this, as the above object.

Object Type:  Custom Table

Rows Per Page: 5

Custom SWQL Query:

 

SELECT 
    'LTM' as Type, '/Orion/F5/F5LTMDetails.aspx?NetObject=F5LTM:' + TOSTRING(n.nodeid) as _linkfor_Type
     , n.Caption as F5, n.DetailsUrl as _linkfor_F5
    , '/Orion/images/StatusIcons/Small-' + n.StatusLED as _iconfor_F5
    , p.ShortName as Pool_Name
    ,p.DetailsUrl as _linkfor_Pool_Name
    ,'/Orion/images/StatusIcons/Small-' + p.OrionStatusDescription + '.GIF'  as _iconfor_Pool_Name
    ,'' as Enabled    
    ,'/Orion/images/StatusIcons/Small-' + case when p.EnabledDescription = 'Enabled' then 'UP' else 'DOWN' END + '.GIF' as _iconfor_Enabled    
    ,p.LBModeDescription as LB_Mode
    ,p.MemberCountTotal as Members
    ,p.MemberCountActual as Actual
    ,case when p.OrionStatus <> 1 then  p.F5StatusReason end as Details
FROM Orion.F5.LTM.Pool p
    inner join orion.Nodes n
        on p.nodeID = n.nodeID

 

Search SWQL Query:

SELECT 
    'LTM' as Type, '/Orion/F5/F5LTMDetails.aspx?NetObject=F5LTM:' + TOSTRING(n.nodeid) as _linkfor_Type
    , n.Caption as F5, n.DetailsUrl as _linkfor_F5
    , '/Orion/images/StatusIcons/Small-' + n.StatusLED as _iconfor_F5
    , p.ShortName as Pool_Name
    ,p.DetailsUrl as _linkfor_Pool_Name
    ,'/Orion/images/StatusIcons/Small-' + p.OrionStatusDescription + '.GIF'  as _iconfor_Pool_Name
    ,'' as Enabled    
    ,'/Orion/images/StatusIcons/Small-' + case when p.EnabledDescription = 'Enabled' then 'UP' else 'DOWN' END + '.GIF' as _iconfor_Enabled    
    ,p.LBModeDescription as LB_Mode
    ,p.MemberCountTotal as Members
    ,p.MemberCountActual as Actual
    ,case when p.OrionStatus <> 1 then  p.F5StatusReason end as Details
FROM Orion.F5.LTM.Pool p
    inner join orion.Nodes n
        on p.nodeID = n.nodeID
where p.ShortName like '%${SEARCH_STRING}%'
    or p.VirtualServer.VirtualIPAddress.IPAddress like '%${SEARCH_STRING}%'
order by n.Caption

 

Pool Members - LTM

Object Type:  Custom Table

Rows Per Page: 5

Custom SWQL Query:

 

SELECT   'LTM' as Type, '/Orion/F5/F5LTMDetails.aspx?NetObject=F5LTM:' + TOSTRING(n.nodeid) as _linkfor_Type
, n.Caption as F5, n.DetailsUrl as _linkfor_F5
    , '/Orion/images/StatusIcons/Small-' + n.StatusLED as _iconfor_F5
    , p.ShortName as Pool_Name
    ,p.DetailsUrl as _linkfor_Pool_Name
    ,'/Orion/images/StatusIcons/Small-' + p.OrionStatusDescription + '.GIF'  as _iconfor_Pool_Name

    ,substring(pm.ShortName, length( p.ShortName )+2, 999)   as  Pool_Member
    ,pm.DetailsUrl as _linkfor_Pool_Member    
    ,'/Orion/images/StatusIcons/Small-' + pm.OrionStatusDescription + '.GIF'  as _iconfor_Pool_Member
    ,case when pm.F5Status <> 1 then pm.F5StatusReason end as Detail
    --,pm.Port, pm.Enabled, pm.F5Status, pm.F5StatusReason, pm.OrionStatus, PPS_In, PPS_Out, BPS_In, BPS_Out, Connections, ConnectionsPerSec, RequestsPerSec, Sessions, pm.ShortName, pm.DisplayName, pm.DetailsUrl, pm.Description, pm.F5StatusDescription, pm.OrionStatusDescription, pm.EnabledDescription, pm.DisableReason
FROM Orion.F5.LTM.PoolMember pm
    inner join orion.Nodes n
        on pm.nodeID = n.nodeID
    inner join Orion.F5.LTM.Pool p
        on pm.PoolIndex = p.PoolIndex
        and pm.NodeID = p.NodeID
order by n.Caption , pm.ShortName

 

Search SWQL Query:

SELECT   'LTM' as Type, '/Orion/F5/F5LTMDetails.aspx?NetObject=F5LTM:' + TOSTRING(n.nodeid) as _linkfor_Type
,n.Caption as F5, n.DetailsUrl as _linkfor_F5
    , '/Orion/images/StatusIcons/Small-' + n.StatusLED as _iconfor_F5
    , p.ShortName as Pool_Name
    ,p.DetailsUrl as _linkfor_Pool_Name
    ,'/Orion/images/StatusIcons/Small-' + p.OrionStatusDescription + '.GIF'  as _iconfor_Pool_Name

    ,substring(pm.ShortName, length( p.ShortName )+2, 999)   as  Pool_Member
    ,pm.DetailsUrl as _linkfor_Pool_Member    
    ,'/Orion/images/StatusIcons/Small-' + pm.OrionStatusDescription + '.GIF'  as _iconfor_Pool_Member
    ,case when pm.F5Status <> 1 then pm.F5StatusReason end as Detail
    --,pm.Port, pm.Enabled, pm.F5Status, pm.F5StatusReason, pm.OrionStatus, PPS_In, PPS_Out, BPS_In, BPS_Out, Connections, ConnectionsPerSec, RequestsPerSec, Sessions, pm.ShortName, pm.DisplayName, pm.DetailsUrl, pm.Description, pm.F5StatusDescription, pm.OrionStatusDescription, pm.EnabledDescription, pm.DisableReason
FROM Orion.F5.LTM.PoolMember pm
    inner join orion.Nodes n
        on pm.nodeID = n.nodeID
    inner join Orion.F5.LTM.Pool p
        on pm.PoolIndex = p.PoolIndex
        and pm.NodeID = p.NodeID
where p.ShortName like '%${SEARCH_STRING}%' or  pm.ShortName like '%${SEARCH_STRING}%'
    or pm.pool.VirtualServer.VirtualIPAddress.IPAddress like '%${SEARCH_STRING}%'
order by n.Caption , pm.ShortName

 

Concurrent Connections by Virtual Server

This is a standard widget, for a change.

Object Type:  Concurrent Connections By Virtual Server

Maximum Number of Virtual Servers to Display: 10

Amount of historical data to load: Last 7 days

Default Zoom Range: Today

Sample Interval: Every 15 minutes

 

Concurrent Connections by Virtual Server

Another standard widget.

Object Type:  Active Alerts

 

F5 Audit Events

This is a custom query.  Only so that we can do a more compact view of audited changes, and to make it have some interactivity.   Note the queries limit the data to the last 100 audit records.

Object Type:  Custom Table

Rows Per Page: 5

Custom SWQL Query:

 

SELECT TOP 100 ObservationTimestamp as Time
    , n.Caption as F5
    , n.DetailsUrl as _linkfor_F5
    , AuditEventMessage as Log_Message
    , e.DetailsUrl as  _linkfor_Log_Message
FROM Orion.AuditingEvents e
    inner join orion.nodes n 
        on n.nodeID = e.NetworkNode
    inner join orion.AuditingActionTypes a
        on a.ActionTypeID = e.ActionTypeID
where n.Vendor = 'F5 Networks, Inc.'
order by auditeventid desc

 

Search SWQL Query:

 

SELECT TOP 100 ObservationTimestamp as Time
    , n.Caption as F5
    , n.DetailsUrl as _linkfor_F5
    , AuditEventMessage as Log_Message
    , e.DetailsUrl as  _linkfor_Log_Message
FROM Orion.AuditingEvents e
    inner join orion.nodes n 
        on n.nodeID = e.NetworkNode
    inner join orion.AuditingActionTypes a
        on a.ActionTypeID = e.ActionTypeID
where n.Vendor = 'F5 Networks, Inc.'
    AND (
n.Caption like '%${SEARCH_STRING}%'
or AuditEventMessage like '%${SEARCH_STRING}%'
)
order by auditeventid desc

 

Last 5 Config Changes

Another standard widget.

Object Type:  Last XX Config Changes

Number of configs to display: 5

 

EXPERIMENTAL - BUT FUN - SECTION

Second Page - Netflow Data

This is a work in progress.  Uses an embedded IFRAME, and targetted links.  I currently have it filtered to the subset of Virtual Servers that have netflow.  If not filtered then there are too many rows of data.  Note that I only have Virtual Server IPs.  I could also do Pool Member IPs.  I should also point out that I have the links loading Conversations.  I would like to change this to also have a link for the Applications graph.

I cannot do a search like for other widgets, as I am using SQL so I can retrieve the IP address.

 

F5 Virtual Servers

This is a complicated query, as I have to do some advanced string handling that is really a bit beyond the SWQL functions.  The IP links for IPAM are in the form aaabbbcccdddeeefff (for a.b.c.d IP addresses)

Object Type:  Custom Query

Rows Per Page: 5

Data Source: - SWQL

 

 

 

 

select  Distinct Type, _linkfor_Type, F5, _linkfor_F5, _linkfor_Virtual_Server, Virtual_Server, Port, Detail
    , '<a href="'
     + '/Orion/DetachResource.aspx?ResourceID=1488&NetObject=NSF%3aT%3aLast+2+Hours%3bFD%3aBoth%3bIPV%3aBoth%3bE%3a'
     + isnull( ip6,
        concat( (case length(o1) when 1 then '00' when 2 then '0' else '' end + o1 )
            , (case length(o2) when 1 then '00' when 2 then '0' else '' end + o2 )
            , (case length(o3) when 1 then '00' when 2 then '0' else '' end + o3 )
            , (case length(o4) when 1 then '00' when 2 then '0' else '' end + o4 )   )
       ) 
      + '" target="f5_nta">' + p2.IPAddress + '</a>' 
        as ParamIP
from (
    select Type, _linkfor_Type, F5, _linkfor_F5, _linkfor_Virtual_Server, Virtual_Server, Port, Detail
        ,IPAddress, IP6
        ,case when IP6 is null then SUBSTRING(p1.IPAddress, 1, p1.p1-1 ) end as O1
        ,case when IP6 is null then SUBSTRING(p1.IPAddress, p1.p1+1, (p1.p2-p1.p1-1) ) end as O2
        ,case when IP6 is null then SUBSTRING(p1.IPAddress, p1.p2+1, (p1.p3-p1.p2-1) ) end as O3
        ,case when IP6 is null then SUBSTRING(p1.IPAddress, p1.p3+1, 999 ) end as O4
    from (
    SELECT      vs.VirtualIPAddress.IPAddress
        ,charindex('.', vs.VirtualIPAddress.IPAddress) as p1    
        ,charindex('.', vs.VirtualIPAddress.IPAddress,  (charindex('.', vs.VirtualIPAddress.IPAddress)+1)  ) as p2
        ,charindex('.', vs.VirtualIPAddress.IPAddress,  charindex('.', vs.VirtualIPAddress.IPAddress,  (charindex('.', vs.VirtualIPAddress.IPAddress)+1)  )+1    ) as p3
        ,case when vs.VirtualIPAddress.IPAddress like '%:%' then replace(vs.VirtualIPAddress.IPAddress, ':', '') END as IP6
     ,'LTM' as Type, '/Orion/F5/F5LTMDetails.aspx?NetObject=F5LTM:' + TOSTRING(n.nodeid) as _linkfor_Type
        , n.Caption as F5, n.DetailsUrl as _linkfor_F5
        , '/Orion/images/StatusIcons/Small-' + n.StatusLED as _iconfor_F5
        ,vs.ShortName as Virtual_Server
        ,'/Orion/F5/F5VirtualServerDetails.aspx?NetObject=F5VS:' + TOSTRING( vs.VirtualServerID) as _linkfor_Virtual_Server
        ,'/Orion/images/StatusIcons/Small-' + case vs.F5Status when 4 then 'UNKNOWN' when 1 then 'UP' when 3 then 'DOWN' end + '.gif' as _iconfor_Virtual_Server
        ,vs.Port
        ,case when vs.F5StatusReason <> 'The virtual server is available' then vs.F5statusReason end as Detail   
    FROM Orion.F5.LTM.VirtualServer vs
        inner join Orion.Nodes n
            on vs.NodeID = n.NodeID
    where '0.0.0.0' <> vs.VirtualIPAddress.IPAddress and n.Caption like '%APM%'
    ) as p1
) as p2

 

 Table Layout

  • F5
  • Virtual Server
  • IP Address - Allow HTML tags = yes

 

Netflow Data

HTML:

 

<iframe name="f5_nta" style="width:100%;height:750px;" src="/Orion/DetachResource.aspx?ResourceID=1488&NetObject=NSF%3aT%3aLast+2+Hours%3bFD%3aBoth%3bIPV%3aBoth%3bE%3a115178104172"></iframe>

 

 

 

 

 

3 Replies

Great piece of work and well written up, double kudos for sharing.

0 Kudos
MVP
MVP

Well done! I've gotten tagged to write some queries for F5 before but this is so much more awesome!

0 Kudos
Level 11

Yes, please do share.  I really like what I see here and would like to do something similar.