Blueprint Help Send comments on this topic.
Diagnostics

Glossary Item Box

There are actually two overloads but maybe we'll leave it like this for now

 

Description

CLIP provides a diagnostics service that allows user code to generate and manage diagnostics and also display CLIP runtime generated diagnostics (see the Reference Section Diagnostics for a full description of the Service and the available options).

The ClpDiag function has identical syntax to the standard 'C' printf function. However the resulting string output is handled by a user defined function (or MFC TRACE if not specified).  The function will return TRUE if successful, or FALSE if an error occurs.

Uns ClpDiag( char *fmt [,arg]... );               

When running Master/Slave applications all diagnostics, whether raised by Slaves, Sub-Masters or Master can be handled locally or passed to the Master for handling (default). All diagnostics will be automatically logged (in a default format) to a log file depending on the user defined Output parameters.

Users wishing to generate their own output format need to provide an appropriate diagnostic handler.

It is sometimes useful to process the diagnostic locally AND pass the diagnostic to the Master for centralised logging. (Eg each slave has its own GUI and operator, only the local operator needs to know about the local error - invalid input). Since CDL only allows one Diagnostic Handler per Process (and Master/Slaves are usually built from the same process), the diagnostic handler needs to identify which build this is and take the appropriate action.

 

Would the example below actually work?  It assumes all processes define CMasterDlg and CSlaveDlg

Eg.

// Registered Diagnostic Handler
void DiagnosticHandler( char* Msg, void* Dlg )
{
   if ( ClpAmMaster() )
   {
      // Display on Master
      ((CMasterDlg*)Dlg)->Diagnostic( Msg );

      // Log to file
      FILE* fp = fopen(...);
      ...
   }
   else
   {
      // Display locally
      ((CSlaveDlg*)Dlg)->Diagnostic( Msg );

      // Send the diagnostic to the Master via a Circuit Store
      ::GetDiagSstIfce()->WriteDiagToStore( Msg );
   }
}

// Store triggered Thrd
Uns DiagThrd::Execute()
{
   while ( TRUE )
   {
      // monitor store for Slave diagnostics
      DiagSst.Open();

      // re-raise as master diagnostic
      ClpDiag( DiagSst.Data().Msg );

      DiagSst.Close();
   }
}

NB. Either a thread or method could be triggered by the store, depending on what actions are required. The above example users a thread simply to illustrate the process.

Although CLIP does embed Master/Slave ids into CLIP raised diagnostics these parameters are not embedded into user raised diagnostics. It is often useful to embed this type of information into diagnostics together with some form of Diagnostic Level Code (eg. SEVERE, ERROR, WARNING, INFORMATION). These codes can then be used by the handlers to take appropriate action.

switch ( Msg[0] )
{
case MASTER:
   switch ( Msg[1] )
   {
   case SEVERE:
      LogDiagnostic( Msg );
      DisplayDiag( Msg );

      ClpSleep(5000);
      ClpExit( -1 );
      break;

   case ERROR:
      ResetProcessing();
   case WARNING:
      DisplayDiag( Msg );
   case INFORMATION:
      LogDiagnostic( Msg );
      break;
   }
   break;
...
}