Best Practices

It is recommended that you use the following best practices when developing ITRS Geneos data views using Solace Geneos Agent framework.

Monitor Jar File and Package Names

It is recommended that classes used by one monitor should be placed into one jar file. The name of the jar file and properties file should match the monitor class name. This makes upgrading user developed monitors more manageable.

However, if several monitor classes share the same helper classes, there are two ways to bundle classes:

  1. Bundle shared classes into one jar file, and while monitor classes are still in their individual jar file.
  2. Bundle monitors and shared classes into one jar.

Option 1 is the preferred approach because it makes upgrading a specific monitor easier. In the sample project, a few helper classes that could be shared among monitors are bundled into sample-util.jar, while classes used exclusively by UsersMonitor are bundled into users-monitor.jar.

Different monitor classes and helper classes should be packaged in a way to avoid class name conflict.

Default Data View Names

Default data view names are reserved for the Solace Geneos Agent, and the monitors provided by the agent are not meant to be overwritten. If you want to use the same view name but with customer-specific monitors, you can choose a different sampler, group header, or managed entity.

Multiple Data Views in One Monitor

For simplicity, it is recommended that one monitor generates one data view. However, the agent framework also supports a monitor to generate multiple data views if doing so makes data collecting and reporting more efficient.

In the monitor properties file, there is a section for view definition:

#### view definition
# view name
#view.v0.viewName=xxx
# view active or not
#view.v0.active=true
# Sampler name
#view.v0.sampler=SolaceSampler
# Group header
#view.v0.groupHeader=SolOS
# Managed Entities
#view.v0.managedEntities=[np0, ManEnt]
 
# view name
#view.v1.viewName=yyy
# view active or not
#view.v1.active=true
# Sampler name
#view.v1.sampler=SolaceSampler
# Group header
#view.v1.groupHeader=SolOS
# Managed Entities
#view.v1.managedEntities=[np0, ManEnt]

In normal cases, you only need to give view.v0.viewName a correct view name. However, if more views will be generated, then view.v1.viewName, view.v2.viewName, and so on can be added to the monitor properties file.

When this monitor properties file is loaded by the agent, the monitor will have two views created and stored in the monitor’s viewMap to be retrieved and updated during collection and reporting time.

If different views have different sampler, group header, or managed entities, they can all be configured through the monitor properties file.

Introducing User-Defined Properties

As mentioned in Configuration Properties, the agent only loads properties it understands into the corresponding services and monitors. If there is a need to add additional properties, monitor developers can do the following:

  1. For properties that will be shared by many monitors, monitor developers should add these properties into a user properties file whose name starts with _user. It is recommended that you do not add these properties to the global solgeneosagent.properties because it could cause naming conflicts with future agent loads or monitors developed by other people.

    For example, if there is a need to introduce a new property for Netprobe service, developers should create a user_x.properties file and define the property there.

    The Netprobe service property has a pre-defined notion in solgeneosagent.properties file: netprobe.<alias>.<propertyName>. So the property defined in the user properties file should look like:

    netprobe.np0.msgVpns=blue,red

    The monitor implementation can call the following to retrieve these properties:

    UserPropertiesConfig userPropsConfig = SolGeneosAgent.onlyInstance.
        getUserPropertiesConfig("_user_x.properties");
    if (userPropsConfig != null && userPropsConfig.getProperties() != null) {
      String msgVpns =            
        userPropsConfig.getProperties().getProperty("netprobe.np0.msgVpns");
    }

    For a Netprobe service, netprobe.<alias> property prefix is stored in the Netprobe Service object; therefore the full property name can be obtained from the Netprobe service by providing the property suffix. Netprobe services configured for the monitor or its views can be retrieved from the monitor implementation class or the containing views. The following code snippet shows how to retrieve the above user defined property with the new approach to reduce hard coding.

    UserPropertiesConfig userPropsConfig = SolGeneosAgent.onlyInstance.
        getUserPropertiesConfig("_user_x.properties");
    if (userPropsConfig != null && userPropsConfig.getProperties() != null) {
      NetprobeManagedEntityMapping mapping =       
        getNetprobeManagedEntityMappings().iterator().next();
      NetProbeService theNetProbe NetProbeService.getNetProbe(mapping.getNetprobeAlias());
      String msgVpns =
        userPropsConfig.getProperties().getProperty(theNetProbe.getPropertyName("msgVpn");
    }
    
  2. For properties specific to a monitor, add the property to the monitor properties file. For example, property msgVpns is required for a monitor. The property looks like this in the monitor properties file:

    msgVpns=blue,red

    To retrieve the property from the monitor, you can do the following:

    MonitorConfig monitorPropsConfig = SolGeneosAgent.onlyInstance.getMonitorConfig(this);

    String msgVpns = monitorPropsConfig.getProperties().getProperty("msgVpns");

  3. For properties specific to a particular view contained in the monitor, they should be added to the view definition in the monitor properties file. For example, the monitor generates two views, view 1 gets data from message VPN blue and red, view 2 gets data from message VPN green and yellow. The properties should look like this in the monitor properties file:

    view.v0.msgVpns=blue,red

    view.v1.msgVpns=green,yellow

    To retrieve the properties from the monitor, the developer can do the following:

    MonitorConfig monitorPropsConfig=     SolGeneosAgent.onlyInstance.getMonitorConfig(this);
    TreeMap<String, View> viewMap = getViewMap();
    if (viewMap != null && viewMap.size() > 0) {
      for (Iterator<String> viewIt = viewMap.keySet().iterator();
          viewIt.hasNext();) {
        View view = viewMap.get(viewIt.next());
        String msgVpns = monitorPropsConfig.getProperties().getProperty(
          view.getPropertyName("msgVpns"));
      }
    }

Different View Content for Different Netprobes in a Monitor

One instance of Solace Geneos Agentcan communicate with more than one Netprobes. Different views can be configured to collect data and send it to different Netprobes.

However, sometimes a view is required to have different content depending on the Netprobe. For example, Netprobe-Apps is only interested in Queues of Message VPN red and blue, while Netprobe-QA is interested in Queues of Message VPN green and yellow.

The agent framework does not dictate the layout or content of each data view, as long as they are Geneos Netprobe compliant. Therefore, it is totally up to the monitor developers to decide what goes into each data view. However, developers should try to avoid hard code association between view content and Netprobes. The recommended approach is to define additional properties for the Netprobe service or the views, so as to design the associations through properties.

For the above example, the monitor developer can add msgVpns property to the Netprobe server configuration. During collecting, the monitor can query the event broker properly depending on the value of this property and report the corresponding data to the intended Netprobes.

Monitor Threading Model

Monitors are driven by the following threads:

  1. Monitor Timer
  2. Collecting context thread (default to DefaultCollectingContext, which is provided by the agent service)
  3. Reporting context thread (default to DefaultReportingContext, which is provided by the agent service)

Monitors extending from BaseMonitor must share the Monitor Timer thread. However, collecting context and report context threads can be overwritten with monitor specific threads.

The default monitors that bundled with Solace Geneos Agentuse the following rules:

  • All the monitors use the DefaultReportingContext for reporting data to Netprobes.
  • Monitors that must communicate with the event broker through SEMP use DefaultCollectingContext for data collecting
  • Monitors such as ServiceStatsMonitor and MonitorStatsMonitor that do no require SEMP use SelfMonitorCollectingContext, which is also provided by the agent service.

When developing your own monitors, if collecting context is set to null, then the data collecting task is executed on the Monitor Timer thread. On the other hand, if it is set to a user-defined threading context, then the data collecting tasks are executed on their own thread. The same behavior applies to reporting context.

To make the agent more scalable, it is highly recommended that user-developed monitors utilize the three default threading contexts provided by the agent service, and only override the collecting context thread or reporting context thread when it is necessary.

Share Objects Among Monitors

Sometimes objects may need to be shared among monitors, such as the http client used by the UsersMonitor sample.

Monitor developers can create their own caching data structures to store these shared objects, or they can use userObjects provided by Solace Geneos Agent.

To access and update userObjects, call:

  • SolGeneosAgent.onlyInstance.getUserObject(keyString)
  • SolGeneosAgent.onlyInstance.setUserObject(keyString, Object)

For example, the http client used by UsersMonitor can be stored and retrieved by calling:

  • SolGeneosAgent.onlyInstance.getUserObject("httpClientKey");
  • SolGeneosAgent.onlyInstance.setUserObject("httpClientKey", httpClient);

The above two methods are thread-safe. However, once the shared object is obtained from the cache, if it is being accessed from multiple threads, monitor developers must guarantee its thread safety.