(C++通訊架構學習筆記):日誌列印、優化main函式呼叫順序

Asinmy發表於2020-11-24

目錄

基礎設施之日誌列印

設定時區

日誌等級劃分

捋順main函式中程式碼執行順序

基礎設施之日誌列印

  • 日誌的重要性:供日後執行維護人員去檢視、定位和解決問題
  • ngx_printf.cxx:放和列印格式相關的函式
  • ngx_log.cxx:放和日誌相關的函式

【ngx_log_stderr()  】

  • ngx_log_stderr()  :三個特殊檔案描述符,談到了標準錯誤 STDERR_FILENO,代表螢幕
  • ngx_log_stderr():往螢幕上列印一條錯誤資訊,功能類似於printf
    • printf("mystring=%s,myint=%d,%d","mytest",15,20)。
      • (1)根據可變的引數,組合出一個字串:mystring=mytest,myint=15,20。
      • (2)往螢幕上顯示出這個組合出來的字串。
  • ngx_log_stderr():可以支援任意我們想支援的格式化字元 %d, %f,對於擴充套件原有功能非常有幫助。

【示例】

  • 函式呼叫關係
(i)void ngx_log_stderr(int err, const char *fmt, ...)
(i)    p = ngx_vslprintf(p,last,fmt,args); //實現了自我可定製的printf類似的功能
(i)        buf = ngx_sprintf_num(buf, last, ui64, zero, hex, width);
(i)    p = ngx_log_errno(p, last, err);
  • 在main函式中呼叫 

設定時區

  • 我們要設定成CST時區,以保證日期,時間顯示的都正確
  • 我們常看到的時區,有如下幾個:
    • PST【PST美國太平洋標準時間】 = GMT - 8;
    • GMT【格林尼治平均時間Greenwich Mean Time】等同於英國倫敦本地時間
    • UTC【通用協調時Universal Time Coordinated】 = GMT
    • CST【北京時間:北京時區是東八區,領先UTC八個小時】

【更改時區方式】

  • 輸入命令:tzselect

  • 【注意】還需要拷貝生成的檔案
cp /usr/share/zoneinfo/Asia/Shanghai  /etc/localtime

日誌等級劃分

  • 劃分日誌等級,一共分8級,分級的目的是方便管理,顯示,過濾等等
  • 日誌級別從高到低,數字最小的級別最高,數字最大的級別最低

【日誌等級定義】

  • nginx.conf檔案中進行配置

  • ngx_log.cxx
//描述:日誌初始化,就是把日誌檔案開啟 ,注意這裡邊涉及到釋放的問題,如何解決?
void ngx_log_init()
{
    u_char *plogname = NULL;
    size_t nlen;

    //從配置檔案中讀取和日誌相關的配置資訊
    CConfig *p_config = CConfig::GetInstance();
    plogname = (u_char *)p_config->GetString("Log");
    if(plogname == NULL)
    {
        //沒讀到,就要給個預設的路徑檔名了
        plogname = (u_char *) NGX_ERROR_LOG_PATH; //"logs/error.log" ,logs目錄需要提前建立出來
    }
    ngx_log.log_level = p_config->GetIntDefault("LogLevel",NGX_LOG_NOTICE);//預設日誌等級為6【注意】 ,如果讀失敗,就給預設日誌等級
    //nlen = strlen((const char *)plogname);

    //只寫開啟|追加到末尾|檔案不存在則建立【這個需要跟第三引數指定檔案訪問許可權】
    //mode = 0644:檔案訪問許可權, 6: 110    , 4: 100:     【使用者:讀寫, 使用者所在組:讀,其他:讀】 
    ngx_log.fd = open((const char *)plogname,O_WRONLY|O_APPEND|O_CREAT,0644);  
    if (ngx_log.fd == -1)  //如果有錯誤,則直接定位到 標準錯誤上去 
    {
        ngx_log_stderr(errno,"[alert] could not open error log file: open() \"%s\" failed", plogname);
        ngx_log.fd = STDERR_FILENO; //直接定位到標準錯誤去了        
    } 
    return;
}
  • main函式中進行呼叫

  • nginx_global.h

  • nginx.cxx

捋順main函式中程式碼執行順序

//本檔案用的函式宣告
static void freeresource();

//和設定標題有關的全域性量
char **g_os_argv;            //原始命令列引數陣列,在main中會被賦值
char *gp_envmem = NULL;      //指向自己分配的env環境變數的記憶體,在ngx_init_setproctitle()函式中會被分配記憶體
int  g_environlen = 0;       //環境變數所佔記憶體大小

//和程式本身有關的全域性量
pid_t ngx_pid;               //當前程式的pid

int main(int argc, char *const *argv)
{   
    int exitcode = 0;           //退出程式碼,先給0表示正常退出

    //(1)無傷大雅也不需要釋放的放最上邊    
    ngx_pid = getpid();         //取得程式pid
    g_os_argv = (char **) argv; //儲存引數指標    

    //(2)初始化失敗,就要直接退出的
    //配置檔案必須最先要,後邊初始化啥的都用,所以先把配置讀出來,供後續使用 
    CConfig *p_config = CConfig::GetInstance(); //單例類
    if(p_config->Load("nginx.conf") == false) //把配置檔案內容載入到記憶體        
    {        
        ngx_log_stderr(0,"配置檔案[%s]載入失敗,退出!","nginx.conf");
        //exit(1);終止程式,在main中出現和return效果一樣 ,exit(0)表示程式正常, exit(1)/exit(-1)表示程式異常退出,exit(2)表示表示系統找不到指定的檔案
        exitcode = 2; //標記找不到檔案
        goto lblexit;
    }
    
    //(3)一些初始化函式,準備放這裡
    ngx_log_init();             //日誌初始化(建立/開啟日誌檔案)


    //(4)一些不好歸類的其他類別的程式碼,準備放這裡
    ngx_init_setproctitle();    //把環境變數搬家

    
    //--------------------------------------------------------------    
    for(;;)
    //for(int i = 0; i < 10;++i)
    {
        sleep(1); //休息1秒        
        printf("休息1秒\n");        

    }
      
    //--------------------------------------
lblexit:
    //(5)該釋放的資源要釋放掉
    freeresource();  //一系列的main返回前的釋放動作函式
    printf("程式退出,再見!\n");
    return exitcode;
}

//專門在程式執行末尾釋放資源的函式【一系列的main返回前的釋放動作函式】
void freeresource()
{
    //(1)對於因為設定可執行程式標題導致的環境變數分配的記憶體,我們應該釋放
    if(gp_envmem)
    {
        delete []gp_envmem;
        gp_envmem = NULL;
    }

    //(2)關閉日誌檔案
    if(ngx_log.fd != STDERR_FILENO && ngx_log.fd != -1)  
    {        
        close(ngx_log.fd); //不用判斷結果了
        ngx_log.fd = -1; //標記下,防止被再次close吧        
    }
}

 

相關文章