1. 程式人生 > >Apache服務啟動失敗couldn't start errorlog process, unable to open logs

Apache服務啟動失敗couldn't start errorlog process, unable to open logs

在某使用者環境下,Apache服務啟動失敗,報錯資訊如下

couldn't start errorlog process

 unable to open logs

Apache是我們的產品元件,未防止日誌過大

我們使用了Apache自帶的切割滾存日誌的元件rotatelogs.exe

在httpd.conf配置如下:

ErrorLog "|bin/rotatelogs.exe logs/%Y%m%d%H%M%S_error.log 30M"

只要遮蔽這個設定,就可以正常啟動Apache,谷歌了下,有人說這是Apache已知BUG,

但是連續兩個使用者反饋這個問題,找了個可以遠端的環境定位了下問題:

居然是因為環境變數的問題

定位過程如下:

1>確認rotatelogs.exe本身可以執行,

2>按網上的說法嘗試把bin/rotatelogs.exe改為全路徑,不生效

3>上工具,ProcMon,篩選了程序映像名保含“rotatelogs.exe”,無任何發現

4>感覺不對勁,加上“httpd.exe”篩選,也沒看出什麼毛病

5>重置ProcMon的Filter,再啟動httpd.exe

結果發現c:\windows\system32\cmd.exe NOT FOUND

使用者的系統盤是D盤,C盤系統目錄沒有cmd.exe,於是在c:\windows\system32目錄下放了個cmd.exe,

果然可以啟動服務,原來如此!!!!!!!


暫停嘗試,翻了下 Apache的程式碼,搜了下“couldn't start errorlog process”

最終找到

    i = strlen(progname);
        if (i >= 4 && (strcasecmp(progname + i - 4, ".bat") == 0
                    || strcasecmp(progname + i - 4, ".cmd") == 0))
        {
            char *shellcmd = getenv("COMSPEC");
            if (!shellcmd) {
                if (attr->errfn) {
                    attr->errfn(pool, APR_EINVAL, "COMSPEC envar is not set");
                }
                return APR_EINVAL;
            }

原來是讀的環境變數,

把使用者的環境變數COMSPEC糾正過來就OK了


反思:

這個過程中我忽略了個細節,Apache是通過cmd.exe呼叫rotatelogs.exe的,這個我之前是知道的,但是終究沒有跟Apache的報錯日誌聯絡在一起