Overview
This sample shows how to track a Logic App Standard workflow in Business Activity Monitoring (BAM) using the pull model with Application Insights as the data source. The scenario is a railcar loading process that sends updates to SAP. BAM queries the Application Insights requests table to surface transaction status, tracked properties, and stage detail in the Turbo360 portal.
Business value
This sample gives business and operations users a clear, self-service view of what has been processed, whether it succeeded or failed, and direct access to transaction detail — without requiring Azure portal access. The query patterns shown here are reusable across other Logic App Standard workflows: update the action names, workflow name, and promoted tracked properties to adapt them to your scenario.
Sample scenario
The scenario tracks a stateful Logic App Standard workflow (Railcar-Loaded-ToSAP) that processes incoming railcar messages and sends them to SAP. BAM surfaces a summary view of all transaction instances, and users can open any instance to see the outcome of each stage.
Video walkthrough
The following video provides a walkthrough of this sample.
Business Activity Monitoring queries
This sample uses one parent query and two child queries. The parent query identifies transaction instances. Each child query maps to a transaction stage and is correlated to the parent using the promoted WorkflowRunId field. You can adapt all three queries to other workflows by changing the Logic App name, workflow name, action names, and the tracked properties you want to promote.
Parent query
The parent query finds the action start event for the Parse JSON action — which has tracked properties on it — and joins it to the corresponding HTTP action event to determine the overall transaction result. This join pattern infers transaction success or failure at the workflow level using a case statement on the end action's success field. The query promotes business properties from the tracked properties block (Batch_, Rail_Car_Id_, Load_Slip_Id_, and others) so users can filter and search by those values in the Turbo360 tracking grid.
let input_LogicApp_Name = 'ms-bootcamp-logicapp';
let input_Workflow_Name = 'Railcar-Loaded-ToSAP';
let input_StartActionName = 'Parse_JSON_-_Railcar_Message';
let input_EndActionName = 'HTTP_-_Send_to_SAP';
let startActionEvents = requests
| where cloud_RoleName == input_LogicApp_Name
| where operation_Name == input_Workflow_Name
| where name == input_StartActionName
| extend LogicAppName = cloud_RoleName
| extend workflowName_ = operation_Name
| extend actionName_ = name
| extend workflowId_ = tostring(parse_json(tostring(customDimensions.resource)).workflowId)
| extend runId_ = tostring(parse_json(tostring(customDimensions.resource)).runId)
| extend trackedProperties_ = tostring(customDimensions.trackedProperties)
| extend Batch_ = tostring(parse_json(trackedProperties_).Batch)
| extend Load_Slip_Id_ = tostring(parse_json(trackedProperties_).Load_Slip_Id)
| extend Message_Type_ = tostring(parse_json(trackedProperties_).Message_Type)
| extend Product_Code_ = tostring(parse_json(trackedProperties_).Product_Code)
| extend Product_Code_Full_ = tostring(parse_json(trackedProperties_).Product_Code_Full)
| extend Production_Date_ = tostring(parse_json(trackedProperties_).Production_Date)
| extend Rail_Car_Id_ = tostring(parse_json(trackedProperties_).Rail_Car_Id)
| extend StartTime = timestamp
| extend StartSuccess = success;
let endActionEvents = requests
| where cloud_RoleName == input_LogicApp_Name
| where operation_Name == input_Workflow_Name
| where name == input_StartActionName
| extend LogicAppName = cloud_RoleName
| extend workflowName_ = operation_Name
| extend actionName_ = input_EndActionName
| extend workflowId_ = tostring(parse_json(tostring(customDimensions.resource)).workflowId)
| extend runId_ = tostring(parse_json(tostring(customDimensions.resource)).runId)
| extend EndTime = timestamp
| extend EndSuccess = success;
startActionEvents | join kind=inner (endActionEvents) on runId_
| extend OverallStatus = case(
EndSuccess == 'True', 'Succeeded',
EndSuccess == 'False', 'Failed',
'In Progress')
| extend Duration = EndTime - StartTime
| project timestamp, WorkflowName = workflowName_, LogicAppName, WorkflowRunId = runId_, OverallStatus, StartTime, EndTime, Duration, Batch_, Rail_Car_Id_, Production_Date_, Product_Code_Full_, Product_Code_, Message_Type_, Load_Slip_Id_
| order by StartTime desc
Message validated stage
This child query retrieves the Parse JSON action event for a specific transaction instance. It uses the WorkflowRunId promoted from the parent query to filter to the correct run, and extends the tracked properties so the stage detail panel can display the business data associated with this step.
let input_LogicApp_Name = "ms-bootcamp-logicapp";
let input_Workflow_Name = "Railcar-Loaded-ToSAP";
let input_StartActionName = "Parse_JSON_-_Railcar_Message";
requests
| where cloud_RoleName == input_LogicApp_Name
| where operation_Name == input_Workflow_Name
| where name == input_StartActionName
| where operation_Id == {WorkflowRunId}
| extend LogicAppName = cloud_RoleName
| extend workflowName_ = operation_Name
| extend actionName_ = name
| extend workflowId_ = tostring(parse_json(tostring(customDimensions.resource)).workflowId)
| extend runId_ = tostring(parse_json(tostring(customDimensions.resource)).runId)
| extend trackedProperties_ = tostring(customDimensions.trackedProperties)
| extend Batch_ = tostring(parse_json(trackedProperties_).Batch)
| extend Load_Slip_Id_ = tostring(parse_json(trackedProperties_).Load_Slip_Id)
| extend Message_Type_ = tostring(parse_json(trackedProperties_).Message_Type)
| extend Product_Code_ = tostring(parse_json(trackedProperties_).Product_Code)
| extend Product_Code_Full_ = tostring(parse_json(trackedProperties_).Product_Code_Full)
| extend Production_Date_ = tostring(parse_json(trackedProperties_).Production_Date)
| extend Rail_Car_Id_ = tostring(parse_json(trackedProperties_).Rail_Car_Id)
SAP updated stage
This child query retrieves the HTTP action event that represents the SAP update step. It confirms whether the send-to-SAP action completed successfully for this transaction instance and surfaces the result in the second stage shape of the BAM transaction diagram.
let input_LogicApp_Name = "ms-bootcamp-logicapp";
let input_Workflow_Name = "Railcar-Loaded-ToSAP";
let input_ActionName = "HTTP_-_Send_to_SAP";
requests
| where cloud_RoleName == input_LogicApp_Name
| where operation_Name == input_Workflow_Name
| where name == input_ActionName
| where operation_Id == {WorkflowRunId}
| extend LogicAppName = cloud_RoleName
| extend workflowName_ = operation_Name
| extend actionName_ = name
| extend workflowId_ = tostring(parse_json(tostring(customDimensions.resource)).workflowId)
| extend runId_ = tostring(parse_json(tostring(customDimensions.resource)).runId)