admin管理员组文章数量:1794759
深入浅出思科VPP24.02系列:日志模块vlib
01=上期内容回顾
本期我们将继续深入浅出思科vpp24.02系列专题,介绍VPP的日志log功能初始化的函数的业务逻辑介绍。
02=vlib_log_init函数介绍
在往期的内容中,我们介绍了思科VPP软件对日志功能的初始化的函数vlib_log_init()的业务逻辑介绍,其在vlib_main()中备调用的。
log模块初始化逻辑如下所示
代码语言:javascript代码运行次数:0运行复制clib_error_t *vlib_log_init (vlib_main_t *vm)
{
vlib_log_main_t *lm = &log_main;
vlib_log_class_registration_t *r = lm->registrations;
gettimeofday (&lm->time_zero_timeval, 0);
lm->time_zero = vlib_time_now (vm);
vec_validate (lm->entries, lm->size);
while (r)
{
r->class = vlib_log_register_class (r->class_name, r->subclass_name);
if (r->default_level)
vlib_log_get_subclass_data (r->class)->level = r->default_level;
if (r->default_syslog_level)
vlib_log_get_subclass_data (r->class)->syslog_level =
r->default_syslog_level;
r = r->next;
}
r = lm->registrations;
while (r)
{
vlib_log_debug (r->class, "initialized");
r = r->next;
}
return 0;
}
函数声明:clib_error_t *vlib_log_init (vlib_main_t *vm);
返回值:此处应该返回clib_error_t 类型的更佳。
03=函数工程意义分析
1、日志系统的主要结构体:这里lm是指向日志系统主要结构的指针,它引用了全局变量log_main。这个结构包含了日志系统的各种状态和配置。。
代码语言:javascript代码运行次数:0运行复制 vlib_log_main_t *lm = &log_main;
vlib_log_class_registration_t *r = lm->registrations;
结构体介绍:vlib_log_main_t用于管理和配置日志记录的行为:
代码语言:javascript代码运行次数:0运行复制typedef struct
{
vlib_log_entry_t *entries;
vlib_log_class_data_t *classes;
int size, next, count;
int default_rate_limit;
int default_log_level;
int default_syslog_log_level;
int unthrottle_time;
u32 max_class_name_length;
/* time zero */
struct timeval time_zero_timeval;
f64 time_zero;
/* config */
vlib_log_class_config_t *configs;
uword *config_index_by_name;
int add_to_elog;
/* registrations */
vlib_log_class_registration_t *registrations;
} vlib_log_main_t
结构体参数解释:
- vlib_log_entry_t *entries;这是一个指向日志条目数组的指针,每个条目记录了一个具体的日志事件。
- vlib_log_class_data_t *classes;指向日志类别数据数组的指针,日志类别用于区分不同类型的日志消息。
- int size, next, count;size 表示日志条目数组的大小。
next
指向下一个将要写入的日志条目的索引。count
表示当前已记录的日志条目数量。 - 日志配置参数
- int default_rate_limit; 默认速率限制,用于控制日志输出的频率。
- int default_log_level; 默认日志级别,决定哪些级别的日志消息应该被记录。
- int default_syslog_log_level; 默认的系统日志级别,控制哪些级别的日志应该被发送到系统日志。
- int unthrottle_time; 解限时间,用于在达到速率限制后,指定多少时间后可以再次记录日志。
u32 max_class_name_length;
日志类别名称的最大长度。- 时间相关
- struct timeval time_zero_timeval; 记录了“时间零点”的timeval结构体,用于时间戳的计算。
- f64 time_zero; “时间零点”的浮点数表示,通常用于更精确的时间计算。
- 配置信息
- vlib_log_class_config_t *configs; 指向日志类别配置数组的指针。
- uword *config_index_by_name; 通过日志类别名称查找配置的索引数组。
- int add_to_elog; 一个标志,指示是否将日志消息添加到错误日志中。
- 注册信息:
vlib_log_class_registration_t *registrations;
指向日志类别注册信息的指针,用于跟踪哪些日志类别已经被注册。
2、时间戳操作
代码语言:javascript代码运行次数:0运行复制 gettimeofday (&lm->time_zero_timeval, 0);
lm->time_zero = vlib_time_now (vm);
gettimeofday 是linux系统函数,它的目的是获取当前时间戳,并将其存储在lm->time_zero_timeval中。
lm->time_zero = vlib_time_now(vm);使用VPP时间函数获取时间戳,将其存放在lm->time_zero 之中。
3、验证日志条目数量的大小,确保其大小够用,该部分会采用vpp的vec机制,如果空间大小不够,会自动拓展来确保空间足够。
代码语言:javascript代码运行次数:0运行复制vec_validate (lm->entries, lm->size);
4、注册日志类别和日志的level等级
代码语言:javascript代码运行次数:0运行复制while (r)
{
r->class = vlib_log_register_class (r->class_name, r->subclass_name);
if (r->default_level)
vlib_log_get_subclass_data (r->class)->level = r->default_level;
if (r->default_syslog_level)
vlib_log_get_subclass_data (r->class)->syslog_level = r->default_syslog_level;
r = r->next;
}
技术点补充:syslog的日志等级介绍,其level分为如下所示的等级,一般默认使用log_info等级。
代码语言:javascript代码运行次数:0运行复制LOG_EMERG system is unusable
LOG_ALERT action must be taken immediately
LOG_CRIT critical conditions
LOG_ERR error conditions
LOG_WARNING warning conditions
LOG_NOTICE normal, but significant, condition
LOG_INFO informational message
LOG_DEBUG debug-level message
5、输出初始化标志
代码语言:javascript代码运行次数:0运行复制r = lm->registrations;
while (r)
{
vlib_log_debug (r->class, "initialized");
r = r->next;
}
6、返回值:源代码中为return 0 建议修改为返回clib_error_t 里面的参数
04=log模块的使用方法介绍
1、首先在vpp启动配置文件中配置文件生成的路径,配置文件的详细参数可以参考如下文所述。
Ubuntu系统运行VPP24.02系列:startup.conf配置文件解读
代码语言:javascript代码运行次数:0运行复制unix {
nodaemon
log /var/log/vpp/vpp.log
full-coredump
cli-listen /run/vpp/cli.sock
gid vpp
startup-config /etc/vpp/start.txt
}
在unix的配置参数下,配置的是log文件生成的路径,如果不存在OS下创建该路径即可,也可以按照需求设置指定的日志路径下。
2、配置log模块的默认level参数,也是在startup.conf文件中配置,这里的level 等级可以按照需求自行配置syslog的告警等级。
代码语言:javascript代码运行次数:0运行复制logging {
default-log-level info
default-syslog-log-level info
}
3、查询配置信息,将lm里面存储的log 配置信息输出,该输出工作在管理线程main线程上。
代码语言:javascript代码运行次数:0运行复制static clib_error_t *show_log_config (vlib_main_t * vm,
unformat_input_t * input, vlib_cli_command_t * cmd)
{
clib_error_t *error = 0;
vlib_log_main_t *lm = &log_main;
vlib_log_class_data_t *c;
vlib_log_subclass_data_t *sc;
vlib_cli_output (vm, "%-20s %u entries", "Buffer Size:", lm->size);
vlib_cli_output (vm, "Defaults:\n");
vlib_cli_output (vm, "%-20s %U", " Log Level:",
format_vlib_log_level, lm->default_log_level);
vlib_cli_output (vm, "%-20s %U", " Syslog Log Level:",
format_vlib_log_level, lm->default_syslog_log_level);
vlib_cli_output (vm, "%-20s %u msgs/sec", " Rate Limit:",
lm->default_rate_limit);
vlib_cli_output (vm, "\n");
vlib_cli_output (vm, "%-22s %-14s %-14s %s",
"Class/Subclass", "Level", "Syslog Level", "Rate Limit");
u8 *defstr = format (0, "default");
vec_foreach (c, lm->classes)
{
vlib_cli_output (vm, "%v", c->name);
vec_foreach (sc, c->subclasses)
{
vlib_cli_output (vm, " %-20v %-14U %-14U %d",
sc->name ? sc->name : defstr,
format_vlib_log_level, sc->level,
format_vlib_log_level, sc->syslog_level,
sc->rate_limit);
}
}
vec_free (defstr);
return error;
}
VLIB_CLI_COMMAND (cli_show_log_config, static) = {
.path = "show logging configuration",
.short_help = "show logging configuration",
.function = show_log_config,
};
4、查询生成的log日志方法,通过show logging命令输出
代码语言:javascript代码运行次数:0运行复制static clib_error_t *show_log (vlib_main_t * vm,
unformat_input_t * input, vlib_cli_command_t * cmd)
{
clib_error_t *error = 0;
vlib_log_main_t *lm = &log_main;
vlib_log_entry_t *e;
int i = last_log_entry ();
int count = lm->count;
f64 time_offset;
time_offset = (f64) lm->time_zero_timeval.tv_sec
+ (((f64) lm->time_zero_timeval.tv_usec) * 1e-6) - lm->time_zero;
while (count--)
{
e = vec_elt_at_index (lm->entries, i);
vlib_cli_output (vm, "%U %-10U %-14U %v", format_time_float, NULL,
e->timestamp + time_offset, format_vlib_log_level,
e->level, format_vlib_log_class, e->class, e->string);
i = (i + 1) % lm->size;
}
return error;
}
VLIB_CLI_COMMAND (cli_show_log, static) = {
.path = "show logging",
.short_help = "show logging",
.function = show_log,
};
5、清除操作,通过clear logging命令进行清理
代码语言:javascript代码运行次数:0运行复制static clib_error_t *clear_log (vlib_main_t * vm,
unformat_input_t * input, vlib_cli_command_t * cmd)
{
clib_error_t *error = 0;
vlib_log_main_t *lm = &log_main;
vlib_log_entry_t *e;
int i = last_log_entry ();
int count = lm->count;
while (count--)
{
e = vec_elt_at_index (lm->entries, i);
vec_free (e->string);
i = (i + 1) % lm->size;
}
lm->count = 0;
lm->next = 0;
vlib_log_info (log_log.class, "log cleared");
return error;
}
VLIB_CLI_COMMAND (cli_clear_log, static) = {
.path = "clear logging",
.short_help = "clear logging",
.function = clear_log,
};
05=本次内容总结
本次内容主要是介绍了VPP中日志模块log的初始化操作、使用方法、查询方法、清理方法的介绍,其思维导图可以总结为:
总的来说,在vpp的vlib_log_init()这个函数中,日志系统被初始化,包括设置时间戳参数、创建/验证日志条目数组的大小、注册日志类别以及设置默认的日志级别和syslog级别等的功能。在使用章节中,我们介绍log功能在vpp上的使用方法,有需要的小伙伴们可以根据项目需要自己修改相关的逻辑和配置。好了,本次介绍就到此为止。小伙伴们,你们学会了吗?
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。原始发表:2024-10-15,如有侵权请联系 cloudcommunity@tencent 删除init函数配置日志系统本文标签: 深入浅出思科VPP2402系列日志模块vlib
版权声明:本文标题:深入浅出思科VPP24.02系列:日志模块vlib 内容由林淑君副主任自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.xiehuijuan.com/baike/1754706268a1705447.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论