Skip to main content

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 classMGCLatticeRecurringJobHealthChangedBusinessEvent
Contract classMGCLatticeRecurringJobHealthChangedBusinessEventContract
CategorySystem administration
ModuleModuleAxapta::SystemAdministration
Label IDsRecurringJobHealthChangedBusinessEventName / RecurringJobHealthChangedBusinessEventDescription
TriggerMGCLatticeRecurringJobHealthAlerts -> 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 the Refresh and RefreshAll actions of LatticeRecurringJobHealths.
  • 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 LatticeRecurringJobHealths on 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() and BusinessEventsConfigurationReader::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 fieldDisplay labelType / EDTSourceNotes
legalEntityLegal EntityDataAreaIdcompany the event is raised inLower case (see Company above)
jobNameJob NameIntegrationNamejob nameThe key of LatticeRecurringJobHealths
activityIdActivity IDstrjob activity IDLower case, without braces, as OData returns it. It stays the same when the job is renamed
directionDirectionintjob direction0 Inbound (import), 1 Outbound (export)
directionNameDirection Namestrjob direction (enum symbol)Inbound or Outbound
jobStateJob Stateintjob state0 Inactive, 1 Active
jobStateNameJob State Namestrjob state (enum symbol)
dataProjectData ProjectDMFDefinitionGroupNamethe job's data project
healthStateHealth Stateintnew health0 Inactive, 1 Healthy, 2 Warning, 3 Failing, 4 Broken
healthStateNameHealth State Namestrnew health (enum symbol)
previousHealthStatePrevious Health Stateinthealth before the changeSame values
previousHealthStateNamePrevious Health State Namestrhealth before the change (enum symbol)
stateChangedDateTimeState Changed Date Timeutcdatetimewhen the health changed\/Date(ms)\/
evaluatedDateTimeEvaluated Date Timeutcdatetimewhen the job was evaluatedSame as stateChangedDateTime for this evaluation
reasonsReasonsarray of strthe reasons for the new healthOne sentence each, worst first; [] for Healthy and Inactive
backlogCountBacklog Countintmessages waitingImport: enqueued and not yet processed; export: exported and not yet acknowledged
oldestBacklogDateTimeOldest Backlog Date Timeutcdatetimeoldest waiting messageUnset (\/Date(-2208988800000)\/) when nothing waits
backlogAgeMinutesBacklog Age Minutesintage of the oldest waiting message at the evaluation0 when nothing waits
failedMessageCountFailed Message Countintmessages failed in the failure window
windowHoursWindow Hoursintthe failure window in useThe job's threshold, or 24
partialExecutionCountPartial Execution Countintmessages processed with failed rows in the window
lastMessageDateTimeLast Message Date Timeutcdatetimenewest messageImport: enqueued; export: started. Unset when there is none
stuckMessageCountStuck Message Countintmessages processing longer than the stuck period
enabledClientCountEnabled Client Countintclient applications allowed to submit
mappingErrorCountMapping Error Countintmapping errors on the data projectErrors only; warnings are not counted
processingBatchJobIdProcessing Batch Job IDint64the job's processing batch job0 when missing
processingBatchJobStatusNameProcessing Batch Job Status Namestrits status (BatchStatus symbol)Empty when the ID is 0
monitoringBatchJobIdMonitoring Batch Job IDint64the job's monitoring batch job0 when missing
monitoringBatchJobStatusNameMonitoring Batch Job Status Namestrits 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​

  1. 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 AlertsEnabled to Yes on the job's row of LatticeRecurringJobHealths.
  2. 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.
  3. 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).