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()); |
---|
115 | |
---|
116 | // Print message |
---|
117 | time_t RawTime = getInfo()->getTimestamp(); |
---|
118 | struct tm *TM = localtime(&RawTime); |
---|
119 | printf("%s (%02d:%02d:%02d): %s\n", getInfo()->getName(), TM->tm_hour, |
---|
120 | TM->tm_min, TM->tm_sec, getInfo()->getString()); |
---|
121 | } |
---|
122 | UpdateAlarmSummary(); |
---|
123 | } |
---|
124 | } |
---|
125 | |
---|
126 | |
---|
127 | // Update alarm status summary |
---|
128 | void AlarmHandler::UpdateAlarmSummary() { |
---|
129 | |
---|
130 | int Offset = 0; |
---|
131 | MasterAlarm = 0; |
---|
132 | |
---|
133 | for (int i=0; i<NumServers; i++) { |
---|
134 | snprintf(AlarmSummary+Offset, SUMMARYSIZE-Offset, "%s: %s (%d)\n", Server[i], State[i]<=4 ? StateString[State[i]] : "unknown", State[i]); |
---|
135 | Offset += strlen(AlarmSummary+Offset); |
---|
136 | if (State[i] > MasterAlarm) MasterAlarm = State[i]; |
---|
137 | } |
---|
138 | Summary->updateService(); |
---|
139 | Master->updateService(); |
---|
140 | } |
---|
141 | |
---|
142 | // |
---|
143 | // Main program |
---|
144 | // |
---|
145 | int main() { |
---|
146 | |
---|
147 | DimBrowser Browser; |
---|
148 | char *ServerName, *Node; |
---|
149 | bool Exists; |
---|
150 | |
---|
151 | // Static declaration ensures calling of destructor by exit() |
---|
152 | static AlarmHandler Alarm; |
---|
153 | |
---|
154 | // Request configuration data |
---|
155 | unsigned int Period = atoi(Alarm.GetConfig(SERVER_NAME " period")); |
---|
156 | |
---|
157 | // Check periodically if servers are up |
---|
158 | while(!EvidenceServer::ExitRequest) { |
---|
159 | for (int i=0; i<Alarm.NumServers; i++) { |
---|
160 | Exists = false; |
---|
161 | Browser.getServers(); |
---|
162 | while (Browser.getNextServer(ServerName, Node) == 1) { |
---|
163 | if (strcmp(ServerName, Alarm.Server[i]) == 0) Exists = true; |
---|
164 | } |
---|
165 | if (!Exists) Alarm.State[i] = 4; |
---|
166 | } |
---|
167 | |
---|
168 | Alarm.UpdateAlarmSummary(); |
---|
169 | sleep(Period); |
---|
170 | } |
---|
171 | } |
---|