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 |
|
---|
21 | const char* StateString[] = {"OK", "WARN", "ERROR", "FATAL", "UNAVAILABLE"};
|
---|
22 |
|
---|
23 | //
|
---|
24 | // Data handling class
|
---|
25 | //
|
---|
26 | class 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
|
---|
49 | AlarmHandler::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
|
---|
89 | AlarmHandler::~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
|
---|
102 | void 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
|
---|
129 | void 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 | //
|
---|
146 | int 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 | }
|
---|