source: Evidence/Alarm.cc @ 154

Last change on this file since 154 was 154, checked in by ogrimm, 11 years ago
Updates to status service
File size: 4.7 KB
Line 
1/********************************************************************\
2
3  Alarm handler of the Evidence Control System
4
5  - Checks periodically if all required servers are up
6    (later it should try to start them if not)
7  - Listens to the 'Status' service of each server.
8  - A text describing the state of all servers is published as DIM service.
9    The states are described in StateString[].
10  - A master alarm (indicating most severe of individual alarms) is published.
11   
12  Oliver Grimm, January 2010
13
14\********************************************************************/
15
16#define SERVER_NAME "Alarm"
17#include "Evidence.h"
18
19#define SUMMARYSIZE 10000       // Bytes for alarm summary text
20
21const char* StateString[] = {"OK", "WARN", "ERROR", "FATAL", "UNAVAILABLE"};
22
23//
24// Data handling class
25//
26class AlarmHandler : public DimClient, public EvidenceServer {
27   
28    DimStampedInfo **StatusService;
29
30    void infoHandler();
31
32  public:
33    AlarmHandler();
34    ~AlarmHandler();
35
36        DimService *Summary, *Master;
37       
38        char *AlarmSummary;
39        int MasterAlarm;
40        int *State;   
41    char **Server;
42    unsigned int NumServers;
43    char *ServerList; 
44       
45        void UpdateAlarmSummary();
46}; 
47
48// Constructor
49AlarmHandler::AlarmHandler(): EvidenceServer(SERVER_NAME) {
50
51  AlarmSummary = new char [SUMMARYSIZE];
52  MasterAlarm = 0;
53
54  char *ServerNames = GetConfig(SERVER_NAME " servers");
55
56  // Create DIM services
57  Summary = new DimService(SERVER_NAME"/Summary", AlarmSummary);
58  Master = new DimService(SERVER_NAME"/MasterAlarm", MasterAlarm);
59
60  // Copy original list of servers to observe
61  ServerList = new char [strlen(ServerNames)+1];
62  strcpy(ServerList, ServerNames);
63 
64  // Extract DIM servers to observe
65  Server = new char* [strlen(ServerNames)];
66  NumServers = 0;
67  char *NextToken = strtok(ServerNames, " \t");
68  while (NextToken != NULL) {
69    Server[NumServers++] = NextToken; // Subscribe with handler
70    NextToken = strtok(NULL, " \t");     
71  }
72
73  // Subscribe with handler to 'Status' service of all servers
74  StatusService = new DimStampedInfo* [NumServers];
75  State = new int [NumServers];
76 
77  for (int i=0; i<NumServers; i++) {
78    char *Buffer = new char [strlen(Server[i])+10];
79    strcpy(Buffer, Server[i]);
80    strcat(Buffer, "/Status");
81    StatusService[i] = new DimStampedInfo(Buffer, NO_LINK, this);
82    delete[] Buffer;
83       
84        State[i] = 0;
85  }
86}
87
88// Destructor
89AlarmHandler::~AlarmHandler() {
90
91  for (int i=0; i<NumServers; i++) delete StatusService[i];
92  delete[] StatusService;
93  delete Master;
94  delete Summary;
95  delete[] State;
96  delete[] Server;
97  delete[] ServerList;
98  delete[] AlarmSummary;
99}
100
101// Print messages of status changes to screen and update status string
102void AlarmHandler::infoHandler() {
103
104  // Identify status service
105  for (int i=0; i<NumServers; i++) if (getInfo() == StatusService[i]) {
106
107        // Ignore DIS_DNS (has no status service)
108        if (strcmp(getInfo()->getName(),"DIS_DNS/Status") == 0) return;
109       
110        // Update State: unavailable or current severity of status 
111        if (getInfo()->getSize()==strlen(NO_LINK)+1 &&
112                strcmp(getInfo()->getString(), NO_LINK)==0) State[i] = 4;
113        else {
114          State[i] = *(getInfo()->getString()+getInfo()->getSize()-1);
115
116  printf("*** String length: %d  Message length: %d    Last number: %d\n",strlen(getInfo()->getString()),getInfo()->getSize(),State[i]);
117          // Print message
118          time_t RawTime = getInfo()->getTimestamp();
119          struct tm *TM = localtime(&RawTime);
120          printf("%s (%02d:%02d:%02d): %s\n", getInfo()->getName(), TM->tm_hour,
121                TM->tm_min, TM->tm_sec, getInfo()->getString());         
122        }
123        UpdateAlarmSummary();
124  } 
125}
126
127
128// Update alarm status summary
129void AlarmHandler::UpdateAlarmSummary() {
130 
131  int Offset = 0;
132  MasterAlarm = 0;
133   
134  for (int i=0; i<NumServers; i++) {
135    snprintf(AlarmSummary+Offset, SUMMARYSIZE-Offset, "%s: %s (%d)\n", Server[i], State[i]<=4 ? StateString[State[i]] : "unknown", State[i]);
136        Offset += strlen(AlarmSummary+Offset);
137        if (State[i] > MasterAlarm) MasterAlarm = State[i];
138  }
139  Summary->updateService();
140  Master->updateService();
141}
142
143//         
144// Main program
145//
146int main() {
147   
148  DimBrowser Browser;
149  char *ServerName, *Node;
150  bool Exists;
151 
152  // Static declaration ensures calling of destructor by exit()
153  static AlarmHandler Alarm; 
154 
155  // Request configuration data
156  unsigned int Period = atoi(Alarm.GetConfig(SERVER_NAME " period"));
157
158  // Check periodically if servers are up
159  while(!Alarm.ExitRequest) {
160    for (int i=0; i<Alarm.NumServers; i++) {
161      Exists = false;
162      Browser.getServers();
163      while (Browser.getNextServer(ServerName, Node) == 1) {
164        if (strcmp(ServerName, Alarm.Server[i]) == 0) Exists = true;
165      }
166      if (!Exists) Alarm.State[i] = 4;
167    }
168   
169    Alarm.UpdateAlarmSummary();
170    sleep(Period);
171  }
172}
Note: See TracBrowser for help on using the repository browser.