Adaptive Framework  0.9.0
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
afw_log.c
Go to the documentation of this file.
1 // See the 'COPYING' file in the project root for licensing information.
2 /*
3  * Implementation of afw_log interface for log director
4  *
5  * Copyright (c) 2010-2023 Clemson University
6  *
7  */
8 
9 
15 #include "afw_internal.h"
16 
17 
18 
19 /* Declares and rti/inf defines for interface afw_log */
20 #define AFW_IMPLEMENTATION_ID "log"
21 #include "afw_log_impl_declares.h"
23 
24 static const afw_value_t *
25 impl_log_current_variable_get_cb(
27  const afw_utf8_t *name,
28  afw_xctx_t *xctx);
29 
30 
31 static const afw_log_priority_id_map_entry_t impl_log_priority_id_map[] =
32 {
33  { &afw_s_emerg, afw_log_priority_emerg, "System unusable" },
34  { &afw_s_alert, afw_log_priority_alert, "Immediate action required" },
35  { &afw_s_crit, afw_log_priority_crit, "Critical conditions" },
36  { &afw_s_err, afw_log_priority_err, "Error conditions" },
37  { &afw_s_warning, afw_log_priority_warning, "Warning, errors may occur" },
38  { &afw_s_notice, afw_log_priority_notice, "Normal but significant" },
39  { &afw_s_info, afw_log_priority_info, "Informational" },
40  { &afw_s_debug, afw_log_priority_debug, "Debug" },
41  { &afw_s_trace1, afw_log_priority_trace1, "Trace level 1 message" },
42  { &afw_s_trace2, afw_log_priority_trace2, "Trace level 2 message" },
43  { &afw_s_trace3, afw_log_priority_trace3, "Trace level 3 message" },
44  { &afw_s_trace4, afw_log_priority_trace4, "Trace level 4 message" },
45  { &afw_s_trace5, afw_log_priority_trace5, "Trace level 5 message" },
46  { &afw_s_trace6, afw_log_priority_trace6, "Trace level 6 message" },
47  { &afw_s_trace7, afw_log_priority_trace7, "Trace level 7 message" },
48  { &afw_s_trace8, afw_log_priority_trace8, "Trace level 8 message" },
49  { NULL, afw_log_priority_invalid, "Invalid log priority" }
50 };
51 
52 typedef struct impl_log_entry_s impl_log_entry_t;
53 
55  impl_log_entry_t *next;
56  const afw_log_t *log;
57 };
58 
59 typedef struct impl_log_head_s {
60  impl_log_entry_t *first_log;
61  impl_log_entry_t *last_log;
63 
64 
65 typedef struct impl_log_self_s {
66  afw_log_t pub;
67 
68  impl_log_head_t *head;
70 
71 
72 typedef struct {
73  impl_afw_log_self_t *self;
74  const afw_pool_t *p;
75  afw_log_priority_t priority;
76  const afw_utf8_z_t *source_z;
77  const afw_utf8_t *message;
80  const afw_utf8_t *formatted_message;
82 
83 
84 /* Reset global mask based on log chain. */
85 static void
86 impl_reset_environment_log_mask(afw_xctx_t *xctx)
87 {
88  impl_afw_log_self_t *self;
90  afw_log_priority_mask_t new_mask;
91  afw_log_priority_mask_t *env_mask;
92  afw_log_impl_t *impl;
93 
95  new_mask = 0;
96  self = (impl_afw_log_self_t *)xctx->env->log;
97  for (e = self->head->first_log; e; e = e->next) {
98  if (e->log) {
99  new_mask |= e->log->impl->mask;
100  }
101  }
102  impl = (afw_log_impl_t *)self->pub.impl;
103  impl->mask = new_mask;
104  env_mask = (afw_log_priority_mask_t *)&xctx->env->log_mask;
105  *env_mask = new_mask;
106  }
107  AFW_LOCK_END;
108 }
109 
110 
111 /*
112  * Get common variable callback.
113  *
114  * Note: Make sure to update
115  * afw_log_internal_register_logType_context_type()
116  * with parallel changes to this function.
117  */
118 static const afw_value_t *
119 impl_log_current_variable_get_cb(
121  const afw_utf8_t *name,
122  afw_xctx_t *xctx)
123 {
125  const afw_value_t *result;
126  afw_value_string_t *source;
127 
128  result = NULL;
129 
130  if (afw_utf8_equal(name, &afw_s_message)) {
131  result = afw_value_create_string(wa->message, wa->p, xctx);
132  }
133 
134  else if (afw_utf8_equal(name, &afw_s_xctxUUID)) {
135  result = afw_value_create_string(xctx->uuid, wa->p, xctx);
136  }
137 
138  else if (afw_utf8_equal(name, &afw_s_source)) {
139  if (wa->source_z) {
140  source = afw_value_allocate_string(wa->p, xctx);
141  source->internal.s = afw_utf8_z_source_file(wa->source_z);
142  source->internal.len = strlen(source->internal.s);
143  result = (const afw_value_t *)source;
144  }
145  else {
146  result = afw_value_empty_string;
147  }
148  }
149 
150  return result;
151 }
152 
153 
154 
155 /*
156  * Register logType context type.
157  *
158  * Note: Make sure to update impl_log_current_variable_get_cb()
159  * with parallel changes to this function.
160  */
162  const afw_utf8_t *log_type_id,
163  afw_xctx_t *xctx)
164 {
165  const afw_utf8_t *context_type_id;
166  const afw_utf8_t *conf_object_type_id;
167  const afw_object_t *context_type_object;
168  const afw_object_t *qualifier_definitions;
169  const afw_object_t *variable_definitions;
170 
171  context_type_id = afw_utf8_printf(xctx->env->p, xctx,
172  "logType-%" AFW_UTF8_FMT, AFW_UTF8_FMT_ARG(log_type_id));
173  conf_object_type_id = afw_utf8_printf(xctx->env->p, xctx,
174  "_AdaptiveConf_log_%" AFW_UTF8_FMT, AFW_UTF8_FMT_ARG(log_type_id));
175  context_type_object = afw_context_type_create(
176  context_type_id, xctx->env->p, xctx);
177  qualifier_definitions =
179  context_type_object, xctx);
180  afw_object_meta_add_parent_path(qualifier_definitions,
181  &afw_s_a_context_type_application_qualifier_definitions_path,
182  xctx);
183 
184  variable_definitions =
186  context_type_object, &afw_s_log, xctx);
188  variable_definitions, conf_object_type_id,
189  false, xctx);
190 
191  variable_definitions =
193  context_type_object, &afw_s_current, xctx);
194  afw_context_variable_definition_add_z(variable_definitions,
195  &afw_s_message, &afw_s_internal,
197  "Message",
198  "Unformatted message that is being logged.",
199  NULL, NULL,
200  xctx);
201  afw_context_variable_definition_add_z(variable_definitions,
202  &afw_s_xctxUUID, &afw_s_internal,
204  "UUID",
205  "The current UUID of the execution context (xctx).",
206  NULL, NULL,
207  xctx);
208  afw_context_variable_definition_add_z(variable_definitions,
209  &afw_s_source, &afw_s_internal,
211  "Source",
212  "Source file that issued message.",
213  NULL, NULL,
214  xctx);
215 
217  context_type_object, xctx);
218 }
219 
220 
221 
222 /* Internal create environment log. */
223 extern const afw_log_t *
225  afw_xctx_t *xctx)
226 {
227  impl_afw_log_self_t *self;
228  const afw_log_t *log;
229  afw_log_impl_t *impl;
230 
232  self->pub.inf = &impl_afw_log_inf;
233  log = (const afw_log_t *)self;
234 
235  /* Log id to log_type (implementation_id). */
236  afw_memory_copy(&self->pub.log_id, &impl_afw_log_inf.rti.implementation_id);
237  self->pub.p = xctx->p;
238  self->pub.impl = impl = afw_xctx_calloc_type(afw_log_impl_t, xctx);
239 
240  /* Allocate log head and register its singleton. */
241  self->head = afw_xctx_calloc_type(impl_log_head_t, xctx);
242 
243  /* Return log implementation. */
244  return log;
245 }
246 
247 
248 /* Get priority_id/priority map array. */
251 {
252  return &impl_log_priority_id_map[0];
253 }
254 
255 
256 /* Convert a log priority id to internal. */
259  const afw_utf8_t *priority_id)
260 {
262 
263  for (e = &impl_log_priority_id_map[0]; e->priority_id; e++) {
264  if (afw_utf8_equal(priority_id, e->priority_id)) break;
265  }
266 
267  return e->priority;
268 }
269 
270 
271 /* Convert a log priority to priority id. */
272 AFW_DEFINE(const afw_utf8_t *)
274  afw_log_priority_t priority)
275 {
277 
278  for (e = &impl_log_priority_id_map[0]; e->priority_id; e++)
279  {
280  if (priority == e->priority) break;
281  }
282 
283  return e->priority_id;
284 }
285 
286 
287 
288 /* Add a log to environment. */
289 AFW_DEFINE(void)
291  const afw_log_t * instance,
292  afw_xctx_t *xctx)
293 {
294  afw_log_impl_t *impl = (afw_log_impl_t *)instance->impl;
295  impl_log_entry_t *e;
296  impl_log_head_t *head;
297  const afw_pool_t *p;
298  impl_afw_log_self_t *env_log;
299 
300  /* Use p of environment. */
301  p = xctx->env->p;
302 
303  AFW_LOCK_BEGIN(xctx->env->active_log_list_lock) {
304 
305  /* Register log. Will throw error if already registered. */
306  afw_environment_register_log(&instance->log_id, instance, xctx);
307 
308  /* Get environment log's self. */
309  env_log = (impl_afw_log_self_t *)xctx->env->log;
310 
311  /* Get head of entries. Allocate if necessary. */
312  head = env_log->head;
313  if (!head) {
314  head = afw_pool_calloc_type(p, impl_log_head_t, xctx);
315  env_log->head = head;
316  }
317 
318  /* Replace same log id. */
320  for (e = head->first_log; e; e = e->next) {
321  if (e->log && afw_utf8_equal(&e->log->log_id, &instance->log_id))
322  {
323  if (e->log) {
327  }
328  e->log = instance;
329  break;
330  }
331 
332  }
333  if (e) {
334  break;
335  }
336 
337  /* Allocate new entry. */
339  e->log = instance;
340 
341  /* Add entry to list. */
342  if (!head->first_log) {
343  head->first_log = e;
344  }
345  else {
346  head->last_log->next = e;
347  }
348  head->last_log = e;
349 
350  }
351  AFW_LOCK_END;
352 
353  afw_log_set_mask((const afw_log_t *)env_log, impl->mask, xctx);
354 }
355 
356 
357 /* Set a log's mask and insure env->mask is correct. */
358 AFW_DEFINE(void)
359 afw_log_set_mask(
360  const afw_log_t * instance,
362  afw_xctx_t *xctx)
363 {
364  /* Set own mask. */
365  afw_log_set_own_mask(instance, mask, xctx);
366 
367  /* Reset environment log mask. */
368  impl_reset_environment_log_mask(xctx);
369 }
370 
371 
372 /* Log an message using a printf style format and va_list. */
373 AFW_DEFINE(void)
375  const afw_log_t * instance,
376  afw_log_priority_t priority,
377  const afw_utf8_z_t * source_z,
378  const afw_utf8_z_t * format_z,
379  va_list ap,
380  afw_xctx_t *xctx)
381 {
382  const afw_utf8_t *message;
383 
384  message = afw_utf8_printf_v(format_z, ap, xctx->p, xctx);
385  afw_log_write(instance, priority, source_z, message,
386  xctx);
387 }
388 
389 
390 /* Configuration handler for entry type "log". */
392  const afw_utf8_t *type,
393  const afw_object_t *conf,
394  const afw_utf8_t *source_location,
395  const afw_pool_t *p, afw_xctx_t *xctx)
396 {
397  /* Start log. */
399  conf, source_location,
400  p, xctx);
401 }
402 
403 
404 /*
405  * Implementation of method destroy of interface afw_log.
406  */
407 void
408 impl_afw_log_destroy(
409  const afw_log_t * instance,
410  afw_xctx_t *xctx)
411 {
412  afw_pool_release(instance->p, xctx);
413 }
414 
415 
416 /*
417  * Implementation of method set_mask of interface afw_log.
418  */
419 void
420 impl_afw_log_set_own_mask(
421  const afw_log_t * instance,
423  afw_xctx_t *xctx)
424 {
425  afw_log_impl_t *impl = (afw_log_impl_t *)instance->impl;
426 
427  /* Set mask. */
428  impl->mask = mask;
429 }
430 
431 
432 /* Format a log message. */
433 static void
434 impl_write_formatted_message(
436  afw_xctx_t *xctx)
437 {
438  const afw_value_t *value;
439  int top;
440 
441  /* Make sure there is not a recursive error while logging. */
443  AFW_TRY {
444 
445  if (!wa->p) {
446  wa->p = afw_pool_create(xctx->p, xctx);
447  }
448 
449  /* Add qualifiers, if needed. Note: last one pushed has precedence. */
450  if (wa->e && (wa->e->log->impl->filter || wa->e->log->impl->format))
451  {
453  wa->e->log->properties,
454  true, wa->p, xctx);
455  afw_xctx_push_qualifier(&afw_s_current, NULL, true,
456  impl_log_current_variable_get_cb, (void *)wa,
457  wa->p, xctx);
458  if (wa->e->log->impl->custom_variables) {
459  afw_xctx_push_qualifier_object(&afw_s_custom,
460  wa->e->log->impl->custom_variables,
461  true, wa->p, xctx);
462  }
463  }
464 
465  /* If filter and not true, skip write. */
466  if (wa->e && wa->e->log->impl->filter) {
467  value = afw_value_evaluate(wa->e->log->impl->filter,
468  wa->p, xctx);
469  if (!value ||
470  !afw_value_is_boolean(value) ||
471  !((const afw_value_boolean_t *)value)->internal)
472  {
473  break;
474  }
475  }
476 
477  /* Message with format. */
478  if (wa->e && wa->e->log->impl->format) {
479  value = afw_value_evaluate(wa->e->log->impl->format,
480  wa->p, xctx);
481  if (!value || !afw_value_is_string(value)) {
482  AFW_THROW_ERROR_Z(general,
483  "log format did not evaluate to single string",
484  xctx);
485  }
486  wa->formatted_message =
487  &((afw_value_string_t *)value)->internal;
488  }
489 
490  /* Message with default format. */
491  else {
492  /* No time or program name[pid] */
493  wa->formatted_message = afw_utf8_printf(wa->p, xctx,
494  "[%" AFW_UTF8_FMT
495  " %" AFW_UTF8_FMT
496  "] %" AFW_UTF8_FMT,
497  AFW_UTF8_FMT_ARG(&xctx->env->application_id),
498  AFW_UTF8_FMT_ARG(xctx->uuid),
499  AFW_UTF8_FMT_ARG(wa->message));
500  }
501 
502  /* Write message. If no log started yet, just write to stderr. */
503  if (wa->e) {
504  afw_log_write(wa->e->log, wa->priority,
505  wa->source_z, wa->formatted_message, xctx);
506  } else {
507  fprintf(xctx->env->stderr_fd, "%" AFW_UTF8_FMT "\n",
508  AFW_UTF8_FMT_ARG(wa->formatted_message));
509 
510  /* flush output */
511  fflush(xctx->env->stderr_fd);
512  }
513  }
514 
518  fprintf(xctx->env->stderr_fd,
519  "***ERROR*** while writing log - %s\n", AFW_ERROR_THROWN->message_z);
520  }
521 
522  AFW_FINALLY{
524  }
525 
526  AFW_ENDTRY;
527 }
528 
529 
530 
531 /*
532  * Implementation of method write of interface afw_log.
533  */
534 void
536  const afw_log_t * instance,
537  afw_log_priority_t priority,
538  const afw_utf8_z_t * source_z,
539  const afw_utf8_t * message,
540  afw_xctx_t *xctx)
541 {
543  afw_boolean_t lock_held;
544  afw_boolean_t log_found;
545 
546  wa.self = (impl_afw_log_self_t *)instance;
547  wa.p = NULL;
548  wa.priority = priority;
549  wa.source_z = source_z;
550  wa.message = message;
551  lock_held = false;
552 
553  AFW_TRY {
554 
555  /* Get lock for active list. */
556  afw_lock_obtain(xctx->env->active_log_list_lock, xctx);
557  lock_held = true;
558 
559  /* Make mask from priority for short circuit test. */
560  wa.mask = 1 << priority;
561 
562  /* If logs added to environment, process them. */
563  wa.e = wa.self->head->first_log;
564  log_found = false;
565  if (wa.e) {
566  for (; wa.e; wa.e = wa.e->next) {
567  if (wa.e->log) {
568  log_found = true;
569  if (wa.e->log->impl->mask & wa.mask)
570  {
571  impl_write_formatted_message(&wa, xctx);
572  }
573  }
574  }
575  }
576 
577  /*
578  * If no logs have been added to environment, write to stdout.
579  */
580  if (!log_found) {
581  wa.e = NULL;
582  impl_write_formatted_message(&wa, xctx);
583  }
584  }
585 
589  fprintf(xctx->env->stderr_fd,
590  "***ERROR*** while writing log - %s\n", AFW_ERROR_THROWN->message_z);
591  }
592 
593  AFW_FINALLY{
594  if (lock_held) {
595  afw_lock_release(xctx->env->active_log_list_lock, xctx);
596  }
597  if (wa.p) {
598  afw_pool_destroy(wa.p, xctx);
599  }
600  }
601 
602  AFW_ENDTRY;
603 }
604 
605 
606 
607 void
608 afw_log_internal_register_service_type(afw_xctx_t *xctx)
609 {
610  afw_service_type_t *self;
611 
613  self->inf = &impl_afw_service_type_inf;
614  afw_memory_copy(&self->service_type_id, &afw_s_log);
615  self->conf_type = afw_environment_get_conf_type(&afw_s_log, xctx);
616  if (!self->conf_type) {
617  AFW_THROW_ERROR_Z(general, "conf_type must already be registered",
618  xctx);
619  }
620  self->title = &afw_s_a_service_type_log_title;
621  self->conf_type_object = afw_runtime_get_object(&afw_s__AdaptiveConfType_,
622  &afw_s_log, xctx);
623  afw_environment_register_service_type(&afw_s_log, self, xctx);
624 }
625 
626 
627 /*
628  * Implementation of method related_instance_count of interface afw_service_type.
629  */
631 impl_afw_service_type_related_instance_count (
632  const afw_service_type_t * instance,
633  const afw_utf8_t * id,
634  afw_xctx_t *xctx)
635 {
636  const afw_log_t *log;
637 
638  log = afw_environment_get_log(id, xctx);
639  return (log) ? 1 : 0;
640 }
641 
642 
643 
644 /*
645  * Implementation of method start_cede_p of interface afw_service_type.
646  */
647 void
648 impl_afw_service_type_start_cede_p (
649  const afw_service_type_t * instance,
650  const afw_object_t * properties,
651  const afw_pool_t * p,
652  afw_xctx_t *xctx)
653 {
654  const afw_log_factory_t *factory;
655  const afw_log_t *log;
656  const afw_utf8_t *log_type;
657 
658  log_type = afw_object_old_get_property_as_utf8(properties,
659  &afw_s_logType, p, xctx);
660  if (!log_type) {
661  AFW_THROW_ERROR_Z(general, "parameter logType missing", xctx);
662  }
663 
664  factory = afw_environment_get_log_type(log_type, xctx);
665  if (!factory) {
666  AFW_THROW_ERROR_FZ(general, xctx,
667  "logType %" AFW_UTF8_FMT " is not a registered log type.",
668  AFW_UTF8_FMT_ARG(log_type));
669  }
670 
671  /* Create log. */
672  log = afw_log_factory_create_log_cede_p(factory,
673  properties, p, xctx);
674 
675  /* Add/replace log in environment. */
676  afw_log_add_to_environment(log, xctx);
677 }
678 
679 
680 
681 /*
682  * Implementation of method stop of interface afw_service_type.
683  */
684 void
686  const afw_service_type_t * instance,
687  const afw_utf8_t * id,
688  afw_xctx_t *xctx)
689 {
690  impl_afw_log_self_t *self;
691  impl_log_entry_t *e;
692 
693  afw_environment_register_log(id, NULL, xctx);
694 
695  /*
696  * This counts on afw_service only calling if not stopped, if log is not
697  * found, no error is thrown.
698  */
700  self = (impl_afw_log_self_t *)xctx->env->log;
701  for (e = self->head->first_log; e; e = e->next)
702  {
703  if (e->log && afw_utf8_equal(&e->log->log_id, id)) {
709  e->log = NULL;
710  }
711  }
712  }
713  AFW_LOCK_END;
714 
715  /* Reset environment log mask. */
716  impl_reset_environment_log_mask(xctx);
717 }
718 
719 
720 
721 /*
722  * Implementation of method restart_cede_p of interface afw_service_type.
723  */
724 void
725 impl_afw_service_type_restart_cede_p (
726  const afw_service_type_t * instance,
727  const afw_object_t * properties,
728  const afw_pool_t * p,
729  afw_xctx_t *xctx)
730 {
731  /*
732  * This counts on afw_service only calling if not started, so if stopped,
733  * this will start log. Restart is same as start at this point.
734  */
735  impl_afw_service_type_start_cede_p(instance, properties, p, xctx);
736 }
737 
738 
739 AFW_DEFINE(void)
741  const afw_log_t *log,
742  const afw_utf8_t *property_name,
743  afw_xctx_t *xctx)
744 {
745  AFW_THROW_ERROR_FZ(general, xctx,
746  "Configuration type=log, logId=%" AFW_UTF8_FMT
747  " property name %" AFW_UTF8_FMT " is not valid.",
748  AFW_UTF8_FMT_ARG(&log->log_id),
749  AFW_UTF8_FMT_ARG(property_name));
750 }
751 
752 
753 AFW_DEFINE(void)
755  const afw_log_t *log,
756  const afw_utf8_t *property_name,
757  afw_xctx_t *xctx)
758 {
759  AFW_THROW_ERROR_FZ(general, xctx,
760  "Configuration type=log, logId=%" AFW_UTF8_FMT
761  " property name %" AFW_UTF8_FMT " is required.",
762  AFW_UTF8_FMT_ARG(&log->log_id),
763  AFW_UTF8_FMT_ARG(property_name));
764 }
765 
766 
767 /* Developers should call this in all create functions for afw_log. */
770  const afw_log_inf_t *inf,
771  afw_size_t instance_size,
772  const afw_object_t *properties,
773  const afw_pool_t *p, afw_xctx_t *xctx)
774 {
775  afw_log_t *self;
776  afw_log_impl_t *impl;
778  const afw_utf8_t *hybrid;
779  const afw_utf8_t *s;
780  afw_boolean_t b;
781  afw_boolean_t found;
782 
783  /* Allocate new log instance in new subpool. */
784  self = afw_pool_calloc(p,
785  (instance_size != 0) ? instance_size : sizeof(afw_log_t),
786  xctx);
787  self->inf = inf;
788  self->p = p;
789  self->impl = impl = afw_pool_calloc_type(p, afw_log_impl_t, xctx);
790 
791  /* Prepare properties. */
793  properties, xctx);
794 
795  /* Get source location. Default it to adaptor. */
796  self->source_location = afw_object_old_get_property_as_string(
797  properties, &afw_s_sourceLocation, xctx);
798  if (!self->source_location) {
799  self->source_location = &afw_s_log;
800  }
801 
802  /* Get log_id from parameters. Default to log_type. */
804  &afw_s_logId, p, xctx);
805  memcpy(&self->log_id, s, sizeof(afw_utf8_t));
806 
807  /* Service id. */
808  self->service_id = afw_utf8_printf(p, xctx,
809  "log-%" AFW_UTF8_FMT,
810  AFW_UTF8_FMT_ARG(&self->log_id));
811 
812  /* Process <priority>, if they exists. */
813  for (e = afw_log_get_priority_id_map(); e->priority_id; e++) {
814  b = afw_object_old_get_property_as_boolean(properties, e->priority_id,
815  &found, xctx);
816  if (found) {
817  afw_log_set_priority_in_mask(&impl->mask, e->priority, b);
818  }
819  }
820 
821  /* Compile filter, if it exists. */
822  hybrid = afw_object_old_get_property_as_string(properties,
823  &afw_s_filter, xctx);
824  if (hybrid) {
825  impl->filter = afw_compile_hybrid_source(hybrid,
826  self->source_location, NULL, NULL, p, xctx);
827  }
828 
829  /* Compile format, if it exists. */
830  hybrid = afw_object_old_get_property_as_string(properties,
831  &afw_s_format, xctx);
832  if (hybrid) {
833  impl->format = afw_compile_hybrid_source(hybrid,
834  self->source_location, NULL, NULL, p, xctx);
835  }
836 
837  /* Return new log. */
838  return self;
839 }
AFW_DEFINE(const afw_object_t *)
Adaptive Framework Core Internal.
Interface afw_interface implementation declares.
Interface afw_interface implementation declares.
#define afw_value_is_boolean(A_VALUE)
Macro to determine if value is evaluated boolean.
#define afw_object_old_get_property_as_boolean(object, property_name, found, xctx)
Get property function for data type boolean value.
afw_value_create_string(const afw_utf8_t *internal, const afw_pool_t *p, afw_xctx_t *xctx)
Create function for unmanaged data type string value.
#define afw_object_old_get_property_as_string(object, property_name, xctx)
Get property function for data type string value.
afw_value_allocate_string(const afw_pool_t *p, afw_xctx_t *xctx)
Allocate function for unmanaged data type string value.
afw_value_evaluated_string_inf
Unmanaged evaluated value inf for data type string.
#define afw_value_is_string(A_VALUE)
Macro to determine if value is evaluated string.
#define AFW_UTF8_FMT_ARG(A_STRING)
Convenience Macro for use with AFW_UTF8_FMT to specify arg.
Definition: afw_common.h:605
_Bool afw_boolean_t
Definition: afw_common.h:373
int afw_log_priority_mask_t
Definition: afw_common.h:659
#define AFW_UTF8_FMT
Format string specifier used for afw_utf8_t.
Definition: afw_common.h:588
afw_utf8_octet_t afw_utf8_z_t
NFC normalized UTF-8 null terminated string.
Definition: afw_common.h:523
apr_size_t afw_size_t
size_t.
Definition: afw_common.h:151
enum afw_log_priority_e afw_log_priority_t
Log levels. See afw_log.h for more information.
apr_int64_t afw_integer_t
typedef for big signed int.
Definition: afw_common.h:321
@ afw_log_priority_alert
Definition: afw_common.h:983
@ afw_log_priority_trace3
Definition: afw_common.h:996
@ afw_log_priority_crit
Definition: afw_common.h:984
@ afw_log_priority_trace8
Definition: afw_common.h:1001
@ afw_log_priority_debug
Definition: afw_common.h:989
@ afw_log_priority_trace4
Definition: afw_common.h:997
@ afw_log_priority_notice
Definition: afw_common.h:987
@ afw_log_priority_emerg
Definition: afw_common.h:982
@ afw_log_priority_trace2
Definition: afw_common.h:995
@ afw_log_priority_trace5
Definition: afw_common.h:998
@ afw_log_priority_err
Definition: afw_common.h:985
@ afw_log_priority_trace7
Definition: afw_common.h:1000
@ afw_log_priority_trace6
Definition: afw_common.h:999
@ afw_log_priority_info
Definition: afw_common.h:988
@ afw_log_priority_warning
Definition: afw_common.h:986
@ afw_log_priority_trace1
Definition: afw_common.h:994
#define afw_compile_hybrid_source(string, source_location, parent, shared, p, xctx)
Compile hybrid.
Definition: afw_compile.h:256
afw_context_variable_definition_add_z(const afw_object_t *variable_definitions, const afw_utf8_t *variable_name, const afw_utf8_t *source, const afw_value_inf_t *value_inf, const afw_utf8_z_t *label_z, const afw_utf8_z_t *description_z, const afw_utf8_z_t *data_type_parameter_z, const afw_utf8_z_t *data_type_parameter_formatted_z, afw_xctx_t *xctx)
Add variable definition using 0 terminated label and description.
Definition: afw_context.c:190
afw_context_type_insure_qualifier_definitions_object_exists(const afw_object_t *context_type_object, afw_xctx_t *xctx)
Insure qualifier definitions object exists.
Definition: afw_context.c:85
afw_context_type_insure_variable_definitions_object_exists(const afw_object_t *context_type_object, const afw_utf8_t *qualifier_id, afw_xctx_t *xctx)
Insure variable definitions object exists for qualifier id.
Definition: afw_context.c:109
afw_context_variable_definitions_add_based_on_object_type_id(const afw_object_t *variable_definitions, const afw_utf8_t *object_type_id, afw_boolean_t include_evaluated, afw_xctx_t *xctx)
Add variable definitions based on object type id.
Definition: afw_context.c:433
afw_context_type_create(const afw_utf8_t *context_type_id, const afw_pool_t *p, afw_xctx_t *xctx)
Create a context type object.
Definition: afw_context.c:64
void afw_environment_register_context_type(const afw_utf8_t *context_type_id, const afw_object_t *context_type_object, afw_xctx_t *xctx)
Register an context type.
void afw_environment_register_service_type(const afw_utf8_t *service_type_id, const afw_service_type_t *service_type, afw_xctx_t *xctx)
Register a service type.
const afw_environment_conf_type_t * afw_environment_get_conf_type(const afw_utf8_t *type, afw_xctx_t *xctx)
Get the conf_type associated with type.
const afw_object_t * afw_environment_prepare_conf_type_properties(const afw_object_t *properties, afw_xctx_t *xctx)
Prepare properties for a conf type.
const afw_log_t * afw_environment_get_log(const afw_utf8_t *log_id, afw_xctx_t *xctx)
Get the log instance associated with log id.
const afw_log_factory_t * afw_environment_get_log_type(const afw_utf8_t *log_type, afw_xctx_t *xctx)
Get the log factory instance associated with log type.
void afw_environment_register_log(const afw_utf8_t *log_id, const afw_log_t *log, afw_xctx_t *xctx)
Register a log.
#define AFW_FINALLY
Always executed regardless of error.
Definition: afw_error.h:702
#define AFW_CATCH_UNHANDLED
Catch an unhandled error that occurs in a AFW_TRY block.
Definition: afw_error.h:684
#define AFW_ENDTRY
Ends an AFW try block.
Definition: afw_error.h:727
#define AFW_TRY
Begin an AFW TRY block.
Definition: afw_error.h:634
#define AFW_THROW_ERROR_FZ(code, xctx, format_z,...)
Macro used to set error and 0 rv in xctx and throw it.
Definition: afw_error.h:319
#define AFW_ERROR_THROWN
Access the thrown error. See AFW_TRY.
Definition: afw_error.h:554
#define AFW_THROW_ERROR_Z(code, message_z, xctx)
Macro used to set error and 0 rv in xctx and throw it.
Definition: afw_error.h:283
#define AFW_LOCK_BEGIN(instance)
Macro to begin a lock section.
Definition: afw_lock.h:191
afw_lock_release(const afw_lock_t *instance, afw_xctx_t *xctx)
Release lock.
Definition: afw_lock.c:291
afw_lock_obtain(const afw_lock_t *instance, afw_xctx_t *xctx)
Obtain lock.
Definition: afw_lock.c:254
#define AFW_LOCK_END
Macro to end a lock section.
Definition: afw_lock.h:202
#define afw_log_factory_create_log_cede_p(instance, properties, p, xctx)
Call method create_log_cede_p of interface afw_log_factory.
void impl_afw_log_write(const afw_log_t *instance, afw_log_priority_t priority, const afw_utf8_z_t *source_z, const afw_utf8_t *message, afw_xctx_t *xctx)
Definition: afw_log.c:535
afw_log_impl_create_cede_p(const afw_log_inf_t *inf, afw_size_t instance_size, const afw_object_t *properties, const afw_pool_t *p, afw_xctx_t *xctx)
Developers should call this in all create functions for afw_log.
Definition: afw_log.c:769
afw_log_impl_throw_property_required(const afw_log_t *log, const afw_utf8_t *property_name, afw_xctx_t *xctx)
Developers should call this for missing required configuration property.
Definition: afw_log.c:754
afw_log_impl_throw_property_invalid(const afw_log_t *log, const afw_utf8_t *property_name, afw_xctx_t *xctx)
Developers should call this for configuration property errors.
Definition: afw_log.c:740
#define afw_log_write(instance, priority, source_z, message, xctx)
Call method write of interface afw_log.
#define afw_log_set_own_mask(instance, mask, xctx)
Call method set_own_mask of interface afw_log.
void afw_log_internal_conf_type_create_cede_p(const afw_utf8_t *type, const afw_object_t *conf, const afw_utf8_t *source_location, const afw_pool_t *p, afw_xctx_t *xctx)
Configuration handler for entry type "log".
Definition: afw_log.c:391
const afw_log_t * afw_log_internal_create_environment_log(afw_xctx_t *xctx)
Internal create environment log.
Definition: afw_log.c:224
void afw_log_internal_register_logType_context_type(const afw_utf8_t *log_type_id, afw_xctx_t *xctx)
Register logType context type.
Definition: afw_log.c:161
afw_log_add_to_environment(const afw_log_t *instance, afw_xctx_t *xctx)
Add a log to the list of logs called by environment log.
Definition: afw_log.c:290
afw_log_write_vz(const afw_log_t *instance, afw_log_priority_t priority, const afw_utf8_z_t *source_z, const afw_utf8_z_t *format_z, va_list ap, afw_xctx_t *xctx)
Log an message using a printf style format and va_list.
Definition: afw_log.c:374
afw_log_priority_to_priority_id(afw_log_priority_t priority)
Convert a log priority to priority id.
Definition: afw_log.c:273
afw_log_priority_id_to_priority(const afw_utf8_t *priority_id)
Convert a log priority id to priority.
Definition: afw_log.c:258
void afw_log_set_priority_in_mask(afw_log_priority_mask_t *mask, afw_log_priority_t priority, afw_boolean_t value)
Set the corresponding bit for a priority in a mask.
Definition: afw_log.h:138
afw_log_get_priority_id_map()
Definition: afw_log.c:250
#define afw_memory_copy(to, from)
Copy to preallocated memory of same type.
Definition: afw_memory.h:39
afw_object_meta_add_parent_path(const afw_object_t *instance, const afw_utf8_t *parent_path, afw_xctx_t *xctx)
Add a parent path to instance's meta.
afw_object_old_get_property_as_utf8(const afw_object_t *instance, const afw_utf8_t *property_name, const afw_pool_t *p, afw_xctx_t *xctx)
Get an object's property value as a string in specified pool.
Definition: afw_object.c:531
#define afw_pool_destroy(instance, xctx)
Call method destroy of interface afw_pool.
#define afw_pool_calloc(instance, size, xctx)
Call method calloc of interface afw_pool.
#define afw_pool_release(instance, xctx)
Call method release of interface afw_pool.
#define afw_pool_calloc_type(instance, type, xctx)
Macro to allocate cleared memory to hold type in pool.
Definition: afw_pool.h:167
const afw_pool_t * afw_pool_create(const afw_pool_t *parent, afw_xctx_t *xctx)
Create a new pool.
afw_runtime_get_object(const afw_utf8_t *object_type_id, const afw_utf8_t *object_id, afw_xctx_t *xctx)
Get a runtime object.
Definition: afw_runtime.c:853
void impl_afw_service_type_stop(const afw_service_type_t *instance, const afw_utf8_t *id, afw_xctx_t *xctx)
Definition: afw_log.c:685
afw_service_start_using_AdaptiveConf_cede_p(const afw_object_t *conf, const afw_utf8_t *source_location, const afw_pool_t *p, afw_xctx_t *xctx)
Start a service using AdaptiveConf object and cede p.
Definition: afw_service.c:1147
afw_utf8_printf_v(const afw_utf8_z_t *format, va_list arg, const afw_pool_t *p, afw_xctx_t *xctx)
Create a utf-8 string using a c format string in specified pool.
Definition: afw_utf8.c:477
afw_boolean_t afw_utf8_equal(const afw_utf8_t *s1, const afw_utf8_t *s2)
Check to see if a string equals another string.
afw_utf8_printf(const afw_pool_t *p, afw_xctx_t *xctx, const afw_utf8_z_t *format,...)
Create a utf-8 string using a c format string in specified pool.
Definition: afw_utf8.c:459
afw_utf8_z_source_file(const afw_utf8_z_t *source_z)
Returns value of source_z after last '/ 'or '\'.
Definition: afw_utf8.c:1037
#define afw_value_evaluate(value, p, xctx)
Evaluate value if needed using specific pool.
Definition: afw_value.h:841
afw_value_empty_string
Adaptive value empty string.
Definition: afw_value.h:342
afw_xctx_get_qualifier_stack_top(afw_xctx_t *xctx)
Get qualifier stack top.
Definition: afw_xctx.c:316
afw_xctx_push_qualifier_object(const afw_utf8_t *qualifier_name, const afw_object_t *qualifier_object, afw_boolean_t secure, const afw_pool_t *p, afw_xctx_t *xctx)
Push qualifier object on to stack.
Definition: afw_xctx.c:406
afw_xctx_set_qualifier_stack_top(int top, afw_xctx_t *xctx)
Set stack top index.
Definition: afw_xctx.c:325
#define afw_xctx_calloc_type(type, xctx)
Macro to allocate cleared memory to hold type in xctx's pool.
Definition: afw_xctx.h:199
afw_xctx_push_qualifier(const afw_utf8_t *qualifier, const afw_object_t *qualifier_object, afw_boolean_t secure, afw_xctx_get_variable_t get, void *data, const afw_pool_t *p, afw_xctx_t *xctx)
Push qualifier on to stack.
Definition: afw_xctx.c:359
afw_utf8_t application_id
The id of the application.
Definition: afw_common.h:1404
const afw_lock_t * active_log_list_lock
Lock for protecting changes to active log list.
Definition: afw_common.h:1493
const afw_log_t * log
Director log. This log will direct to other logs.
Definition: afw_common.h:1419
const afw_pool_t * p
Pool used to hold environment.
Definition: afw_common.h:1386
afw_log_priority_mask_t log_mask
Copy of director log's mask for short circuit tests.
Definition: afw_common.h:1461
FILE * stderr_fd
Open file descriptor used for writing error output. Default stderr.
Definition: afw_common.h:1425
Interface afw_log_factory public struct.
Struct for afw_log_impl_t.
Definition: afw_log_impl.h:35
afw_log_priority_mask_t mask
Definition: afw_log_impl.h:53
const afw_object_t * custom_variables
Definition: afw_log_impl.h:44
const afw_value_t * filter
Definition: afw_log_impl.h:47
const afw_value_t * format
Definition: afw_log_impl.h:50
Interface afw_log_inf_s struct.
Definition: afw_log.h:61
Interface afw_log public struct.
Interface afw_object public struct.
Interface afw_pool public struct.
Interface afw_service_type public struct.
NFC normalized UTF-8 string.
Definition: afw_common.h:545
struct for data type boolean values.
Interface afw_value public struct.
struct for data type string values.
Definition: afw_xctx.h:352
void * data
Data that will be passed to get/set.
Definition: afw_xctx.h:367
Interface afw_xctx public struct.
Definition: afw_log.c:54