Konsollogg


Logga på konsolloggen

Konsollog

Konsolloggen innehåller diverse loggning från systemprocesser. Om systemet går orent bör man
titta på för att se om någon process loggar felmeddelanden. Den ligger som en textfil på
$pwrp_log, pwr_'nodename'.log, men kan även öppnas från med rt_xtt från System/SystemMessages.
Loggningarna har fem allvarlighetsnivåer fatalt, fel, varning, info och succé. Fatal och fel är
rödfärgade, varning gulfärgad och info och succé grönfärgade.

Även applikationer kan skriva på konsollogen. Först initierar man konsollogen med errh_Init(),
sedan kan man skriva meddelanden av olika allvarlighetsgrad med errh_Fatal(), errh_Error(),
errh_Warning(), errh_Info() och errh_Success().

errh_Init() anropas före gdh_Init() och har som argument ett namn på applikationen samt ett
applikationsindex som anges med errh_eAnix_Appl1, errh_eAnix_Appl2 etc. Varje applikation ska
ha ett unikt applikationsindex inom noden.

#include "rt_errh.h"

sts = errh_Init( "ra_myappl", errh_eAnix_Appl1);

Till logg funktionerna skickar man den sträng som ska skriva ut i loggen, t ex

errh_Error( "Something went wrong");

Strängen kan även fungera som formatsats som kan innehålla %s för att formatera strängar, %f
för flyttal och %d för heltal, se printf för mer info.

errh_Error( "Number is to high: %d", n);

Formatet %m översätter en statuskod till motsvarande text

catch ( co_error e) {
   errh_Error( "Error status: %m", e.sts());
}

Applikations status

Varje applikation har ett statusord i $Node objektet. Det ligger i attributet ProcStatus[]
i elementet applikationsindex + 20. Detta ska återspegla applikationens tillstånd och
sätts av applikationen själv med med funktionen errh_SetStatus().

errh_SetStatus( PWR__ARUN);

PWR__ARUN är definierad i rt_pwr_msg.h och länkad till texten "Application running".

Andra användbara status är

PWR__APPLSTARTUP "Application starting up" (info)
PWR__APPLRESTART "Application restaring" (info)
PWR__APPLTERM "Application terminated" (fatal)

I nodobjektet finns en systemstatus som är en slags summa av status för alla serverprocesser
och applikationsprocesser. I systemstatus läggs den server- eller applikation-status som har
den högsta allvarlighetsgraden.

Övervakning

En applikation som har anropat errh_Init övervakas av systemet. Den ska anropa funktionen
aproc_TimeStamp() cykliskt, annars sätts applikationsstatus till "Process timeout" (fatal).
Timeouttiden för applikaioner är 5 s.

Applikationobjekt

Man kan även skapa ett applikationsobjekt för applikationen. Detta läggs under i nodhierkin
under $Node objektet och är av klassen Application.

Applikationsobjektet registreras med funktionen aproc_RegisterObject() som har
objektsidentiteten för objektet som argument.

pwr_tObjid aoid;
pwr_tOName name = "Nodes-MyNode-ra_myappl";

sts = gdh_NameToObjid( name, &aoid);
if (EVEN(sts)) throw co_error(sts);

sts = aproc_RegisterObject( aoid);
if (EVEN(sts)) throw co_error(sts);

Statusbilden

Applikationen visas i statusbilden för noden, om applikationen har initierat errh och
registrerat applikationsobjektet. Den kommer att visas under 'Application' på den rad som
motsvara applikationsindex. I bilden visas status för applikationen och senaste/allvarligaste
loggmeddelande.


Fig Detalj ur nodbilden visar status och loggmeddelande för applikationen.

Om processen haltas sätts status till timeout, detta påverkar även systemstatus.


Fig Applikationen har haltats.

Exempel
I det här exemplet har vi jobbat vidare med programmet för xy-kurvan ovan, och fört in
anrop för att sätta applikationsstatus, logga på konsolloggen och registrera
applikationsobjektet.

#include
#include
#include "pwr.h"
#include "pwr_baseclasses.hpp"
#include "rt_gdh.h"
#include "rt_errh.h"
#include "rt_aproc.h"
#include "rt_pwr_msg.h"
#include "co_error.h"

class ra_myappl {
   pwr_Class_XyCurve *curve_ptr;
   pwr_tRefId dlid;
  public:
   ra_myappl() {}
   void init();
   void scan();
   void close();
};

void ra_myappl::init()
{
   pwr_tStatus sts;
   pwr_tOName name = "H1-H2-Curve";
   pwr_tObjid aoid;

   // Init errh with anix 1
   sts = errh_Init( "ra_myappl", errh_eAnix_appl1);
   if ( EVEN(sts)) throw co_error(sts);

   // Write message to consolelog and set application status
   errh_Info( "I feel fine");
   errh_SetStatus( PWR__APPLSTARTUP);

   // Connect to database
   sts = gdh_Init( "ra_myappl");
   if ( EVEN(sts)) throw co_error(sts);

   // Register application object
   sts = gdh_NameToObjid( "Nodes-Saturnus7-ra_myappl", &aoid);
   if ( EVEN(sts)) throw co_error(sts);

   aproc_RegisterObject( aoid);

   // Directlink to curve object
   sts = gdh_RefObjectInfo( name, (void **)&curve_ptr, &dlid, sizeof(*curve_ptr));
   if ( EVEN(sts)) throw co_error(sts);

   errh_SetStatus( PWR__ARUN);
}

void ra_myappl::scan()
{
   for ( unsigned int i = 0;;i++) {
     // Notify that we are still alive
     aproc_TimeStamp();

     if ( i % 5 == 0) {
       for ( int j = 0; j < 100; j++) {
         curve_ptr->XValue[j] = j;
         curve_ptr->YValue[j] = 50 + 50 * sin( 2.0 * M_PI * (j + i) / 100);
       }
       curve_ptr->Update = 1;
     }
     else if ( i % 5 == 2)
       curve_ptr->Update = 0;
     sleep(1);
     if ( i > 360)
       i = 0;
   }
}

void ra_myappl::close()
{
   gdh_UnrefObjectInfo( dlid);
}


int main()
{
   ra_myappl myappl;

   try {
     myappl.init();
   }
   catch ( co_error e) {
     errh_Fatal( "ra_myappl terminated, %m", e.sts());
     errh_SetStatus( PWR__APPLTERM);
     exit(0);
   }
   myappl.scan();
   myappl.close();
}