BAM when you have an existing logic app you cant change
  • 14 Jun 2020
  • 8 Minutes to read
  • Contributors
  • Comment
  • Dark
    Light
  • PDF

BAM when you have an existing logic app you cant change

  • Comment
  • Dark
    Light
  • PDF

Article Summary

If you like the BAM videos I have been doing and want to use BAM but your existing Logic Apps are already in production and you can not change them, fear not you can still use BAM. If you accept a couple of constraints as to how you can use BAM then its possible to subscribe to the diagnostics events that Logic Apps pushes to an event hub and then filter/map the events and forward them to the Serverless360 BAM API. This would allow you to be able to get the value from a BAM view of your processes to simplify the operations of them and to allow some self service for your users but without the need to change your existing logic apps. The main constraints for this pattern are as follows:

  • You need to aim for 1 BAM transaction per Logic App you want to use BAM with
  • You need to map and filter the events from diagnostics to get rid of the noise
  • You would use the CheckPoint with correlation approach discussed in a previous video and correlate events based on the LogicApp run ID.

The below video will walk you through how to do this.

The article I talk about in the video is on this link:
https://docs.serverless360.com/docs/implicit-bam-vs-explicit-bam

Sample Mappings

Below is the example mapping data which I used to filter and map the diagnostics events for BAM.

[
  {
    "workflowId": "/SUBSCRIPTIONS/[My Sub]/RESOURCEGROUPS/BAM_BUSINESSPROCESS_13_NOINSTRUMENTATION/PROVIDERS/MICROSOFT.LOGIC/WORKFLOWS/BP13",
    "bam_businessProcessName": "Business Process 13 - No Instrumentation",
    "bam_transactionName": "BP13",
    "bam_startStageName": "Message Received",
    "bam_endStageName": "Complete",
    "stageMappings": [
      {
        "logicAppStepName": "Compose_-_Do_some_work_1",
        "bam_StageName": "Compose - Do some work 1"
      },
      {
        "logicAppStepName": "Compose_-_Do_some_work_2",
        "bam_StageName": "Compose - Do some work 2"
      },
      {
        "logicAppStepName": "Completed",
        "bam_StageName": "Completed"
      }
    ]
  },
  {
    "workflowId": "/SUBSCRIPTIONS/[My Sub]/RESOURCEGROUPS/BAM_BUSINESSPROCESS_13_NOINSTRUMENTATION/PROVIDERS/MICROSOFT.LOGIC/WORKFLOWS/BP_13_DEMO",
    "bam_businessProcessName": "Business Process 13 - No Instrumentation",
    "bam_transactionName": "BP13-Demo",
    "bam_startStageName": "Received Order",
    "bam_endStageName": "Logic App Complete",
    "stageMappings": [
      {
        "logicAppStepName": "Compose_-_Check_Order",
        "bam_StageName": "Checking Order"
      },
      {
        "logicAppStepName": "Compose_-_Order_Approved",
        "bam_StageName": "Order Approved"
      },
      {
        "logicAppStepName": "Compose_-_Order_Declined",
        "bam_StageName": "Order Exceeds Limit"
      },
      {
        "logicAppStepName": "Compose_-_Process_Order",
        "bam_StageName": "Process Order"
      },
      {
        "logicAppStepName": "Compose_-_Customer_Number",
        "bam_StageName": "Create Customer"
      },
      {
        "logicAppStepName": "Compose_-_Order_Number",
        "bam_StageName": "Create Order"
      }
    ]
  }
]

Sample Logic App Definition

Below is the json for the sample logic app i used to be able to process logic app diagnostics events and to push them to BAM.

{

  //Note: If you want to try this make sure to check the connections at the bottom to make sure they would point to your A Logic App connectors

  "definition": {
    "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
    "actions": {
      "Compose": {
        "inputs": "@triggerBody()?['ContentData']",
        "runAfter": {
          "Parse_JSON_-_Mappings": [
            "Succeeded"
          ]
        },
        "type": "Compose"
      },
      "Compose_-_BAM_Mappings": {
        "inputs": [
          {
            "bam_businessProcessName": "Business Process 13 - No Instrumentation",
            "bam_endStageName": "Complete",
            "bam_startStageName": "Message Received",
            "bam_transactionName": "BP13",
            "stageMappings": [
              {
                "bam_StageName": "Compose - Do some work 1",
                "logicAppStepName": "Compose_-_Do_some_work_1"
              },
              {
                "bam_StageName": "Compose - Do some work 2",
                "logicAppStepName": "Compose_-_Do_some_work_2"
              },
              {
                "bam_StageName": "Completed",
                "logicAppStepName": "Completed"
              }
            ],
            "workflowId": "/SUBSCRIPTIONS/[My Sub ID]/RESOURCEGROUPS/BAM_BUSINESSPROCESS_13_NOINSTRUMENTATION/PROVIDERS/MICROSOFT.LOGIC/WORKFLOWS/BP13"
          },
          {
            "bam_businessProcessName": "Business Process 13 - No Instrumentation",
            "bam_endStageName": "Logic App Complete",
            "bam_startStageName": "Received Order",
            "bam_transactionName": "BP13-Demo",
            "stageMappings": [
              {
                "bam_StageName": "Checking Order",
                "logicAppStepName": "Compose_-_Check_Order"
              },
              {
                "bam_StageName": "Order Approved",
                "logicAppStepName": "Compose_-_Order_Approved"
              },
              {
                "bam_StageName": "Order Exceeds Limit",
                "logicAppStepName": "Compose_-_Order_Declined"
              },
              {
                "bam_StageName": "Process Order",
                "logicAppStepName": "Compose_-_Process_Order"
              },
              {
                "bam_StageName": "Create Customer",
                "logicAppStepName": "Compose_-_Customer_Number"
              },
              {
                "bam_StageName": "Create Order",
                "logicAppStepName": "Compose_-_Order_Number"
              }
            ],
            "workflowId": "/SUBSCRIPTIONS/[My Sub ID]/RESOURCEGROUPS/BAM_BUSINESSPROCESS_13_NOINSTRUMENTATION/PROVIDERS/MICROSOFT.LOGIC/WORKFLOWS/BP_13_DEMO"
          }
        ],
        "runAfter": {},
        "type": "Compose"
      },
      "For_each_-_Event_Hub_Record": {
        "actions": {
          "Compose_-_Event_Hub_Message": {
            "inputs": "@items('For_each_-_Event_Hub_Record')",
            "runAfter": {},
            "type": "Compose"
          },
          "For_each_-_BAM_Mapping": {
            "actions": {
              "Condition_-_Logic_App_Workflow_ID_Matches": {
                "actions": {
                  "Switch": {
                    "cases": {
                      "Case_-_Workflow_Started": {
                        "actions": {
                          "Parse_JSON_-_Logic_App_Started": {
                            "inputs": {
                              "content": "@items('For_each_-_Event_Hub_Record')",
                              "schema": {
                                "properties": {
                                  "category": {
                                    "type": "string"
                                  },
                                  "level": {
                                    "type": "string"
                                  },
                                  "operationName": {
                                    "type": "string"
                                  },
                                  "properties": {
                                    "properties": {
                                      "$schema": {
                                        "type": "string"
                                      },
                                      "correlation": {
                                        "properties": {
                                          "clientTrackingId": {
                                            "type": "string"
                                          }
                                        },
                                        "type": "object"
                                      },
                                      "resource": {
                                        "properties": {
                                          "location": {
                                            "type": "string"
                                          },
                                          "originRunId": {
                                            "type": "string"
                                          },
                                          "resourceGroupName": {
                                            "type": "string"
                                          },
                                          "runId": {
                                            "type": "string"
                                          },
                                          "subscriptionId": {
                                            "type": "string"
                                          },
                                          "workflowId": {
                                            "type": "string"
                                          },
                                          "workflowName": {
                                            "type": "string"
                                          }
                                        },
                                        "type": "object"
                                      },
                                      "startTime": {
                                        "type": "string"
                                      },
                                      "status": {
                                        "type": "string"
                                      },
                                      "tags": {
                                        "properties": {},
                                        "type": "object"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "resourceId": {
                                    "type": "string"
                                  },
                                  "time": {
                                    "type": "string"
                                  },
                                  "workflowId": {
                                    "type": "string"
                                  }
                                },
                                "type": "object"
                              }
                            },
                            "runAfter": {},
                            "type": "ParseJson"
                          },
                          "Start_Transaction_-_Logic_App_Started": {
                            "inputs": {
                              "body": {
                                "MessageBody": "@body('Parse_JSON_-_Logic_App_Started')",
                                "MessageHeader": {
                                  "LogicAppID": "@{body('Parse_JSON_-_Logic_App_Started')?['properties']?['resource']?['runId']}"
                                }
                              },
                              "headers": {
                                "SL360-ArchiveMessage": "True",
                                "SL360-BusinessProcess": "@items('For_each_-_BAM_Mapping')['bam_businessProcessName']",
                                "SL360-IsTransactionComplete": "False",
                                "SL360-Stage": "@items('For_each_-_BAM_Mapping')['bam_startStageName']",
                                "SL360-StageStatus": "Success",
                                "SL360-Transaction": "@items('For_each_-_BAM_Mapping')['bam_transactionName']"
                              },
                              "host": {
                                "connection": {
                                  "name": "@parameters('$connections')['SL360-BAM']['connectionId']"
                                }
                              },
                              "method": "post",
                              "path": "/api/StartTransaction"
                            },
                            "runAfter": {
                              "Parse_JSON_-_Logic_App_Started": [
                                "Succeeded"
                              ]
                            },
                            "type": "ApiConnection"
                          }
                        },
                        "case": "Microsoft.Logic/workflows/workflowRunStarted"
                      },
                      "Case_-_workflowActionCompleted": {
                        "actions": {
                          "Condition_-_Send_Event_to_BAM": {
                            "actions": {
                              "For_each_-_Stage_Mapping": {
                                "actions": {
                                  "Condition_-_Stage_Mapping_Name": {
                                    "actions": {
                                      "Checkpoint_With_Correlation_-_Action_Complete": {
                                        "inputs": {
                                          "body": {
                                            "MessageBody": "@body('Parse_JSON_-_Action_Complete')",
                                            "Property": [
                                              {
                                                "Name": "LogicAppID",
                                                "Value": "@body('Parse_JSON_-_Action_Complete')?['properties']?['resource']?['runId']"
                                              }
                                            ]
                                          },
                                          "headers": {
                                            "SL360-ArchiveMessage": "True",
                                            "SL360-BusinessProcess": "@items('For_each_-_BAM_Mapping')['bam_businessProcessName']",
                                            "SL360-IgnoreNotFound": "True",
                                            "SL360-Stage": "@items('For_each_-_Stage_Mapping')['bam_StageName']",
                                            "SL360-StageStatus": "@{outputs('Compose_-_Stage_Result')}",
                                            "SL360-Transaction": "@items('For_each_-_BAM_Mapping')['bam_transactionName']"
                                          },
                                          "host": {
                                            "connection": {
                                              "name": "@parameters('$connections')['SL360-BAM']['connectionId']"
                                            }
                                          },
                                          "method": "post",
                                          "path": "/api/CheckpointWithCorrelation"
                                        },
                                        "runAfter": {
                                          "Compose_-_Stage_Result": [
                                            "Succeeded"
                                          ]
                                        },
                                        "type": "ApiConnection"
                                      },
                                      "Compose_-_Stage_Result": {
                                        "inputs": "@if(equals(body('Parse_JSON_-_Action_Complete')?['properties']?['status'], 'Succeeded'), 'Success', 'Failure')",
                                        "runAfter": {},
                                        "type": "Compose"
                                      }
                                    },
                                    "expression": {
                                      "and": [
                                        {
                                          "equals": [
                                            "@body('Parse_JSON_-_Action_Complete')?['properties']?['resource']?['actionName']",
                                            "@items('For_each_-_Stage_Mapping')['logicAppStepName']"
                                          ]
                                        }
                                      ]
                                    },
                                    "runAfter": {},
                                    "type": "If"
                                  }
                                },
                                "foreach": "@items('For_each_-_BAM_Mapping')['stageMappings']",
                                "runAfter": {},
                                "type": "Foreach"
                              }
                            },
                            "expression": {
                              "and": [
                                {
                                  "not": {
                                    "equals": [
                                      "@body('Parse_JSON_-_Action_Complete')?['properties']?['status']",
                                      "Skipped"
                                    ]
                                  }
                                }
                              ]
                            },
                            "runAfter": {
                              "Parse_JSON_-_Action_Complete": [
                                "Succeeded"
                              ]
                            },
                            "type": "If"
                          },
                          "Parse_JSON_-_Action_Complete": {
                            "inputs": {
                              "content": "@items('For_each_-_Event_Hub_Record')",
                              "schema": {
                                "properties": {
                                  "category": {
                                    "type": "string"
                                  },
                                  "level": {
                                    "type": "string"
                                  },
                                  "operationName": {
                                    "type": "string"
                                  },
                                  "properties": {
                                    "properties": {
                                      "$schema": {
                                        "type": "string"
                                      },
                                      "correlation": {
                                        "properties": {
                                          "actionTrackingId": {
                                            "type": "string"
                                          },
                                          "clientTrackingId": {
                                            "type": "string"
                                          }
                                        },
                                        "type": "object"
                                      },
                                      "resource": {
                                        "properties": {
                                          "actionName": {
                                            "type": "string"
                                          },
                                          "location": {
                                            "type": "string"
                                          },
                                          "resourceGroupName": {
                                            "type": "string"
                                          },
                                          "runId": {
                                            "type": "string"
                                          },
                                          "subscriptionId": {
                                            "type": "string"
                                          },
                                          "workflowId": {
                                            "type": "string"
                                          },
                                          "workflowName": {
                                            "type": "string"
                                          }
                                        },
                                        "type": "object"
                                      },
                                      "startTime": {
                                        "type": "string"
                                      },
                                      "status": {
                                        "type": "string"
                                      },
                                      "tags": {
                                        "properties": {},
                                        "type": "object"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "resourceId": {
                                    "type": "string"
                                  },
                                  "time": {
                                    "type": "string"
                                  },
                                  "workflowId": {
                                    "type": "string"
                                  }
                                },
                                "type": "object"
                              }
                            },
                            "runAfter": {},
                            "type": "ParseJson"
                          }
                        },
                        "case": "Microsoft.Logic/workflows/workflowActionCompleted"
                      },
                      "Case_-_workflowRunCompleted": {
                        "actions": {
                          "Checkpoint_With_Correlation_-_Logic_App_Finished": {
                            "inputs": {
                              "body": {
                                "MessageBody": "@body('Parse_JSON_-_Logic_App_Complete')",
                                "Property": [
                                  {
                                    "Name": "LogicAppID",
                                    "Value": "@body('Parse_JSON_-_Logic_App_Complete')?['properties']?['resource']?['runId']"
                                  }
                                ]
                              },
                              "headers": {
                                "SL360-ArchiveMessage": "True",
                                "SL360-BusinessProcess": "@items('For_each_-_BAM_Mapping')['bam_businessProcessName']",
                                "SL360-IgnoreNotFound": "True",
                                "SL360-IsTransactionComplete": "True",
                                "SL360-Stage": "@items('For_each_-_BAM_Mapping')['bam_endStageName']",
                                "SL360-StageStatus": "@{outputs('Compose_-_Complete_Stage_Status')}",
                                "SL360-Transaction": "@items('For_each_-_BAM_Mapping')['bam_transactionName']"
                              },
                              "host": {
                                "connection": {
                                  "name": "@parameters('$connections')['SL360-BAM']['connectionId']"
                                }
                              },
                              "method": "post",
                              "path": "/api/CheckpointWithCorrelation"
                            },
                            "runAfter": {
                              "Compose_-_Complete_Stage_Status": [
                                "Succeeded"
                              ]
                            },
                            "type": "ApiConnection"
                          },
                          "Compose_-_Complete_Stage_Status": {
                            "inputs": "@if(equals(body('Parse_JSON_-_Logic_App_Complete')?['properties']?['status'], 'Failed'), 'Failure', 'Success')",
                            "runAfter": {
                              "Parse_JSON_-_Logic_App_Complete": [
                                "Succeeded"
                              ]
                            },
                            "type": "Compose"
                          },
                          "Parse_JSON_-_Logic_App_Complete": {
                            "inputs": {
                              "content": "@items('For_each_-_Event_Hub_Record')",
                              "schema": {
                                "properties": {
                                  "category": {
                                    "type": "string"
                                  },
                                  "level": {
                                    "type": "string"
                                  },
                                  "operationName": {
                                    "type": "string"
                                  },
                                  "properties": {
                                    "properties": {
                                      "$schema": {
                                        "type": "string"
                                      },
                                      "correlation": {
                                        "properties": {
                                          "clientTrackingId": {
                                            "type": "string"
                                          }
                                        },
                                        "type": "object"
                                      },
                                      "endTime": {
                                        "type": "string"
                                      },
                                      "resource": {
                                        "properties": {
                                          "location": {
                                            "type": "string"
                                          },
                                          "originRunId": {
                                            "type": "string"
                                          },
                                          "resourceGroupName": {
                                            "type": "string"
                                          },
                                          "runId": {
                                            "type": "string"
                                          },
                                          "subscriptionId": {
                                            "type": "string"
                                          },
                                          "workflowId": {
                                            "type": "string"
                                          },
                                          "workflowName": {
                                            "type": "string"
                                          }
                                        },
                                        "type": "object"
                                      },
                                      "startTime": {
                                        "type": "string"
                                      },
                                      "status": {
                                        "type": "string"
                                      },
                                      "tags": {
                                        "properties": {},
                                        "type": "object"
                                      }
                                    },
                                    "type": "object"
                                  },
                                  "resourceId": {
                                    "type": "string"
                                  },
                                  "time": {
                                    "type": "string"
                                  },
                                  "workflowId": {
                                    "type": "string"
                                  }
                                },
                                "type": "object"
                              }
                            },
                            "runAfter": {},
                            "type": "ParseJson"
                          }
                        },
                        "case": "Microsoft.Logic/workflows/workflowRunCompleted"
                      }
                    },
                    "default": {
                      "actions": {
                        "Compose_-_Log_Default": {
                          "inputs": "Currently we will skip this\n\n@{body('Parse_JSON_-_Logic_App_Events')}",
                          "runAfter": {},
                          "type": "Compose"
                        }
                      }
                    },
                    "expression": "@items('For_each_-_Event_Hub_Record')?['operationName']",
                    "runAfter": {},
                    "type": "Switch"
                  }
                },
                "description": "Does the logic app id match the id of the workflow in the mappings",
                "expression": {
                  "and": [
                    {
                      "equals": [
                        "@items('For_each_-_Event_Hub_Record')?['workflowId']",
                        "@items('For_each_-_BAM_Mapping')['workflowId']"
                      ]
                    }
                  ]
                },
                "runAfter": {},
                "type": "If"
              }
            },
            "foreach": "@body('Parse_JSON_-_Mappings')",
            "runAfter": {
              "Compose_-_Event_Hub_Message": [
                "Succeeded"
              ]
            },
            "type": "Foreach"
          }
        },
        "foreach": "@body('Parse_JSON_-_Logic_App_Events')?['records']",
        "runAfter": {
          "Parse_JSON_-_Logic_App_Events": [
            "Succeeded"
          ]
        },
        "type": "Foreach"
      },
      "Parse_JSON_-_Logic_App_Events": {
        "inputs": {
          "content": "@triggerBody()?['ContentData']",
          "schema": {
            "properties": {
              "records": {
                "items": {
                  "properties": {
                    "category": {
                      "type": "string"
                    },
                    "level": {
                      "type": "string"
                    },
                    "operationName": {
                      "type": "string"
                    },
                    "resourceId": {
                      "type": "string"
                    },
                    "time": {
                      "type": "string"
                    },
                    "workflowId": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "time",
                    "workflowId",
                    "resourceId",
                    "category",
                    "level",
                    "operationName"
                  ],
                  "type": "object"
                },
                "type": "array"
              }
            },
            "type": "object"
          }
        },
        "runAfter": {
          "Compose": [
            "Succeeded"
          ]
        },
        "type": "ParseJson"
      },
      "Parse_JSON_-_Mappings": {
        "inputs": {
          "content": "@outputs('Compose_-_BAM_Mappings')",
          "schema": {
            "items": {
              "properties": {
                "bam_businessProcessName": {
                  "type": "string"
                },
                "bam_endStageName": {
                  "type": "string"
                },
                "bam_startStageName": {
                  "type": "string"
                },
                "bam_transactionName": {
                  "type": "string"
                },
                "stageMappings": {
                  "items": {
                    "properties": {
                      "bam_StageName": {
                        "type": "string"
                      },
                      "logicAppStepName": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "logicAppStepName",
                      "bam_StageName"
                    ],
                    "type": "object"
                  },
                  "type": "array"
                },
                "workflowId": {
                  "type": "string"
                }
              },
              "required": [
                "workflowId",
                "bam_businessProcessName",
                "bam_transactionName",
                "bam_startStageName",
                "bam_endStageName",
                "stageMappings"
              ],
              "type": "object"
            },
            "type": "array"
          }
        },
        "runAfter": {
          "Compose_-_BAM_Mappings": [
            "Succeeded"
          ]
        },
        "type": "ParseJson"
      }
    },
    "contentVersion": "1.0.0.0",
    "outputs": {},
    "parameters": {
      "$connections": {
        "defaultValue": {},
        "type": "Object"
      }
    },
    "triggers": {
      "When_events_are_available_in_Event_Hub": {
        "inputs": {
          "host": {
            "connection": {
              "name": "@parameters('$connections')['eventhubs']['connectionId']"
            }
          },
          "method": "get",
          "path": "/@{encodeURIComponent('logicapptelemetry')}/events/batch/head",
          "queries": {
            "consumerGroupName": "$Default",
            "contentType": "application/json",
            "maximumEventsCount": 50
          }
        },
        "recurrence": {
          "frequency": "Second",
          "interval": 30
        },
        "splitOn": "@triggerBody()",
        "type": "ApiConnection"
      }
    }
  },
  "parameters": {
    "$connections": {
      "value": {
        "SL360-BAM": {
          "connectionId": "/subscriptions/[Add Subscription]/resourceGroups/BAM_BusinessProcess_13_NoInstrumentation/providers/Microsoft.Web/connections/SL360-BAM",
          "connectionName": "SL360-BAM",
          "id": "/subscriptions/[Add Subscription]/resourceGroups/BAM_BusinessProcess1_SimpleDemo/providers/Microsoft.Web/customApis/SL360-BAM"
        },
        "eventhubs": {
          "connectionId": "/subscriptions/[Add Subscription]/resourceGroups/BAM_BusinessProcess_13_NoInstrumentation/providers/Microsoft.Web/connections/eventhubs",
          "connectionName": "eventhubs",
          "id": "/subscriptions/[Add Subscription]/providers/Microsoft.Web/locations/northeurope/managedApis/eventhubs"
        }
      }
    }
  }
}

Was this article helpful?