1 /**************************************************************************//**
3 * Implementation of EVEL functions relating to the Measurement.
8 * Copyright(c) <2016>, AT&T Intellectual Property. All other rights reserved.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are met:
13 * 1. Redistributions of source code must retain the above copyright notice,
14 * this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement: This product includes
20 * software developed by the AT&T.
21 * 4. Neither the name of AT&T nor the names of its contributors may be used to
22 * endorse or promote products derived from this software without specific
23 * prior written permission.
25 * THIS SOFTWARE IS PROVIDED BY AT&T INTELLECTUAL PROPERTY ''AS IS'' AND ANY
26 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28 * DISCLAIMED. IN NO EVENT SHALL AT&T INTELLECTUAL PROPERTY BE LIABLE FOR ANY
29 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
32 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 *****************************************************************************/
42 #include "evel_internal.h"
43 #include "evel_throttle.h"
45 /**************************************************************************//**
46 * Create a new Measurement event.
48 * @note The mandatory fields on the Measurement must be supplied to this
49 * factory function and are immutable once set. Optional fields have
50 * explicit setter functions, but again values may only be set once so
51 * that the Measurement has immutable properties.
53 * @param measurement_interval
55 * @returns pointer to the newly manufactured ::EVENT_MEASUREMENT. If the
56 * event is not used (i.e. posted) it must be released using
58 * @retval NULL Failed to create the event.
59 *****************************************************************************/
60 EVENT_MEASUREMENT * evel_new_measurement(double measurement_interval)
62 EVENT_MEASUREMENT * measurement = NULL;
66 /***************************************************************************/
67 /* Check preconditions. */
68 /***************************************************************************/
69 assert(measurement_interval >= 0.0);
71 /***************************************************************************/
72 /* Allocate the measurement. */
73 /***************************************************************************/
74 measurement = malloc(sizeof(EVENT_MEASUREMENT));
75 if (measurement == NULL)
77 log_error_state("Out of memory for Measurement");
80 memset(measurement, 0, sizeof(EVENT_MEASUREMENT));
81 EVEL_DEBUG("New measurement is at %lp", measurement);
83 /***************************************************************************/
84 /* Initialize the header & the measurement fields. */
85 /***************************************************************************/
86 evel_init_header(&measurement->header);
87 measurement->header.event_domain = EVEL_DOMAIN_MEASUREMENT;
88 measurement->measurement_interval = measurement_interval;
89 dlist_initialize(&measurement->cpu_usage);
90 dlist_initialize(&measurement->filesystem_usage);
91 dlist_initialize(&measurement->latency_distribution);
92 dlist_initialize(&measurement->vnic_usage);
93 dlist_initialize(&measurement->codec_usage);
94 dlist_initialize(&measurement->feature_usage);
95 dlist_initialize(&measurement->additional_measurements);
96 evel_init_option_double(&measurement->aggregate_cpu_usage);
97 evel_init_option_double(&measurement->mean_request_latency);
98 evel_init_option_double(&measurement->memory_configured);
99 evel_init_option_double(&measurement->memory_used);
100 evel_init_option_double(&measurement->vnfc_scaling_metric);
101 evel_init_option_int(&measurement->concurrent_sessions);
102 evel_init_option_int(&measurement->configured_entities);
103 evel_init_option_int(&measurement->media_ports_in_use);
104 evel_init_option_int(&measurement->request_rate);
105 measurement->major_version = EVEL_MEASUREMENT_MAJOR_VERSION;
106 measurement->minor_version = EVEL_MEASUREMENT_MINOR_VERSION;
113 /**************************************************************************//**
114 * Set the Event Type property of the Measurement.
116 * @note The property is treated as immutable: it is only valid to call
117 * the setter once. However, we don't assert if the caller tries to
118 * overwrite, just ignoring the update instead.
120 * @param measurement Pointer to the Measurement.
121 * @param type The Event Type to be set. ASCIIZ string. The caller
122 * does not need to preserve the value once the function
124 *****************************************************************************/
125 void evel_measurement_type_set(EVENT_MEASUREMENT * measurement,
126 const char * const type)
130 /***************************************************************************/
131 /* Check preconditions and call evel_header_type_set. */
132 /***************************************************************************/
133 assert(measurement != NULL);
134 assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
135 evel_header_type_set(&measurement->header, type);
140 /**************************************************************************//**
141 * Set the Concurrent Sessions property of the Measurement.
143 * @note The property is treated as immutable: it is only valid to call
144 * the setter once. However, we don't assert if the caller tries to
145 * overwrite, just ignoring the update instead.
147 * @param measurement Pointer to the Measurement.
148 * @param concurrent_sessions The Concurrent Sessions to be set.
149 *****************************************************************************/
150 void evel_measurement_conc_sess_set(EVENT_MEASUREMENT * measurement,
151 int concurrent_sessions)
155 /***************************************************************************/
156 /* Check preconditions. */
157 /***************************************************************************/
158 assert(measurement != NULL);
159 assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
160 assert(concurrent_sessions >= 0);
162 evel_set_option_int(&measurement->concurrent_sessions,
164 "Concurrent Sessions");
168 /**************************************************************************//**
169 * Set the Configured Entities property of the Measurement.
171 * @note The property is treated as immutable: it is only valid to call
172 * the setter once. However, we don't assert if the caller tries to
173 * overwrite, just ignoring the update instead.
175 * @param measurement Pointer to the Measurement.
176 * @param configured_entities The Configured Entities to be set.
177 *****************************************************************************/
178 void evel_measurement_cfg_ents_set(EVENT_MEASUREMENT * measurement,
179 int configured_entities)
183 /***************************************************************************/
184 /* Check preconditions. */
185 /***************************************************************************/
186 assert(measurement != NULL);
187 assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
188 assert(configured_entities >= 0);
190 evel_set_option_int(&measurement->configured_entities,
192 "Configured Entities");
196 /**************************************************************************//**
197 * Add an additional set of Errors to the Measurement.
199 * @note The property is treated as immutable: it is only valid to call
200 * the setter once. However, we don't assert if the caller tries to
201 * overwrite, just ignoring the update instead.
203 * @param measurement Pointer to the measurement.
204 * @param receive_discards The number of receive discards.
205 * @param receive_errors The number of receive errors.
206 * @param transmit_discards The number of transmit discards.
207 * @param transmit_errors The number of transmit errors.
208 *****************************************************************************/
209 void evel_measurement_errors_set(EVENT_MEASUREMENT * measurement,
210 int receive_discards,
212 int transmit_discards,
215 MEASUREMENT_ERRORS * errors = NULL;
218 /***************************************************************************/
219 /* Check preconditions. */
220 /***************************************************************************/
221 assert(measurement != NULL);
222 assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
223 assert(receive_discards >= 0);
224 assert(receive_errors >= 0);
225 assert(transmit_discards >= 0);
226 assert(transmit_errors >= 0);
228 if (measurement->errors == NULL)
230 EVEL_DEBUG("Adding Errors: %d, %d; %d, %d",
235 errors = malloc(sizeof(MEASUREMENT_ERRORS));
236 assert(errors != NULL);
237 memset(errors, 0, sizeof(MEASUREMENT_ERRORS));
238 errors->receive_discards = receive_discards;
239 errors->receive_errors = receive_errors;
240 errors->transmit_discards = transmit_discards;
241 errors->transmit_errors = transmit_errors;
242 measurement->errors = errors;
246 errors = measurement->errors;
247 EVEL_DEBUG("Ignoring attempt to add Errors: %d, %d; %d, %d\n"
248 "Errors already set: %d, %d; %d, %d",
253 errors->receive_discards,
254 errors->receive_errors,
255 errors->transmit_discards,
256 errors->transmit_errors);
262 /**************************************************************************//**
263 * Set the Mean Request Latency property of the Measurement.
265 * @note The property is treated as immutable: it is only valid to call
266 * the setter once. However, we don't assert if the caller tries to
267 * overwrite, just ignoring the update instead.
269 * @param measurement Pointer to the Measurement.
270 * @param mean_request_latency The Mean Request Latency to be set.
271 *****************************************************************************/
272 void evel_measurement_mean_req_lat_set(EVENT_MEASUREMENT * measurement,
273 double mean_request_latency)
277 /***************************************************************************/
278 /* Check preconditions. */
279 /***************************************************************************/
280 assert(measurement != NULL);
281 assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
282 assert(mean_request_latency >= 0.0);
284 evel_set_option_double(&measurement->mean_request_latency,
285 mean_request_latency,
286 "Mean Request Latency");
290 /**************************************************************************//**
291 * Set the Memory Configured property of the Measurement.
293 * @note The property is treated as immutable: it is only valid to call
294 * the setter once. However, we don't assert if the caller tries to
295 * overwrite, just ignoring the update instead.
297 * @param measurement Pointer to the Measurement.
298 * @param memory_configured The Memory Configured to be set.
299 *****************************************************************************/
300 void evel_measurement_mem_cfg_set(EVENT_MEASUREMENT * measurement,
301 double memory_configured)
305 /***************************************************************************/
306 /* Check preconditions. */
307 /***************************************************************************/
308 assert(measurement != NULL);
309 assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
310 assert(memory_configured >= 0.0);
312 evel_set_option_double(&measurement->memory_configured,
314 "Memory Configured");
318 /**************************************************************************//**
319 * Set the Memory Used property of the Measurement.
321 * @note The property is treated as immutable: it is only valid to call
322 * the setter once. However, we don't assert if the caller tries to
323 * overwrite, just ignoring the update instead.
325 * @param measurement Pointer to the Measurement.
326 * @param memory_used The Memory Used to be set.
327 *****************************************************************************/
328 void evel_measurement_mem_used_set(EVENT_MEASUREMENT * measurement,
333 /***************************************************************************/
334 /* Check preconditions. */
335 /***************************************************************************/
336 assert(measurement != NULL);
337 assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
338 assert(memory_used >= 0.0);
340 evel_set_option_double(&measurement->memory_used,
346 /**************************************************************************//**
347 * Set the Request Rate property of the Measurement.
349 * @note The property is treated as immutable: it is only valid to call
350 * the setter once. However, we don't assert if the caller tries to
351 * overwrite, just ignoring the update instead.
353 * @param measurement Pointer to the Measurement.
354 * @param request_rate The Request Rate to be set.
355 *****************************************************************************/
356 void evel_measurement_request_rate_set(EVENT_MEASUREMENT * measurement,
361 /***************************************************************************/
362 /* Check preconditions. */
363 /***************************************************************************/
364 assert(measurement != NULL);
365 assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
366 assert(request_rate >= 0);
368 evel_set_option_int(&measurement->request_rate,
374 /**************************************************************************//**
375 * Add an additional CPU usage value name/value pair to the Measurement.
377 * The name and value are null delimited ASCII strings. The library takes
378 * a copy so the caller does not have to preserve values after the function
381 * @param measurement Pointer to the measurement.
382 * @param id ASCIIZ string with the CPU's identifier.
383 * @param usage CPU utilization.
384 *****************************************************************************/
385 void evel_measurement_cpu_use_add(EVENT_MEASUREMENT * measurement,
386 char * id, double usage)
388 MEASUREMENT_CPU_USE * cpu_use = NULL;
391 /***************************************************************************/
392 /* Check assumptions. */
393 /***************************************************************************/
394 assert(measurement != NULL);
395 assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
397 assert(usage >= 0.0);
399 /***************************************************************************/
400 /* Allocate a container for the value and push onto the list. */
401 /***************************************************************************/
402 EVEL_DEBUG("Adding id=%s usage=%lf", id, usage);
403 cpu_use = malloc(sizeof(MEASUREMENT_CPU_USE));
404 assert(cpu_use != NULL);
405 memset(cpu_use, 0, sizeof(MEASUREMENT_CPU_USE));
406 cpu_use->id = strdup(id);
407 cpu_use->usage = usage;
408 assert(cpu_use->id != NULL);
410 dlist_push_last(&measurement->cpu_usage, cpu_use);
415 /**************************************************************************//**
416 * Add an additional File System usage value name/value pair to the
419 * The filesystem_name is null delimited ASCII string. The library takes a
420 * copy so the caller does not have to preserve values after the function
423 * @param measurement Pointer to the measurement.
424 * @param filesystem_name ASCIIZ string with the file-system's UUID.
425 * @param block_configured Block storage configured.
426 * @param block_used Block storage in use.
427 * @param block_iops Block storage IOPS.
428 * @param ephemeral_configured Ephemeral storage configured.
429 * @param ephemeral_used Ephemeral storage in use.
430 * @param ephemeral_iops Ephemeral storage IOPS.
431 *****************************************************************************/
432 void evel_measurement_fsys_use_add(EVENT_MEASUREMENT * measurement,
433 char * filesystem_name,
434 double block_configured,
437 double ephemeral_configured,
438 double ephemeral_used,
441 MEASUREMENT_FSYS_USE * fsys_use = NULL;
444 /***************************************************************************/
445 /* Check assumptions. */
446 /***************************************************************************/
447 assert(measurement != NULL);
448 assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
449 assert(filesystem_name != NULL);
450 assert(block_configured >= 0.0);
451 assert(block_used >= 0.0);
452 assert(block_iops >= 0);
453 assert(ephemeral_configured >= 0.0);
454 assert(ephemeral_used >= 0.0);
455 assert(ephemeral_iops >= 0);
457 /***************************************************************************/
458 /* Allocate a container for the value and push onto the list. */
459 /***************************************************************************/
460 EVEL_DEBUG("Adding filesystem_name=%s", filesystem_name);
461 fsys_use = malloc(sizeof(MEASUREMENT_FSYS_USE));
462 assert(fsys_use != NULL);
463 memset(fsys_use, 0, sizeof(MEASUREMENT_FSYS_USE));
464 fsys_use->filesystem_name = strdup(filesystem_name);
465 fsys_use->block_configured = block_configured;
466 fsys_use->block_used = block_used;
467 fsys_use->block_iops = block_iops;
468 fsys_use->ephemeral_configured = block_configured;
469 fsys_use->ephemeral_used = ephemeral_used;
470 fsys_use->ephemeral_iops = ephemeral_iops;
472 dlist_push_last(&measurement->filesystem_usage, fsys_use);
477 /**************************************************************************//**
478 * Add a Feature usage value name/value pair to the Measurement.
480 * The name is null delimited ASCII string. The library takes
481 * a copy so the caller does not have to preserve values after the function
484 * @param measurement Pointer to the measurement.
485 * @param feature ASCIIZ string with the feature's name.
486 * @param utilization Utilization of the feature.
487 *****************************************************************************/
488 void evel_measurement_feature_use_add(EVENT_MEASUREMENT * measurement,
492 MEASUREMENT_FEATURE_USE * feature_use = NULL;
495 /***************************************************************************/
496 /* Check assumptions. */
497 /***************************************************************************/
498 assert(measurement != NULL);
499 assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
500 assert(feature != NULL);
501 assert(utilization >= 0);
503 /***************************************************************************/
504 /* Allocate a container for the value and push onto the list. */
505 /***************************************************************************/
506 EVEL_DEBUG("Adding Feature=%s Use=%d", feature, utilization);
507 feature_use = malloc(sizeof(MEASUREMENT_FEATURE_USE));
508 assert(feature_use != NULL);
509 memset(feature_use, 0, sizeof(MEASUREMENT_FEATURE_USE));
510 feature_use->feature_id = strdup(feature);
511 assert(feature_use->feature_id != NULL);
512 feature_use->feature_utilization = utilization;
514 dlist_push_last(&measurement->feature_usage, feature_use);
519 /**************************************************************************//**
520 * Add a Additional Measurement value name/value pair to the Report.
522 * The name is null delimited ASCII string. The library takes
523 * a copy so the caller does not have to preserve values after the function
526 * @param measurement Pointer to the Measaurement.
527 * @param group ASCIIZ string with the measurement group's name.
528 * @param name ASCIIZ string containing the measurement's name.
529 * @param value ASCIIZ string containing the measurement's value.
530 *****************************************************************************/
531 void evel_measurement_custom_measurement_add(EVENT_MEASUREMENT * measurement,
532 const char * const group,
533 const char * const name,
534 const char * const value)
536 MEASUREMENT_GROUP * measurement_group = NULL;
537 CUSTOM_MEASUREMENT * custom_measurement = NULL;
538 DLIST_ITEM * item = NULL;
541 /***************************************************************************/
542 /* Check assumptions. */
543 /***************************************************************************/
544 assert(measurement != NULL);
545 assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
546 assert(group != NULL);
547 assert(name != NULL);
548 assert(value != NULL);
550 /***************************************************************************/
551 /* Allocate a container for the name/value pair. */
552 /***************************************************************************/
553 EVEL_DEBUG("Adding Measurement Group=%s Name=%s Value=%s",
555 custom_measurement = malloc(sizeof(CUSTOM_MEASUREMENT));
556 assert(custom_measurement != NULL);
557 memset(custom_measurement, 0, sizeof(CUSTOM_MEASUREMENT));
558 custom_measurement->name = strdup(name);
559 assert(custom_measurement->name != NULL);
560 custom_measurement->value = strdup(value);
561 assert(custom_measurement->value != NULL);
563 /***************************************************************************/
564 /* See if we have that group already. */
565 /***************************************************************************/
566 item = dlist_get_first(&measurement->additional_measurements);
569 measurement_group = (MEASUREMENT_GROUP *) item->item;
570 assert(measurement_group != NULL);
572 EVEL_DEBUG("Got measurement group %s", measurement_group->name);
573 if (strcmp(group, measurement_group->name) == 0)
575 EVEL_DEBUG("Found existing Measurement Group");
578 item = dlist_get_next(item);
581 /***************************************************************************/
582 /* If we didn't have the group already, create it. */
583 /***************************************************************************/
586 EVEL_DEBUG("Creating new Measurement Group");
587 measurement_group = malloc(sizeof(MEASUREMENT_GROUP));
588 assert(measurement_group != NULL);
589 memset(measurement_group, 0, sizeof(MEASUREMENT_GROUP));
590 measurement_group->name = strdup(group);
591 assert(measurement_group->name != NULL);
592 dlist_initialize(&measurement_group->measurements);
593 dlist_push_last(&measurement->additional_measurements, measurement_group);
596 /***************************************************************************/
597 /* If we didn't have the group already, create it. */
598 /***************************************************************************/
599 dlist_push_last(&measurement_group->measurements, custom_measurement);
604 /**************************************************************************//**
605 * Add a Codec usage value name/value pair to the Measurement.
607 * The name is null delimited ASCII string. The library takes
608 * a copy so the caller does not have to preserve values after the function
611 * @param measurement Pointer to the measurement.
612 * @param codec ASCIIZ string with the codec's name.
613 * @param utilization Number of codecs in use.
614 *****************************************************************************/
615 void evel_measurement_codec_use_add(EVENT_MEASUREMENT * measurement,
619 MEASUREMENT_CODEC_USE * codec_use = NULL;
622 /***************************************************************************/
623 /* Check assumptions. */
624 /***************************************************************************/
625 assert(measurement != NULL);
626 assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
627 assert(codec != NULL);
628 assert(utilization >= 0.0);
630 /***************************************************************************/
631 /* Allocate a container for the value and push onto the list. */
632 /***************************************************************************/
633 EVEL_DEBUG("Adding Codec=%s Use=%d", codec, utilization);
634 codec_use = malloc(sizeof(MEASUREMENT_CODEC_USE));
635 assert(codec_use != NULL);
636 memset(codec_use, 0, sizeof(MEASUREMENT_CODEC_USE));
637 codec_use->codec_id = strdup(codec);
638 assert(codec_use->codec_id != NULL);
639 codec_use->number_in_use = utilization;
641 dlist_push_last(&measurement->codec_usage, codec_use);
646 /**************************************************************************//**
647 * Set the Aggregate CPU Use property of the Measurement.
649 * @note The property is treated as immutable: it is only valid to call
650 * the setter once. However, we don't assert if the caller tries to
651 * overwrite, just ignoring the update instead.
653 * @param measurement Pointer to the measurement.
654 * @param cpu_use The CPU use to set.
655 *****************************************************************************/
656 void evel_measurement_agg_cpu_use_set(EVENT_MEASUREMENT * measurement,
661 /***************************************************************************/
662 /* Check preconditions. */
663 /***************************************************************************/
664 assert(measurement != NULL);
665 assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
666 assert(cpu_use >= 0.0);
668 evel_set_option_double(&measurement->aggregate_cpu_usage,
674 /**************************************************************************//**
675 * Set the Media Ports in Use property of the Measurement.
677 * @note The property is treated as immutable: it is only valid to call
678 * the setter once. However, we don't assert if the caller tries to
679 * overwrite, just ignoring the update instead.
681 * @param measurement Pointer to the measurement.
682 * @param media_ports_in_use The media port usage to set.
683 *****************************************************************************/
684 void evel_measurement_media_port_use_set(EVENT_MEASUREMENT * measurement,
685 int media_ports_in_use)
689 /***************************************************************************/
690 /* Check preconditions. */
691 /***************************************************************************/
692 assert(measurement != NULL);
693 assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
694 assert(media_ports_in_use >= 0);
696 evel_set_option_int(&measurement->media_ports_in_use,
698 "Media Ports In Use");
702 /**************************************************************************//**
703 * Set the VNFC Scaling Metric property of the Measurement.
705 * @note The property is treated as immutable: it is only valid to call
706 * the setter once. However, we don't assert if the caller tries to
707 * overwrite, just ignoring the update instead.
709 * @param measurement Pointer to the measurement.
710 * @param scaling_metric The scaling metric to set.
711 *****************************************************************************/
712 void evel_measurement_vnfc_scaling_metric_set(EVENT_MEASUREMENT * measurement,
713 double scaling_metric)
717 /***************************************************************************/
718 /* Check preconditions. */
719 /***************************************************************************/
720 assert(measurement != NULL);
721 assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
722 assert(scaling_metric >= 0.0);
724 evel_set_option_double(&measurement->vnfc_scaling_metric,
726 "VNFC Scaling Metric");
730 /**************************************************************************//**
731 * Create a new Latency Bucket to be added to a Measurement event.
733 * @note The mandatory fields on the ::MEASUREMENT_LATENCY_BUCKET must be
734 * supplied to this factory function and are immutable once set.
735 * Optional fields have explicit setter functions, but again values
736 * may only be set once so that the ::MEASUREMENT_LATENCY_BUCKET has
737 * immutable properties.
739 * @param count Count of events in this bucket.
741 * @returns pointer to the newly manufactured ::MEASUREMENT_LATENCY_BUCKET.
742 * If the structure is not used it must be released using free.
743 * @retval NULL Failed to create the Latency Bucket.
744 *****************************************************************************/
745 MEASUREMENT_LATENCY_BUCKET * evel_new_meas_latency_bucket(const int count)
747 MEASUREMENT_LATENCY_BUCKET * bucket;
751 /***************************************************************************/
752 /* Check preconditions. */
753 /***************************************************************************/
756 /***************************************************************************/
757 /* Allocate, then set Mandatory Parameters. */
758 /***************************************************************************/
759 EVEL_DEBUG("Creating bucket, count = %d", count);
760 bucket = malloc(sizeof(MEASUREMENT_LATENCY_BUCKET));
761 assert(bucket != NULL);
763 /***************************************************************************/
764 /* Set Mandatory Parameters. */
765 /***************************************************************************/
766 bucket->count = count;
768 /***************************************************************************/
769 /* Initialize Optional Parameters. */
770 /***************************************************************************/
771 evel_init_option_double(&bucket->high_end);
772 evel_init_option_double(&bucket->low_end);
779 /**************************************************************************//**
780 * Set the High End property of the Measurement Latency Bucket.
782 * @note The property is treated as immutable: it is only valid to call
783 * the setter once. However, we don't assert if the caller tries to
784 * overwrite, just ignoring the update instead.
786 * @param bucket Pointer to the Measurement Latency Bucket.
787 * @param high_end High end of the bucket's range.
788 *****************************************************************************/
789 void evel_meas_latency_bucket_high_end_set(
790 MEASUREMENT_LATENCY_BUCKET * const bucket,
791 const double high_end)
795 /***************************************************************************/
796 /* Check preconditions. */
797 /***************************************************************************/
798 assert(high_end >= 0.0);
799 evel_set_option_double(&bucket->high_end, high_end, "High End");
804 /**************************************************************************//**
805 * Set the Low End property of the Measurement Latency Bucket.
807 * @note The property is treated as immutable: it is only valid to call
808 * the setter once. However, we don't assert if the caller tries to
809 * overwrite, just ignoring the update instead.
811 * @param bucket Pointer to the Measurement Latency Bucket.
812 * @param low_end Low end of the bucket's range.
813 *****************************************************************************/
814 void evel_meas_latency_bucket_low_end_set(
815 MEASUREMENT_LATENCY_BUCKET * const bucket,
816 const double low_end)
820 /***************************************************************************/
821 /* Check preconditions. */
822 /***************************************************************************/
823 assert(low_end >= 0.0);
824 evel_set_option_double(&bucket->low_end, low_end, "Low End");
828 /**************************************************************************//**
829 * Add an additional Measurement Latency Bucket to the specified event.
831 * @param measurement Pointer to the Measurement event.
832 * @param bucket Pointer to the Measurement Latency Bucket to add.
833 *****************************************************************************/
834 void evel_meas_latency_bucket_add(EVENT_MEASUREMENT * const measurement,
835 MEASUREMENT_LATENCY_BUCKET * const bucket)
839 /***************************************************************************/
840 /* Check preconditions. */
841 /***************************************************************************/
842 assert(measurement != NULL);
843 assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
844 assert(bucket != NULL);
845 dlist_push_last(&measurement->latency_distribution, bucket);
850 /**************************************************************************//**
851 * Add an additional Latency Distribution bucket to the Measurement.
853 * This function implements the previous API, purely for convenience.
855 * @param measurement Pointer to the measurement.
856 * @param low_end Low end of the bucket's range.
857 * @param high_end High end of the bucket's range.
858 * @param count Count of events in this bucket.
859 *****************************************************************************/
860 void evel_measurement_latency_add(EVENT_MEASUREMENT * const measurement,
861 const double low_end,
862 const double high_end,
865 MEASUREMENT_LATENCY_BUCKET * bucket = NULL;
869 /***************************************************************************/
870 /* Trust the assertions in the underlying methods. */
871 /***************************************************************************/
872 bucket = evel_new_meas_latency_bucket(count);
873 evel_meas_latency_bucket_low_end_set(bucket, low_end);
874 evel_meas_latency_bucket_high_end_set(bucket, high_end);
875 evel_meas_latency_bucket_add(measurement, bucket);
880 /**************************************************************************//**
881 * Create a new vNIC Use to be added to a Measurement event.
883 * @note The mandatory fields on the ::MEASUREMENT_VNIC_USE must be supplied
884 * to this factory function and are immutable once set. Optional
885 * fields have explicit setter functions, but again values may only be
886 * set once so that the ::MEASUREMENT_VNIC_USE has immutable
889 * @param vnic_id ASCIIZ string with the vNIC's ID.
890 * @param packets_in Total packets received.
891 * @param packets_out Total packets transmitted.
892 * @param bytes_in Total bytes received.
893 * @param bytes_out Total bytes transmitted.
895 * @returns pointer to the newly manufactured ::MEASUREMENT_VNIC_USE.
896 * If the structure is not used it must be released using
897 * ::evel_free_measurement_vnic_use.
898 * @retval NULL Failed to create the vNIC Use.
899 *****************************************************************************/
900 MEASUREMENT_VNIC_USE * evel_new_measurement_vnic_use(char * const vnic_id,
901 const int packets_in,
902 const int packets_out,
906 MEASUREMENT_VNIC_USE * vnic_use;
910 /***************************************************************************/
911 /* Check preconditions. */
912 /***************************************************************************/
913 assert(vnic_id != NULL);
914 assert(packets_in >= 0);
915 assert(packets_out >= 0);
916 assert(bytes_in >= 0);
917 assert(bytes_out >= 0);
919 /***************************************************************************/
920 /* Allocate, then set Mandatory Parameters. */
921 /***************************************************************************/
922 EVEL_DEBUG("Adding VNIC ID=%s", vnic_id);
923 vnic_use = malloc(sizeof(MEASUREMENT_VNIC_USE));
924 assert(vnic_use != NULL);
925 vnic_use->vnic_id = strdup(vnic_id);
926 vnic_use->packets_in = packets_in;
927 vnic_use->packets_out = packets_out;
928 vnic_use->bytes_in = bytes_in;
929 vnic_use->bytes_out = bytes_out;
931 /***************************************************************************/
932 /* Initialize Optional Parameters. */
933 /***************************************************************************/
934 evel_init_option_int(&vnic_use->broadcast_packets_in);
935 evel_init_option_int(&vnic_use->broadcast_packets_out);
936 evel_init_option_int(&vnic_use->multicast_packets_in);
937 evel_init_option_int(&vnic_use->multicast_packets_out);
938 evel_init_option_int(&vnic_use->unicast_packets_in);
939 evel_init_option_int(&vnic_use->unicast_packets_out);
946 /**************************************************************************//**
949 * Free off the ::MEASUREMENT_VNIC_USE supplied. Will free all the contained
952 * @note It does not free the vNIC Use itself, since that may be part of a
954 *****************************************************************************/
955 void evel_free_measurement_vnic_use(MEASUREMENT_VNIC_USE * const vnic_use)
959 /***************************************************************************/
960 /* Check preconditions. */
961 /***************************************************************************/
962 assert(vnic_use != NULL);
963 assert(vnic_use->vnic_id != NULL);
965 /***************************************************************************/
966 /* Free the duplicated string. */
967 /***************************************************************************/
968 free(vnic_use->vnic_id);
969 vnic_use->vnic_id = NULL;
974 /**************************************************************************//**
975 * Set the Broadcast Packets Received property of the vNIC Use.
977 * @note The property is treated as immutable: it is only valid to call
978 * the setter once. However, we don't assert if the caller tries to
979 * overwrite, just ignoring the update instead.
981 * @param vnic_use Pointer to the vNIC Use.
982 * @param broadcast_packets_in
983 * Broadcast packets received.
984 *****************************************************************************/
985 void evel_vnic_use_bcast_pkt_in_set(MEASUREMENT_VNIC_USE * const vnic_use,
986 const int broadcast_packets_in)
990 /***************************************************************************/
991 /* Check preconditions. */
992 /***************************************************************************/
993 assert(broadcast_packets_in >= 0);
995 evel_set_option_int(&vnic_use->broadcast_packets_in,
996 broadcast_packets_in,
997 "Broadcast Packets Received");
1002 /**************************************************************************//**
1003 * Set the Broadcast Packets Transmitted property of the vNIC Use.
1005 * @note The property is treated as immutable: it is only valid to call
1006 * the setter once. However, we don't assert if the caller tries to
1007 * overwrite, just ignoring the update instead.
1009 * @param vnic_use Pointer to the vNIC Use.
1010 * @param broadcast_packets_out
1011 * Broadcast packets transmitted.
1012 *****************************************************************************/
1013 void evel_vnic_use_bcast_pkt_out_set(MEASUREMENT_VNIC_USE * const vnic_use,
1014 const int broadcast_packets_out)
1018 /***************************************************************************/
1019 /* Check preconditions. */
1020 /***************************************************************************/
1021 assert(broadcast_packets_out >= 0);
1023 evel_set_option_int(&vnic_use->broadcast_packets_out,
1024 broadcast_packets_out,
1025 "Broadcast Packets Transmitted");
1030 /**************************************************************************//**
1031 * Set the Multicast Packets Received property of the vNIC Use.
1033 * @note The property is treated as immutable: it is only valid to call
1034 * the setter once. However, we don't assert if the caller tries to
1035 * overwrite, just ignoring the update instead.
1037 * @param vnic_use Pointer to the vNIC Use.
1038 * @param multicast_packets_in
1039 * Multicast packets received.
1040 *****************************************************************************/
1041 void evel_vnic_use_mcast_pkt_in_set(MEASUREMENT_VNIC_USE * const vnic_use,
1042 const int multicast_packets_in)
1046 /***************************************************************************/
1047 /* Check preconditions. */
1048 /***************************************************************************/
1049 assert(multicast_packets_in >= 0);
1051 evel_set_option_int(&vnic_use->multicast_packets_in,
1052 multicast_packets_in,
1053 "Multicast Packets Received");
1058 /**************************************************************************//**
1059 * Set the Multicast Packets Transmitted property of the vNIC Use.
1061 * @note The property is treated as immutable: it is only valid to call
1062 * the setter once. However, we don't assert if the caller tries to
1063 * overwrite, just ignoring the update instead.
1065 * @param vnic_use Pointer to the vNIC Use.
1066 * @param multicast_packets_out
1067 * Multicast packets transmitted.
1068 *****************************************************************************/
1069 void evel_vnic_use_mcast_pkt_out_set(MEASUREMENT_VNIC_USE * const vnic_use,
1070 const int multicast_packets_out)
1074 /***************************************************************************/
1075 /* Check preconditions. */
1076 /***************************************************************************/
1077 assert(multicast_packets_out >= 0);
1079 evel_set_option_int(&vnic_use->multicast_packets_out,
1080 multicast_packets_out,
1081 "Multicast Packets Transmitted");
1086 /**************************************************************************//**
1087 * Set the Unicast Packets Received property of the vNIC Use.
1089 * @note The property is treated as immutable: it is only valid to call
1090 * the setter once. However, we don't assert if the caller tries to
1091 * overwrite, just ignoring the update instead.
1093 * @param vnic_use Pointer to the vNIC Use.
1094 * @param unicast_packets_in
1095 * Unicast packets received.
1096 *****************************************************************************/
1097 void evel_vnic_use_ucast_pkt_in_set(MEASUREMENT_VNIC_USE * const vnic_use,
1098 const int unicast_packets_in)
1102 /***************************************************************************/
1103 /* Check preconditions. */
1104 /***************************************************************************/
1105 assert(unicast_packets_in >= 0);
1107 evel_set_option_int(&vnic_use->unicast_packets_in,
1109 "Unicast Packets Received");
1114 /**************************************************************************//**
1115 * Set the Unicast Packets Transmitted property of the vNIC Use.
1117 * @note The property is treated as immutable: it is only valid to call
1118 * the setter once. However, we don't assert if the caller tries to
1119 * overwrite, just ignoring the update instead.
1121 * @param vnic_use Pointer to the vNIC Use.
1122 * @param unicast_packets_out
1123 * Unicast packets transmitted.
1124 *****************************************************************************/
1125 void evel_vnic_use_ucast_pkt_out_set(MEASUREMENT_VNIC_USE * const vnic_use,
1126 const int unicast_packets_out)
1130 /***************************************************************************/
1131 /* Check preconditions. */
1132 /***************************************************************************/
1133 assert(unicast_packets_out >= 0);
1135 evel_set_option_int(&vnic_use->unicast_packets_out,
1136 unicast_packets_out,
1137 "Unicast Packets Transmitted");
1142 /**************************************************************************//**
1143 * Add an additional vNIC Use to the specified Measurement event.
1145 * @param measurement Pointer to the measurement.
1146 * @param vnic_use Pointer to the vNIC Use to add.
1147 *****************************************************************************/
1148 void evel_meas_vnic_use_add(EVENT_MEASUREMENT * const measurement,
1149 MEASUREMENT_VNIC_USE * const vnic_use)
1153 /***************************************************************************/
1154 /* Check preconditions. */
1155 /***************************************************************************/
1156 assert(measurement != NULL);
1157 assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
1158 assert(vnic_use != NULL);
1160 dlist_push_last(&measurement->vnic_usage, vnic_use);
1165 /**************************************************************************//**
1166 * Add an additional vNIC usage record Measurement.
1168 * This function implements the previous API, purely for convenience.
1170 * The ID is null delimited ASCII string. The library takes a copy so the
1171 * caller does not have to preserve values after the function returns.
1173 * @param measurement Pointer to the measurement.
1174 * @param vnic_id ASCIIZ string with the vNIC's ID.
1175 * @param packets_in Total packets received.
1176 * @param packets_out Total packets transmitted.
1177 * @param broadcast_packets_in Broadcast packets received.
1178 * @param broadcast_packets_out Broadcast packets transmitted.
1179 * @param bytes_in Total bytes received.
1180 * @param bytes_out Total bytes transmitted.
1181 * @param multicast_packets_in Multicast packets received.
1182 * @param multicast_packets_out Multicast packets transmitted.
1183 * @param unicast_packets_in Unicast packets received.
1184 * @param unicast_packets_out Unicast packets transmitted.
1185 *****************************************************************************/
1186 void evel_measurement_vnic_use_add(EVENT_MEASUREMENT * const measurement,
1187 char * const vnic_id,
1188 const int packets_in,
1189 const int packets_out,
1190 const int broadcast_packets_in,
1191 const int broadcast_packets_out,
1193 const int bytes_out,
1194 const int multicast_packets_in,
1195 const int multicast_packets_out,
1196 const int unicast_packets_in,
1197 const int unicast_packets_out)
1199 MEASUREMENT_VNIC_USE * vnic_use = NULL;
1202 /***************************************************************************/
1203 /* Trust the assertions in the underlying methods. */
1204 /***************************************************************************/
1205 vnic_use = evel_new_measurement_vnic_use(vnic_id,
1210 evel_vnic_use_bcast_pkt_in_set(vnic_use, broadcast_packets_in);
1211 evel_vnic_use_bcast_pkt_out_set(vnic_use, broadcast_packets_out);
1212 evel_vnic_use_mcast_pkt_in_set(vnic_use, multicast_packets_in);
1213 evel_vnic_use_mcast_pkt_out_set(vnic_use, multicast_packets_out);
1214 evel_vnic_use_ucast_pkt_in_set(vnic_use, unicast_packets_in);
1215 evel_vnic_use_ucast_pkt_out_set(vnic_use, unicast_packets_out);
1216 evel_meas_vnic_use_add(measurement, vnic_use);
1219 /**************************************************************************//**
1220 * Encode the measurement as a JSON measurement.
1222 * @param jbuf Pointer to the ::EVEL_JSON_BUFFER to encode into.
1223 * @param event Pointer to the ::EVENT_HEADER to encode.
1224 *****************************************************************************/
1225 void evel_json_encode_measurement(EVEL_JSON_BUFFER * jbuf,
1226 EVENT_MEASUREMENT * event)
1228 MEASUREMENT_CPU_USE * cpu_use = NULL;
1229 MEASUREMENT_FSYS_USE * fsys_use = NULL;
1230 MEASUREMENT_LATENCY_BUCKET * bucket = NULL;
1231 MEASUREMENT_VNIC_USE * vnic_use = NULL;
1232 MEASUREMENT_ERRORS * errors = NULL;
1233 MEASUREMENT_FEATURE_USE * feature_use = NULL;
1234 MEASUREMENT_CODEC_USE * codec_use = NULL;
1235 MEASUREMENT_GROUP * measurement_group = NULL;
1236 CUSTOM_MEASUREMENT * custom_measurement = NULL;
1237 DLIST_ITEM * item = NULL;
1238 DLIST_ITEM * nested_item = NULL;
1242 /***************************************************************************/
1243 /* Check preconditions. */
1244 /***************************************************************************/
1245 assert(event != NULL);
1246 assert(event->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
1248 evel_json_encode_header(jbuf, &event->header);
1249 evel_json_open_named_object(jbuf, "measurementsForVfScalingFields");
1251 /***************************************************************************/
1252 /* Mandatory fields. */
1253 /***************************************************************************/
1254 evel_enc_kv_double(jbuf, "measurementInterval", event->measurement_interval);
1256 /***************************************************************************/
1257 /* Optional fields. */
1258 /***************************************************************************/
1259 evel_enc_kv_opt_int(jbuf, "concurrentSessions", &event->concurrent_sessions);
1260 evel_enc_kv_opt_int(jbuf, "configuredEntities", &event->configured_entities);
1262 /***************************************************************************/
1264 /***************************************************************************/
1265 evel_json_checkpoint(jbuf);
1266 if (evel_json_open_opt_named_list(jbuf, "cpuUsageArray"))
1268 bool item_added = false;
1270 item = dlist_get_first(&event->cpu_usage);
1271 while (item != NULL)
1273 cpu_use = (MEASUREMENT_CPU_USE*) item->item;
1274 assert(cpu_use != NULL);
1276 if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
1280 evel_json_open_object(jbuf);
1281 evel_enc_kv_string(jbuf, "cpuIdentifier", cpu_use->id);
1282 evel_enc_kv_double(jbuf, "percentUsage", cpu_use->usage);
1283 evel_json_close_object(jbuf);
1286 item = dlist_get_next(item);
1288 evel_json_close_list(jbuf);
1290 /*************************************************************************/
1291 /* If we've not written anything, rewind to before we opened the list. */
1292 /*************************************************************************/
1295 evel_json_rewind(jbuf);
1299 /***************************************************************************/
1300 /* Filesystem Usage list. */
1301 /***************************************************************************/
1302 evel_json_checkpoint(jbuf);
1303 if (evel_json_open_opt_named_list(jbuf, "filesystemUsageArray"))
1305 bool item_added = false;
1307 item = dlist_get_first(&event->filesystem_usage);
1308 while (item != NULL)
1310 fsys_use = (MEASUREMENT_FSYS_USE *) item->item;
1311 assert(fsys_use != NULL);
1313 if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
1314 "filesystemUsageArray",
1315 fsys_use->filesystem_name))
1317 evel_json_open_object(jbuf);
1319 jbuf, "blockConfigured", fsys_use->block_configured);
1320 evel_enc_kv_int(jbuf, "blockIops", fsys_use->block_iops);
1321 evel_enc_kv_double(jbuf, "blockUsed", fsys_use->block_used);
1323 jbuf, "ephemeralConfigured", fsys_use->ephemeral_configured);
1324 evel_enc_kv_int(jbuf, "ephemeralIops", fsys_use->ephemeral_iops);
1325 evel_enc_kv_double(jbuf, "ephemeralUsed", fsys_use->ephemeral_used);
1326 evel_enc_kv_string(jbuf, "filesystemName", fsys_use->filesystem_name);
1327 evel_json_close_object(jbuf);
1330 item = dlist_get_next(item);
1332 evel_json_close_list(jbuf);
1334 /*************************************************************************/
1335 /* If we've not written anything, rewind to before we opened the list. */
1336 /*************************************************************************/
1339 evel_json_rewind(jbuf);
1343 /***************************************************************************/
1344 /* Latency distribution. */
1345 /***************************************************************************/
1346 item = dlist_get_first(&event->latency_distribution);
1347 if ((item != NULL) &&
1348 evel_json_open_opt_named_list(jbuf, "latencyDistribution"))
1350 while (item != NULL)
1352 bucket = (MEASUREMENT_LATENCY_BUCKET*) item->item;
1353 assert(bucket != NULL);
1355 evel_json_open_object(jbuf);
1356 evel_enc_kv_opt_double(
1357 jbuf, "lowEndOfLatencyBucket", &bucket->low_end);
1358 evel_enc_kv_opt_double(
1359 jbuf, "highEndOfLatencyBucket", &bucket->high_end);
1360 evel_enc_kv_int(jbuf, "countsInTheBucket", bucket->count);
1361 evel_json_close_object(jbuf);
1362 item = dlist_get_next(item);
1364 evel_json_close_list(jbuf);
1367 evel_enc_kv_opt_double(
1368 jbuf, "meanRequestLatency", &event->mean_request_latency);
1369 evel_enc_kv_opt_double(jbuf, "memoryConfigured", &event->memory_configured);
1370 evel_enc_kv_opt_double(jbuf, "memoryUsed", &event->memory_used);
1371 evel_enc_kv_opt_int(jbuf, "requestRate", &event->request_rate);
1373 /***************************************************************************/
1375 /***************************************************************************/
1376 evel_json_checkpoint(jbuf);
1377 if (evel_json_open_opt_named_list(jbuf, "vNicUsageArray"))
1379 bool item_added = false;
1381 item = dlist_get_first(&event->vnic_usage);
1382 while (item != NULL)
1384 vnic_use = (MEASUREMENT_VNIC_USE *) item->item;
1385 assert(vnic_use != NULL);
1387 if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
1391 evel_json_open_object(jbuf);
1393 /*********************************************************************/
1394 /* Mandatory fields. */
1395 /*********************************************************************/
1396 evel_enc_kv_int(jbuf, "bytesIn", vnic_use->bytes_in);
1397 evel_enc_kv_int(jbuf, "bytesOut", vnic_use->bytes_out);
1398 evel_enc_kv_int(jbuf, "packetsIn", vnic_use->packets_in);
1399 evel_enc_kv_int(jbuf, "packetsOut", vnic_use->packets_out);
1400 evel_enc_kv_string(jbuf, "vNicIdentifier", vnic_use->vnic_id);
1402 /*********************************************************************/
1403 /* Optional fields. */
1404 /*********************************************************************/
1405 evel_enc_kv_opt_int(
1406 jbuf, "broadcastPacketsIn", &vnic_use->broadcast_packets_in);
1407 evel_enc_kv_opt_int(
1408 jbuf, "broadcastPacketsOut", &vnic_use->broadcast_packets_out);
1409 evel_enc_kv_opt_int(
1410 jbuf, "multicastPacketsIn", &vnic_use->multicast_packets_in);
1411 evel_enc_kv_opt_int(
1412 jbuf, "multicastPacketsOut", &vnic_use->multicast_packets_out);
1413 evel_enc_kv_opt_int(
1414 jbuf, "unicastPacketsIn", &vnic_use->unicast_packets_in);
1415 evel_enc_kv_opt_int(
1416 jbuf, "unicastPacketsOut", &vnic_use->unicast_packets_out);
1418 evel_json_close_object(jbuf);
1421 item = dlist_get_next(item);
1424 evel_json_close_list(jbuf);
1426 /*************************************************************************/
1427 /* If we've not written anything, rewind to before we opened the list. */
1428 /*************************************************************************/
1431 evel_json_rewind(jbuf);
1435 evel_enc_kv_opt_double(
1436 jbuf, "aggregateCpuUsage", &event->aggregate_cpu_usage);
1437 evel_enc_kv_opt_int(
1438 jbuf, "numberOfMediaPortsInUse", &event->media_ports_in_use);
1439 evel_enc_kv_opt_double(
1440 jbuf, "vnfcScalingMetric", &event->vnfc_scaling_metric);
1442 /***************************************************************************/
1444 /***************************************************************************/
1445 if ((event->errors != NULL) &&
1446 evel_json_open_opt_named_object(jbuf, "errors"))
1448 errors = event->errors;
1449 evel_enc_kv_int(jbuf, "receiveDiscards", errors->receive_discards);
1450 evel_enc_kv_int(jbuf, "receiveErrors", errors->receive_errors);
1451 evel_enc_kv_int(jbuf, "transmitDiscards", errors->transmit_discards);
1452 evel_enc_kv_int(jbuf, "transmitErrors", errors->transmit_errors);
1453 evel_json_close_object(jbuf);
1456 /***************************************************************************/
1457 /* Feature Utilization list. */
1458 /***************************************************************************/
1459 evel_json_checkpoint(jbuf);
1460 if (evel_json_open_opt_named_list(jbuf, "featureUsageArray"))
1462 bool item_added = false;
1464 item = dlist_get_first(&event->feature_usage);
1465 while (item != NULL)
1467 feature_use = (MEASUREMENT_FEATURE_USE*) item->item;
1468 assert(feature_use != NULL);
1470 if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
1471 "featureUsageArray",
1472 feature_use->feature_id))
1474 evel_json_open_object(jbuf);
1475 evel_enc_kv_string(jbuf, "featureIdentifier", feature_use->feature_id);
1477 jbuf, "featureUtilization", feature_use->feature_utilization);
1478 evel_json_close_object(jbuf);
1481 item = dlist_get_next(item);
1483 evel_json_close_list(jbuf);
1485 /*************************************************************************/
1486 /* If we've not written anything, rewind to before we opened the list. */
1487 /*************************************************************************/
1490 evel_json_rewind(jbuf);
1494 /***************************************************************************/
1495 /* Codec Utilization list. */
1496 /***************************************************************************/
1497 evel_json_checkpoint(jbuf);
1498 if (evel_json_open_opt_named_list(jbuf, "codecUsageArray"))
1500 bool item_added = false;
1502 item = dlist_get_first(&event->codec_usage);
1503 while (item != NULL)
1505 codec_use = (MEASUREMENT_CODEC_USE*) item->item;
1506 assert(codec_use != NULL);
1508 if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
1510 codec_use->codec_id))
1512 evel_json_open_object(jbuf);
1513 evel_enc_kv_string(jbuf, "codecIdentifier", codec_use->codec_id);
1514 evel_enc_kv_int(jbuf, "numberInUse", codec_use->number_in_use);
1515 evel_json_close_object(jbuf);
1518 item = dlist_get_next(item);
1520 evel_json_close_list(jbuf);
1522 /*************************************************************************/
1523 /* If we've not written anything, rewind to before we opened the list. */
1524 /*************************************************************************/
1527 evel_json_rewind(jbuf);
1531 /***************************************************************************/
1532 /* Additional Measurement Groups list. */
1533 /***************************************************************************/
1534 evel_json_checkpoint(jbuf);
1535 if (evel_json_open_opt_named_list(jbuf, "additionalMeasurements"))
1537 bool item_added = false;
1539 item = dlist_get_first(&event->additional_measurements);
1540 while (item != NULL)
1542 measurement_group = (MEASUREMENT_GROUP *) item->item;
1543 assert(measurement_group != NULL);
1545 if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
1546 "additionalMeasurements",
1547 measurement_group->name))
1549 evel_json_open_object(jbuf);
1550 evel_enc_kv_string(jbuf, "name", measurement_group->name);
1551 evel_json_open_opt_named_list(jbuf, "measurements");
1553 /*********************************************************************/
1554 /* Measurements list. */
1555 /*********************************************************************/
1556 nested_item = dlist_get_first(&measurement_group->measurements);
1557 while (nested_item != NULL)
1559 custom_measurement = (CUSTOM_MEASUREMENT *) nested_item->item;
1560 assert(custom_measurement != NULL);
1562 evel_json_open_object(jbuf);
1563 evel_enc_kv_string(jbuf, "name", custom_measurement->name);
1564 evel_enc_kv_string(jbuf, "value", custom_measurement->value);
1565 evel_json_close_object(jbuf);
1566 nested_item = dlist_get_next(nested_item);
1568 evel_json_close_list(jbuf);
1569 evel_json_close_object(jbuf);
1572 item = dlist_get_next(item);
1574 evel_json_close_list(jbuf);
1576 /*************************************************************************/
1577 /* If we've not written anything, rewind to before we opened the list. */
1578 /*************************************************************************/
1581 evel_json_rewind(jbuf);
1585 /***************************************************************************/
1586 /* Although optional, we always generate the version. Note that this */
1587 /* closes the object, too. */
1588 /***************************************************************************/
1589 evel_enc_version(jbuf,
1590 "measurementsForVfScalingVersion",
1591 event->major_version,
1592 event->major_version);
1593 evel_json_close_object(jbuf);
1598 /**************************************************************************//**
1599 * Free a Measurement.
1601 * Free off the Measurement supplied. Will free all the contained allocated
1604 * @note It does not free the Measurement itself, since that may be part of a
1606 *****************************************************************************/
1607 void evel_free_measurement(EVENT_MEASUREMENT * event)
1609 MEASUREMENT_CPU_USE * cpu_use = NULL;
1610 MEASUREMENT_FSYS_USE * fsys_use = NULL;
1611 MEASUREMENT_LATENCY_BUCKET * bucket = NULL;
1612 MEASUREMENT_VNIC_USE * vnic_use = NULL;
1613 MEASUREMENT_FEATURE_USE * feature_use = NULL;
1614 MEASUREMENT_CODEC_USE * codec_use = NULL;
1615 MEASUREMENT_GROUP * measurement_group = NULL;
1616 CUSTOM_MEASUREMENT * measurement = NULL;
1620 /***************************************************************************/
1621 /* Check preconditions. As an internal API we don't allow freeing NULL */
1622 /* events as we do on the public API. */
1623 /***************************************************************************/
1624 assert(event != NULL);
1625 assert(event->header.event_domain == EVEL_DOMAIN_MEASUREMENT);
1627 /***************************************************************************/
1628 /* Free all internal strings then the header itself. */
1629 /***************************************************************************/
1630 cpu_use = dlist_pop_last(&event->cpu_usage);
1631 while (cpu_use != NULL)
1633 EVEL_DEBUG("Freeing CPU use Info (%s)", cpu_use->id);
1636 cpu_use = dlist_pop_last(&event->cpu_usage);
1639 fsys_use = dlist_pop_last(&event->filesystem_usage);
1640 while (fsys_use != NULL)
1642 EVEL_DEBUG("Freeing Filesystem Use info (%s)", fsys_use->filesystem_name);
1643 free(fsys_use->filesystem_name);
1645 fsys_use = dlist_pop_last(&event->filesystem_usage);
1648 bucket = dlist_pop_last(&event->latency_distribution);
1649 while (bucket != NULL)
1651 EVEL_DEBUG("Freeing Latency Bucket");
1653 bucket = dlist_pop_last(&event->latency_distribution);
1656 vnic_use = dlist_pop_last(&event->vnic_usage);
1657 while (vnic_use != NULL)
1659 EVEL_DEBUG("Freeing vNIC use Info (%s)", vnic_use->vnic_id);
1660 evel_free_measurement_vnic_use(vnic_use);
1662 vnic_use = dlist_pop_last(&event->vnic_usage);
1665 codec_use = dlist_pop_last(&event->codec_usage);
1666 while (codec_use != NULL)
1668 EVEL_DEBUG("Freeing Codec use Info (%s)", codec_use->codec_id);
1669 free(codec_use->codec_id);
1671 codec_use = dlist_pop_last(&event->codec_usage);
1674 if (event->errors != NULL)
1676 EVEL_DEBUG("Freeing Errors");
1677 free(event->errors);
1680 feature_use = dlist_pop_last(&event->feature_usage);
1681 while (feature_use != NULL)
1683 EVEL_DEBUG("Freeing Feature use Info (%s)", feature_use->feature_id);
1684 free(feature_use->feature_id);
1686 feature_use = dlist_pop_last(&event->feature_usage);
1689 measurement_group = dlist_pop_last(&event->additional_measurements);
1690 while (measurement_group != NULL)
1692 EVEL_DEBUG("Freeing Measurement Group (%s)", measurement_group->name);
1694 measurement = dlist_pop_last(&measurement_group->measurements);
1695 while (measurement != NULL)
1697 EVEL_DEBUG("Freeing Measurement (%s)", measurement->name);
1698 free(measurement->name);
1699 free(measurement->value);
1701 measurement = dlist_pop_last(&measurement_group->measurements);
1703 free(measurement_group->name);
1704 free(measurement_group);
1705 measurement_group = dlist_pop_last(&event->additional_measurements);
1708 evel_free_header(&event->header);