解決nginx在記錄post數(shù)據(jù)時 中文字符轉(zhuǎn)成16進制的問題

1. 問題描述

nginx 在獲取post數(shù)據(jù)時候重挑,如果是中文,則轉(zhuǎn)換成16進制顯示在日志文件中,如下圖所示瓜喇。

Paste_Image.png

日志格式為: log_format postdata '$remote_addr | $request_body | $resp_body';

此篇文章記錄下解決此次問題的過程屿脐。

最新版本解決方式

適合nginx 1.11.8 以上版本

在nginx 1.11.8 以上版本中log_format 增加了escape=json 參數(shù)涕蚤,在配置日志格式時加上此參數(shù)可以不轉(zhuǎn)義變量內(nèi)容,官方文檔-參數(shù)說明

日志配置

log_format postdata '$remote_addr | $request_body | $resp_body';
log_format postdata escape=json '$remote_addr | $request_body | $resp_body';

日志輸出

image.png

第一條日志是不加escape=json 參數(shù)后的诵,log_format輸出的
第二條日志是加上escape=json 參數(shù)后万栅,log_format輸出的

2. 軟件版本

  • 系統(tǒng) centos 6.7 X86_64
  • nginx 1.11.5
  • lua-nginx-module 0.10.7
  • PHP 5.6.27

測試環(huán)境部署見:Nginx 使用lua-nginx-module 來獲取post請求中得request和response信息

3. 收集信息

收集信息-階段1:

在遇到此類問題的時候,我們大多是使用搜索引擎搜索答案西疤,因為這樣來的更快一些烦粒。當遇到這個問題的時候,我感覺也無從下手代赁,隨即在google中搜索答案扰她,沒過多久,便找到了同類人芭碍,也遇到了這個問題

此次搜索關(guān)鍵字: nginx log 中文 16進制

Paste_Image.png

出處:https://groups.google.com/forum/#!topic/openresty/PYvvfj5RKCg

這個里面提到了:

  • 為什么會出現(xiàn)這個問題义黎?
    
  • 解決辦法
    

當時情況,在大量的搜索結(jié)果下豁跑,剛開始沒注意到這里面的問題廉涕,認為這個是openresty的解決辦法。就繼續(xù)搜索信息了艇拍。

收集信息-階段2:

經(jīng)過上面得信息狐蜕,我們可以得知,nginx現(xiàn)在是把中文字符轉(zhuǎn)換成16進制卸夕。

所以關(guān)鍵字變成了:nginx 不支持中文

從這個關(guān)鍵字便發(fā)現(xiàn)了下面得信息

Paste_Image.png

來自: http://navyaijm.blog.51cto.com/4647068/1082169

從這里面獲得了:
- 通過降級nginx來解決問題

這位博主通過過降級nginx 程序來達到支持中文得效果层释,當時目測這文章是2012年得,比較久遠快集,而且還需要降級贡羔,就沒有嘗試這類方法。

信息收集-階段3:

這次搜索解決答案也有一段時間了个初,突然想起了階段1時發(fā)現(xiàn)得解決方法乖寒,里面有個命令可以關(guān)閉nginx轉(zhuǎn)換16進制得命令。隨即搜索關(guān)鍵字改成: nginx log escape characters

通過這個關(guān)鍵字找到了下列有用信息院溺。

Paste_Image.png

來自: http://mailman.nginx.org/pipermail/nginx/2008-January/003051.html

從這里面獲得了:

  • 在2008年得時候楣嘁,通過這個path,讓不可打印得字符轉(zhuǎn)成16進制。
  • attachment.bin 文件記錄了是哪個源代碼文件的補丁逐虚。

通過查看這個文件聋溜,發(fā)現(xiàn)了 ngx_http_log_escape 這函數(shù)是轉(zhuǎn)換16進制的。要知道nginx源代碼已經(jīng)被很多國人都閱讀過叭爱,肯定有相關(guān)的解釋撮躁。

隨即關(guān)鍵字變成了: nginx ngx_http_log_escape

通過搜索發(fā)現(xiàn)了下列的源碼解釋

static uintptr_t
ngx_http_log_escape(u_char *dst, u_char *src, size_t size)
{
    ngx_uint_t      n;
    /* 這是十六進制字符表 */
    static u_char   hex[] = "0123456789ABCDEF";

    /* 這是ASCII碼表,每一位表示一個符號买雾,其中值為1表示此符號需要轉(zhuǎn)換馒胆,值為0表示不需要轉(zhuǎn)換 */
    static uint32_t   escape[] = {
        0xffffffff, /* 1111 1111 1111 1111  1111 1111 1111 1111 */

                    /* ?>=< ;:98 7654 3210  /.-, +*)( '&%$ #"!  */
        0x00000004, /* 0000 0000 0000 0000  0000 0000 0000 0100 */

                    /* _^]\ [ZYX WVUT SRQP  ONML KJIH GFED CBA@ */
        0x10000000, /* 0001 0000 0000 0000  0000 0000 0000 0000 */

                    /*  ~}| {zyx wvut srqp  onml kjih gfed cba` */
        0x80000000, /* 1000 0000 0000 0000  0000 0000 0000 0000 */

        0xffffffff, /* 1111 1111 1111 1111  1111 1111 1111 1111 */
        0xffffffff, /* 1111 1111 1111 1111  1111 1111 1111 1111 */
        0xffffffff, /* 1111 1111 1111 1111  1111 1111 1111 1111 */
        0xffffffff, /* 1111 1111 1111 1111  1111 1111 1111 1111 */
    };


    if (dst == NULL) {

        /* find the number of the characters to be escaped */

        n = 0;

        while (size) {
            if (escape[*src >> 5] & (1 << (*src & 0x1f))) {
                n++;
            }
            src++;
            size--;
        }

        return (uintptr_t) n;
        /* 返回需要轉(zhuǎn)換的字符總數(shù)*/
    }

    while (size) {
         /* escape[*src >> 5],escape每一行保存了32個符號,
         所以右移5位凝果,即除以32就找到src對應的字符保存在escape的行,
         (1 << (*src & 0x1f))此符號在escape一行中的位置睦尽,
         相&結(jié)果就是判斷src符號位是否為1器净,需不需要轉(zhuǎn)換 */
        if (escape[*src >> 5] & (1 << (*src & 0x1f))) {
            *dst++ = '\\';
            *dst++ = 'x';
            /* 一個字符占一個字節(jié)8位,每4位轉(zhuǎn)成一個16進制表示 */
            /* 高4位轉(zhuǎn)換成16進制 */
            *dst++ = hex[*src >> 4];
            /* 低4位轉(zhuǎn)換成16進制*/
            *dst++ = hex[*src & 0xf];
            src++;

        } else {
            /* 不需要轉(zhuǎn)換的字符直接賦值 */
            *dst++ = *src++;
        }
        size--;
    }

    return (uintptr_t) dst;
}

感謝大神:http://blog.csdn.net/l09711/article/details/46712325

從上面解釋來看当凡,我們只需要*src不轉(zhuǎn)換16進制就可以山害。

4. 解決方法

源碼文件為:src/http/modules/ngx_http_log_module.c

修改源碼如下圖所示,

Paste_Image.png

然后重新編譯沿量,安裝nginx

./configure   --prefix=/usr/local/nginx   --user=nginx   --group=nginx   --with-http_ssl_module   --with-http_flv_module   --with-http_stub_status_module   --with-http_gzip_static_module   --with-http_realip_module   --http-client-body-temp-path=/var/tmp/nginx/client/   --http-proxy-temp-path=/var/tmp/nginx/proxy/   --http-fastcgi-temp-path=/var/tmp/nginx/fcgi/   --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi   --http-scgi-temp-path=/var/tmp/nginx/scgi   --with-pcre --add-module=../lua-nginx-module-0.10.7
 /usr/local/nginx/sbin/nginx -s stop
make -j2 && make install
/usr/local/nginx/sbin/nginx

再次post 數(shù)據(jù)到nginx里

Paste_Image.png

查看日志會發(fā)現(xiàn)中文不在轉(zhuǎn)換16進制了浪慌。


Paste_Image.png

第1-2行,是沒有修改源碼前朴则,向nginx url post數(shù)據(jù)权纤,中文被轉(zhuǎn)換成16進制。
第3-5行乌妒,修改源碼后汹想,中文就不會轉(zhuǎn)換為16進制了。也沒有什么亂碼撤蚊。

至此古掏,遇到得問題已解決,在修改源碼得情況下侦啸,目前還沒有發(fā)現(xiàn)什么影響之處槽唾,如由朋友發(fā)現(xiàn),請聯(lián)系我lework[@]yeah.net

5. 總結(jié)

在遇到錯誤得時候光涂,我們往往不知道該怎么搜索此類答案庞萍,我想大家應該都會把錯誤信息放在搜索引擎中搜索,關(guān)鍵字要隨著搜索得到的信息從而不斷變化忘闻,才能往根源得問題靠近挂绰。在搜索引擎給出的大量信息,要懂得抓取有用的信息,不能忽視已經(jīng)給出問題答案的信息葵蒂,即使信息比較久遠交播。像階段1得情況,我如果仔細閱讀上面得解答信息践付,應該會很快得找到問題所在的根源秦士。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市永高,隨后出現(xiàn)的幾起案子隧土,更是在濱河造成了極大的恐慌,老刑警劉巖命爬,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件曹傀,死亡現(xiàn)場離奇詭異,居然都是意外死亡饲宛,警方通過查閱死者的電腦和手機皆愉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來艇抠,“玉大人幕庐,你說我怎么就攤上這事〖矣伲” “怎么了异剥?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長絮重。 經(jīng)常有香客問我冤寿,道長,這世上最難降的妖魔是什么青伤? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任疚沐,我火速辦了婚禮,結(jié)果婚禮上潮模,老公的妹妹穿的比我還像新娘亮蛔。我一直安慰自己,他們只是感情好擎厢,可當我...
    茶點故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布究流。 她就那樣靜靜地躺著,像睡著了一般动遭。 火紅的嫁衣襯著肌膚如雪芬探。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天厘惦,我揣著相機與錄音偷仿,去河邊找鬼哩簿。 笑死,一個胖子當著我的面吹牛酝静,可吹牛的內(nèi)容都是我干的节榜。 我是一名探鬼主播,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼别智,長吁一口氣:“原來是場噩夢啊……” “哼宗苍!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起薄榛,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤讳窟,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后敞恋,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體丽啡,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年硬猫,在試婚紗的時候發(fā)現(xiàn)自己被綠了补箍。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡浦徊,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出天梧,到底是詐尸還是另有隱情盔性,我是刑警寧澤,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布呢岗,位于F島的核電站冕香,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏后豫。R本人自食惡果不足惜悉尾,卻給世界環(huán)境...
    茶點故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望挫酿。 院中可真熱鬧构眯,春花似錦、人聲如沸早龟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽葱弟。三九已至壹店,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間芝加,已是汗流浹背硅卢。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人将塑。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓缕贡,卻偏偏與公主長得像,于是被迫代替她去往敵國和親萍聊。 傳聞我的和親對象是個殘疾皇子聊替,可洞房花燭夜當晚...
    茶點故事閱讀 44,864評論 2 354

推薦閱讀更多精彩內(nèi)容