Integrating with AppDynamics


The BMC Helix Intelligent Integrations AppDynamics connector collects events, metrics, and topology data from AppDynamics APM, DB and EUM.

You can view the collected data in various BMC Helix applications and derive the following benefits:

BMC Helix application

Type of data collected or viewed

Benefits

BMC Helix Operations Management

Events

Use a centralized event view to monitor and manage events, perform event operations, and filter events. Identify actionable events from a large volume of event data by processing events.

For more information, see Monitoring events and reducing event noise.

BMC Helix Operations Management

Metrics

Use alarm and variate policies to detect anomalies and eliminate false positives for more accurate results while monitoring the health of your system.

For more information, see Detecting anomalies by using static and dynamic thresholds.

BMC Helix Discovery

Topology

Collect all CIs from AppDynamicsin BMC Helix Discovery. 

Collect services from AppDynamicsin BMC Helix Discovery in a format that can be consumed by BMC Helix AIOps.   

For more information, see Managing your IT infrastructure.

BMC Helix AIOps

Situations (created from events)

Improve the mean time to resolve (MTTR) based on the situation-driven workflow.

Lower the mean time to detect or discover (MTTD) and the time required for investigating tickets.

For more information, see Monitoring situations

BMC Helix Dashboards

Metrics

Create dashboards to get a consolidated view of data collected from third-party products across your environment. 

Improve the efficiency of your system by monitoring the key performance metrics and respond to issues quickly to minimize the down time.

For more information, see Creating and customizing dashboards.

BMC Helix AIOps

Services (created from topology)

Monitor the overall health of a service.  When the service gets impacted by any factor, view the events generated because of the impact, analyze the causes of the impact, and quickly remediate those events to restore the health of the impacted service.

For more information, see Monitoring services.

Supported versions

BMC Helix Intelligent Integrations supports the following versions of AppDynamics for data collection:

  • 26.1.0
  • 25.10.x
  • 25.7.x
  • 25.1
  • 24.7.0

Before you begin

Make sure you perform the following actions before you configure a connection with AppDynamics:

AppDynamics requirements

The user account with which you plan to connect to AppDynamics has the following roles assigned:

  • Applications & Dashboards Viewer
  • Dashboards Viewer
  • DB Monitoring User
  • Server Monitoring user
  • Universal Agent User
  • Workflow Executor

BMC Helix Intelligent Integrations prerequisites

  • Depending on the location of the third-party product (SaaS, on-premises), choose one or more BMC Helix Intelligent Integrations deployment modes and review the corresponding port requirements. For information about various deployment modes and port requirements, see Deployment scenarios.
  • Based on the deployment mode, use the BMC Helix Intelligent Integrations SaaS deployment or the BMC Helix Intelligent Integrations on-premises gateway or both. For more information about the gateway, see Deploying the BMC Helix Intelligent Integrations on-premises gateway.
  • The on-premises gateway must be able to reach the third-party product on the required port (default is 443).

In the preceding list, third-party product refers to AppDynamics.

Task 1: To configure the connection with AppDynamics

  1. To access BMC Helix Intelligent Integrations, perform one of the following steps depending on your deployment mode:
    • BMC Helix Intelligent Integrations SaaS – Log on to BMC Helix Portal, and click the BMC Helix Intelligent Integrations tile.
    • BMC Helix Intelligent Integrations on-premises gateway – Use the following URL to access BMC Helix Intelligent Integrations: https://hostName:portNumber/swpui
  2. On the CONNECTORS  tab, click add_icon.png in the SOURCES panel.
  3. Click the AppDynamics APM, DB & EUM tile.

  4. Specify the following details for the source connection:
    1. Specify a unique instance name.

      Success

      Best practice
      We recommend that you specify the instance name in the following format: 

      <sourceType>_<sourceControllerServerName>{_<InstanceQualifier>}

      The instance qualifier helps you to distinguish the multiple instances configured from the same source server. For example, you can name your instances as AppDynamics_Host_PROD, AppDynamics_Host_TEST, and so on.

    2. Specify the AppDynamics host name.
    3. Specify the AppDynamics HTTP or HTTPS port number, depending on the connection protocol (the default port number is 443).
    4. Select the HTTPS option to use an HTTPS connection to the AppDynamics host.

      Error
      Warning

      Do not select the Allow Unsigned Certificate option in a production environment. You can select this option to allow unsigned certificates in a test environment. To learn how to install SSL certificates, see the ​AppDynamics​ documentation.

    5. Specify the number of maximum concurrent REST API requests that should be executed during a collection schedule (default value is 5).
    6. Specify the AppDynamics account name.
    7. Use one of the following authentication methods :
      • Specify user name and password. Ensure that the specified user has the roles assigned specified in the AppDynamics prerequisites  section.
      • Select the Use oAuth2 option to specify client name and secret key. Ensure that the client name is registered as an API client in AppDynamics . For more information about generating the secret key, see AppDynamics documentation, Generate the Token through OAuth API.

    8. Click Proxy and specify whether you want to configure a proxy server. If yes, specify the host name and port number (default value is 8888).
  5. Click VALIDATE AND CREATE.
    The specified connection details are validated and the corresponding source connection is created in the Source Connection list.
  6. Select the source connection that you created from the list if it is not selected already.

    Warning

    Important

    The destination host connection is created and configured automatically for each tenant when the source connection is created.

     

  7. Make sure that you select the options for the required data types to collect data.
  8. Configure the collectors for the selected data types by clicking the respective data type in the Collectors section. 

    Click here to view the collection parameters for the selected data types

    Important: The ✅️  symbol indicates that this field is applicable to the data type.

    Parameter Name

    Data Type

    AppDynamics Events (REST Pull)

    AppDynamics Health Rule Violations (REST Pull)

    AppDynamics Managed Metrics (REST Pull)

    AppDynamics Topology (REST Pull)

    Select one of the following options to specify the data collection frequency:

    • Duration: When you select this option, data collection happens constantly. Specify the schedule in minutes, hours, or day. 
      Default: 5 minutes
      Example:
      Collection Schedule
      is set to 5 mins.
      Current time is 00:30.

      If you run the collector just after 00:30, data is collected every 5 mins, first at 00:30 and next at 00:35, and so on.  
    • Cron schedule: When you select this option, data collection happens periodically. Specify the schedule by using a cron expression.
      A cron expression is a string consisting of five subexpressions (fields) that describe individual details of the schedule.  
      These fields, separated by blank spaces, can contain any of the allowed values with various combinations of the allowed characters for that field.
      Default: */5 * * * * (evaluates to 5 minutes)

      Format:
      Minutes Hours (24-hour format) Day of Month Month Day of Week

      Example:
      If you specify 10 15 3 7 * , data is collected at 15:10 hours every third day in the month of July.

    For more information about how this parameter affects data collection, see Data collection schedule.

    ✅️

    ✅️

    ✅️

    ✅️

    Specify the historical time period (in minutes) from the current time for which the data should be collected.

    Default: 5 minutes

    Example:

    Collection Schedule is set to 5 mins.
     Data Collection Window is set to 5 mins.
     Current time is 00:30.

    If you run the collector just after 00:30, data is collected first at 00:30 for the interval 00:25 - 00:30, and next at 00:35 for the interval 00:30 - 00:35, and so on.

    For more information about how this parameter affects data collection, see Data collection window.

    ✅️

    ✅️

    ✅️

    ❌️

    Applications

    Select All or a subset of application tags from the list.

    This list is updated automatically from AppDynamics .

    ✅️

    ✅️

    ✅️

    ✅️

    Paths
    Select All or a subset of paths from the list.
    This list is updated automatically from AppDynamics .

    ❌️

    ❌️

    ✅️

    ❌️

    Severity
    Select All or a subset of severities from the list.

    ✅️

    ❌️

    ❌️

    ❌️

    Severities
    Select All or a subset of severities from the list.

    ❌️

    ✅️

    ❌️

    ❌️

    Event Type

    Select one or more event types from the list.

    ✅️

    ❌️

    ❌️

    ❌️

    HRV Types

    Select All or a subset of health rule violations from the list.

    This list is updated automatically from AppDynamics.

    ❌️

    ✅️

    ❌️

    ❌️

    Affected Collection Types

    Select All or a subset of affected collection types from the list.

    This list is updated automatically from AppDynamics .

    ❌️

    ✅️

    ❌️

    ❌️

    Servers

    Select All or a subset of servers from the list.

    ❌️

    ✅️

    ❌️

    ❌️

    HRV Duplicate Window

    Specify the historical period from the current time for which data for the duplicate health rule violations should not be collected.

    If you set it to 0, data for the duplicate health rule violations is also collected.

    ❌️

    ✅️

    ❌️

    ❌️

  9. Click CREATE COLLECTORS to create the required collector streams for the selected data types.

  10. Configure the distributors for the selected data types by clicking the respective data type in the Distributors section.

    Click here to view the distribution parameters for the selected data types

     

    Parameter name

    Description

    AppDynamics Events (REST Pull)AppDynamics Health Rule Violations (REST Pull)AppDynamics Managed Metrics (REST Pull)AppDynamics Topology (REST Pull)

    Max Batching Size

    Specify the maximum number of data items to send in a single POST request to the destination API.
    The batch size 
    depends on the destination’s ability to buffer the incoming data.

    Default: 250

    ✅️✅️✅️✅️

    Max Batching Delay

    Specify the maximum time (in seconds) to wait before building and processing a batch.

    Default: 3 seconds 

    ✅️✅️✅️✅️

    Base Retry Delay

    Specify the initial time (in seconds) for which to wait before retrying to build and process a batch.
    The waiting time increases in the following sequence: n1, n2, n3, and so on, where n indicates the number of seconds.

    Default: 2 seconds

    Example: Base Retry Delay is set to 2 seconds. Retry is performed after 2, 4, 8, 16, ... seconds.

    ✅️✅️✅️✅️

    Max Intra-Retry Delay

    Specify the maximum limit for the base retry delay.

    Default: 60 seconds

    Example: Max Intra-Retry Delay is set to 60 seconds.
    Base Retry Delay is set to 2 seconds. Retries are performed 2, 4, 8, 16, 32,... seconds later.

    ✅️✅️✅️✅️

    Max Retry Duration

    Specify the total time for retrying a delivery. For REST destinations, a delivery is a batch of data items in one POST request. 

    Default: 5 minutes

    Example: Max Retry Duration is set to 8 hours.
    Base Retry Delay is set to 2 seconds. Requests are sent for 2+4+8+16+32+64+132... until 8 hours in total duration is reached. After that, no subsequent attempts are made to retry the delivery. The assumption here is that if there is an outage or other issue with the destination tool, recovery should take less than the value of the Max Retry Duration parameter to be completed.

    ✅️✅️✅️✅️

    Attributes To Be Dropped When Updating Events

    Specify the event attributes that you do not want to be updated in BMC Helix Operations Management when events are updated.

    For example, if you do not want an event's severity, source address, source category, and subcategory to be updated in BMC Helix Operations Management, you need to specify those attributes in a comma-separated format: severity,source_address,source_category,source_subcategory.

    Important: You can obtain the event attribute names in BMC Helix Operations Management, by exporting any event data in JSON, BAROC, XML, or CSV format. The exported file contains all attributes of the event data, and from there you can identify the attributes to be dropped. 

    ✅️✅️✅️✅️
    Device Filters and Metrics filtersDevice and Metrics filters help remove unwanted data and send only the required data to BMC Helix applications. The data is filtered by using the regular expression (regex) provided for device name, monitor name, monitor type, and metrics, and is sent to BMC Helix applications.
    Device Name RegexSpecify the regex for the device name. Metrics for devices whose names match the regex are sent to BMC Helix applications.
    Examples:
    • To send data for the devices that contain the string Linux in their names, specify the regex as .*Linux.*.
    • To send data for the devices that contain the string Cisco and Linux, specify the regex as (?=.*Cisco)(?=.*Linux).*.
    • To send the data for the devices whose names start with the string Linux, specify the regex as ^Linux.*. 
    Important:
    If you are using multiple regex, make sure that the regex do not conflict.
    For example, do not enter .*Linux.* and ^(?!.*Linux).* together. The former regex sends metrics for the devices whose names contain the string Linux, while the latter regex sends metrics for the devices whose names do not contain the string Linux.
    ❌️❌️✅️❌️
    Monitor Name RegexSpecify the regex for the monitor name. Metrics for the monitors whose names match the regex are sent to BMC Helix applications.
    Examples:
    • To send data for the monitors that contain the string system in their names, specify the regex as .*system.*.
    • To filter out the data for monitors that contain system in their name, specify the regex as ^(?!.*system).*.
    • To send the data for monitors whose names start with the string system, specify the regex as ^system.*.
    Important:
    If you are using multiple regex, make sure that the regex do not conflict.
    For example, do not enter .*system.* and ^(?!.*system).* together. The former regex sends metrics for the monitors whose names contain the string system, while the latter regex sends metrics for the monitors whose names do not contain the string system.
    ❌️❌️✅️❌️
    Monitor Type RegexSpecify the regex for the monitor type. Metrics are sent to BMC Helix applications for the monitor type that matches the regex.
    Examples:
    • To send data for the monitor type that contains the string health, specify the regex as .*health.*.
    • To send data for the monitor type that starts with the string health, specify the regex as ^health.*.
    • To filter out the monitor type that contains the string health, specify the regex as ^(?!.*health).*.
    Important:
    If you are using multiple regex, make sure that the regex do not conflict.
    For example, do not enter, ^health.* and ^(?!.*health).* together. The former regex collects metrics for the monitor type whose names contain the string health, while the latter regex collects data for the monitor types whose names do not contain the string health.
    ❌️❌️✅️❌️
    Metrics RegexSpecify the regex for the metrics. Metrics are sent to BMC Helix applications whose names match the regex.
    Examples:
    • To send metrics that contain the string avg in their names, specify the regex as .*avg.*.
    • To filter out the metrics that contain the string avg, specify the regex as ^(?!.*avg).*.
    • To send metrics whose names start with the string avg, specify the regex as ^avg.*.
    Important:
    If you are using multiple regex, make sure that the regex do not conflict.
    For example, do not enter, .*avg.* and ^(?!.*avg).* together. The former regex sends metrics whose name contains the string avg, while the latter regex sends metrics whose name does not contain the string avg.
    ❌️❌️✅️❌️
    Events FiltersEvents filters help remove unwanted data and send only the required events to BMC Helix applications. The data is filtered by using the regular expression (regex) provided for host, message, and detailed message and is sent to BMC Helix applications.
    Host RegexSpecify the regex for the host name. Events for the hosts whose names match the regex are sent to BMC Helix applications.
    Examples:
    • To send data for the host name /inventory/pricing, specify the regex as ^/inventory/pricing$.
    • To filter out data whose host name contains the string inventory, specify the regex as ^(?!.*inventory).*.
    • To send the data for the host whose names start with the string inventory, specify the regex as ^inventory.*. 
    Important:
    If you are using multiple regex, make sure that the regex do not conflict.
    For example, do not enter .*(inventory).* and ^(?!.*inventory).* together. The former regex sends events for the hosts whose names contain the string inventory, while the latter regex sends events for the hosts whose names do not contain the string inventory.
    ✅️✅️❌️❌️
    Message RegexSpecify the regex for the event message. Messages for the events that match the regex are sent to BMC Helix applications.
    Examples:
    • To send events whose messages contain the string HRV alert, specify the regex as .*HRV alert*.
    • To filter out the events whose message contains the string HRV alert, specify the regex as ^(?!.*HRV alert).*.
    • To send events whose message starts with the string HRV alert, specify the regex as ^(HRV alert).*. 
    Important:
    If you are using multiple regex, make sure that the regex do not conflict.
    For example, do not enter .*HRV alert.* and ^(?!.*HRV alert).* together. The former regex sends events whose message contains the string HRV alert, while the latter regex sends events whose message do not contain the string HRV alert.
    ✅️✅️❌️ 
    Detailed Message RegexSpecify the regex for the detailed message. Detailed messages for the events that match the regex are sent to BMC Helix applications.
    Examples:​​
    • To send events whose detailed message contains the string ci_display_name: easyTravel-k8s, specify the regex as .*ci_display_name: easyTravel-k8s.*.
    • To filter out the events whose detailed message contains the string ci_display_name: easyTravel-k8s, specify the regex as ^(?!.*ci_display_name: easyTravel-k8s).*.
    • To send the events whose detailed message starts with the string ci_display_name: easyTravel-k8s, specify the regex as ^(ci_display_name: easyTravel-k8s).*.
    Important:
    If you are using multiple regex, make sure that the regex do not conflict.
    For example, do not enter .*ci_display_name: easyTravel-k8s.* and ^(?!.*ci_display_name: easyTravel-k8s).* together. The former regex sends events whose detailed message contains the string ci_display_name: easyTravel-k8s, while the latter regex sends events whose message do not contain the string ci_display_name: easyTravel-k8s.
    ✅️✅️❌️❌️
    ))
  11. Click CREATE DISTRIBUTORS to create the required distributor streams for the selected data types.
  12. Click VALIDATE AND CREATE and then click SAVE STREAM to save the stream.
    After you save the stream, the connection that you just created is listed on the SOURCES panel.
  13. (Optional) Perform the following steps if you want to collect and view the metrics data in a hierarchical manner. Otherwise, skip to step 14. 
    With the custom JSLT, each AppDynamics metric category is represented as a single monitor, with related metrics organized hierarchically beneath it, rather than being displayed as individual metrics as separate monitors. Otherwise, each metric is displayed as an individual monitor.
    1. On the SOURCES panel, click Configure Mediator ConfigureMediator_icon.pngfor the source connection that you created and then expand APPDYNAMICS METRICS and navigate to the DISTRIBUTOR CONFIGURATION tab.
    2. To view JSON in edit mode, click Edit JSON.
    3. Search for the following line:

       "jsltField": "//NO JSLT",
    4. Delete the existing value from the jsltField field; the result should look as follows:

      "jsltField": "",
    5. To disable the edit mode for JSON, click Edit JSON.
    6. In the JSLT field, enter the following JSLT:

      Click here to see the JSLT
      //host name is decided based on the tier name is present or not if yes then its the host or else application is the host

      let tempHost = if (lowercase(.measurementGroup[0]) == "backends" and (starts-with(lowercase(.extras.tierName),"discovered backend call") == true or starts-with(lowercase(.extras.tierName),"external application") == true )) .extras.applicationName

      let host = if ($tempHost != "" and $tempHost != null)  $tempHost else ( if ( .extras.tierName != "" ) .extras.tierName else .extras.applicationName )

      //
      let hostType = if ( .extras.tierName == $host ) "Server" else "Application"

      let metricNameWithoutBrackets = replace(replace(.name,"\\)",""),"\\(","")
      let metricPathWithoutBrackets = replace(replace(.extras.metricPath,"\\)",""),"\\(","")

      let value = .value
      let time = .originTimestamp
      let metricName = .name
      let unit = .unit
      let external_id = .extras.ciExternalId

      let entityNames = replace(replace($metricPathWithoutBrackets,$host+"\\|",""),$metricNameWithoutBrackets,"")
      let monitorNames = split($entityNames,"\\|")

      //to remove empty entity names / monitor names  
      def removeEmptyArrayItems(mn) (
       [for ($mn) . if (. != "" and . != null)]
      )

      let remainingEntityNames = removeEmptyArrayItems($monitorNames)  

      //we are currently assuming max 10 levels
      let counter = [ 0,1,2,3,4,5,6,7,8,9]

      //function to create entity type for "overall application performace"
      def monitorTypesForOAP() (
       if (size($remainingEntityNames) > 1 )(
        if ($remainingEntityNames[1] == "External Calls")(
         [ "AppDynamics_"+.measurementGroup[0],
           "AppDynamics_"+.measurementGroup[0]+"_External_Calls",
           "AppDynamics_"+.measurementGroup[0]+"_Call"
         ])
        else
        (
         if ($remainingEntityNames[1] == "Individual Nodes")(
       ["AppDynamics_"+.measurementGroup[0],
           "AppDynamics_"+.measurementGroup[0]+"_Individual_Nodes",
           "AppDynamics_"+.measurementGroup[0]+"_Node"
       ]
       +

          if ($remainingEntityNames[3] == "External Calls")(
        ["AppDynamics_"+.measurementGroup[0]+"_Node_External_Calls",
         "AppDynamics_"+.measurementGroup[0]+"_Node_Call"
        ]
          )else (
        ["AppDynamics_"+.measurementGroup[0]+"_Node_Thread_Tasks",
            "AppDynamics_"+.measurementGroup[0]+"_Node_Task",
            "AppDynamics_"+.measurementGroup[0]+"_Node_Task_External_Calls",
            "AppDynamics_"+.measurementGroup[0]+"_Node_Task_Call"
        ]
          )
         )
         else
         (
          if ($remainingEntityNames[1] == "Thread Tasks")(
       ["AppDynamics_"+.measurementGroup[0],
           "AppDynamics_"+.measurementGroup[0]+"_Thread_Tasks",
           "AppDynamics_"+.measurementGroup[0]+"_Task",
           "AppDynamics_"+.measurementGroup[0]+"_Task_External_Calls",
           "AppDynamics_"+.measurementGroup[0]+"_Task_Call"
       ])
       else
       ( [ "AppDynamics_"+.measurementGroup[0],
              "AppDynamics_"+.measurementGroup[0]+ "_" + $remainingEntityNames[1],
              "AppDynamics_"+.measurementGroup[0]+ "_" + $remainingEntityNames[1] + "_Level1"
         ]
        )
         )
        )
      )
      else ( [] )
      )//end of function


      def monitorTypesForAIPHardwareResources(addLevel) (
       
        ["AppDynamics_Application Infrastructure Performance_" + (if ($addLevel == 0) "" else "Node_") + $remainingEntityNames[1+$addLevel] + "_" + $remainingEntityNames[2+$addLevel] ]
        +
        if ( size($remainingEntityNames) > 3 + $addLevel) (
       [ "AppDynamics_Application Infrastructure Performance_" + (if ($addLevel == 0) "" else "Node_") + $remainingEntityNames[1+$addLevel] + "_Single_" + $remainingEntityNames[2+$addLevel]]
        )
        else [""]
      )



      def monitorTypesForAIPIndividualNodes() (
          ["AppDynamics_Application Infrastructure Performance_Node",
           "AppDynamics_Application Infrastructure Performance_Node_" + $remainingEntityNames[3]
          ]

       +

       if ($remainingEntityNames[3] == "Hardware Resources") (
        monitorTypesForAIPHardwareResources(2)
          )else ( if ($remainingEntityNames[3] == "JVM") (
          monitorTypesForAIPJVM(2)
         )else (
             if ($remainingEntityNames[3] == "Agent")(
           [ "AppDynamics_Application Infrastructure Performance_Node_" + $remainingEntityNames[3] + "_" + $remainingEntityNames[4] ]
          )else(
             if ($remainingEntityNames[3] == "JMX")(
             monitorTypesForAIPJMX(2)
          )
         
          )
         )
       )
         
      )

      def monitorTypesForAIPJMX(addLevel) (
        ["AppDynamics_Application Infrastructure Performance_" + (if ($addLevel == 0) "" else "Node_") + $remainingEntityNames[1+$addLevel] + "_" + $remainingEntityNames[2+$addLevel]]

        +

         if ( contains("Container",$remainingEntityNames[2 + $addLevel]) == true )(
        ["AppDynamics_Application Infrastructure Performance_" + (if ($addLevel == 0) "" else "Node_") + $remainingEntityNames[1+$addLevel] + "_Server"]
         ) else (
             if (contains("Server",$remainingEntityNames[2 + $addLevel]) == true)(
        ["AppDynamics_Application Infrastructure Performance_" + (if ($addLevel == 0) "" else "Node_") + $remainingEntityNames[1+$addLevel] + "_Server"]
             )else(
              if (contains("Pool",$remainingEntityNames[2 + $addLevel]) == true )(
           ["AppDynamics_Application Infrastructure Performance_" + (if ($addLevel == 0) "" else "Node_") + $remainingEntityNames[1+$addLevel] + "_Pool"]
              )else(
          if (contains("Coherence",$remainingEntityNames[2 + $addLevel]) == true ) (
           ["AppDynamics_Application Infrastructure Performance_" + (if ($addLevel == 0) "" else "Node_") + $remainingEntityNames[1+$addLevel] + "_" + $remainingEntityNames[3+$addLevel]]
           +
          [for ([4+$addLevel,5+$addLevel,6+$addLevel,7+$addLevel,8+$addLevel,9+$addLevel ])  "AppDynamics_Application Infrastructure Performance_" + (if ($addLevel == 0) "" else "Node_") + $remainingEntityNames[1+$addLevel] + "_" + $remainingEntityNames[3+$addLevel] + "_" + $counter[. - (3+$addLevel)]]
          
               )
              )
         )
         )
      )



      def monitorTypesForAIPJVM(addLevel) (
         if (size($remainingEntityNames) == 3 + $addLevel)(
        ["AppDynamics_Application Infrastructure Performance_" + (if ($addLevel == 0) "" else "Node_") + $remainingEntityNames[1+$addLevel] + "_" + $remainingEntityNames[2+$addLevel]]
       )
         else (
         if (size($remainingEntityNames) == 4 + $addLevel)(
         ["AppDynamics_Application Infrastructure Performance_" + (if ($addLevel == 0) "" else "Node_") + $remainingEntityNames[1+$addLevel] + "_" + $remainingEntityNames[2+$addLevel],
         "AppDynamics_Application Infrastructure Performance_" + (if ($addLevel == 0) "" else "Node_") + $remainingEntityNames[1+$addLevel] + "_" + $remainingEntityNames[2+$addLevel] + "_" + $remainingEntityNames[3+$addLevel]]
         )else (
         if (size($remainingEntityNames) == 5 + $addLevel)(
         ["AppDynamics_Application Infrastructure Performance_" + (if ($addLevel == 0) "" else "Node_") + $remainingEntityNames[1+$addLevel] + "_" + $remainingEntityNames[2+$addLevel],
          "AppDynamics_Application Infrastructure Performance_" + (if ($addLevel == 0) "" else "Node_") + $remainingEntityNames[1+$addLevel] + "_" + $remainingEntityNames[2+$addLevel] + "_" + $remainingEntityNames[3+$addLevel],
          "AppDynamics_Application Infrastructure Performance_" + (if ($addLevel == 0) "" else "Node_") + $remainingEntityNames[1+$addLevel] + "_" + $remainingEntityNames[2+$addLevel] + "_Pool"]
        )
         )
         )  
      )


      //function to create entity type for "buisness transaction performace"
      def monitorTypesForAIP() (
        [ "AppDynamics_Application Infrastructure Performance",
          "AppDynamics_Application Infrastructure Performance_" + $remainingEntityNames[1] ]

        +

        if ($remainingEntityNames[1] == "Individual Nodes")(
           monitorTypesForAIPIndividualNodes()
         )//end of if for handling individual calls
         else (
           if ($remainingEntityNames[1] == "JVM")(
              monitorTypesForAIPJVM(0)
           )//end of handling jvm
        else (
          if ($remainingEntityNames[1] == "Hardware Resources")(
          monitorTypesForAIPHardwareResources(0)
        )
        else(
          if ($remainingEntityNames[1] == "Agent")(
           [ "AppDynamics_Application Infrastructure Performance_" + $remainingEntityNames[1] + "_" + $remainingEntityNames[2] ]
          )
          else ( //to handle jmx
           monitorTypesForAIPJMX(0)
          )
        )
        )//end of second if handling jvm
         )//end of first which is for individual calls
      )


      //function to create entity type for "buisness transaction performace"
      def monitorTypesForBT() (
        [ "AppDynamics_Business Transaction Performance",
          "AppDynamics_Business Transaction Performance_Business_Transactions",
          "AppDynamics_Business Transaction Performance_Transaction" ]
        +
        if (size($remainingEntityNames) > 3 and $remainingEntityNames[3] == "Individual Nodes")(
        [ "AppDynamics_Business Transaction Performance_Transaction_Individual_Nodes",
          "AppDynamics_Business Transaction Performance_Transaction_Node"
        ])
        else (
         if (size($remainingEntityNames) > 3 and $remainingEntityNames[3] == "External Calls")(
        [ "AppDynamics_Business Transaction Performance_Transaction_External_Calls",
          "AppDynamics_Business Transaction Performance_Transaction_Call"  
        ])
         else (
            if (size($remainingEntityNames) > 3 and $remainingEntityNames[3] == "Thread Tasks")(
           [ "AppDynamics_Business Transaction Performance_Transaction_Thread_Tasks",
             "AppDynamics_Business Transaction Performance_Transaction_Task"  
           ])
            else (
          [ "AppDynamics_Business Transaction Performance_Transaction_"+$remainingEntityNames[3],
            "AppDynamics_Business Transaction Performance_Transaction_"+$remainingEntityNames[4]  
          ])
         )
        )
        +
        if (size($remainingEntityNames) > 5 and $remainingEntityNames[3] == "Individual Nodes" and $remainingEntityNames[5] == "External Calls" )(
          [ "AppDynamics_Business Transaction Performance_Transaction_Node_External_Calls",
            "AppDynamics_Business Transaction Performance_Transaction_Node_Call"
          ])
        else (
          if (size($remainingEntityNames) > 5 and $remainingEntityNames[3] == "Individual Nodes" and $remainingEntityNames[5] == "Thread Tasks" )(
        [ "AppDynamics_Business Transaction Performance_Transaction_Node_Thread_Tasks",
          "AppDynamics_Business Transaction Performance_Transaction_Node_Task"  
        ])
           else (
        if (size($remainingEntityNames) > 5 and $remainingEntityNames[3] == "External Calls")(
           [ "AppDynamics_Business Transaction Performance_Transaction_Node_Call_Server"] )  
           else ( [""] )
           )
        )
      )

      def monitorTypesForBackends() (
         ["AppDynamics_Backends"] +
         if (size($remainingEntityNames) > 1 and (starts-with(lowercase($remainingEntityNames[1]),"discovered backend call") == true or starts-with(lowercase($remainingEntityNames[1]),"external application") == true ))(
            ["AppDynamics_Backend"]
         )
      )

      def monitorTypesForErrors() (
         ["AppDynamics_Errors"] +
         ["AppDynamics_Error"] +
          if (size($remainingEntityNames) == 4 and $remainingEntityNames[2] == "Individual Nodes")  (
        ["AppDynamics_Error_Individual_Nodes",
            "AppDynamics_Error_Node"]
       )else (
         if (size($remainingEntityNames) == 6 and $remainingEntityNames[2] == "Individual Nodes" and $remainingEntityNames[4] == "Business Transactions")  (
             ["AppDynamics_Error_Individual_Nodes",
                 "AppDynamics_Error_Node",
              "AppDynamics_Error_Node_Business_Transactions",
                 "AppDynamics_Error_Node_Transaction"]
          ) else (
             if (size($remainingEntityNames) == 4 and $remainingEntityNames[2] == "Business Transactions")  (
               ["AppDynamics_Error_Business_Transactions",
                  "AppDynamics_Error_Transaction"]
            )
          )
       )
      )

      def monitorTypesForServiceEndpoints() (
         ["AppDynamics_Service_Endpoints"] +
         ["AppDynamics_Service_Endpoint"] +
          if (size($remainingEntityNames) == 4 and $remainingEntityNames[2] == "Individual Nodes")  (
        ["AppDynamics_Endpoint_Individual_Nodes",
            "AppDynamics_Endpoint_Node"]
       )
      )


      //based on paths we need to create various entity types ids also called as monitor type ids this is important for hierarchy on bhom device page
      let monitorTypes = if (.measurementGroup[0] == "Overall Application Performance") monitorTypesForOAP()
                         else (if (.measurementGroup[0] == "Business Transaction Performance") monitorTypesForBT()
             else (if (.measurementGroup[0] == "Application Infrastructure Performance") removeEmptyLabels(monitorTypesForAIP())
             else (if (.measurementGroup[0] == "Backends") monitorTypesForBackends()
             else (if (.measurementGroup[0] == "Errors") monitorTypesForErrors() else monitorTypesForServiceEndpoints()))))


      //Entitynames should be unique we can have  dumplicate display name which is instanceName but not the duplicate entity name so we need to construnct it based on which level
      def uniqueEntityName(num)
      join($remainingEntityNames[0 : $num + 1], "_")


      //function which check how many actual Entitynames are present in a single kafka response for one metric
      //based on the for loop on counter we a parenet hierarchy is created in form or labels
      def allLabels() (
      if (size($remainingEntityNames) == 1 )(
      [{ "labels": {
         "metricName" : $metricName,
         "hostname" : $host,
         "entityId" : join(["AppDynamics", ":", $host, ":", "AppDynamics_" + .measurementGroup[0], ":", .measurementGroup[0]], ""),
         "entityTypeId" : "AppDynamics_" + .measurementGroup[0],
         "entityName" : .measurementGroup[0],
         "isKpi" : true,
         "source" : "AppDynamics",
         "external_id" : $external_id,
         "unit" : $unit,
         "hostType" : $hostType
      },
      "samples" : [{
         "value" : $value,
         "timestamp" : $time
       }]
      }
      ])
      else
      (
      [
      for ( $counter  )(
       if ( . < size($remainingEntityNames))(
       {
        "labels": {
       "metricName" : if (. == size($remainingEntityNames) - 1) $metricName else "Availability",       
       "hostname" : $host,
       "entityTypeId" : $monitorTypes[.],
       "entityName" : uniqueEntityName(.),
       "entityId" : "AppDynamics:" + $host + ":" + $monitorTypes[.] + ":" + uniqueEntityName(.) ,
       "unit" : if (. == size($remainingEntityNames) - 1) $unit else "Percent" ,
       "isKpi" : "true",
       "hostType" : $hostType,
       "source" : "AppDynamics",
       "external_id" : $external_id,
       "extras" :  if ( string(.) != "0" ) (
         {  
             "parentEntityName" : replace(uniqueEntityName(. - 1),"[/=+?:; ]","_")  ,
             "parentEntityTypeId" : replace($monitorTypes[. - 1],"[/=+?:; ]","_"),
             "instanceName" : $remainingEntityNames[.]  
         }
       )
         },
         "samples" : [{
        "value" : if (. == size($remainingEntityNames) - 1 )  $value else "100",
        "timestamp" : $time
         }]
        }
       )
       else
       ({})
      )//end of for loop
      ]
      )
      )//end of function

      //function which remove empty objects
      def removeEmptyLabels(labels) (
      [for ($labels) . if (. != {})]
      )

      //Our construnctions of labels starts here
      let labels = allLabels()

      //we remove all empty objects and send it to bhom
      removeEmptyLabels($labels)
    7. Click SAVE & CLOSE.
  14. On the SOURCES panel, move the slider to the right to start the data stream for the connector you created.

    Important
    For a data stream, the Run Latency (max/avg), Items (Avg per Run), and Last Run Status columns on the Streams page might show the status as No Runs during the data collection process. After completion of the process, these columns are updated with an appropriate status.

    For more information about data streams, see Managing data streams

Task 2: To verify the connection

In BMC Helix Intelligent Integrations, on the SOURCES panel, confirm that the data streams for the integration you created are running. Data streaming is indicated by moving colored arrows.

AppDynamics_MetricsStream.png

  • A moving dark blue arrow (EventsStream_Icon.png) indicates that the event stream is running. Event data will be pushed according to the configured Collection Schedule interval.
  • A moving red arrow (MetricsStream_Icon.png) indicates that the metric stream is running. Metric data will be pushed according to the configured Collection Schedule interval.
  • A moving light blue arrow (TopologyStream_Icon.png) indicates that the topology stream is running. Topology data will be pushed according to the configured Collection Schedule interval.

Task 3: To view data in BMC Helix applications

View data collected from AppDynamics in multiple BMC Helix applications.

To view events in BMC Helix Operations Management

  1. In BMC Helix Operations Management, select Monitoring > Events.
  2. Filter the events by the AppDynamicEvent (for AppDynamics events) or AppDynamicHRVEvent (for AppDynamics Health Rule Violations) classes.
    AppDynamic.png

Incoming events from AppDynamics are processed in BMC Helix Operations Management through a set of deduplication rules to determine whether the incoming event is a duplicate event or a new event. For more information, see Event deduplication, suppression, and closure for reducing event noise.

For more information about events, see Monitoring and managing events.

To view metrics in BMC Helix Operations Management

The servers monitored by AppDynamics appear as devices and various metric categories in AppDynamics appear as monitors  in BMC Helix Operations Management. You can view the metrics under these monitors.

  1. In BMC Helix Operations Management, select Monitoring > Devices.
  2. Click the link for the device for which you want to view metrics.
  3. On the Monitors tab, expand the monitor hierarchy, and click the metric for which you want to view data.
    The Performance Overview tab shows the metric graph.
    AppDynamics_Metrics_262.png

For information about metrics, see Viewing collected data.

To view the topology data in BMC Helix Discovery

In BMC Helix Discovery, select Explore > Data, and click <count> Import Records in the Miscellaneous section. The Import Record List page shows the CI records received from AppDynamics.

For information about records, see Managing your IT infrastructure.

To view services and situations in BMC Helix AIOps

Before you view services and situations in BMC Helix AIOps, create a Business Service model in BMC Helix Discovery. For information about creating models, see Managing models.  

In BMC Helix AIOps, on the Overview page, view the services and situations for the event and topology data received from AppDynamics

For information about services, see Monitoring services. For information about Situations, see Monitoring situations

Related topics

Editing and deleting connectors

Monitoring BMC Helix Intelligent Integrations

 

Tip: For faster searching, add an asterisk to the end of your partial query. Example: cert*

BMC Helix Intelligent Integrations 26.1