This article details how to troubleshoot and debug your deployed instance of the IoMT FHIR Connector for Azure. Below will cover troubleshooting your deployed instance as well as how to debug locally.
An instance of Application Insights is deployed as part of the IoMT FHIR Connector for Azure. From here you can see errors and telemetry for logical components of the connector. In addition to the information contained in Application Insights each component deployed (Event Hub & Stream Analytics) has its own telemetry you can use as well. Some important information includes the number of messages received and sent on the Event Hubs and the watermark delay along with input and output events of the Stream Analytic job.
All telemetry below can be viewed in Application Insights. Select the metrics section. The telemetry documented will fall under the custom category.
-
MeasurementIngestionLatency: The difference between the ingestion time on the event hub end point and received by the FHIR conversion function. Measured in milliseconds.
-
MeasurementGroup: The number of unique groupings of measurements across type, device, patient, and configured time period generated by the FHIR conversion function. Should directly correlate to the number of observations being created or updated.
-
Measurement: The number of raw value readings received by the FHIR conversion function.
-
DeviceEvent: The number of raw events received by the connector prior to any normalization.
-
NormalizedEvent: The number of mapped normalized values outputted from the normalization step.
-
DeviceEventProcessingLatency: The time between an event's ingestion and being processed for normalization. A large value here indicates a backlog of events being processed for normalization. Measured in milliseconds.
-
Handled Exceptions: The number of handled exceptions for a given category. In order to not stall the pipeline certain non recoverable errors are categorized and then recorded as telemetry. The current exceptions handled are:
Exception Description PatientDeviceMismatchException In Create mode, if both the device and patient exist but the device is linked to another patient this exception will be thrown. ResourceIdentityNotDefinedException Thrown when a resource identifier is expected and required for the current mode (Create, Lookup, Lookup w/Encounter). The actual telemetry event will be specific to the type of resource identifier missing (i.e. Patient, Device, or Encounter). NotSupportedException Typically thrown if their isn't a supported template or value type during processing. FhirResourceNotFoundException Thrown when the identifier provided in the message isn't found. The actual telemetry recorded will be specific the type of resource not found (i.e. Patient, Device, or Encounter).
-
Messages are being sent but I don't see any output on the normalized data Event Hub.
First ensure you have properly deployed the configuration with your template(s) into the Storage Blob template container with the name
devicecontent.json
. If there is a problem loading templates the issue will surface in Application Insights as ArgumentNullExceptions.Another potiential cause is your device content templates aren't matching the payloads being sent. If possible you can try debugging locally. Otherwise you can try retrieving messages from the device data Event Hub and investigating the payload. The are example unit tests in the solution you can modify to match your template and payload so you can check the template is being applied as intended.
-
Messages are processed but I don't see the FHIR conversion being called.
Check the Stream Analytics job and make sure it isn't delayed. If the volume is too high you may need to increase streaming units to scale the job up. Checking the current job watermark is a good first step.
-
Messages are processed and job output are being sent to the FHIR conversion but I don't see any observations created.
Check that you have properly created a device resource that is linked to a patient resource in the FHIR server. The device id extracted by the template should match the device identifier on device resource in FHIR. If not setup correcly you will see PatientNotFoundException or DeviceNotFoundException metrics in Applications Insights.
The core logic of the IoMT FHIR Connector for Azure is handled by two Azure Functions. You can run functions project locally.
Please be sure you have the prerequisites met for debugging Azure Functions on your machine.
In addition to the Azure Functions prerequisites the following tasks need to be done prior to starting the project:
- Ensure
Microsoft.Health.Ingest.Host.csproj
is the startup project in the solution. - Provide your device content and FHIR mapping. The default during debugging is to use the Azure Storage Emulator. It should be installed as part of the Azure Function prerequisites.
- Provide a completed
local.settings.json
file in the root of the project. A partially completed version can found here. An example is also available below.
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FhirVersion": "R4",
"FhirService:Authority": "<<Insert FHIR server OAuth authority>>",
"FhirService:ClientId": "<<Insert FHIR server OAuth client credential client id>>",
"FhirService:ClientSecret": "<<Insert FHIR server OAuth client credential client secret>>",
"FhirService:Resource": "<<Insert FHIR server OAuth resource URL>>",
"FhirService:Url": "<<Insert FHIR server URL>>",
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"InputEventHub": "<<Insert deviceinput reader SharedAccessKey connection string>>",
"OutputEventHub": "<<Insert normalizeddata writer SharedAccessKey connection string>>",
"ResourceIdentity:ResourceIdentityServiceType": "Lookup",
"ResourceIdentity:DefaultDeviceIdentifierSystem": "",
"Template:DeviceContent": "devicecontent.json",
"Template:FhirMapping": "fhirmapping.json"
}
}
Once you have completed the prerequisites you can run the solution/project. The Azure Function host will start up. The Event Hub processing function responsible for normalization, NormalizeDeviceData
, will automatically start. Once started it will read events from the EventHub connection provided in the local.settings.json
.
The FHIR conversion function, MeasurementCollectionToFhir
, can be invoked through you preferred tool (Postman, curl, etc.). The local endpoint should output to the console. You can submit POST requests to the endpoint. The expected input is an array of Microsoft.Health.Fhir.Ingest.Data.IMeasurementGroup
. An example is below.
[
{
"deviceid": "com.apple.health.33BE1D5F-A55B-43BB-ABEA-9C0FBF71BA18",
"data": [
{
"occurrenceTimeUtc": "2019-07-26T21:51:45.0000000Z",
"type": "heartrate",
"ingestionTimeUtc": "2019-07-26T21:58:35.9680000Z",
"deviceId": "com.apple.health.33BE1D5F-A55B-43BB-ABEA-9C0FBF71BA18",
"properties": [
{
"name": "hr",
"value": "65"
}
]
}
],
"windowtime": "2019-07-26T21:52:00.0000000Z",
"measuretype": "heartrate",
"count": 1
}
]