nginx 로그 모듈 분석

nginx 로그 모듈 분석
 
    ngx_errlog_module 모듈 은 nginx 로그 정 보 를 처리 하 는 데 사 용 됩 니 다. nginx 의 core 모듈 중 하나 입 니 다.해석 을 통한 errorlog 설정 항목 은 지정 한 파일 에 서로 다른 등급 의 로그 정 보 를 출력 합 니 다.nginx 시작 과정 에서 설정 파일 을 분석 하 는 중 errorlog 설정 항목 은 errlog 모듈 의 ngx 를 호출 합 니 다.error_log 함수 로 해석 합 니 다.ngx_error_log 함 수 는 errorlog 설정 항목 의 값 은 ngx 에 저 장 됩 니 다.cycle->new_log 구성원 중 설정 파일 에 여러 개의 error 가 있 을 때log 설정 항목 이 적 용 될 때, ngx 를 통 해cycle->new_log. next 멤버 들 이 조직 합 니 다.설정 파일 에 error 가 없 으 면log 설정 항목, 설정 파일 을 분석 한 후 errlog 모듈 의 ngx 를 호출 합 니 다.log_open_default 함 수 는 로그 레벨 을 기본적으로 NGX 로 설정 합 니 다.LOG_ERR, 로그 파일 을 NGX 로 설정ERROR_LOG_PATH (이 매크로 는 configure 에서 지정 합 니 다).설정 파일 에 error 가 있 든 없 든로그 설정 항목 은 항상 로그 출력 이 있 습 니 다. nginx 에서 출력 로 그 를 금지 하 는 유일한 방법 은 error로그 설정 항목 의 출력 로그 파일 이름 은 / dev / null 로 지정 되 었 습 니 다.
 
nginx 로그 레벨
    stderr (0)>= emerg(1) >= alert(2) >= crit(3) >= err(4)>= warn(5) >= notice(6) >= info(7) >= debug(8)
    debug 레벨 이 가장 낮 고 stderr 레벨 이 가장 높 습 니 다.괄호 안의 데 이 터 는 로그 등급 에 대응 하 는 값 입 니 다.
 
error_로그 설정 항목
    error_log  file | stderr |syslog:server=address[,parameter=value]  [debug| info | notice | warn | error | crit | alert | emerg | debug_core |debug_alloc | debug_mutex | debug_event | debug_http | debug_mail | debug_mysql];
    기본 값: errorlog  logs/error.logs   error
    로 그 는 세 가지 출력 방식 이 있 습 니 다. 파일 (file) 로 출력 하고 화면 (stderr) 으로 출력 하 며 syslog (syslog) 로 출력 합 니 다. debug출력 을 표시 하 는 디 버 깅 로그 형식 입 니 다.로그 정 보 를 출력 할 때 로그 등급 이 지정 한 등급 보다 클 때 만 로 그 를 출력 합 니 다. 예 를 들 어:
    error_log  logs/err.logs err
    err 등급 과 같은 로그 정 보 를 logs / err. logs 파일 에 출력 합 니 다. 즉, err, crit, alert, emerg, stderr 로그 정 보 를 출력 합 니 다.
    설정 파일 에 여러 개의 error 가 있 을 때log 설정 항목 이 유효 할 때 상황 이 다 릅 니 다. 다음 과 같 습 니 다.
    error_log  logs/warn.logs  warn
    error_log  logs/alert.logs   alert
    로그 단계 가 alert 보다 클 때 warn. logs 및 alert. logs 파일 에 동시에 출력 되 며, 로그 단계 가 alert 에서 warn 사이 에 있 을 때 warn. logs 파일 에 만 출력 됩 니 다.로그 단계 가 warn 보다 낮 을 때 출력 하지 않 습 니 다.
 
로그 대상 의 구조 체 저장
struct ngx_log_s {
    ngx_uint_t           log_level;        //    
    ngx_open_file_t     *file;             //         

    ngx_atomic_uint_t    connection; //           

    ngx_log_handler_pt   handler;     //          ,      debug   。
    void                *data;    //  handler    , handler       

    /*
     * we declare "action" as "char *" because the actions are usually
     * the static strings and in the "u_char *" case we have to override
     * their types all the time
     */

    char                *action;   //     ,nginx     (      )

    ngx_log_t           *next;  //         
};

자주 사용 하 는 로그 출력 인터페이스:
 
#define ngx_log_error(level, log, ...)                                        \
    if ((log)->log_level >= level) ngx_log_error_core(level, log, __VA_ARGS__)

void ngx_log_error_core(ngx_uint_t level, ngx_log_t *log, ngx_err_t err,
    const char *fmt, ...);

#define ngx_log_debug(level, log, ...)                                        \
    if ((log)->log_level & level)                                             \
        ngx_log_error_core(NGX_LOG_DEBUG, log, __VA_ARGS__)

    ngx_log_error 매크로 는 먼저 들 어 오 는 level 이 ngx 보다 작은 지 판단 합 니 다.cycle->new_log.log_level (여러 개의 log 대상 이 존재 할 때 new log 는 우선 순위 가 가장 낮은 대상, 즉 등급 이 가장 큰 대상 으로 저 장 됩 니 다).level 이 작 으 면 출력 로그 가 필요 없습니다.
    ngx_log_error_core 함수 매개 변수 설명: level 은 로그 등급 을 표시 하고 log 는 로그 대상 을 표시 하 며 err 는 보통 errno 와 같 게 설정 합 니 다.
 
ngx_log_open_기본 함수:
/***nginx                 ***/
ngx_int_t
ngx_log_open_default(ngx_cycle_t *cycle)
{
    static ngx_str_t  error_log = ngx_string(NGX_ERROR_LOG_PATH);

    /***           error_log    new_log.file   ***/
    if (cycle->new_log.file == NULL) {
        cycle->new_log.file = ngx_conf_open_file(cycle, &error_log);
        if (cycle->new_log.file == NULL) {
            return NGX_ERROR;
        }

        cycle->new_log.log_level = NGX_LOG_ERR;
    }

    return NGX_OK;
}

ngx_error_log 함수:
/***           error_log           ***/
static char *
ngx_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    ngx_log_t  *dummy;

    //new_log              
    dummy = &cf->cycle->new_log;

    return ngx_log_set_log(cf, &dummy);
}

ngx_log_set_log 함수:
char *
ngx_log_set_log(ngx_conf_t *cf, ngx_log_t **head)
{
    ngx_log_t  *new_log;
    ngx_str_t  *value, name;

    /***       log_level ==0 ,               ***/
    if (*head != NULL && (*head)->log_level == 0) {
        new_log = *head;

    } else {

        new_log = ngx_pcalloc(cf->pool, sizeof(ngx_log_t));
        if (new_log == NULL) {
            return NGX_CONF_ERROR;
        }

        if (*head == NULL) {
            *head = new_log;
        }
    }

    /***elts   error_log     ,value[0] == "error_log", ...***/
    value = cf->args->elts;

    /***          ***/
    if (ngx_strcmp(value[1].data, "stderr") == 0) {
        ngx_str_null(&name);
        cf->cycle->log_use_stderr = 1;

    } else {
    /***     ***/
        name = value[1];
    }

    /***        。ngx_cycle->open_files               ,  name        
               ,      。***/
    new_log->file = ngx_conf_open_file(cf->cycle, &name);
    if (new_log->file == NULL) {
        return NGX_CONF_ERROR;
    }

    /***  error_log         ***/
    if (ngx_log_set_levels(cf, new_log) != NGX_CONF_OK) {
        return NGX_CONF_ERROR;
    }

    /***        ngx_cycle->new_log   ***/
    if (*head != new_log) {
        ngx_log_insert(*head, new_log);
    }

    return NGX_CONF_OK;
}


ngx_log_set_levels 함수:
static char *
ngx_log_set_levels(ngx_conf_t *cf, ngx_log_t *log)
{
    ngx_uint_t   i, n, d, found;
    ngx_str_t   *value;

    if (cf->args->nelts == 2) {
        log->log_level = NGX_LOG_ERR;
        return NGX_CONF_OK;
    }

    value = cf->args->elts;

    for (i = 2; i < cf->args->nelts; i++) {
        found = 0;

        /***      ***/
        for (n = 1; n <= NGX_LOG_DEBUG; n++) {
            if (ngx_strcmp(value[i].data, err_levels[n].data) == 0) {

                if (log->log_level != 0) {
                    ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                                       "duplicate log level \"%V\"",
                                       &value[i]);
                    return NGX_CONF_ERROR;
                }

                log->log_level = n;
                found = 1;
                break;
            }
        }

        /***  debug    ***/
        for (n = 0, d = NGX_LOG_DEBUG_FIRST; d <= NGX_LOG_DEBUG_LAST; d <<= 1) {
            if (ngx_strcmp(value[i].data, debug_levels[n++]) == 0) {
                if (log->log_level & ~NGX_LOG_DEBUG_ALL) {
                    ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                                       "invalid log level \"%V\"",
                                       &value[i]);
                    return NGX_CONF_ERROR;
                }

                log->log_level |= d;
                found = 1;
                break;
            }
        }


        /***    ,  error_log       ***/
        if (!found) {
            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                               "invalid log level \"%V\"", &value[i]);
            return NGX_CONF_ERROR;
        }
    }

    /***      debug ,           debug all,      debug  ***/
    if (log->log_level == NGX_LOG_DEBUG) {
        log->log_level = NGX_LOG_DEBUG_ALL;
    }

    return NGX_CONF_OK;
}

ngx_log_insert 함수:
/***                 ***/
static void
ngx_log_insert(ngx_log_t *log, ngx_log_t *new_log)
{
    ngx_log_t  tmp;

    /***                     ***/
    if (new_log->log_level > log->log_level) {

        /*
         * list head address is permanent, insert new log after
         * head and swap its contents with head
         */

        tmp = *log;
        *log = *new_log;
        *new_log = tmp;

        log->next = new_log;
        return;
    }

    /***          ,        ***/
    while (log->next) {
        if (new_log->log_level > log->next->log_level) {
            new_log->next = log->next;
            log->next = new_log;
            return;
        }

        log = log->next;
    }

    log->next = new_log;
}

좋은 웹페이지 즐겨찾기