Heim  >  Artikel  >  Backend-Entwicklung  >  Nginx-Modulentwicklung: ngx_xqw_backtrace_module

Nginx-Modulentwicklung: ngx_xqw_backtrace_module

WBOY
WBOYOriginal
2016-08-08 09:24:051095Durchsuche

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

  1. Konfigurationsstruktur erstellen
<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.

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn