1 /**************************************************************************//**
3 * Implementation of EVEL functions relating to Event Headers - since
4 * Heartbeats only contain the Event Header, the Heartbeat factory function is
10 * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 * http://www.apache.org/licenses/LICENSE-2.0
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
22 *****************************************************************************/
30 #include "evel_internal.h"
31 #include "evel_throttle.h"
34 /**************************************************************************//**
35 * Unique sequence number for events from this VNF.
36 *****************************************************************************/
37 static int event_sequence = 1;
39 /**************************************************************************//**
40 * Set the next event_sequence to use.
42 * @param sequence The next sequence number to use.
43 *****************************************************************************/
44 void evel_set_next_event_sequence(const int sequence)
48 EVEL_INFO("Setting event sequence to %d, was %d ", sequence, event_sequence);
49 event_sequence = sequence;
54 /**************************************************************************//**
55 * Create a new heartbeat event.
57 * @note that the heartbeat is just a "naked" commonEventHeader!
59 * @returns pointer to the newly manufactured ::EVENT_HEADER. If the event is
60 * not used it must be released using ::evel_free_event
61 * @retval NULL Failed to create the event.
62 *****************************************************************************/
63 EVENT_HEADER * evel_new_heartbeat()
65 EVENT_HEADER * heartbeat = NULL;
68 /***************************************************************************/
69 /* Allocate the header. */
70 /***************************************************************************/
71 heartbeat = malloc(sizeof(EVENT_HEADER));
72 if (heartbeat == NULL)
74 log_error_state("Out of memory");
77 memset(heartbeat, 0, sizeof(EVENT_HEADER));
79 /***************************************************************************/
80 /* Initialize the header. Get a new event sequence number. Note that if */
81 /* any memory allocation fails in here we will fail gracefully because */
82 /* everything downstream can cope with NULLs. */
83 /***************************************************************************/
84 evel_init_header(heartbeat);
85 evel_force_option_string(&heartbeat->event_type, "Autonomous heartbeat");
92 /**************************************************************************//**
93 * Initialize a newly created event header.
95 * @param header Pointer to the header being initialized.
96 *****************************************************************************/
97 void evel_init_header(EVENT_HEADER * const header)
99 char scratchpad[EVEL_MAX_STRING_LEN + 1] = {0};
104 assert(header != NULL);
106 gettimeofday(&tv, NULL);
108 /***************************************************************************/
109 /* Initialize the header. Get a new event sequence number. Note that if */
110 /* any memory allocation fails in here we will fail gracefully because */
111 /* everything downstream can cope with NULLs. */
112 /***************************************************************************/
113 header->event_domain = EVEL_DOMAIN_HEARTBEAT;
114 snprintf(scratchpad, EVEL_MAX_STRING_LEN, "%d", event_sequence);
115 header->event_id = strdup(scratchpad);
116 header->functional_role = strdup(functional_role);
117 header->last_epoch_microsec = tv.tv_usec + 1000000 * tv.tv_sec;
118 header->priority = EVEL_PRIORITY_NORMAL;
119 header->reporting_entity_name = strdup(openstack_vm_name());
120 header->source_name = strdup(openstack_vm_name());
121 header->sequence = event_sequence;
122 header->start_epoch_microsec = header->last_epoch_microsec;
123 header->major_version = EVEL_HEADER_MAJOR_VERSION;
124 header->minor_version = EVEL_HEADER_MINOR_VERSION;
127 /***************************************************************************/
128 /* Optional parameters. */
129 /***************************************************************************/
130 evel_init_option_string(&header->event_type);
131 evel_force_option_string(&header->reporting_entity_id, openstack_vm_uuid());
132 evel_force_option_string(&header->source_id, openstack_vm_uuid());
137 /**************************************************************************//**
138 * Set the Event Type property of the event header.
140 * @note The property is treated as immutable: it is only valid to call
141 * the setter once. However, we don't assert if the caller tries to
142 * overwrite, just ignoring the update instead.
144 * @param header Pointer to the ::EVENT_HEADER.
145 * @param type The Event Type to be set. ASCIIZ string. The caller
146 * does not need to preserve the value once the function
148 *****************************************************************************/
149 void evel_header_type_set(EVENT_HEADER * const header,
150 const char * const type)
154 /***************************************************************************/
155 /* Check preconditions. */
156 /***************************************************************************/
157 assert(header != NULL);
158 assert(type != NULL);
160 evel_set_option_string(&header->event_type, type, "Event Type");
165 /**************************************************************************//**
166 * Set the Start Epoch property of the event header.
168 * @note The Start Epoch defaults to the time of event creation.
170 * @param header Pointer to the ::EVENT_HEADER.
171 * @param start_epoch_microsec
172 * The start epoch to set, in microseconds.
173 *****************************************************************************/
174 void evel_start_epoch_set(EVENT_HEADER * const header,
175 const unsigned long long start_epoch_microsec)
179 /***************************************************************************/
180 /* Check preconditions and assign the new value. */
181 /***************************************************************************/
182 assert(header != NULL);
183 header->start_epoch_microsec = start_epoch_microsec;
188 /**************************************************************************//**
189 * Set the Last Epoch property of the event header.
191 * @note The Last Epoch defaults to the time of event creation.
193 * @param header Pointer to the ::EVENT_HEADER.
194 * @param last_epoch_microsec
195 * The last epoch to set, in microseconds.
196 *****************************************************************************/
197 void evel_last_epoch_set(EVENT_HEADER * const header,
198 const unsigned long long last_epoch_microsec)
202 /***************************************************************************/
203 /* Check preconditions and assign the new value. */
204 /***************************************************************************/
205 assert(header != NULL);
206 header->last_epoch_microsec = last_epoch_microsec;
211 /**************************************************************************//**
212 * Set the Reporting Entity Name property of the event header.
214 * @note The Reporting Entity Name defaults to the OpenStack VM Name.
216 * @param header Pointer to the ::EVENT_HEADER.
217 * @param entity_name The entity name to set.
218 *****************************************************************************/
219 void evel_reporting_entity_name_set(EVENT_HEADER * const header,
220 const char * const entity_name)
224 /***************************************************************************/
225 /* Check preconditions and assign the new value. */
226 /***************************************************************************/
227 assert(header != NULL);
228 assert(entity_name != NULL);
229 assert(header->reporting_entity_name != NULL);
231 /***************************************************************************/
232 /* Free the previously allocated memory and replace it with a copy of the */
234 /***************************************************************************/
235 free(header->reporting_entity_name);
236 header->reporting_entity_name = strdup(entity_name);
241 /**************************************************************************//**
242 * Set the Reporting Entity Id property of the event header.
244 * @note The Reporting Entity Id defaults to the OpenStack VM UUID.
246 * @param header Pointer to the ::EVENT_HEADER.
247 * @param entity_id The entity id to set.
248 *****************************************************************************/
249 void evel_reporting_entity_id_set(EVENT_HEADER * const header,
250 const char * const entity_id)
254 /***************************************************************************/
255 /* Check preconditions and assign the new value. */
256 /***************************************************************************/
257 assert(header != NULL);
258 assert(entity_id != NULL);
260 /***************************************************************************/
261 /* Free the previously allocated memory and replace it with a copy of the */
262 /* provided one. Note that evel_force_option_string strdups entity_id. */
263 /***************************************************************************/
264 evel_free_option_string(&header->reporting_entity_id);
265 evel_force_option_string(&header->reporting_entity_id, entity_id);
270 /**************************************************************************//**
271 * Encode the event as a JSON event object according to AT&T's schema.
273 * @param jbuf Pointer to the ::EVEL_JSON_BUFFER to encode into.
274 * @param event Pointer to the ::EVENT_HEADER to encode.
275 *****************************************************************************/
276 void evel_json_encode_header(EVEL_JSON_BUFFER * jbuf,
277 EVENT_HEADER * event)
284 /***************************************************************************/
285 /* Check preconditions. */
286 /***************************************************************************/
287 assert(jbuf != NULL);
288 assert(jbuf->json != NULL);
289 assert(jbuf->max_size > 0);
290 assert(event != NULL);
292 domain = evel_event_domain(event->event_domain);
293 priority = evel_event_priority(event->priority);
294 evel_json_open_named_object(jbuf, "commonEventHeader");
296 /***************************************************************************/
297 /* Mandatory fields. */
298 /***************************************************************************/
299 evel_enc_kv_string(jbuf, "domain", domain);
300 evel_enc_kv_string(jbuf, "eventId", event->event_id);
301 evel_enc_kv_string(jbuf, "functionalRole", event->functional_role);
302 evel_enc_kv_ull(jbuf, "lastEpochMicrosec", event->last_epoch_microsec);
303 evel_enc_kv_string(jbuf, "priority", priority);
305 jbuf, "reportingEntityName", event->reporting_entity_name);
306 evel_enc_kv_int(jbuf, "sequence", event->sequence);
307 evel_enc_kv_string(jbuf, "sourceName", event->source_name);
308 evel_enc_kv_ull(jbuf, "startEpochMicrosec", event->start_epoch_microsec);
310 jbuf, "version", event->major_version, event->minor_version);
312 /***************************************************************************/
313 /* Optional fields. */
314 /***************************************************************************/
315 evel_enc_kv_opt_string(jbuf, "eventType", &event->event_type);
316 evel_enc_kv_opt_string(
317 jbuf, "reportingEntityId", &event->reporting_entity_id);
318 evel_enc_kv_opt_string(jbuf, "sourceId", &event->source_id);
320 evel_json_close_object(jbuf);
325 /**************************************************************************//**
326 * Free an event header.
328 * Free off the event header supplied. Will free all the contained allocated
331 * @note It does not free the header itself, since that may be part of a
333 *****************************************************************************/
334 void evel_free_header(EVENT_HEADER * const event)
338 /***************************************************************************/
339 /* Check preconditions. As an internal API we don't allow freeing NULL */
340 /* events as we do on the public API. */
341 /***************************************************************************/
342 assert(event != NULL);
344 /***************************************************************************/
345 /* Free all internal strings. */
346 /***************************************************************************/
347 free(event->event_id);
348 evel_free_option_string(&event->event_type);
349 free(event->functional_role);
350 evel_free_option_string(&event->reporting_entity_id);
351 free(event->reporting_entity_name);
352 evel_free_option_string(&event->source_id);
353 free(event->source_name);
358 /**************************************************************************//**
359 * Encode the event as a JSON event object according to AT&T's schema.
361 * @param json Pointer to where to store the JSON encoded data.
362 * @param max_size Size of storage available in json_body.
363 * @param event Pointer to the ::EVENT_HEADER to encode.
364 * @returns Number of bytes actually written.
365 *****************************************************************************/
366 int evel_json_encode_event(char * json,
368 EVENT_HEADER * event)
370 EVEL_JSON_BUFFER json_buffer;
371 EVEL_JSON_BUFFER * jbuf = &json_buffer;
372 EVEL_THROTTLE_SPEC * throttle_spec;
376 /***************************************************************************/
377 /* Get the latest throttle specification for the domain. */
378 /***************************************************************************/
379 throttle_spec = evel_get_throttle_spec(event->event_domain);
381 /***************************************************************************/
382 /* Initialize the JSON_BUFFER and open the top-level objects. */
383 /***************************************************************************/
384 evel_json_buffer_init(jbuf, json, max_size, throttle_spec);
385 evel_json_open_object(jbuf);
386 evel_json_open_named_object(jbuf, "event");
388 switch (event->event_domain)
390 case EVEL_DOMAIN_HEARTBEAT:
391 evel_json_encode_header(jbuf, event);
394 case EVEL_DOMAIN_FAULT:
395 evel_json_encode_fault(jbuf, (EVENT_FAULT *)event);
398 case EVEL_DOMAIN_MEASUREMENT:
399 evel_json_encode_measurement(jbuf, (EVENT_MEASUREMENT *)event);
402 case EVEL_DOMAIN_MOBILE_FLOW:
403 evel_json_encode_mobile_flow(jbuf, (EVENT_MOBILE_FLOW *)event);
406 case EVEL_DOMAIN_REPORT:
407 evel_json_encode_report(jbuf, (EVENT_REPORT *)event);
410 case EVEL_DOMAIN_SERVICE:
411 evel_json_encode_service(jbuf, (EVENT_SERVICE *)event);
414 case EVEL_DOMAIN_SIGNALING:
415 evel_json_encode_signaling(jbuf, (EVENT_SIGNALING *)event);
418 case EVEL_DOMAIN_STATE_CHANGE:
419 evel_json_encode_state_change(jbuf, (EVENT_STATE_CHANGE *)event);
422 case EVEL_DOMAIN_SYSLOG:
423 evel_json_encode_syslog(jbuf, (EVENT_SYSLOG *)event);
426 case EVEL_DOMAIN_OTHER:
427 evel_json_encode_other(jbuf, (EVENT_OTHER *)event);
430 case EVEL_DOMAIN_INTERNAL:
432 EVEL_ERROR("Unexpected domain %d", event->event_domain);
436 evel_json_close_object(jbuf);
437 evel_json_close_object(jbuf);
439 /***************************************************************************/
441 /***************************************************************************/
442 assert(jbuf->depth == 0);
449 /**************************************************************************//**
450 * Initialize an event instance id.
452 * @param instance_id Pointer to the event instance id being initialized.
453 * @param vendor_id The vendor id to encode in the event instance id.
454 * @param event_id The event id to encode in the event instance id.
455 *****************************************************************************/
456 void evel_init_event_instance_id(EVEL_EVENT_INSTANCE_ID * const instance_id,
457 const char * const vendor_id,
458 const char * const event_id)
462 /***************************************************************************/
463 /* Check preconditions. */
464 /***************************************************************************/
465 assert(instance_id != NULL);
466 assert(vendor_id != NULL);
467 assert(event_id != NULL);
469 /***************************************************************************/
470 /* Store the mandatory parts. */
471 /***************************************************************************/
472 instance_id->vendor_id = strdup(vendor_id);
473 instance_id->event_id = strdup(event_id);
475 /***************************************************************************/
476 /* Initialize the optional parts. */
477 /***************************************************************************/
478 evel_init_option_string(&instance_id->product_id);
479 evel_init_option_string(&instance_id->subsystem_id);
480 evel_init_option_string(&instance_id->event_friendly_name);
485 /**************************************************************************//**
486 * Free an event instance id.
488 * @param instance_id Pointer to the event instance id being initialized.
489 *****************************************************************************/
490 void evel_free_event_instance_id(EVEL_EVENT_INSTANCE_ID * const instance_id)
494 /***************************************************************************/
495 /* Check preconditions. */
496 /***************************************************************************/
497 assert(instance_id != NULL);
498 assert(instance_id->vendor_id != NULL);
499 assert(instance_id->event_id != NULL);
501 /***************************************************************************/
502 /* Free everything. */
503 /***************************************************************************/
504 free(instance_id->vendor_id);
505 free(instance_id->event_id);
506 evel_free_option_string(&instance_id->product_id);
507 evel_free_option_string(&instance_id->subsystem_id);
508 evel_free_option_string(&instance_id->event_friendly_name);
513 /**************************************************************************//**
514 * Encode the instance id as a JSON object according to AT&T's schema.
516 * @param jbuf Pointer to the ::EVEL_JSON_BUFFER to encode into.
517 * @param instance_id Pointer to the ::EVEL_EVENT_INSTANCE_ID to encode.
518 *****************************************************************************/
519 void evel_json_encode_instance_id(EVEL_JSON_BUFFER * jbuf,
520 EVEL_EVENT_INSTANCE_ID * instance_id)
524 /***************************************************************************/
525 /* Check preconditions. */
526 /***************************************************************************/
527 assert(jbuf != NULL);
528 assert(jbuf->json != NULL);
529 assert(jbuf->max_size > 0);
530 assert(instance_id != NULL);
531 assert(instance_id->vendor_id != NULL);
532 assert(instance_id->event_id != NULL);
534 evel_json_open_named_object(jbuf, "eventInstanceIdentifier");
536 /***************************************************************************/
537 /* Mandatory fields. */
538 /***************************************************************************/
539 evel_enc_kv_string(jbuf, "vendorId", instance_id->vendor_id);
540 evel_enc_kv_string(jbuf, "eventId", instance_id->event_id);
542 /***************************************************************************/
543 /* Optional fields. */
544 /***************************************************************************/
545 evel_enc_kv_opt_string(jbuf, "productId", &instance_id->product_id);
546 evel_enc_kv_opt_string(jbuf, "subsystemId", &instance_id->subsystem_id);
547 evel_enc_kv_opt_string(
548 jbuf, "eventFriendlyName", &instance_id->event_friendly_name);
550 evel_json_close_object(jbuf);