Enterprise Manager Cloud Control, SNMP, and Plug-Ins – Technical Steps

Enterprise Manager Cloud Control, SNMP, and Plug-Ins – Technical Steps

In my previous blog (Enterprise Manager Cloud Control, SNMP, and Plug-Ins – The Background), I shared my frustration in trying to create a plug-in in OEM. Here are the technical steps for a very simple plug-in.

Preparing the Plug-in

To build your own plug-in, you need to download a development kit:

  1. To download the Extensibility Development Kit (EDK) using UI, from the Setupmenu, select Extensibility, and then select Development Kit.


To download the EDK using EMCLI, run the following steps:

  1. Log in to OEM:

$ /oracle/em/middleware/bin/emcli login -username=sysman

Enter password :


Login successful

  1. Download the EDK zip archive:

$ emcli get_ext_dev_kit

Downloading edk.zip

File saved as edk.zip

File(s) downloaded successfully

  1. Unpack the downloaded EDK ZIP archive to a directory on your local system. For example:

$ unzip

There are several restrictions and guidelines you should know before you create your plug-in. Most of them can be found at the following link: About Plug-in Metadata

Restrictions and Guidelines

  1. Each plug-in must be assigned a version. The plug-in versioning syntax is as follows: a.b.c.d.e, where:
  • b = The version of the Enterprise Manager EDK used for development (13.1, 13.2, and so on)
  • c = The developer-assigned plug-in version; this value must be incremented with each plug-in release on the same Enterprise Manager Cloud Control release
  • d = Indicates whether the plug-in is a beta version or a production version; the value 0 indicates beta, and 1 or higher indicates production
  • e = For future use; the default value is 0

Putting it all together, the following example shows the first version of a plug-in created for Enterprise Manager Cloud Control 13c:

  1. Each time you deploy a new plug-in version, you must increase the version number. I created a script using the sed command to increase the number:

sed -i “s/13.3.0.${PREV_VER}.0/13.3.0.${CURR_VER}.0/g” plugin.xml agent/plugin_registry.xml


find ${STAGE_DIR} -type f -name “*xml”|xargs grep -l META_VER | xargs sed -i “s/META_VER=\”13.${PREV_VER}/META_VER=\”13.${CURR_VER}/g”

  1. Plug-ins are identified by a unique plug-in identifier (ID). The plug-in ID has three parts:
    1. Vendor ID (8 characters maximum); for example: test
    2. Product ID (8 characters maximum); for example: switch
    3. Plug-in Tag (4 characters maximum); for example: xkey
  2. The content in the following files should be identical with each other:
    1. agent/default_collection/test_switch_xkey.xml
    2. agent/metadata/test_switch_xkey.xml



Folder Structure

The structure of the folders and files should be like this:

├── agent

│   ├── default_collection

│   │   └── test_switch_xkey.xml

│   ├── metadata

│   │   └── test_switch_xkey.xml

│   └── plugin_registry.xml

├── discovery

│   ├── test_switch_xkey_snmp_discovery.pl

│   └── test_switch_xkey_snmp_discovery.xml

├── oms

│   └── metadata

│       ├── test_switch_xkey.xml

│       ├── default_collection

│       │   └── test_switch_xkey.xml

│       ├── discovery

│       └── targetType

│           └── test_switch_xkey.xml

└── plugin.xml

Metadata File

A basic plug-in requires metadata for the plug-in itself, including information such as the name and version that is used by Oracle Management Service and Management Agents, definition of a metric indicating whether the monitored target is up, and definition of the frequency at which metric data should be collected.

Metadata file example:

<?xml version=”1.0″?>

<TargetMetadata META_VER=”13.73″ TYPE=”test_switch_xkey”>


        <Label NLSID=”hs_displayname”>SNMP Plugin</Label>


    <Metric NAME=”SnmpTrap” TYPE=”TABLE”>


          <Label NLSID=”MY_threshold”>Snmp Trap</Label>


        <CategoryValue CLASS=”Default” CATEGORY_NAME=”Fault”/>


              <ColumnDescriptor NAME=”TimeOfEvent” TYPE=”STRING” IS_KEY=”TRUE”>


                  <Label NLSID=”timeOfEvent_1″>Name</Label>

                    <Description NLSID=”timeOfEvent”>Time Of Event</Description>

                  <Unit NLSID=”EM_SYS_STANDARD_NA_NA”>NA</Unit>




              <ColumnDescriptor NAME=”EventDetails” TYPE=”STRING” IS_KEY=”FALSE”>


                  <Label NLSID=”eventDetails_1″>EventDetails</Label>

                    <Description NLSID=”eventDetails”>Trap Event Details</Description>

                  <Unit NLSID=”EM_SYS_STANDARD_NA_NA”>NA</Unit>





        <PushDescriptor RECVLET_ID=”SNMPTrap”>

            <Property NAME=”MatchTrapOID” SCOPE=”GLOBAL”></Property>

            <Property NAME=”MatchAgentAddr” SCOPE=”INSTANCE”>ipaddress</Property>

            <Property NAME=”KeyTimeOfEventOID” SCOPE=”GLOBAL”></Property>

            <Property NAME=”ContextTimeOfEventOID” SCOPE=”GLOBAL”></Property>

            <Property NAME=”DataEventDetailsOID” SCOPE=”GLOBAL”></Property>

            <Property NAME=”ContextStatusOID” SCOPE=”GLOBAL”></Property>

            <Property NAME=”SeverityCodeOID” SCOPE=”GLOBAL”>;0=CLEAR,4=WARNING,5=CRITICAL,6=CRITICAL</Property>

            <CredentialRef NAME=”monCreds”>monCredentials</CredentialRef>




        <CredentialSet NAME=”monCredentials” USAGE=”MONITORING”>


            <Label NLSID=”hs_monCredentials”>Credentials</Label>


            <AllowedCredType TYPE=”SNMPV1Creds” />




        <InstanceProperty NAME=”ipaddress” CREDENTIAL=”FALSE” OPTIONAL=”TRUE”>


            <Label NLSID=”hs_ipaddress”>Sender’s IP Address</Label>





A few points:

  • A key column will be updated when there is a new trap with the same key.
  • MatchAgentAddr is dynamic. That is, it is not hard coded. When you deploy the plug-in, you can enter the sender IP address.
  • The credential (community) is also dynamic and can be set when deploying the plug-in.
  • If all of your traps have a default trap ID and you have the same fields in all of your traps, you can have only one PushDescriptor. Otherwise, you will need to define for each of the traps an XML section of PushDescriptor.
  • A severity level that is set to CLEAR the alert is recommended.

Default Collection

The default collection metadata file for a target type defines the following:

  • The metric data (including configuration collection metric data) to be collected from targets and written to the Management Repository
  • The frequency at which this metric data is collected
  • Thresholds that, when exceeded, will cause a Metric Alert event to be raised
  • An optional message to display when a threshold is exceeded

Default collection example:

<?xml version=”1.0″?>

<TargetCollection TYPE=”test_switch_xkey” META_VER=”13.73″>

  <CollectionItem NAME=”SnmpTrap”>

    <MetricColl NAME=”SnmpTrap”>

      <Condition PUSH=”TRUE”



        MESSAGE=”SNMP Trap – The value for %columnName% is %value%%%. – Alert”

        CLEAR_MESSAGE=”SNMP Trap – The value for %columnName% is %value%%%. – Cleared”

        MESSAGE_NLSID=”snmp_trap_alert” />





Note that the value of the TYPE attribute and the META_VER attribute in the default collection metadata file must match the TYPE and the META_VER values defined in the target type metadata file to create an association between them.

Plug-in Deployment

Creating the plug-in is done via several commands. Importing and deploying the plug-in can be done via the command line or by web interface. It is handy and easy to use a script to deploy automatically – this is the approach I chose.

Set Your Environment

I used the Java from OMS database home:

$ export JAVA_HOME=/oracle/product/

$ export PATH=/oracle/product/$PATH

Validate that the plug-in files are valid:

$ /oracle/em/middleware/sysman/edk/bin/empdk validate_plugin -stage_dir /home/oracle/stage -format text -tmp_dir /tmp -out_dir /tmp

Create the plug-in:

/oracle/em/middleware/sysman/edk/bin/empdk create_plugin -stage_dir /home/oracle/stage -conn_desc <oms_database>:<oms_database port>:<oms_service_name> -repos_user sysman -out_dir /tmp

Import the plug-in to OEM:

/oracle/em/middleware/bin/emcli import_update -file=/tmp/  -omslocal

Deploy the plug-in to the OMS:

/oracle/em/middleware/bin/emcli deploy_plugin_on_server -plugin=test.switch.xkey: -sys_password=<change_on_install>

Verify the deployment progress of the plug-in:

$ /oracle/em/middleware/bin/emcli get_plugin_deployment_status -plugin=test.switch.xkey

Wait for “Status” to be: Success

Deploy the plug-in to the agent:

/oracle/em/middleware/bin/emcli deploy_plugin_on_agent -agent_names=”<monitoring server>:3872″ -plugin=”test.switch.xkey”

Verify the deployment progress of the plug-in:

$ /oracle/em/middleware/bin/emcli get_plugin_deployment_status -plugin=test.switch.xkey

Wait for “Status” to be: Success

Adding Targets

The last step in plug-in deployment is to add a target. To add a target on a managed host by specifying the target monitoring properties, follow these steps:

  1. From the Setupmenu, select Add Target, and then select Add Targets Manually. Cloud Control displays the Add Targets Manually page.
  2. On the Add Targets Manually page, select Add Targets Declaratively by Specifying Target Monitoring Properties.
    • Add Target Name
    • Community is usually: public
    • Enter the IP address of the sender



Plug-in Undeployment

Undeploy the plug-in from the agent:

$ /oracle/em/middleware/bin/emcli undeploy_plugin_from_agent  -plugin=”test.switch.xkey:″ -agent_names=”<monitoring server>:3872″ -delete_targets

Verify the undeployment progress of the plug-in:

$ /oracle/em/middleware/bin/emcli get_plugin_deployment_status -plugin=test.switch.xkey

Wait for “Status” to be: Success

Undeploy the plug-in from the OMS:

$ /oracle/em/middleware/bin/emcli undeploy_plugin_from_server  -plugin=”test.switch.xkey:″ -sys_password=<change_on_install>

Verify the undeployment progress of the OMS:

$ /oracle/em/middleware/bin/emcli get_plugin_deployment_status -plugin=test.switch.xkey

Wait for “Status” to be: Success

Testing and Debugging

  • Send SNMP trap to the agent
  • Check whether the agent received the trap and filter the matching metric

$ tailf -100 /oracle/em/agent/agent_inst/sysman/log/gcagent_sdk.trc


2018-12-14 21:01:36,449 [151:F60C8AF1] INFO – =====SNMPRecvlt received V2 notification=====:


2018-12-14 21:01:36,449 [151:F60C8AF1] INFO – SNMPV2 notification from host

2018-12-14 21:01:36,449 [151:F60C8AF1] INFO – Notification Details:

2018-12-14 21:01:36,449 [151:F60C8AF1] INFO – CommandResponderEvent[securityModel=2, securityLevel=1, maxSizeResponsePDU=65535, pduHandle=PduHandle[0], stateReference=StateReference[msgID=0,pduHandle=PduHandle[0],securityEngineID=null,securityModel=null,securityName=public,securityLevel=1,contextEngineID=null,contextName=null,retryMsgIDs=null], pdu=TRAP[requestID=0, errorStatus=Success(0), errorIndex=0, VBS[ = 1:02:47.22; =; = 07:e2:0c:0e:12:3b:24:00; = Axxana; = env14; = collector; = Black Box external power recovered. trace id: 0x7fe898004a00; = 5; = 3; =]], messageProcessingModel=1, securityName=public, processed=false, peerAddress=, transportMapping=org.snmp4j.transport.DefaultUdpTransportMapping@71d78ff, tmStateReference=null]AF1] INFO – oid 3: val : Axxana

2018-12-14 21:01:36,450 [151:F60C8AF1] INFO – oid 4: val : env14

2018-12-14 21:01:36,450 [151:F60C8AF1] INFO – oid 5: val : collector

2018-12-14 21:01:36,450 [151:F60C8AF1] INFO – oid 6: val : Black Box external power recovered. trace id: 0x7fe898004a00

2018-12-14 21:01:36,450 [151:F60C8AF1] INFO – oid 7: val : 5

2018-12-14 21:01:36,450 [151:F60C8AF1] INFO – oid 8: val : 3

2018-12-14 21:01:36,450 [151:F60C8AF1] INFO – oid 9: val :

2018-12-14 21:01:36,451 [151:F60C8AF1] INFO – Matching metric found …

 metric name : SnmpTrap MatchTrapOID: MatchAgentAddress :

2018-12-14 21:01:36,451 [151:F60C8AF1] INFO – Trap received is for sending Data

2018-12-14 21:01:36,451 [151:F60C8AF1] INFO – Sending datapoint for metric , test_switch_xkey.cc_snmp,SnmpTrap

Sample output in the web interface: