1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
|
DROP FUNCTION IF EXISTS get_sla_ok_percent;
DELIMITER //
CREATE FUNCTION get_sla_ok_percent(
in_host_id binary(20),
in_service_id binary(20),
in_start_time bigint unsigned,
in_end_time bigint unsigned
)
RETURNS decimal(7, 4)
READS SQL DATA
BEGIN
DECLARE result decimal(7, 4);
DECLARE row_event_time bigint unsigned;
DECLARE row_event_type enum('state_change', 'downtime_start', 'downtime_end', 'end');
DECLARE row_event_prio int;
DECLARE row_hard_state tinyint unsigned;
DECLARE row_previous_hard_state tinyint unsigned;
DECLARE last_event_time bigint unsigned;
DECLARE last_hard_state tinyint unsigned;
DECLARE active_downtimes int unsigned;
DECLARE problem_time bigint unsigned;
DECLARE total_time bigint unsigned;
DECLARE done int;
DECLARE cur CURSOR FOR
(
-- all downtime_start events before the end of the SLA interval
-- for downtimes that overlap the SLA interval in any way
SELECT
GREATEST(downtime_start, in_start_time) AS event_time,
'downtime_start' AS event_type,
1 AS event_prio,
NULL AS hard_state,
NULL AS previous_hard_state
FROM sla_history_downtime d
WHERE d.host_id = in_host_id
AND ((in_service_id IS NULL AND d.service_id IS NULL) OR d.service_id = in_service_id)
AND d.downtime_start < in_end_time
AND d.downtime_end >= in_start_time
) UNION ALL (
-- all downtime_end events before the end of the SLA interval
-- for downtimes that overlap the SLA interval in any way
SELECT
downtime_end AS event_time,
'downtime_end' AS event_type,
2 AS event_prio,
NULL AS hard_state,
NULL AS previous_hard_state
FROM sla_history_downtime d
WHERE d.host_id = in_host_id
AND ((in_service_id IS NULL AND d.service_id IS NULL) OR d.service_id = in_service_id)
AND d.downtime_start < in_end_time
AND d.downtime_end >= in_start_time
AND d.downtime_end < in_end_time
) UNION ALL (
-- all state events strictly in interval
SELECT
event_time,
'state_change' AS event_type,
0 AS event_prio,
hard_state,
previous_hard_state
FROM sla_history_state s
WHERE s.host_id = in_host_id
AND ((in_service_id IS NULL AND s.service_id IS NULL) OR s.service_id = in_service_id)
AND s.event_time > in_start_time
AND s.event_time < in_end_time
) UNION ALL (
-- end event to keep loop simple, values are not used
SELECT
in_end_time AS event_time,
'end' AS event_type,
3 AS event_prio,
NULL AS hard_state,
NULL AS previous_hard_state
)
ORDER BY event_time, event_prio;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
IF in_end_time <= in_start_time THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'end time must be greater than start time';
END IF;
-- Use the latest event at or before the beginning of the SLA interval as the initial state.
SELECT hard_state INTO last_hard_state
FROM sla_history_state s
WHERE s.host_id = in_host_id
AND ((in_service_id IS NULL AND s.service_id IS NULL) OR s.service_id = in_service_id)
AND s.event_time <= in_start_time
ORDER BY s.event_time DESC
LIMIT 1;
-- If this does not exist, use the previous state from the first event after the beginning of the SLA interval.
IF last_hard_state IS NULL THEN
SELECT previous_hard_state INTO last_hard_state
FROM sla_history_state s
WHERE s.host_id = in_host_id
AND ((in_service_id IS NULL AND s.service_id IS NULL) OR s.service_id = in_service_id)
AND s.event_time > in_start_time
ORDER BY s.event_time ASC
LIMIT 1;
END IF;
-- If this also does not exist, use the current host/service state.
IF last_hard_state IS NULL THEN
IF in_service_id IS NULL THEN
SELECT hard_state INTO last_hard_state
FROM host_state s
WHERE s.host_id = in_host_id;
ELSE
SELECT hard_state INTO last_hard_state
FROM service_state s
WHERE s.host_id = in_host_id
AND s.service_id = in_service_id;
END IF;
END IF;
IF last_hard_state IS NULL THEN
SET last_hard_state = 0;
END IF;
SET problem_time = 0;
SET total_time = in_end_time - in_start_time;
SET last_event_time = in_start_time;
SET active_downtimes = 0;
SET done = 0;
OPEN cur;
read_loop: LOOP
FETCH cur INTO row_event_time, row_event_type, row_event_prio, row_hard_state, row_previous_hard_state;
IF done THEN
LEAVE read_loop;
END IF;
IF row_previous_hard_state = 99 THEN
SET total_time = total_time - (row_event_time - last_event_time);
ELSEIF ((in_service_id IS NULL AND last_hard_state > 0) OR (in_service_id IS NOT NULL AND last_hard_state > 1))
AND last_hard_state != 99
AND active_downtimes = 0
THEN
SET problem_time = problem_time + row_event_time - last_event_time;
END IF;
SET last_event_time = row_event_time;
IF row_event_type = 'state_change' THEN
SET last_hard_state = row_hard_state;
ELSEIF row_event_type = 'downtime_start' THEN
SET active_downtimes = active_downtimes + 1;
ELSEIF row_event_type = 'downtime_end' THEN
SET active_downtimes = active_downtimes - 1;
END IF;
END LOOP;
CLOSE cur;
SET result = 100 * (total_time - problem_time) / total_time;
RETURN result;
END//
DELIMITER ;
ALTER TABLE hostgroup
DROP INDEX idx_hostroup_name,
ADD INDEX idx_hostgroup_name (name) COMMENT 'Host/service/host group list filtered by host group name';
ALTER TABLE notification_history
MODIFY `text` longtext NOT NULL;
ALTER TABLE host_state
ADD COLUMN previous_soft_state tinyint unsigned NOT NULL AFTER hard_state,
CHANGE attempt check_attempt tinyint unsigned NOT NULL,
CHANGE timeout check_timeout int unsigned DEFAULT NULL;
ALTER TABLE service_state
ADD COLUMN previous_soft_state tinyint unsigned NOT NULL AFTER hard_state,
CHANGE attempt check_attempt tinyint unsigned NOT NULL,
CHANGE timeout check_timeout int unsigned DEFAULT NULL;
ALTER TABLE checkcommand_argument
ADD COLUMN `separator` varchar(255) DEFAULT NULL AFTER set_if;
ALTER TABLE eventcommand_argument
ADD COLUMN `separator` varchar(255) DEFAULT NULL AFTER set_if;
ALTER TABLE notificationcommand_argument
ADD COLUMN `separator` varchar(255) DEFAULT NULL AFTER set_if;
ALTER TABLE notification_history
ADD INDEX idx_notification_history_env_send_time (environment_id, send_time) COMMENT 'Filter for history retention';
ALTER TABLE acknowledgement_history
ADD INDEX idx_acknowledgement_history_env_clear_time (environment_id, clear_time) COMMENT 'Filter for history retention';
ALTER TABLE comment_history
ADD INDEX idx_comment_history_env_remove_time (environment_id, remove_time) COMMENT 'Filter for history retention';
ALTER TABLE downtime_history
ADD INDEX idx_downtime_history_env_end_time (environment_id, end_time) COMMENT 'Filter for history retention';
ALTER TABLE flapping_history
ADD INDEX idx_flapping_history_env_end_time (environment_id, end_time) COMMENT 'Filter for history retention';
ALTER TABLE state_history
ADD INDEX idx_state_history_env_event_time (environment_id, event_time) COMMENT 'Filter for history retention',
CHANGE attempt check_attempt tinyint unsigned NOT NULL;
ALTER TABLE icon_image
DROP PRIMARY KEY,
MODIFY id binary(20) NOT NULL COMMENT 'sha1(environment.id + icon_image)',
ADD PRIMARY KEY (id);
ALTER TABLE action_url
DROP PRIMARY KEY,
MODIFY id binary(20) NOT NULL COMMENT 'sha1(environment.id + action_url)',
ADD PRIMARY KEY (id);
ALTER TABLE notes_url
DROP PRIMARY KEY,
MODIFY id binary(20) NOT NULL COMMENT 'sha1(environment.id + notes_url)',
ADD PRIMARY KEY (id);
ALTER TABLE customvar
MODIFY name varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL;
ALTER TABLE customvar_flat
MODIFY flatname varchar(512) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'Path converted with `.` and `[ ]`';
ALTER TABLE host
CHANGE checkcommand checkcommand_name varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'checkcommand.name',
CHANGE check_timeperiod
check_timeperiod_name varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'timeperiod.name',
CHANGE eventcommand eventcommand_name varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'eventcommand.name',
CHANGE zone zone_name varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'zone.name',
CHANGE command_endpoint command_endpoint_name varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'endpoint.name';
ALTER TABLE service
CHANGE checkcommand checkcommand_name varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'checkcommand.name',
CHANGE check_timeperiod
check_timeperiod_name varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'timeperiod.name',
CHANGE eventcommand eventcommand_name varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'eventcommand.name',
CHANGE zone zone_name varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'zone.name',
CHANGE command_endpoint command_endpoint_name varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'endpoint.name';
CREATE TABLE sla_history_state (
id binary(20) NOT NULL COMMENT 'state_history.id (may reference already deleted rows)',
environment_id binary(20) NOT NULL COMMENT 'environment.id',
endpoint_id binary(20) DEFAULT NULL COMMENT 'endpoint.id',
object_type enum('host', 'service') NOT NULL,
host_id binary(20) NOT NULL COMMENT 'host.id',
service_id binary(20) DEFAULT NULL COMMENT 'service.id',
event_time bigint unsigned NOT NULL COMMENT 'unix timestamp the event occurred',
hard_state TINYINT UNSIGNED NOT NULL COMMENT 'hard state after this event',
previous_hard_state TINYINT UNSIGNED NOT NULL COMMENT 'hard state before this event',
PRIMARY KEY (id),
INDEX idx_sla_history_state_event (host_id, service_id, event_time) COMMENT 'Filter for calculating the sla reports',
INDEX idx_sla_history_state_env_event_time (environment_id, event_time) COMMENT 'Filter for sla history retention'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin ROW_FORMAT=DYNAMIC;
INSERT INTO sla_history_state
(id, environment_id, endpoint_id, object_type, host_id, service_id, event_time, hard_state, previous_hard_state)
SELECT id, environment_id, endpoint_id, object_type, host_id, service_id, event_time, hard_state, previous_hard_state
FROM state_history
WHERE state_type = 'hard'
ON DUPLICATE KEY UPDATE sla_history_state.id = sla_history_state.id;
CREATE TABLE sla_history_downtime (
environment_id binary(20) NOT NULL COMMENT 'environment.id',
endpoint_id binary(20) DEFAULT NULL COMMENT 'endpoint.id',
object_type enum('host', 'service') NOT NULL,
host_id binary(20) NOT NULL COMMENT 'host.id',
service_id binary(20) DEFAULT NULL COMMENT 'service.id',
downtime_id binary(20) NOT NULL COMMENT 'downtime.id (may reference already deleted rows)',
downtime_start BIGINT UNSIGNED NOT NULL COMMENT 'start time of the downtime',
downtime_end BIGINT UNSIGNED NOT NULL COMMENT 'end time of the downtime',
PRIMARY KEY (downtime_id),
INDEX idx_sla_history_downtime_event (host_id, service_id, downtime_start, downtime_end) COMMENT 'Filter for calculating the sla reports',
INDEX idx_sla_history_downtime_env_downtime_end (environment_id, downtime_end) COMMENT 'Filter for sla history retention'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin ROW_FORMAT=DYNAMIC;
INSERT INTO sla_history_downtime
(environment_id, endpoint_id, object_type, host_id, service_id, downtime_id, downtime_start, downtime_end)
SELECT environment_id, endpoint_id, object_type, host_id, service_id, downtime_id,
start_time AS downtime_start, IF(has_been_cancelled = 'y', cancel_time, end_time) AS downtime_end
FROM downtime_history
ON DUPLICATE KEY UPDATE sla_history_downtime.downtime_id = sla_history_downtime.downtime_id;
INSERT INTO icingadb_schema (version, TIMESTAMP)
VALUES (3, UNIX_TIMESTAMP() * 1000);
|