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(c) <2016>, AT&T Intellectual Property. All other rights reserved.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions are met:
15 * 1. Redistributions of source code must retain the above copyright notice,
16 * this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright notice,
18 * this list of conditions and the following disclaimer in the documentation
19 * and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement: This product includes
22 * software developed by the AT&T.
23 * 4. Neither the name of AT&T nor the names of its contributors may be used to
24 * endorse or promote products derived from this software without specific
25 * prior written permission.
27 * THIS SOFTWARE IS PROVIDED BY AT&T INTELLECTUAL PROPERTY ''AS IS'' AND ANY
28 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
29 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
30 * DISCLAIMED. IN NO EVENT SHALL AT&T INTELLECTUAL PROPERTY BE LIABLE FOR ANY
31 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
32 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
33 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
34 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
36 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 *****************************************************************************/
45 #include "evel_internal.h"
46 #include "evel_throttle.h"
49 /**************************************************************************//**
50 * Unique sequence number for events from this VNF.
51 *****************************************************************************/
52 static int event_sequence = 1;
54 /**************************************************************************//**
55 * Set the next event_sequence to use.
57 * @param sequence The next sequence number to use.
58 *****************************************************************************/
59 void evel_set_next_event_sequence(const int sequence)
63 EVEL_INFO("Setting event sequence to %d, was %d ", sequence, event_sequence);
64 event_sequence = sequence;
69 /**************************************************************************//**
70 * Create a new heartbeat event.
72 * @note that the heartbeat is just a "naked" commonEventHeader!
74 * @returns pointer to the newly manufactured ::EVENT_HEADER. If the event is
75 * not used it must be released using ::evel_free_event
76 * @retval NULL Failed to create the event.
77 *****************************************************************************/
78 EVENT_HEADER * evel_new_heartbeat()
80 EVENT_HEADER * heartbeat = NULL;
83 /***************************************************************************/
84 /* Allocate the header. */
85 /***************************************************************************/
86 heartbeat = malloc(sizeof(EVENT_HEADER));
87 if (heartbeat == NULL)
89 log_error_state("Out of memory");
92 memset(heartbeat, 0, sizeof(EVENT_HEADER));
94 /***************************************************************************/
95 /* Initialize the header. Get a new event sequence number. Note that if */
96 /* any memory allocation fails in here we will fail gracefully because */
97 /* everything downstream can cope with NULLs. */
98 /***************************************************************************/
99 evel_init_header(heartbeat);
100 evel_force_option_string(&heartbeat->event_type, "Autonomous heartbeat");
107 /**************************************************************************//**
108 * Initialize a newly created event header.
110 * @param header Pointer to the header being initialized.
111 *****************************************************************************/
112 void evel_init_header(EVENT_HEADER * const header)
114 char scratchpad[EVEL_MAX_STRING_LEN + 1] = {0};
119 assert(header != NULL);
121 gettimeofday(&tv, NULL);
123 /***************************************************************************/
124 /* Initialize the header. Get a new event sequence number. Note that if */
125 /* any memory allocation fails in here we will fail gracefully because */
126 /* everything downstream can cope with NULLs. */
127 /***************************************************************************/
128 header->event_domain = EVEL_DOMAIN_HEARTBEAT;
129 snprintf(scratchpad, EVEL_MAX_STRING_LEN, "%d", event_sequence);
130 header->event_id = strdup(scratchpad);
131 header->functional_role = strdup(functional_role);
132 header->last_epoch_microsec = tv.tv_usec + 1000000 * tv.tv_sec;
133 header->priority = EVEL_PRIORITY_NORMAL;
134 header->reporting_entity_name = strdup(openstack_vm_name());
135 header->source_name = strdup(openstack_vm_name());
136 header->sequence = event_sequence;
137 header->start_epoch_microsec = header->last_epoch_microsec;
138 header->major_version = EVEL_HEADER_MAJOR_VERSION;
139 header->minor_version = EVEL_HEADER_MINOR_VERSION;
142 /***************************************************************************/
143 /* Optional parameters. */
144 /***************************************************************************/
145 evel_init_option_string(&header->event_type);
146 evel_force_option_string(&header->reporting_entity_id, openstack_vm_uuid());
147 evel_force_option_string(&header->source_id, openstack_vm_uuid());
152 /**************************************************************************//**
153 * Set the Event Type property of the event header.
155 * @note The property is treated as immutable: it is only valid to call
156 * the setter once. However, we don't assert if the caller tries to
157 * overwrite, just ignoring the update instead.
159 * @param header Pointer to the ::EVENT_HEADER.
160 * @param type The Event Type to be set. ASCIIZ string. The caller
161 * does not need to preserve the value once the function
163 *****************************************************************************/
164 void evel_header_type_set(EVENT_HEADER * const header,
165 const char * const type)
169 /***************************************************************************/
170 /* Check preconditions. */
171 /***************************************************************************/
172 assert(header != NULL);
173 assert(type != NULL);
175 evel_set_option_string(&header->event_type, type, "Event Type");
180 /**************************************************************************//**
181 * Set the Start Epoch property of the event header.
183 * @note The Start Epoch defaults to the time of event creation.
185 * @param header Pointer to the ::EVENT_HEADER.
186 * @param start_epoch_microsec
187 * The start epoch to set, in microseconds.
188 *****************************************************************************/
189 void evel_start_epoch_set(EVENT_HEADER * const header,
190 const unsigned long long start_epoch_microsec)
194 /***************************************************************************/
195 /* Check preconditions and assign the new value. */
196 /***************************************************************************/
197 assert(header != NULL);
198 header->start_epoch_microsec = start_epoch_microsec;
203 /**************************************************************************//**
204 * Set the Last Epoch property of the event header.
206 * @note The Last Epoch defaults to the time of event creation.
208 * @param header Pointer to the ::EVENT_HEADER.
209 * @param last_epoch_microsec
210 * The last epoch to set, in microseconds.
211 *****************************************************************************/
212 void evel_last_epoch_set(EVENT_HEADER * const header,
213 const unsigned long long last_epoch_microsec)
217 /***************************************************************************/
218 /* Check preconditions and assign the new value. */
219 /***************************************************************************/
220 assert(header != NULL);
221 header->last_epoch_microsec = last_epoch_microsec;
226 /**************************************************************************//**
227 * Set the Reporting Entity Name property of the event header.
229 * @note The Reporting Entity Name defaults to the OpenStack VM Name.
231 * @param header Pointer to the ::EVENT_HEADER.
232 * @param entity_name The entity name to set.
233 *****************************************************************************/
234 void evel_reporting_entity_name_set(EVENT_HEADER * const header,
235 const char * const entity_name)
239 /***************************************************************************/
240 /* Check preconditions and assign the new value. */
241 /***************************************************************************/
242 assert(header != NULL);
243 assert(entity_name != NULL);
244 assert(header->reporting_entity_name != NULL);
246 /***************************************************************************/
247 /* Free the previously allocated memory and replace it with a copy of the */
249 /***************************************************************************/
250 free(header->reporting_entity_name);
251 header->reporting_entity_name = strdup(entity_name);
256 /**************************************************************************//**
257 * Set the Reporting Entity Id property of the event header.
259 * @note The Reporting Entity Id defaults to the OpenStack VM UUID.
261 * @param header Pointer to the ::EVENT_HEADER.
262 * @param entity_id The entity id to set.
263 *****************************************************************************/
264 void evel_reporting_entity_id_set(EVENT_HEADER * const header,
265 const char * const entity_id)
269 /***************************************************************************/
270 /* Check preconditions and assign the new value. */
271 /***************************************************************************/
272 assert(header != NULL);
273 assert(entity_id != NULL);
275 /***************************************************************************/
276 /* Free the previously allocated memory and replace it with a copy of the */
277 /* provided one. Note that evel_force_option_string strdups entity_id. */
278 /***************************************************************************/
279 evel_free_option_string(&header->reporting_entity_id);
280 evel_force_option_string(&header->reporting_entity_id, entity_id);
285 /**************************************************************************//**
286 * Encode the event as a JSON event object according to AT&T's schema.
288 * @param jbuf Pointer to the ::EVEL_JSON_BUFFER to encode into.
289 * @param event Pointer to the ::EVENT_HEADER to encode.
290 *****************************************************************************/
291 void evel_json_encode_header(EVEL_JSON_BUFFER * jbuf,
292 EVENT_HEADER * event)
299 /***************************************************************************/
300 /* Check preconditions. */
301 /***************************************************************************/
302 assert(jbuf != NULL);
303 assert(jbuf->json != NULL);
304 assert(jbuf->max_size > 0);
305 assert(event != NULL);
307 domain = evel_event_domain(event->event_domain);
308 priority = evel_event_priority(event->priority);
309 evel_json_open_named_object(jbuf, "commonEventHeader");
311 /***************************************************************************/
312 /* Mandatory fields. */
313 /***************************************************************************/
314 evel_enc_kv_string(jbuf, "domain", domain);
315 evel_enc_kv_string(jbuf, "eventId", event->event_id);
316 evel_enc_kv_string(jbuf, "functionalRole", event->functional_role);
317 evel_enc_kv_ull(jbuf, "lastEpochMicrosec", event->last_epoch_microsec);
318 evel_enc_kv_string(jbuf, "priority", priority);
320 jbuf, "reportingEntityName", event->reporting_entity_name);
321 evel_enc_kv_int(jbuf, "sequence", event->sequence);
322 evel_enc_kv_string(jbuf, "sourceName", event->source_name);
323 evel_enc_kv_ull(jbuf, "startEpochMicrosec", event->start_epoch_microsec);
325 jbuf, "version", event->major_version, event->minor_version);
327 /***************************************************************************/
328 /* Optional fields. */
329 /***************************************************************************/
330 evel_enc_kv_opt_string(jbuf, "eventType", &event->event_type);
331 evel_enc_kv_opt_string(
332 jbuf, "reportingEntityId", &event->reporting_entity_id);
333 evel_enc_kv_opt_string(jbuf, "sourceId", &event->source_id);
335 evel_json_close_object(jbuf);
340 /**************************************************************************//**
341 * Free an event header.
343 * Free off the event header supplied. Will free all the contained allocated
346 * @note It does not free the header itself, since that may be part of a
348 *****************************************************************************/
349 void evel_free_header(EVENT_HEADER * const event)
353 /***************************************************************************/
354 /* Check preconditions. As an internal API we don't allow freeing NULL */
355 /* events as we do on the public API. */
356 /***************************************************************************/
357 assert(event != NULL);
359 /***************************************************************************/
360 /* Free all internal strings. */
361 /***************************************************************************/
362 free(event->event_id);
363 evel_free_option_string(&event->event_type);
364 free(event->functional_role);
365 evel_free_option_string(&event->reporting_entity_id);
366 free(event->reporting_entity_name);
367 evel_free_option_string(&event->source_id);
368 free(event->source_name);
373 /**************************************************************************//**
374 * Encode the event as a JSON event object according to AT&T's schema.
376 * @param json Pointer to where to store the JSON encoded data.
377 * @param max_size Size of storage available in json_body.
378 * @param event Pointer to the ::EVENT_HEADER to encode.
379 * @returns Number of bytes actually written.
380 *****************************************************************************/
381 int evel_json_encode_event(char * json,
383 EVENT_HEADER * event)
385 EVEL_JSON_BUFFER json_buffer;
386 EVEL_JSON_BUFFER * jbuf = &json_buffer;
387 EVEL_THROTTLE_SPEC * throttle_spec;
391 /***************************************************************************/
392 /* Get the latest throttle specification for the domain. */
393 /***************************************************************************/
394 throttle_spec = evel_get_throttle_spec(event->event_domain);
396 /***************************************************************************/
397 /* Initialize the JSON_BUFFER and open the top-level objects. */
398 /***************************************************************************/
399 evel_json_buffer_init(jbuf, json, max_size, throttle_spec);
400 evel_json_open_object(jbuf);
401 evel_json_open_named_object(jbuf, "event");
403 switch (event->event_domain)
405 case EVEL_DOMAIN_HEARTBEAT:
406 evel_json_encode_header(jbuf, event);
409 case EVEL_DOMAIN_FAULT:
410 evel_json_encode_fault(jbuf, (EVENT_FAULT *)event);
413 case EVEL_DOMAIN_MEASUREMENT:
414 evel_json_encode_measurement(jbuf, (EVENT_MEASUREMENT *)event);
417 case EVEL_DOMAIN_MOBILE_FLOW:
418 evel_json_encode_mobile_flow(jbuf, (EVENT_MOBILE_FLOW *)event);
421 case EVEL_DOMAIN_REPORT:
422 evel_json_encode_report(jbuf, (EVENT_REPORT *)event);
425 case EVEL_DOMAIN_SERVICE:
426 evel_json_encode_service(jbuf, (EVENT_SERVICE *)event);
429 case EVEL_DOMAIN_SIGNALING:
430 evel_json_encode_signaling(jbuf, (EVENT_SIGNALING *)event);
433 case EVEL_DOMAIN_STATE_CHANGE:
434 evel_json_encode_state_change(jbuf, (EVENT_STATE_CHANGE *)event);
437 case EVEL_DOMAIN_SYSLOG:
438 evel_json_encode_syslog(jbuf, (EVENT_SYSLOG *)event);
441 case EVEL_DOMAIN_OTHER:
442 evel_json_encode_other(jbuf, (EVENT_OTHER *)event);
445 case EVEL_DOMAIN_INTERNAL:
447 EVEL_ERROR("Unexpected domain %d", event->event_domain);
451 evel_json_close_object(jbuf);
452 evel_json_close_object(jbuf);
454 /***************************************************************************/
456 /***************************************************************************/
457 assert(jbuf->depth == 0);
464 /**************************************************************************//**
465 * Initialize an event instance id.
467 * @param instance_id Pointer to the event instance id being initialized.
468 * @param vendor_id The vendor id to encode in the event instance id.
469 * @param event_id The event id to encode in the event instance id.
470 *****************************************************************************/
471 void evel_init_event_instance_id(EVEL_EVENT_INSTANCE_ID * const instance_id,
472 const char * const vendor_id,
473 const char * const event_id)
477 /***************************************************************************/
478 /* Check preconditions. */
479 /***************************************************************************/
480 assert(instance_id != NULL);
481 assert(vendor_id != NULL);
482 assert(event_id != NULL);
484 /***************************************************************************/
485 /* Store the mandatory parts. */
486 /***************************************************************************/
487 instance_id->vendor_id = strdup(vendor_id);
488 instance_id->event_id = strdup(event_id);
490 /***************************************************************************/
491 /* Initialize the optional parts. */
492 /***************************************************************************/
493 evel_init_option_string(&instance_id->product_id);
494 evel_init_option_string(&instance_id->subsystem_id);
495 evel_init_option_string(&instance_id->event_friendly_name);
500 /**************************************************************************//**
501 * Free an event instance id.
503 * @param instance_id Pointer to the event instance id being initialized.
504 *****************************************************************************/
505 void evel_free_event_instance_id(EVEL_EVENT_INSTANCE_ID * const instance_id)
509 /***************************************************************************/
510 /* Check preconditions. */
511 /***************************************************************************/
512 assert(instance_id != NULL);
513 assert(instance_id->vendor_id != NULL);
514 assert(instance_id->event_id != NULL);
516 /***************************************************************************/
517 /* Free everything. */
518 /***************************************************************************/
519 free(instance_id->vendor_id);
520 free(instance_id->event_id);
521 evel_free_option_string(&instance_id->product_id);
522 evel_free_option_string(&instance_id->subsystem_id);
523 evel_free_option_string(&instance_id->event_friendly_name);
528 /**************************************************************************//**
529 * Encode the instance id as a JSON object according to AT&T's schema.
531 * @param jbuf Pointer to the ::EVEL_JSON_BUFFER to encode into.
532 * @param instance_id Pointer to the ::EVEL_EVENT_INSTANCE_ID to encode.
533 *****************************************************************************/
534 void evel_json_encode_instance_id(EVEL_JSON_BUFFER * jbuf,
535 EVEL_EVENT_INSTANCE_ID * instance_id)
539 /***************************************************************************/
540 /* Check preconditions. */
541 /***************************************************************************/
542 assert(jbuf != NULL);
543 assert(jbuf->json != NULL);
544 assert(jbuf->max_size > 0);
545 assert(instance_id != NULL);
546 assert(instance_id->vendor_id != NULL);
547 assert(instance_id->event_id != NULL);
549 evel_json_open_named_object(jbuf, "eventInstanceIdentifier");
551 /***************************************************************************/
552 /* Mandatory fields. */
553 /***************************************************************************/
554 evel_enc_kv_string(jbuf, "vendorId", instance_id->vendor_id);
555 evel_enc_kv_string(jbuf, "eventId", instance_id->event_id);
557 /***************************************************************************/
558 /* Optional fields. */
559 /***************************************************************************/
560 evel_enc_kv_opt_string(jbuf, "productId", &instance_id->product_id);
561 evel_enc_kv_opt_string(jbuf, "subsystemId", &instance_id->subsystem_id);
562 evel_enc_kv_opt_string(
563 jbuf, "eventFriendlyName", &instance_id->event_friendly_name);
565 evel_json_close_object(jbuf);