Moduleinführung
Wenn Nginx während des Betriebs das abnormale Exit-Signal SIGINT empfängt, wird der aktuelle Funktionsaufrufstapel in die Protokolldatei ausgegeben. Neben der Handhabung von SIGINT können Sie im Modul auch entsprechende Signale hinzufügen.
Modulentwicklungsprozess
<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>
Jedes Modul verfügt über eine entsprechende Konfigurationsstruktur.
2. Implementieren Sie create_conf, um Speicher für die Konfigurationsstruktur zu reservieren und den entsprechenden Zeiger zurückzugeben
<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>
Das Obige ist der Prozess zum Erstellen der Struktur.
3. Legen Sie für jedes Konfigurationselement eine Set-Callback-Funktion fest. Wenn der Konfigurationselementparameter eine Zahl ist, können Sie ihn auf ngx_conf_set_num_slot setzen, andernfalls müssen Sie ihn selbst implementieren.
<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>
Das Obige ist der Prozess des Parsens von Konfigurationselementen
4. Die Initialisierungssignalverarbeitungsfunktion
<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>
ist rund um die Sigaktion
implementiert
5. Beim Schreiben der Ausnahmebehandlungsfunktion
<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>
müssen Sie die Signalverarbeitungsfunktion auf die Standardverarbeitungssituation zurücksetzen und das Signal nach Abschluss der Verarbeitung erneut senden.
Referenzmaterialien
Das von Taobao veröffentlichte ngx_backtrace_module-Modul
ngx_xqw_backtrace_module-Download-Link
http://download.csdn.net/detail/wxq714586001/8719535
Das Obige stellt die Entwicklung des Nginx-Moduls vor: ngx_xqw_backtrace_module, einschließlich der relevanten Inhalte. Ich hoffe, es wird für Freunde hilfreich sein, die sich für PHP-Tutorials interessieren.