AT&T ECOMP Vendor Event Listener library  0.1
evel_reporting_measurement.c
Go to the documentation of this file.
1 /**************************************************************************/
44 #include <string.h>
45 #include <assert.h>
46 #include <stdlib.h>
47 
48 #include "evel.h"
49 #include "evel_internal.h"
50 #include "evel_throttle.h"
51 
52 /**************************************************************************/
66 EVENT_REPORT * evel_new_report(double measurement_interval)
67 {
68  EVENT_REPORT * report = NULL;
69 
70  EVEL_ENTER();
71 
72  /***************************************************************************/
73  /* Check preconditions. */
74  /***************************************************************************/
75  assert(measurement_interval >= 0.0);
76 
77  /***************************************************************************/
78  /* Allocate the report. */
79  /***************************************************************************/
80  report = malloc(sizeof(EVENT_REPORT));
81  if (report == NULL)
82  {
83  log_error_state("Out of memory for Report");
84  goto exit_label;
85  }
86  memset(report, 0, sizeof(EVENT_REPORT));
87  EVEL_DEBUG("New report is at %lp", report);
88 
89  /***************************************************************************/
90  /* Initialize the header & the report fields. */
91  /***************************************************************************/
92  evel_init_header(&report->header);
94  report->measurement_interval = measurement_interval;
95 
100 
101 exit_label:
102  EVEL_EXIT();
103  return report;
104 }
105 
106 /**************************************************************************/
119  const char * const type)
120 {
121  EVEL_ENTER();
122 
123  /***************************************************************************/
124  /* Check preconditions and call evel_header_type_set. */
125  /***************************************************************************/
126  assert(report != NULL);
127  assert(report->header.event_domain == EVEL_DOMAIN_REPORT);
128  evel_header_type_set(&report->header, type);
129 
130  EVEL_EXIT();
131 }
132 
133 /**************************************************************************/
145  char * feature,
146  int utilization)
147 {
148  MEASUREMENT_FEATURE_USE * feature_use = NULL;
149  EVEL_ENTER();
150 
151  /***************************************************************************/
152  /* Check assumptions. */
153  /***************************************************************************/
154  assert(report != NULL);
155  assert(report->header.event_domain == EVEL_DOMAIN_REPORT);
156  assert(feature != NULL);
157  assert(utilization >= 0);
158 
159  /***************************************************************************/
160  /* Allocate a container for the value and push onto the list. */
161  /***************************************************************************/
162  EVEL_DEBUG("Adding Feature=%s Use=%d", feature, utilization);
163  feature_use = malloc(sizeof(MEASUREMENT_FEATURE_USE));
164  assert(feature_use != NULL);
165  memset(feature_use, 0, sizeof(MEASUREMENT_FEATURE_USE));
166  feature_use->feature_id = strdup(feature);
167  assert(feature_use->feature_id != NULL);
168  feature_use->feature_utilization = utilization;
169 
170  dlist_push_last(&report->feature_usage, feature_use);
171 
172  EVEL_EXIT();
173 }
174 
175 /**************************************************************************/
188  const char * const group,
189  const char * const name,
190  const char * const value)
191 {
193  CUSTOM_MEASUREMENT * measurement = NULL;
194  DLIST_ITEM * item = NULL;
195  EVEL_ENTER();
196 
197  /***************************************************************************/
198  /* Check assumptions. */
199  /***************************************************************************/
200  assert(report != NULL);
201  assert(report->header.event_domain == EVEL_DOMAIN_REPORT);
202  assert(group != NULL);
203  assert(name != NULL);
204  assert(value != NULL);
205 
206  /***************************************************************************/
207  /* Allocate a container for the name/value pair. */
208  /***************************************************************************/
209  EVEL_DEBUG("Adding Measurement Group=%s Name=%s Value=%s",
210  group, name, value);
211  measurement = malloc(sizeof(CUSTOM_MEASUREMENT));
212  assert(measurement != NULL);
213  memset(measurement, 0, sizeof(CUSTOM_MEASUREMENT));
214  measurement->name = strdup(name);
215  assert(measurement->name != NULL);
216  measurement->value = strdup(value);
217  assert(measurement->value != NULL);
218 
219  /***************************************************************************/
220  /* See if we have that group already. */
221  /***************************************************************************/
222  item = dlist_get_first(&report->measurement_groups);
223  while (item != NULL)
224  {
225  measurement_group = (MEASUREMENT_GROUP *) item->item;
226  assert(measurement_group != NULL);
227 
228  EVEL_DEBUG("Got measurement group %s", measurement_group->name);
229  if (strcmp(group, measurement_group->name) == 0)
230  {
231  EVEL_DEBUG("Found existing Measurement Group");
232  break;
233  }
234  item = dlist_get_next(item);
235  }
236 
237  /***************************************************************************/
238  /* If we didn't have the group already, create it. */
239  /***************************************************************************/
240  if (item == NULL)
241  {
242  EVEL_DEBUG("Creating new Measurement Group");
243  measurement_group = malloc(sizeof(MEASUREMENT_GROUP));
244  assert(measurement_group != NULL);
245  memset(measurement_group, 0, sizeof(MEASUREMENT_GROUP));
246  measurement_group->name = strdup(group);
247  assert(measurement_group->name != NULL);
248  dlist_initialize(&measurement_group->measurements);
249  dlist_push_last(&report->measurement_groups, measurement_group);
250  }
251 
252  /***************************************************************************/
253  /* If we didn't have the group already, create it. */
254  /***************************************************************************/
255  dlist_push_last(&measurement_group->measurements, measurement);
256 
257  EVEL_EXIT();
258 }
259 
260 /**************************************************************************/
267  EVENT_REPORT * event)
268 {
269  MEASUREMENT_FEATURE_USE * feature_use = NULL;
272  DLIST_ITEM * item = NULL;
273  DLIST_ITEM * nested_item = NULL;
274 
275  EVEL_ENTER();
276 
277  /***************************************************************************/
278  /* Check preconditions. */
279  /***************************************************************************/
280  assert(event != NULL);
281  assert(event->header.event_domain == EVEL_DOMAIN_REPORT);
282 
283  evel_json_encode_header(jbuf, &event->header);
284  evel_json_open_named_object(jbuf, "measurementsForVfReportingFields");
285  evel_enc_kv_double(jbuf, "measurementInterval", event->measurement_interval);
286 
287  /***************************************************************************/
288  /* Feature Utilization list. */
289  /***************************************************************************/
290  evel_json_checkpoint(jbuf);
291  if (evel_json_open_opt_named_list(jbuf, "featureUsageArray"))
292  {
293  bool item_added = false;
294 
295  item = dlist_get_first(&event->feature_usage);
296  while (item != NULL)
297  {
298  feature_use = (MEASUREMENT_FEATURE_USE*) item->item;
299  assert(feature_use != NULL);
300 
302  "featureUsageArray",
303  feature_use->feature_id))
304  {
305  evel_json_open_object(jbuf);
306  evel_enc_kv_string(jbuf, "featureIdentifier", feature_use->feature_id);
308  jbuf, "featureUtilization", feature_use->feature_utilization);
310  item_added = true;
311  }
312  item = dlist_get_next(item);
313  }
314  evel_json_close_list(jbuf);
315 
316  /*************************************************************************/
317  /* If we've not written anything, rewind to before we opened the list. */
318  /*************************************************************************/
319  if (!item_added)
320  {
321  evel_json_rewind(jbuf);
322  }
323  }
324 
325  /***************************************************************************/
326  /* Additional Measurement Groups list. */
327  /***************************************************************************/
328  evel_json_checkpoint(jbuf);
329  if (evel_json_open_opt_named_list(jbuf, "additionalMeasurements"))
330  {
331  bool item_added = false;
332 
333  item = dlist_get_first(&event->measurement_groups);
334  while (item != NULL)
335  {
336  measurement_group = (MEASUREMENT_GROUP *) item->item;
337  assert(measurement_group != NULL);
338 
340  "additionalMeasurements",
341  measurement_group->name))
342  {
343  evel_json_open_object(jbuf);
344  evel_enc_kv_string(jbuf, "name", measurement_group->name);
345  evel_json_open_named_list(jbuf, "measurements");
346 
347  /*********************************************************************/
348  /* Measurements list. */
349  /*********************************************************************/
350  nested_item = dlist_get_first(&measurement_group->measurements);
351  while (nested_item != NULL)
352  {
353  custom_measurement = (CUSTOM_MEASUREMENT *) nested_item->item;
354  assert(custom_measurement != NULL);
355 
356  evel_json_open_object(jbuf);
357  evel_enc_kv_string(jbuf, "name", custom_measurement->name);
358  evel_enc_kv_string(jbuf, "value", custom_measurement->value);
360  nested_item = dlist_get_next(nested_item);
361  }
362  evel_json_close_list(jbuf);
364  item_added = true;
365  }
366  item = dlist_get_next(item);
367  }
368  evel_json_close_list(jbuf);
369 
370  /*************************************************************************/
371  /* If we've not written anything, rewind to before we opened the list. */
372  /*************************************************************************/
373  if (!item_added)
374  {
375  evel_json_rewind(jbuf);
376  }
377  }
378 
379  /***************************************************************************/
380  /* Although optional, we always generate the version. Note that this */
381  /* closes the object, too. */
382  /***************************************************************************/
383  evel_enc_version(jbuf,
384  "measurementFieldsVersion",
385  event->major_version,
386  event->major_version);
388 
389  EVEL_EXIT();
390 }
391 
392 /**************************************************************************/
401 {
402  MEASUREMENT_FEATURE_USE * feature_use = NULL;
405 
406  EVEL_ENTER();
407 
408  /***************************************************************************/
409  /* Check preconditions. As an internal API we don't allow freeing NULL */
410  /* events as we do on the public API. */
411  /***************************************************************************/
412  assert(event != NULL);
413  assert(event->header.event_domain == EVEL_DOMAIN_REPORT);
414 
415  /***************************************************************************/
416  /* Free all internal strings then the header itself. */
417  /***************************************************************************/
418  feature_use = dlist_pop_last(&event->feature_usage);
419  while (feature_use != NULL)
420  {
421  EVEL_DEBUG("Freeing Feature use Info (%s)", feature_use->feature_id);
422  free(feature_use->feature_id);
423  free(feature_use);
424  feature_use = dlist_pop_last(&event->feature_usage);
425  }
426  measurement_group = dlist_pop_last(&event->measurement_groups);
427  while (measurement_group != NULL)
428  {
429  EVEL_DEBUG("Freeing Measurement Group (%s)", measurement_group->name);
430 
431  custom_measurement = dlist_pop_last(&measurement_group->measurements);
432  while (custom_measurement != NULL)
433  {
434  EVEL_DEBUG("Freeing mesaurement (%s)", custom_measurement->name);
435 
436  free(custom_measurement->name);
437  free(custom_measurement->value);
438  free(custom_measurement);
439  custom_measurement = dlist_pop_last(&measurement_group->measurements);
440  }
441 
442  free(measurement_group->name);
443  free(measurement_group);
444  measurement_group = dlist_pop_last(&event->measurement_groups);
445  }
446 
447  evel_free_header(&event->header);
448 
449  EVEL_EXIT();
450 }
Feature Usage.
Definition: evel.h:614
DLIST measurement_groups
Definition: evel.h:667
#define EVEL_DEBUG(FMT,...)
Definition: evel.h:3621
Report.
Definition: evel.h:650
DLIST_ITEM * dlist_get_first(DLIST *list)
Definition: double_list.c:162
char * name
Definition: evel.h:633
void evel_json_open_named_list(EVEL_JSON_BUFFER *jbuf, const char *const key)
Add the key and opening bracket of a named list to a JSON buffer.
int minor_version
Definition: evel.h:656
void dlist_initialize(DLIST *list)
List initialization.
Definition: double_list.c:55
void evel_report_feature_use_add(EVENT_REPORT *report, char *feature, int utilization)
Add a Feature usage value name/value pair to the Report.
void * item
Definition: double_list.h:47
double measurement_interval
Definition: evel.h:661
EVENT_HEADER header
Definition: evel.h:654
EVEL_THROTTLE_SPEC * throttle_spec
void evel_json_encode_report(EVEL_JSON_BUFFER *jbuf, EVENT_REPORT *event)
Encode the report as a JSON report.
#define EVEL_EXIT()
Definition: evel.h:3631
EVENT_REPORT * evel_new_report(double measurement_interval)
Create a new Report event.
void evel_json_close_list(EVEL_JSON_BUFFER *jbuf)
Add the closing bracket of a list to a JSON buffer.
#define EVEL_ENTER()
Definition: evel.h:3626
Header for EVEL library.
void evel_report_type_set(EVENT_REPORT *report, const char *const type)
Set the Event Type property of the Report.
DLIST measurements
Definition: evel.h:625
DLIST feature_usage
Definition: evel.h:666
void evel_enc_kv_string(EVEL_JSON_BUFFER *jbuf, const char *const key, const char *const value)
Encode a string key and string value to a EVEL_JSON_BUFFER.
void evel_json_close_object(EVEL_JSON_BUFFER *jbuf)
Add the closing bracket of an object to a JSON buffer.
void evel_enc_kv_int(EVEL_JSON_BUFFER *jbuf, const char *const key, const int value)
Encode a string key and integer value to a EVEL_JSON_BUFFER.
void evel_free_report(EVENT_REPORT *event)
Free a Report.
void evel_json_open_named_object(EVEL_JSON_BUFFER *jbuf, const char *const key)
Add the opening bracket of an object to a JSON buffer.
void evel_json_open_object(EVEL_JSON_BUFFER *jbuf)
Add the opening bracket of an object to a JSON buffer.
A Mobile Flow event.
Definition: evel.h:136
void evel_json_checkpoint(EVEL_JSON_BUFFER *jbuf)
Add a checkpoint - a stake in the ground to which we can rewind.
EVEL_EVENT_DOMAINS event_domain
Definition: evel.h:420
void evel_enc_kv_double(EVEL_JSON_BUFFER *jbuf, const char *const key, const double value)
Encode a string key and double value to a EVEL_JSON_BUFFER.
void evel_json_encode_header(EVEL_JSON_BUFFER *jbuf, EVENT_HEADER *event)
Encode the event as a JSON event object according to AT&T&#39;s schema.
Definition: evel_event.c:291
#define EVEL_REPORT_MAJOR_VERSION
Definition: evel.h:640
void evel_free_header(EVENT_HEADER *const event)
Free an event header.
Definition: evel_event.c:349
void * dlist_pop_last(DLIST *list)
Definition: double_list.c:73
void dlist_push_last(DLIST *list, void *item)
Definition: double_list.c:132
bool evel_json_open_opt_named_list(EVEL_JSON_BUFFER *jbuf, const char *const key)
Add the key and opening bracket of an optional named list to a JSON buffer.
void log_error_state(char *format,...)
Definition: evel_logging.c:98
void evel_report_custom_measurement_add(EVENT_REPORT *report, const char *const group, const char *const name, const char *const value)
Add a Additional Measurement value name/value pair to the Report.
DLIST_ITEM * dlist_get_next(DLIST_ITEM *item)
Definition: double_list.c:172
void evel_json_rewind(EVEL_JSON_BUFFER *jbuf)
Rewind to the latest checkoint.
void evel_header_type_set(EVENT_HEADER *const header, const char *const type)
Set the Event Type property of the event header.
Definition: evel_event.c:164
EVEL throttle definitions.
EVEL internal definitions.
void evel_enc_version(EVEL_JSON_BUFFER *jbuf, const char *const key, const int major_version, const int minor_version)
Encode a key and version.
void evel_init_header(EVENT_HEADER *const header)
Initialize a newly created event header.
Definition: evel_event.c:112
int major_version
Definition: evel.h:655
#define EVEL_REPORT_MINOR_VERSION
Definition: evel.h:641
bool evel_throttle_suppress_nv_pair(EVEL_THROTTLE_SPEC *throttle_spec, const char *const field_name, const char *const name)
Determine whether a name-value pair should be allowed (not suppressed).
char * name
Definition: evel.h:624
Measurement Group.
Definition: evel.h:623
char * value
Definition: evel.h:634
Custom Defined Measurement.
Definition: evel.h:632