source: Evidence/Alarm.cc@ 188

Last change on this file since 188 was 181, checked in by ogrimm, 15 years ago
Updated config request
File size: 4.4 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 // Create DIM services
55 Summary = new DimService(SERVER_NAME"/Summary", AlarmSummary);
56 Master = new DimService(SERVER_NAME"/MasterAlarm", MasterAlarm);
57
58 // Copy original list of servers to observe
59 char *ServerNames = GetConfig("servers");
60 ServerList = new char [strlen(ServerNames)+1];
61 strcpy(ServerList, ServerNames);
62
63 // Extract DIM servers to observe
64 Server = new char* [strlen(ServerNames)];
65 NumServers = 0;
66 char *NextToken = strtok(ServerNames, " \t");
67 while (NextToken != NULL) {
68 Server[NumServers++] = NextToken; // Subscribe with handler
69 NextToken = strtok(NULL, " \t");
70 }
71
72 // Subscribe with handler to 'Status' service of all servers
73 StatusService = new DimStampedInfo* [NumServers];
74 State = new int [NumServers];
75
76 for (int i=0; i<NumServers; i++) {
77 char *Buffer = new char [strlen(Server[i])+10];
78 strcpy(Buffer, Server[i]);
79 strcat(Buffer, "/Status");
80 StatusService[i] = new DimStampedInfo(Buffer, NO_LINK, this);
81 delete[] Buffer;
82
83 State[i] = 0;
84 }
85}
86
87// Destructor
88AlarmHandler::~AlarmHandler() {
89
90 for (int i=0; i<NumServers; i++) delete StatusService[i];
91 delete[] StatusService;
92 delete Master;
93 delete Summary;
94 delete[] State;
95 delete[] Server;
96 delete[] ServerList;
97 delete[] AlarmSummary;
98}
99
100// Print messages of status changes to screen and update status string
101void AlarmHandler::infoHandler() {
102
103 // Identify status service
104 for (int i=0; i<NumServers; i++) if (getInfo() == StatusService[i]) {
105
106 // Ignore DIS_DNS (has no status service)
107 if (strcmp(getInfo()->getName(),"DIS_DNS/Status") == 0) return;
108
109 // Update State: unavailable or current severity of status
110 if (!ServiceOK(getInfo())) State[i] = 4;
111 else {
112 State[i] = *(getInfo()->getString()+getInfo()->getSize()-1);
113
114 // Print message
115 time_t RawTime = getInfo()->getTimestamp();
116 struct tm *TM = localtime(&RawTime);
117 printf("%s (%02d:%02d:%02d): %s\n", getInfo()->getName(), TM->tm_hour,
118 TM->tm_min, TM->tm_sec, getInfo()->getString());
119 }
120 UpdateAlarmSummary();
121 }
122}
123
124
125// Update alarm status summary
126void AlarmHandler::UpdateAlarmSummary() {
127
128 int Offset = 0;
129 MasterAlarm = 0;
130
131 for (int i=0; i<NumServers; i++) {
132 snprintf(AlarmSummary+Offset, SUMMARYSIZE-Offset, "%s: %s (%d)\n", Server[i], State[i]<=4 ? StateString[State[i]] : "unknown", State[i]);
133 Offset += strlen(AlarmSummary+Offset);
134 if (State[i] > MasterAlarm) MasterAlarm = State[i];
135 }
136 Summary->updateService();
137 Master->updateService();
138}
139
140//
141// Main program
142//
143int main() {
144
145 DimBrowser Browser;
146 char *ServerName, *Node;
147 bool Exists;
148
149 // Static declaration ensures calling of destructor by exit()
150 static AlarmHandler Alarm;
151
152 // Check periodically if servers are up
153 while(!Alarm.ExitRequest) {
154 for (int i=0; i<Alarm.NumServers; i++) {
155 Exists = false;
156 Browser.getServers();
157 while (Browser.getNextServer(ServerName, Node) == 1) {
158 if (strcmp(ServerName, Alarm.Server[i]) == 0) Exists = true;
159 }
160 if (!Exists) Alarm.State[i] = 4;
161 }
162
163 Alarm.UpdateAlarmSummary();
164 sleep(atoi(Alarm.GetConfig("period")));
165 }
166}
Note: See TracBrowser for help on using the repository browser.