FD.io VPP  v21.06
Vector Packet Processing
log.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <stdbool.h>
17 #include <vlib/vlib.h>
18 #include <vlib/log.h>
19 #include <vlib/unix/unix.h>
20 #include <syslog.h>
21 #include <vppinfra/elog.h>
22 
23 vlib_log_main_t log_main = {
24  .default_log_level = VLIB_LOG_LEVEL_NOTICE,
25  .default_syslog_log_level = VLIB_LOG_LEVEL_WARNING,
26  .unthrottle_time = 3,
27  .size = 512,
28  .add_to_elog = 1,
29  .default_rate_limit = 50,
30 };
31 
32 /* *INDENT-OFF* */
33 VLIB_REGISTER_LOG_CLASS (log_log, static) = {
34  .class_name = "log",
35 };
36 /* *INDENT-ON* */
37 
38 static const int colors[] = {
39  [VLIB_LOG_LEVEL_EMERG] = 1, /* red */
40  [VLIB_LOG_LEVEL_ALERT] = 1, /* red */
41  [VLIB_LOG_LEVEL_CRIT] = 1, /* red */
42  [VLIB_LOG_LEVEL_ERR] = 1, /* red */
43  [VLIB_LOG_LEVEL_WARNING] = 3, /* yellow */
44  [VLIB_LOG_LEVEL_NOTICE] = 2, /* green */
45  [VLIB_LOG_LEVEL_INFO] = 4, /* blue */
46  [VLIB_LOG_LEVEL_DEBUG] = 6, /* cyan */
47 };
48 
49 static const int log_level_to_syslog_priority[] = {
50  [VLIB_LOG_LEVEL_EMERG] = LOG_EMERG,
51  [VLIB_LOG_LEVEL_ALERT] = LOG_ALERT,
52  [VLIB_LOG_LEVEL_CRIT] = LOG_CRIT,
53  [VLIB_LOG_LEVEL_ERR] = LOG_ERR,
54  [VLIB_LOG_LEVEL_WARNING] = LOG_WARNING,
55  [VLIB_LOG_LEVEL_NOTICE] = LOG_NOTICE,
56  [VLIB_LOG_LEVEL_INFO] = LOG_INFO,
57  [VLIB_LOG_LEVEL_DEBUG] = LOG_DEBUG,
58  [VLIB_LOG_LEVEL_DISABLED] = LOG_DEBUG,
59 };
60 
61 int
63 {
65  int i;
66 
67  i = lm->next - lm->count;
68 
69  if (i < 0)
70  i += lm->size;
71  return i;
72 }
73 
74 static vlib_log_class_data_t *
76 {
78  return vec_elt_at_index (lm->classes, (ci >> 16));
79 }
80 
83 {
85  return vec_elt_at_index (c->subclasses, (ci & 0xffff));
86 }
87 
88 u8 *
89 format_vlib_log_class (u8 * s, va_list * args)
90 {
91  vlib_log_class_t ci = va_arg (*args, vlib_log_class_t);
94 
95  if (sc->name)
96  return format (s, "%v/%v", c->name, sc->name);
97  else
98  return format (s, "%v", c->name, 0);
99 }
100 
101 u8 *
102 format_indent (u8 * s, va_list * args)
103 {
104  u8 *v = va_arg (*args, u8 *);
105  u32 indent = va_arg (*args, u32);
106  u8 *c;
107 
108  /* *INDENT-OFF* */
109  vec_foreach (c, v)
110  {
111  vec_add (s, c, 1);
112  if (c[0] == '\n')
113  for (u32 i = 0; i < indent; i++)
114  vec_add1 (s, (u8) ' ');
115  }
116  /* *INDENT-ON* */
117  return s;
118 }
119 
120 static int
122 {
123  if (configured == VLIB_LOG_LEVEL_DISABLED)
124  return 0;
125  if (level > configured)
126  return 0;
127  return 1;
128 }
129 
130 void
131 vlib_log (vlib_log_level_t level, vlib_log_class_t class, char *fmt, ...)
132 {
134  vlib_log_main_t *lm = &log_main;
135  vlib_log_entry_t *e;
137  va_list va;
138  f64 t = vlib_time_now (vm);
139  f64 delta = t - sc->last_event_timestamp;
140  int log_enabled = log_level_is_enabled (level, sc->level);
141  int syslog_enabled = log_level_is_enabled (level, sc->syslog_level);
142  u8 *s = 0;
143 
144  /* make sure we are running on the main thread to avoid use in dataplane
145  code, for dataplane logging consider use of event-logger */
146  ASSERT (vlib_get_thread_index () == 0);
147 
148  if ((log_enabled || syslog_enabled) == 0)
149  return;
150 
151  vec_validate (lm->entries, lm->size);
152 
153  if ((delta > lm->unthrottle_time) ||
154  (sc->is_throttling == 0 && (delta > 1)))
155  {
156  sc->last_event_timestamp = t;
157  sc->last_sec_count = 0;
158  sc->is_throttling = 0;
159  }
160  else
161  {
162  sc->last_sec_count++;
163  if (sc->last_sec_count > sc->rate_limit)
164  return;
165  else if (sc->last_sec_count == sc->rate_limit)
166  {
167  vec_reset_length (s);
168  s = format (s, "--- message(s) throttled ---");
169  sc->is_throttling = 1;
170  }
171  }
172 
173  if (s == 0)
174  {
175  va_start (va, fmt);
176  s = va_format (s, fmt, &va);
177  va_end (va);
178  }
179 
180  if (syslog_enabled)
181  {
182  u8 *l = 0;
184  {
185  int indent = 0;
186  int with_colors = (unix_main.flags & UNIX_FLAG_NOCOLOR) == 0;
187  u8 *fmt;
188  if (with_colors)
189  {
190  l = format (l, "\x1b[%um", 90 + colors[level]);
191  indent = vec_len (l);
192  }
193  fmt = format (0, "%%-%uU [%%-6U]: ", lm->max_class_name_length);
195  l = format (l, (char *) fmt, format_vlib_log_class, class,
196  format_vlib_log_level, level);
197  vec_free (fmt);
198  indent = vec_len (l) - indent;
199  if (with_colors)
200  l = format (l, "\x1b[0m");
201  l = format (l, "%U", format_indent, s, indent);
202  fformat (stderr, "%v\n", l);
203  fflush (stderr);
204  }
205  else
206  {
207  l = format (l, "%U", format_vlib_log_class, class);
208  int prio = log_level_to_syslog_priority[level];
209  int is_term = vec_c_string_is_terminated (l) ? 1 : 0;
210 
211  syslog (prio, "%.*s: %.*s", (int) vec_len (l), l,
212  (int) vec_len (s) - is_term, s);
213  }
214  vec_free (l);
215  }
216 
217  if (log_enabled)
218  {
219  e = vec_elt_at_index (lm->entries, lm->next);
220  vec_free (e->string);
221  e->level = level;
222  e->class = class;
223  e->string = s;
224  e->timestamp = t;
225  s = 0;
226 
227  if (lm->add_to_elog)
228  {
229  /* *INDENT-OFF* */
230  ELOG_TYPE_DECLARE(ee) =
231  {
232  .format = "log-%s: %s",
233  .format_args = "t4T4",
234  .n_enum_strings = 9,
235  .enum_strings = {
236  "emerg",
237  "alert",
238  "crit",
239  "err",
240  "warn",
241  "notice",
242  "info",
243  "debug",
244  "disabled",
245  },
246  };
247  struct {
248  u32 log_level;
249  u32 string_index;
250  } *ed;
251  /* *INDENT-ON* */
253  ed->log_level = level;
254  ed->string_index =
256  }
257 
258  lm->next = (lm->next + 1) % lm->size;
259  if (lm->size > lm->count)
260  lm->count++;
261  }
262 
263  vec_free (s);
264 }
265 
266 static vlib_log_class_t
267 vlib_log_register_class_internal (char *class, char *subclass, u32 limit)
268 {
269  vlib_log_main_t *lm = &log_main;
270  vlib_log_class_data_t *c = NULL;
273  vlib_log_class_config_t *cc = 0, *scc = 0;
274  uword *p;
275  u8 *str;
276  u32 length = 0;
277 
278  if ((p = hash_get_mem (lm->config_index_by_name, class)))
279  cc = vec_elt_at_index (lm->configs, p[0]);
280 
281  str = format (0, "%s/%s%c", class, subclass, 0);
282  if ((p = hash_get_mem (lm->config_index_by_name, (char *) str)))
283  scc = vec_elt_at_index (lm->configs, p[0]);
284  vec_free (str);
285 
286  vec_foreach (tmp, lm->classes)
287  {
288  if (vec_len (tmp->name) != strlen (class))
289  continue;
290  if (!memcmp (class, tmp->name, vec_len (tmp->name)))
291  {
292  c = tmp;
293  break;
294  }
295  }
296  if (!c)
297  {
298  vec_add2 (lm->classes, c, 1);
299  c->index = c - lm->classes;
300  c->name = format (0, "%s", class);
301  }
302  length = vec_len (c->name);
303 
304  vec_add2 (c->subclasses, s, 1);
305  s->index = s - c->subclasses;
306  s->name = subclass ? format (0, "%s", subclass) : 0;
307 
308  if (scc && scc->rate_limit != ~0)
309  s->rate_limit = scc->rate_limit;
310  else if (cc && cc->rate_limit != ~0)
311  s->rate_limit = cc->rate_limit;
312  else if (limit)
313  s->rate_limit = limit;
314  else
316 
317  if (scc && scc->level != ~0)
318  s->level = scc->level;
319  else if (cc && cc->level != ~0)
320  s->level = cc->level;
321  else
322  s->level = lm->default_log_level;
323 
324  if (scc && scc->syslog_level != ~0)
325  s->syslog_level = scc->syslog_level;
326  else if (cc && cc->syslog_level != ~0)
327  s->syslog_level = cc->syslog_level;
328  else
330 
331  if (subclass)
332  length += 1 + vec_len (s->name);
333  if (length > lm->max_class_name_length)
335  return (c->index << 16) | (s->index);
336 }
337 
339 vlib_log_register_class (char *class, char *subclass)
340 {
341  return vlib_log_register_class_internal (class, subclass,
342  0 /* default rate limit */ );
343 }
344 
346 vlib_log_register_class_rate_limit (char *class, char *subclass, u32 limit)
347 {
348  return vlib_log_register_class_internal (class, subclass, limit);
349 }
350 
351 
352 u8 *
353 format_vlib_log_level (u8 * s, va_list * args)
354 {
355  vlib_log_level_t i = va_arg (*args, vlib_log_level_t);
356  char *t = 0;
357 
358  switch (i)
359  {
360 #define _(uc,lc) case VLIB_LOG_LEVEL_##uc: t = #lc; break;
362 #undef _
363  default:
364  return format (s, "unknown");
365  }
366  return format (s, "%s", t);
367 }
368 
369 static clib_error_t *
371 {
372  vlib_log_main_t *lm = &log_main;
374 
375  gettimeofday (&lm->time_zero_timeval, 0);
376  lm->time_zero = vlib_time_now (vm);
377 
378  vec_validate (lm->entries, lm->size);
379 
380  while (r)
381  {
383  if (r->default_level)
385  if (r->default_syslog_level)
387  r = r->next;
388  }
389 
390  r = lm->registrations;
391  while (r)
392  {
393  vlib_log_debug (r->class, "initialized");
394  r = r->next;
395  }
396  return 0;
397 }
398 
400 
401 
402 static clib_error_t *
404  unformat_input_t * input, vlib_cli_command_t * cmd)
405 {
406  clib_error_t *error = 0;
407  vlib_log_main_t *lm = &log_main;
408  vlib_log_entry_t *e;
409  int i = last_log_entry ();
410  int count = lm->count;
411  f64 time_offset;
412 
413  time_offset = (f64) lm->time_zero_timeval.tv_sec
414  + (((f64) lm->time_zero_timeval.tv_usec) * 1e-6) - lm->time_zero;
415 
416  while (count--)
417  {
418  e = vec_elt_at_index (lm->entries, i);
419  vlib_cli_output (vm, "%U %-10U %-14U %v",
420  format_time_float, 0, e->timestamp + time_offset,
423  i = (i + 1) % lm->size;
424  }
425 
426  return error;
427 }
428 
429 /* *INDENT-OFF* */
430 VLIB_CLI_COMMAND (cli_show_log, static) = {
431  .path = "show logging",
432  .short_help = "show logging",
433  .function = show_log,
434 };
435 /* *INDENT-ON* */
436 
437 static clib_error_t *
439  unformat_input_t * input, vlib_cli_command_t * cmd)
440 {
441  clib_error_t *error = 0;
442  vlib_log_main_t *lm = &log_main;
445 
446  vlib_cli_output (vm, "%-20s %u entries", "Buffer Size:", lm->size);
447  vlib_cli_output (vm, "Defaults:\n");
448  vlib_cli_output (vm, "%-20s %U", " Log Level:",
450  vlib_cli_output (vm, "%-20s %U", " Syslog Log Level:",
452  vlib_cli_output (vm, "%-20s %u msgs/sec", " Rate Limit:",
453  lm->default_rate_limit);
454  vlib_cli_output (vm, "\n");
455  vlib_cli_output (vm, "%-22s %-14s %-14s %s",
456  "Class/Subclass", "Level", "Syslog Level", "Rate Limit");
457 
458 
459  u8 *defstr = format (0, "default");
460  vec_foreach (c, lm->classes)
461  {
462  vlib_cli_output (vm, "%v", c->name);
463  vec_foreach (sc, c->subclasses)
464  {
465  vlib_cli_output (vm, " %-20v %-14U %-14U %d",
466  sc->name ? sc->name : defstr,
469  sc->rate_limit);
470  }
471  }
472  vec_free (defstr);
473 
474  return error;
475 }
476 
477 /* *INDENT-OFF* */
478 VLIB_CLI_COMMAND (cli_show_log_config, static) = {
479  .path = "show logging configuration",
480  .short_help = "show logging configuration",
481  .function = show_log_config,
482 };
483 /* *INDENT-ON* */
484 
485 static clib_error_t *
487  unformat_input_t * input, vlib_cli_command_t * cmd)
488 {
489  clib_error_t *error = 0;
490  vlib_log_main_t *lm = &log_main;
491  vlib_log_entry_t *e;
492  int i = last_log_entry ();
493  int count = lm->count;
494 
495  while (count--)
496  {
497  e = vec_elt_at_index (lm->entries, i);
498  vec_free (e->string);
499  i = (i + 1) % lm->size;
500  }
501 
502  lm->count = 0;
503  lm->next = 0;
504  vlib_log_info (log_log.class, "log cleared");
505  return error;
506 }
507 
508 /* *INDENT-OFF* */
509 VLIB_CLI_COMMAND (cli_clear_log, static) = {
510  .path = "clear logging",
511  .short_help = "clear logging",
512  .function = clear_log,
513 };
514 /* *INDENT-ON* */
515 
516 static uword
517 unformat_vlib_log_level (unformat_input_t * input, va_list * args)
518 {
519  vlib_log_level_t *level = va_arg (*args, vlib_log_level_t *);
520  u8 *level_str = NULL;
521  uword rv = 1;
522  if (unformat (input, "%s", &level_str))
523  {
524 #define _(uc, lc) \
525  const char __##uc[] = #lc; \
526  if (!strcmp ((const char *) level_str, __##uc)) \
527  { \
528  *level = VLIB_LOG_LEVEL_##uc; \
529  rv = 1; \
530  goto done; \
531  }
533  rv = 0;
534 #undef _
535  }
536 done:
537  vec_free (level_str);
538  return rv;
539 }
540 
541 static uword
542 unformat_vlib_log_class (unformat_input_t * input, va_list * args)
543 {
544  vlib_log_class_data_t **class = va_arg (*args, vlib_log_class_data_t **);
545  uword rv = 0;
546  u8 *class_str = NULL;
547  vlib_log_main_t *lm = &log_main;
548  if (unformat (input, "%v", &class_str))
549  {
550  vlib_log_class_data_t *cdata;
551  vec_foreach (cdata, lm->classes)
552  {
553  if (vec_is_equal (cdata->name, class_str))
554  {
555  *class = cdata;
556  rv = 1;
557  break;
558  }
559  }
560  }
561  vec_free (class_str);
562  return rv;
563 }
564 
565 static clib_error_t *
567  unformat_input_t * input, vlib_cli_command_t * cmd)
568 {
569  unformat_input_t _line_input, *line_input = &_line_input;
570  clib_error_t *rv = NULL;
571  int rate_limit;
572  bool set_rate_limit = false;
573  bool set_level = false;
574  bool set_syslog_level = false;
575  vlib_log_level_t level;
576  vlib_log_level_t syslog_level;
577 
578  /* Get a line of input. */
579  if (!unformat_user (input, unformat_line_input, line_input))
580  return 0;
581 
582  vlib_log_class_data_t *class = NULL;
583  if (!unformat (line_input, "%U", unformat_vlib_log_class, &class))
584  {
585  return clib_error_return (0, "unknown log class `%U'",
586  format_unformat_error, line_input);
587  }
588  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
589  {
590  if (unformat (line_input, "rate-limit %d", &rate_limit))
591  {
592  set_rate_limit = true;
593  }
594  else
595  if (unformat
596  (line_input, "level %U", unformat_vlib_log_level, &level))
597  {
598  set_level = true;
599  }
600  else
601  if (unformat
602  (line_input, "syslog-level %U", unformat_vlib_log_level,
603  &syslog_level))
604  {
605  set_syslog_level = true;
606  }
607  else
608  {
609  return clib_error_return (0, "unknown input `%U'",
610  format_unformat_error, line_input);
611  }
612  }
613 
614  if (set_level)
615  {
616  vlib_log_subclass_data_t *subclass;
617  vec_foreach (subclass, class->subclasses)
618  {
619  subclass->level = level;
620  }
621  }
622  if (set_syslog_level)
623  {
624  vlib_log_subclass_data_t *subclass;
625  vec_foreach (subclass, class->subclasses)
626  {
627  subclass->syslog_level = syslog_level;
628  }
629  }
630  if (set_rate_limit)
631  {
632  vlib_log_subclass_data_t *subclass;
633  vec_foreach (subclass, class->subclasses)
634  {
635  subclass->rate_limit = rate_limit;
636  }
637  }
638 
639  return rv;
640 }
641 
642 /* *INDENT-OFF* */
643 VLIB_CLI_COMMAND (cli_set_log, static) = {
644  .path = "set logging class",
645  .short_help = "set logging class <class> [rate-limit <int>] "
646  "[level <level>] [syslog-level <level>]",
647  .function = set_log_class,
648 };
649 /* *INDENT-ON* */
650 
651 static clib_error_t *
653  unformat_input_t * input, vlib_cli_command_t * cmd)
654 {
655  unformat_input_t _line_input, *line_input = &_line_input;
656  clib_error_t *rv = NULL;
657  int unthrottle_time;
658  vlib_log_main_t *lm = &log_main;
659 
660  /* Get a line of input. */
661  if (!unformat_user (input, unformat_line_input, line_input))
662  return 0;
663 
664  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
665  {
666  if (unformat (line_input, "%d", &unthrottle_time))
667  lm->unthrottle_time = unthrottle_time;
668  else
669  return clib_error_return (0, "unknown input `%U'",
670  format_unformat_error, line_input);
671  }
672 
673  return rv;
674 }
675 
676 /* *INDENT-OFF* */
677 VLIB_CLI_COMMAND (cli_set_log_params, static) = {
678  .path = "set logging unthrottle-time",
679  .short_help = "set logging unthrottle-time <int>",
680  .function = set_log_unth_time,
681 };
682 /* *INDENT-ON* */
683 
684 static clib_error_t *
686  unformat_input_t * input, vlib_cli_command_t * cmd)
687 {
688  unformat_input_t _line_input, *line_input = &_line_input;
689  clib_error_t *rv = NULL;
690  int size;
691  vlib_log_main_t *lm = &log_main;
692 
693  /* Get a line of input. */
694  if (!unformat_user (input, unformat_line_input, line_input))
695  return 0;
696 
697  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
698  {
699  if (unformat (line_input, "%d", &size))
700  {
701  lm->size = size;
702  vec_validate (lm->entries, lm->size);
703  }
704  else
705  return clib_error_return (0, "unknown input `%U'",
706  format_unformat_error, line_input);
707  }
708 
709  return rv;
710 }
711 
712 /* *INDENT-OFF* */
713 VLIB_CLI_COMMAND (cli_set_log_size, static) = {
714  .path = "set logging size",
715  .short_help = "set logging size <int>",
716  .function = set_log_size,
717 };
718 /* *INDENT-ON* */
719 
720 static uword
722 {
723  vlib_log_class_data_t *class = va_arg (*args, vlib_log_class_data_t *);
724  vlib_log_subclass_data_t **subclass =
725  va_arg (*args, vlib_log_subclass_data_t **);
726  uword rv = 0;
727  u8 *subclass_str = NULL;
728  if (unformat (input, "%v", &subclass_str))
729  {
730  vlib_log_subclass_data_t *scdata;
731  vec_foreach (scdata, class->subclasses)
732  {
733  if (vec_is_equal (scdata->name, subclass_str))
734  {
735  rv = 1;
736  *subclass = scdata;
737  break;
738  }
739  }
740  }
741  vec_free (subclass_str);
742  return rv;
743 }
744 
745 static clib_error_t *
747  unformat_input_t * input, vlib_cli_command_t * cmd)
748 {
749  unformat_input_t _line_input, *line_input = &_line_input;
750  /* Get a line of input. */
751  if (!unformat_user (input, unformat_line_input, line_input))
752  return 0;
753 
754  vlib_log_class_data_t *class = NULL;
755  vlib_log_subclass_data_t *subclass = NULL;
756  vlib_log_level_t level;
757  if (unformat (line_input, "%U", unformat_vlib_log_level, &level))
758  {
759  if (unformat (line_input, "%U", unformat_vlib_log_class, &class))
760  {
761  if (unformat
762  (line_input, "%U", unformat_vlib_log_subclass, class,
763  &subclass))
764  {
765  vlib_log (level,
766  (class->index << 16) | (subclass->index), "%U",
767  format_unformat_input, line_input);
768  }
769  else
770  {
771  return clib_error_return (0,
772  "unknown log subclass near beginning of `%U'",
773  format_unformat_error, line_input);
774  }
775  }
776  else
777  {
778  return clib_error_return (0,
779  "unknown log class near beginning of `%U'",
780  format_unformat_error, line_input);
781  }
782  }
783  else
784  {
785  return clib_error_return (0, "unknown log level near beginning of `%U'",
786  format_unformat_error, line_input);
787  }
788  return 0;
789 }
790 
791 /* *INDENT-OFF* */
792 VLIB_CLI_COMMAND (cli_test_log, static) = {
793  .path = "test log",
794  .short_help = "test log <level> <class> <subclass> <message>",
795  .function = test_log_class_subclass,
796 };
797 /* *INDENT-ON* */
798 
799 static clib_error_t *
801 {
802  vlib_log_main_t *lm = &log_main;
804  uword *p;
805 
806  if (lm->config_index_by_name == 0)
807  lm->config_index_by_name = hash_create_string (0, sizeof (uword));
808 
809  p = hash_get_mem (lm->config_index_by_name, name);
810 
811  if (p)
812  return clib_error_return (0, "logging class '%s' already configured",
813  name);
814 
815  clib_memset_u8 (&tmp, 0xff, sizeof (vlib_log_class_config_t));
816 
818  {
819  if (unformat (input, "level %U", unformat_vlib_log_level, &tmp.level))
820  ;
821  else if (unformat (input, "syslog-level %U", unformat_vlib_log_level,
822  &tmp.syslog_level))
823  ;
824  else if (unformat (input, "rate-limit %u", &tmp.rate_limit))
825  ;
826  else
827  return clib_error_return (0, "unknown input '%U'",
828  format_unformat_error, input);
829  }
830 
831  vec_add2 (lm->configs, cc, 1);
832  clib_memcpy_fast (cc, &tmp, sizeof (vlib_log_class_config_t));
833  cc->name = name;
834  hash_set_mem (lm->config_index_by_name, name, cc - lm->configs);
835  return 0;
836 }
837 
838 static clib_error_t *
840 {
841  vlib_log_main_t *lm = &log_main;
842  unformat_input_t sub_input;
843  u8 *class = 0;
844 
846  {
847  if (unformat (input, "size %d", &lm->size))
848  vec_validate (lm->entries, lm->size);
849  else if (unformat (input, "unthrottle-time %d", &lm->unthrottle_time))
850  ;
851  else if (unformat (input, "default-log-level %U",
853  ;
854  else if (unformat (input, "default-syslog-log-level %U",
857  ;
858  else if (unformat (input, "add-to-elog"))
859  lm->add_to_elog = 1;
860  else if (unformat (input, "class %s %U", &class,
861  unformat_vlib_cli_sub_input, &sub_input))
862  {
863  clib_error_t *err;
864  err = log_config_class (vm, (char *) class, &sub_input);
865  class = 0;
866  unformat_free (&sub_input);
867  if (err)
868  return err;
869  }
870  else
871  {
872  return unformat_parse_error (input);
873  }
874  }
875 
876  return 0;
877 }
878 
880 
881 /*
882  * fd.io coding-style-patch-verification: ON
883  *
884  * Local Variables:
885  * eval: (c-set-style "gnu")
886  * End:
887  */
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
Definition: log.c:339
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:524
static clib_error_t * show_log_config(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: log.c:438
__clib_export u8 * va_format(u8 *s, const char *fmt, va_list *va)
Definition: format.c:391
vlib_log_class_t class
Definition: log.h:85
unix_main_t unix_main
Definition: main.c:62
static clib_error_t * show_log(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: log.c:403
static const int colors[]
Definition: log.c:38
#define UNIX_FLAG_NOSYSLOG
Definition: unix.h:62
static clib_error_t * log_config_class(vlib_main_t *vm, char *name, unformat_input_t *input)
Definition: log.c:800
u8 * format_time_float(u8 *s, va_list *args)
Definition: unix-formats.c:363
#define vec_c_string_is_terminated(V)
Test whether a vector is a NULL terminated c-string.
Definition: vec.h:1125
u8 * format_vlib_log_level(u8 *s, va_list *args)
Definition: log.c:353
vlib_log_entry_t * entries
Definition: log.h:95
vnet_hw_if_output_node_runtime_t * r
vlib_log_level_t level
Definition: log.h:55
u32 flags
Definition: unix.h:58
VLIB_REGISTER_LOG_CLASS(log_log, static)
static vlib_log_class_data_t * get_class_data(vlib_log_class_t ci)
Definition: log.c:75
int last_log_entry()
Definition: log.c:62
#define foreach_vlib_log_level
Definition: log.h:22
vlib_log_level_t syslog_level
Definition: log.h:57
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:325
static clib_error_t * clear_log(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: log.c:486
#define vec_terminate_c_string(V)
(If necessary) NULL terminate a vector containing a c-string.
Definition: vec.h:1133
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:607
vlib_log_class_data_t * classes
Definition: log.h:96
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:645
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:989
f64 timestamp
Definition: log.h:46
#define hash_set_mem(h, key, value)
Definition: hash.h:275
int add_to_elog
Definition: log.h:112
string name[64]
Definition: fib.api:25
vlib_log_level_t level
Definition: log.h:74
vlib_log_class_registration_t * registrations
Definition: log.h:115
unsigned char u8
Definition: types.h:56
static uword unformat_vlib_log_subclass(unformat_input_t *input, va_list *args)
Definition: log.c:721
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
double f64
Definition: types.h:142
unsigned int u32
Definition: types.h:88
#define vec_add(V, E, N)
Add N elements to end of vector V (no header, unspecified alignment)
Definition: vec.h:689
__clib_export word fformat(FILE *f, char *fmt,...)
Definition: format.c:466
static clib_error_t * vlib_log_init(vlib_main_t *vm)
Definition: log.c:370
log_level
Definition: vpe_types.api:33
u32 vlib_log_class_t
Definition: vlib.h:52
if(node->flags &VLIB_NODE_FLAG_TRACE) vnet_interface_output_trace(vm
static clib_error_t * log_config(vlib_main_t *vm, unformat_input_t *input)
Definition: log.c:839
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:172
struct timeval time_zero_timeval
Definition: log.h:106
description fragment has unexpected format
Definition: map.api:433
struct vlib_log_registration * next
Definition: log.h:90
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
#define clib_error_return(e, args...)
Definition: error.h:99
#define UNIX_FLAG_NOCOLOR
Definition: unix.h:63
#define vlib_log_info(...)
Definition: log.h:136
char * subclass_name
Definition: log.h:84
static vlib_log_class_t vlib_log_register_class_internal(char *class, char *subclass, u32 limit)
Definition: log.c:267
u8 * format_indent(u8 *s, va_list *args)
Definition: log.c:102
int __clib_unused rv
Definition: application.c:491
vlib_log_class_t vlib_log_register_class_rate_limit(char *class, char *subclass, u32 limit)
Definition: log.c:346
static const int log_level_to_syslog_priority[]
Definition: log.c:49
int default_log_level
Definition: log.h:100
#define hash_create_string(elts, value_bytes)
Definition: hash.h:690
while(n_left_from > 0)
unformat_function_t unformat_line_input
Definition: format.h:275
Definition: cJSON.c:88
static clib_error_t * set_log_class(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: log.c:566
struct _unformat_input_t unformat_input_t
u32 size
Definition: vhost_user.h:125
int default_syslog_log_level
Definition: log.h:101
u32 * tmp
#define ELOG_DATA(em, f)
Definition: elog.h:484
int size
Definition: log.h:97
static clib_error_t * set_log_unth_time(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: log.c:652
vlib_log_main_t log_main
Definition: log.c:23
vlib_log_level_t syslog_level
Definition: log.h:75
static clib_error_t * test_log_class_subclass(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: log.c:746
#define vlib_log_debug(...)
Definition: log.h:137
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
int next
Definition: log.h:97
int cJSON_bool fmt
Definition: cJSON.h:160
RFC5424 syslog protocol declarations.
The fine-grained event logger allows lightweight, thread-safe event logging at minimum cost...
u8 * format_unformat_input(u8 *s, va_list *va)
Definition: unformat.c:143
#define VLIB_EARLY_CONFIG_FUNCTION(x, n,...)
Definition: init.h:220
#define UNFORMAT_END_OF_INPUT
Definition: format.h:137
svmdb_client_t * c
static_always_inline uword vlib_get_thread_index(void)
Definition: threads.h:208
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:261
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:395
void vlib_log(vlib_log_level_t level, vlib_log_class_t class, char *fmt,...)
Definition: log.c:131
static vlib_log_subclass_data_t * get_subclass_data(vlib_log_class_t ci)
Definition: log.c:82
vlib_log_subclass_data_t * subclasses
Definition: log.h:69
#define ELOG_TYPE_DECLARE(f)
Definition: elog.h:442
#define vec_is_equal(v1, v2)
Compare two vectors, not NULL-pointer tolerant.
Definition: vec.h:1024
int default_rate_limit
Definition: log.h:99
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:163
uword unformat_vlib_cli_sub_input(unformat_input_t *i, va_list *args)
Definition: cli.c:163
Definition: log.h:42
#define ASSERT(truth)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:716
vlib_log_class_t class
Definition: log.h:45
#define UNIX_FLAG_INTERACTIVE
Definition: unix.h:60
int count
Definition: log.h:97
static uword unformat_vlib_log_class(unformat_input_t *input, va_list *args)
Definition: log.c:542
static uword unformat_vlib_log_level(unformat_input_t *input, va_list *args)
Definition: log.c:517
char const int length
Definition: cJSON.h:163
vlib_log_level_t default_syslog_level
Definition: log.h:87
char * class_name
Definition: log.h:83
static_always_inline void * clib_memcpy_fast(void *restrict dst, const void *restrict src, size_t n)
Definition: string.h:92
static_always_inline void clib_memset_u8(void *p, u8 val, uword count)
Definition: string.h:441
vlib_log_level_t level
Definition: log.h:44
f64 time_zero
Definition: log.h:107
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:38
vlib_log_class_config_t * configs
Definition: log.h:110
#define unformat_parse_error(input)
Definition: format.h:261
vlib_log_level_t default_level
Definition: log.h:86
u32 max_class_name_length
Definition: log.h:103
u8 * format_vlib_log_class(u8 *s, va_list *args)
Definition: log.c:89
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static clib_error_t * set_log_size(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: log.c:685
u64 uword
Definition: types.h:112
static void unformat_free(unformat_input_t *i)
Definition: format.h:155
#define hash_get_mem(h, key)
Definition: hash.h:269
f64 last_event_timestamp
Definition: log.h:59
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
uword * config_index_by_name
Definition: log.h:111
static int log_level_is_enabled(vlib_log_level_t level, vlib_log_level_t configured)
Definition: log.c:121
#define vec_foreach(var, vec)
Vector iterator.
vlib_log_level_t
Definition: log.h:33
u8 count
Definition: dhcp.api:208
u8 * string
Definition: log.h:47
elog_main_t elog_main
Definition: main.h:300
int unthrottle_time
Definition: log.h:102
vlib_global_main_t vlib_global_main
Definition: main.c:1786
__clib_export u32 elog_string(elog_main_t *em, char *fmt,...)
add a string to the event-log string table
Definition: elog.c:582
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:163