模块介绍
当nginx运行过程中收到异常退出信号SIGINT,会将当前函数调用堆栈输出到日志文件当中。除了处理SIGINT之外,还可以在模块中添加相应信号。
模块开发流程
<code><span>typedef</span><span>struct</span> ngx_xqw_backtrace_conf_s{
ngx_log_t *<span>log</span>; <span>// 日志</span>
ngx_int_t size; <span>// 栈最大深度</span>
}ngx_xqw_backtrace_conf_t;</code>每个模块都有相应的配置结构体。
2. 实现create_conf为配置结构体分配内存,并返回相应的指针
<code><span>// 初始化配置结构体</span><span>static</span><span>void</span> *
ngx_http_xqw_backtrace_create_conf(ngx_cycle_t *cycle)
{
ngx_xqw_backtrace_conf_t *bcf = <span>NULL</span>;
bcf = ngx_palloc(cycle->pool, <span>sizeof</span>(ngx_xqw_backtrace_conf_t));
<span>if</span> (bcf == <span>NULL</span>)
<span>return</span><span>NULL</span>;
bcf->size = NGX_CONF_UNSET;
<span>return</span> bcf;
}</code>以上是创建结构体流程。
3. 为每个配置项设置set回调函数。如果配置项参数是数字,可以将set设置为ngx_conf_set_num_slot,否则需要自己实现。
<code><span>// a、用ngx_get_conf得到该模块的结构体</span><span>// b、获取配置项中的参数 cf->cycle->elts</span><span>// c、由参数构造模块结构体中的成员</span>
static char*
ngx_xqw_backtrace_log(ngx_conf_t <span>*cf</span>, ngx_command_t <span>*cmd</span>, void <span>*conf</span>)
{
ngx_str_t <span>file</span>, <span>*value</span>;
ngx_log_t <span>*log</span>;
ngx_xqw_backtrace_conf_t <span>*bcf</span>;
bcf = (ngx_xqw_backtrace_conf_t <span>*)</span> ngx_get_conf(cf->cycle->conf_ctx,
ngx_xqw_backtrace_module);
value = cf->args->elts;
<span>file</span> = value[<span>1</span>];
<span>// 解析配置文件出错返回 NGX_CONF_ERROR</span><span>if</span> (ngx_conf_full_name(cf->cycle, &<span>file</span>, <span>1</span>) != NGX_OK)
<span>return</span> NGX_CONF_ERROR;
<span>log</span> = ngx_log_create(cf->cycle, &<span>file</span>);
<span>if</span> (<span>log</span> == NULL)
<span>return</span> NGX_CONF_ERROR;
bcf-><span>log</span> = <span>log</span>;
bcf-><span>log</span>->log_level = NGX_LOG_ERR; <span>// 每个LOGFILE都有相应的级别,</span><span>// 需要设置好级别后才能输出到自定义的LOGFILE</span><span>return</span> NGX_CONF_OK;
}
</code>以上是 解析配置项的流程
4. 初始化信号的处理函数
<code><span>static</span> ngx_int_t
ngx_init_error_signal(ngx_log_t *log)
{
ngx_backtrace_signal_t *sigs;
<span>struct</span> sigaction sa;
<span>// 不需要用index的循环方法</span><span>for</span> (sigs = ngx_backtrace_signals; sigs->name != <span>NULL</span>; sigs ++)
{
ngx_memzero(&sa, <span>sizeof</span>(<span>struct</span> sigaction));
sa<span>.sa_handler</span> = sigs->handler;
sigemptyset(&sa<span>.sa_mask</span>);
<span>if</span> (sigaction(sigs->value, &sa, <span>NULL</span>) == -<span>1</span>)
{
perror(<span>"sigaction"</span>);
<span>return</span> NGX_ERROR;
}
}
<span>return</span> NGX_OK;
}</code>围绕sigaction实现
5. 编写异常处理函数
<code>static <span>void</span>
ngx_backtrace_signal_handler(int sig)
{
ngx_backtrace_signal_t <span>*</span>sigs;
ngx_xqw_backtrace_conf_t <span>*</span>bcf;
<span>void</span><span>*</span>buff;
size_t size;
bcf <span>=</span> (ngx_xqw_backtrace_conf_t<span>*</span>) ngx_get_conf(ngx_cycle<span>-></span>conf_ctx,
ngx_xqw_backtrace_module);
ngx_log_error(NGX_LOG_ERR, bcf<span>-></span><span>log</span>, <span>0</span>, <span>"hello error\n"</span>);
<span>if</span> (bcf <span>==</span><span>NULL</span>)
fprintf(stderr, <span>"ngx_get_conf error\n"</span>);
for (sigs <span>=</span> ngx_backtrace_signals; sigs<span>-></span>name <span>!=</span><span>NULL</span>; <span>++</span> sigs)
<span>if</span> (sigs<span>-></span>value <span>==</span> sig)
break;
<span>// 要退出了,故将信号设置为默认处理方式</span>
struct sigaction sa;
ngx_memzero(<span>&</span>sa, sizeof(struct sigaction));
sigemptyset(<span>&</span>sa<span>.</span>sa_mask);
sa<span>.</span>sa_handler <span>=</span> SIG_DFL;
<span>if</span> (sigaction(sigs<span>-></span>value, <span>&</span>sa, <span>NULL</span>) <span>==</span><span>-</span><span>1</span>)
perror(<span>"signal handler sigaction:"</span>);
<span>if</span> (bcf<span>-></span>size <span>==</span> NGX_CONF_UNSET)
bcf<span>-></span>size <span>=</span> MAX_STACK_SIZE;
buff <span>=</span> (<span>void</span><span>*</span>)ngx_palloc(ngx_cycle<span>-></span>pool,
bcf<span>-></span>size <span>*</span> sizeof (<span>void</span><span>*</span>));
<span>if</span> (buff <span>==</span><span>NULL</span>)
fprintf(stderr, <span>"ngx_palloc error\n"</span>);
size <span>=</span> backtrace(buff, bcf<span>-></span>size);
backtrace_symbols_fd(buff, size, bcf<span>-></span><span>log</span><span>-></span>file<span>-></span>fd);
kill(ngx_getpid(), sig);
}</code>需要将信号的处理函数恢复为默认处理情况,处理完成后并再次发送该信号。
参考资料
淘宝发布的ngx_backtrace_module模块
ngx_xqw_backtrace_module下载链接
http://download.csdn.net/detail/wxq714586001/8719535
以上就介绍了nginx模块开发:ngx_xqw_backtrace_module,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号