Recurring data job health changed
Fires when the health of a data management recurring data job changes, for example from Healthy to Failing when its messages start to fail, or from Broken back to Healthy after the job is repaired, for a job whose health alerts are switched on. It is the summary of a job's state; DMF execution completed stays the detail of each execution. A job that stays in one state is not reported again.
| Event class | MGCLatticeRecurringJobHealthChangedBusinessEvent |
| Contract class | MGCLatticeRecurringJobHealthChangedBusinessEventContract |
| Category | System administration |
| Module | ModuleAxapta::SystemAdministration |
| Label IDs | RecurringJobHealthChangedBusinessEventName / RecurringJobHealthChangedBusinessEventDescription |
| Trigger | MGCLatticeRecurringJobHealthAlerts -> a job's evaluated health differs from its stored health, alerts on, evaluated before |
Trigger / Hook
- Raised by the Lattice recurring data job health alerts background process (process automation, polled every 15 minutes by default), which evaluates the health of every recurring data job and stores it on the job's health row (
LatticeRecurringJobHealths). An evaluation started any other way raises it in the same way: Refresh health, Refresh all, Activate, Deactivate, Repair, the client application actions and saving the health thresholds on the Recurring integration health and Recurring integration details pages, and theRefreshandRefreshAllactions ofLatticeRecurringJobHealths. - Firing condition, per job: the evaluated health differs from the health stored by the previous evaluation, the job's Alerts enabled (
AlertsEnabled) is Yes, and the job had been evaluated before. One change raises one event. - Not raised: while the health stays the same (a job that stays Broken is reported once); for a job with alerts off; for a job's first evaluation, which sets the starting point. Switching alerts on for a job that was already evaluated also raises nothing until its health next changes; read the current health from Recurring integration health or
LatticeRecurringJobHealths. - Company: recurring data jobs are shared by all legal entities. The event is raised in the company of the job's processing batch job (the company the job runs in), or, when the job has none (for example an active job whose batch job was deleted), in the company the evaluation runs in. It is published only when that company has activated the event; activate it for all legal entities to receive every job's alerts. A change in a company that has not activated the event is not sent later.
- Timing: the health row is saved first and the event is sent after it, so a consumer that reads
LatticeRecurringJobHealthson receipt sees the new health. If the event for one job cannot be sent, a warning is logged, the other jobs are still processed, and that change is not sent again. - Enablement gate:
BusinessEventsFramework::Enabled()andBusinessEventsConfigurationReader::isBusinessEventEnabled(classStr(MGCLatticeRecurringJobHealthChangedBusinessEvent))in the job's company.
Health states and thresholds
The states, in order of severity: Inactive (0), Healthy (1), Warning (2), Failing (3), Broken (4); the worst reason wins. In short: Broken when an active job's batch job is missing, on hold, in error, ended or canceled, when an active import job has no enabled client application, or when its data project has mapping errors; Failing when failed messages in the failure window reach the failure threshold; Warning for an old backlog, messages processed with failed rows, stuck messages or silence, and for an inactive job with waiting messages. Each job's thresholds (failure window, backlog age, silence period, stuck period, failure threshold) and the Alerts enabled switch are on the Health thresholds FastTab of Recurring integration details and on LatticeRecurringJobHealths; the full rules are described with that entity in the API reference.
Payload Contract
One row per [DataMember], in declaration order. Values are the job's health row as saved by the evaluation that changed the state, plus the job.
| JSON field | Display label | Type / EDT | Source | Notes |
|---|---|---|---|---|
legalEntity | Legal Entity | DataAreaId | company the event is raised in | Lower case (see Company above) |
jobName | Job Name | IntegrationName | job name | The key of LatticeRecurringJobHealths |
activityId | Activity ID | str | job activity ID | Lower case, without braces, as OData returns it. It stays the same when the job is renamed |
direction | Direction | int | job direction | 0 Inbound (import), 1 Outbound (export) |
directionName | Direction Name | str | job direction (enum symbol) | Inbound or Outbound |
jobState | Job State | int | job state | 0 Inactive, 1 Active |
jobStateName | Job State Name | str | job state (enum symbol) | |
dataProject | Data Project | DMFDefinitionGroupName | the job's data project | |
healthState | Health State | int | new health | 0 Inactive, 1 Healthy, 2 Warning, 3 Failing, 4 Broken |
healthStateName | Health State Name | str | new health (enum symbol) | |
previousHealthState | Previous Health State | int | health before the change | Same values |
previousHealthStateName | Previous Health State Name | str | health before the change (enum symbol) | |
stateChangedDateTime | State Changed Date Time | utcdatetime | when the health changed | \/Date(ms)\/ |
evaluatedDateTime | Evaluated Date Time | utcdatetime | when the job was evaluated | Same as stateChangedDateTime for this evaluation |
reasons | Reasons | array of str | the reasons for the new health | One sentence each, worst first; [] for Healthy and Inactive |
backlogCount | Backlog Count | int | messages waiting | Import: enqueued and not yet processed; export: exported and not yet acknowledged |
oldestBacklogDateTime | Oldest Backlog Date Time | utcdatetime | oldest waiting message | Unset (\/Date(-2208988800000)\/) when nothing waits |
backlogAgeMinutes | Backlog Age Minutes | int | age of the oldest waiting message at the evaluation | 0 when nothing waits |
failedMessageCount | Failed Message Count | int | messages failed in the failure window | |
windowHours | Window Hours | int | the failure window in use | The job's threshold, or 24 |
partialExecutionCount | Partial Execution Count | int | messages processed with failed rows in the window | |
lastMessageDateTime | Last Message Date Time | utcdatetime | newest message | Import: enqueued; export: started. Unset when there is none |
stuckMessageCount | Stuck Message Count | int | messages processing longer than the stuck period | |
enabledClientCount | Enabled Client Count | int | client applications allowed to submit | |
mappingErrorCount | Mapping Error Count | int | mapping errors on the data project | Errors only; warnings are not counted |
processingBatchJobId | Processing Batch Job ID | int64 | the job's processing batch job | 0 when missing |
processingBatchJobStatusName | Processing Batch Job Status Name | str | its status (BatchStatus symbol) | Empty when the ID is 0 |
monitoringBatchJobId | Monitoring Batch Job ID | int64 | the job's monitoring batch job | 0 when missing |
monitoringBatchJobStatusName | Monitoring Batch Job Status Name | str | its status (BatchStatus symbol) | Empty when the ID is 0 |
Every Lattice event also carries the Lattice ordering and correlation envelope, inherited from MGCLatticeBusinessEventContractBase: eventSequence, correlationId and schemaVersion (1 for this contract), see the README, plus the standard D365 F&O envelope fields (BusinessEventId, BusinessEventLegalEntity, ContextRecordSubject, ControlNumber, EventId, EventTime, EventTimeIso8601, InitiatingUserAADObjectId, MajorVersion, MinorVersion, ParentContextRecordSubjects). Do not rely on the order of members in the delivered JSON.
correlationId is the batch task of the background process run (BatchTask:<RecId>), so the events of one run share it; an event raised from an evaluation outside batch (for example Refresh health on the page) correlates to itself (Event:<guid>).
Example Payload
An hourly import job starts failing, and its oldest message has waited 200 minutes:
{
"BusinessEventId": "MGCLatticeRecurringJobHealthChangedBusinessEvent",
"ControlNumber": 5637152210,
"EventId": "6C1E7A42-0B9D-4F35-A1C8-3D72E5B9F014",
"EventTime": "\/Date(1793025004000)\/",
"EventTimeIso8601": "2026-10-26T14:30:04.2210356Z",
"MajorVersion": 0,
"MinorVersion": 0,
"BusinessEventLegalEntity": "USMF",
"ContextRecordSubject": "",
"InitiatingUserAADObjectId": "{577C3196-7236-B014-2312-29B924A43BF7}",
"ParentContextRecordSubjects": [],
"eventSequence": 51207,
"correlationId": "BatchTask:5637160412",
"schemaVersion": 1,
"legalEntity": "usmf",
"jobName": "Customer groups inbound",
"activityId": "3f2a9c1e-7d45-4b8a-9e21-6c0f4d8b2a57",
"direction": 0,
"directionName": "Inbound",
"jobState": 1,
"jobStateName": "Active",
"dataProject": "CustomerGroupsInbound",
"healthState": 3,
"healthStateName": "Failing",
"previousHealthState": 1,
"previousHealthStateName": "Healthy",
"stateChangedDateTime": "\/Date(1793025000000)\/",
"evaluatedDateTime": "\/Date(1793025000000)\/",
"reasons": [
"Messages that failed in the last 24 hours: 1.",
"Messages waiting to be processed: 1. The oldest has waited 200 minutes (threshold 180 minutes)."
],
"backlogCount": 1,
"oldestBacklogDateTime": "\/Date(1793013000000)\/",
"backlogAgeMinutes": 200,
"failedMessageCount": 1,
"windowHours": 24,
"partialExecutionCount": 0,
"lastMessageDateTime": "\/Date(1793024832000)\/",
"stuckMessageCount": 0,
"enabledClientCount": 1,
"mappingErrorCount": 0,
"processingBatchJobId": 5637158811,
"processingBatchJobStatusName": "Waiting",
"monitoringBatchJobId": 5637158812,
"monitoringBatchJobStatusName": "Waiting"
}
Activation
- Switch alerts on for the jobs to watch: on Recurring integration health (System administration > Inquiries > Lattice > Integration operations), open the job's Recurring integration details and set Alerts enabled to Yes on the Health thresholds FastTab, or set
AlertsEnabledto Yes on the job's row ofLatticeRecurringJobHealths. - In the D365FO client, go to System administration > Setup > Business events > Business events catalog, find "Recurring data job health changed" (Category System administration), and use Activate to bind it to an endpoint, for all legal entities or for the company your recurring data jobs run in.
- Check that the Lattice recurring data job health alerts background process is enabled on System administration > Setup > Process automations > Background processes. Change its interval there (default every 15 minutes).