socketlog

說明

 

SocketLog適合Ajax調試和API調試, 舉一個常見的場景,用SocketLog來作微信調試, 咱們在作微信API開發的時候,若是API有bug,微信只提示「改公衆帳號暫時沒法提供服務,請稍候再試」 ,咱們根本不知道API出來什麼問題。 有了SocketLog就不同了, 咱們能夠知道微信給API傳遞了哪些參數, 程序有錯誤咱們也能看見錯誤信息(下方有張圖片,可能加載慢,請耐心等待一下)php

微信調試

  • 正在運行的API有bug,不能var_dump進行調試,由於會影響client的調用。 將日誌寫到文件,查看也不方便,特別是帶調用棧或大數據結構的文件日誌,查看日誌十分困難。 這時候用SocketLog最好,SocketLog經過websocket將調試日誌打印到瀏覽器的console中。你還能夠用它來分析開源程序,分析SQL性能,結合taint分析程序漏洞。
  • Chrome插件安裝:https://chrome.google.com/webstore/detail/socketlog/apkmbfpihjhongonfcgdagliaglghcod (若是不能正常訪問這個頁面,你能夠用下面手動安裝的方法進行安裝)
  • 目錄結構:
  • chrome 目錄是 chrome插件的源代碼
  • chrome.crx 文件是chrome插件的安裝包, 若是你沒法從chrome應用商店安裝,可進行手動安裝, 瀏覽器地址欄輸入並打開: chrome://extensions/ ,而後將chrome.crx拖入便可安裝。
  • php 目錄下的SocketLog.class.php是發送日誌的類庫,咱們在發送日誌的時候,須要載入這個類庫而後調用函數slog便可。
  • 效果展現: 咱們在瀏覽網站的時候在瀏覽器console中就知道程序作了什麼,這對於二次開發產品十分有用。 下面效果圖在console中打印出瀏覽discuz程序時,執行了哪些sql語句, 以及執行sql語句的調用棧。程序的warning,notice等錯誤信息也能夠打到console中。 enter image description here

使用方法

  • 首先,請在chrome瀏覽器上安裝好插件。
  • 而後,啓用Websocket服務,該服務是nodejs寫的,在server目錄下,請先確保你的環境已經安裝nodejs, 啓動Websocket服務運行命令 node server/index.js , 將會在本地起一個websocket服務 ,監聽端口是1229 。 若是想服務後臺運行: nohup node server/index.js > /dev/null &
  • 在本身的程序中發送日誌:css

    <?php
    include './php/SocketLog.class.php';
    slog('hello world');
    ?>
  • 用slog函數發送日誌, 支持多種日誌類型:html

    slog('msg','log');  //通常日誌
    slog('msg','error'); //錯誤日誌
    slog('msg','info'); //信息日誌
    slog('msg','warn'); //警告日誌
    slog('msg','trace');// 輸入日誌同時會打出調用棧
    slog('msg','alert');//將日誌以alert方式彈出
    slog('msg','log','color:red;font-size:20px;');//自定義日誌的樣式,第三個參數爲css樣式
  • 經過上面例子能夠看出, slog函數支持三個參數:node

  • 第一個參數是日誌內容,日誌內容不光能支持字符串喲,你們若是傳遞數組,對象等同樣能夠打印到console中。
  • 第二個參數是日誌類型,可選,若是沒有指定日誌類型默認類型爲log, 第三個參數是自定樣式,在這裏寫上你自定義css樣式便可。

配置

  • 在載入SocketLog.class.php文件後,還能夠對SocketLog進行一些配置。
  • 例如:咱們若是想將程序的報錯信息頁輸出到console,能夠配置mysql

    <?php
    include './php/SocketLog.class.php';
    slog(array(
    'error_handler'=>true
    ),'set_config');
    echo notice;//製造一個notice報錯
    slog('這裏是輸出的通常日誌');
    ?>
  • 配置SocketLog也是用slog函數, 第一個參數傳遞配置項的數組,第二個參數設置爲set_config
  • 還支持其餘配置項git

    <?php
    include './php/SocketLog.class.php';
    slog(array(
    'host'=>'localhost',//websocket服務器地址,默認localhost
    'port'=>'1229',//websocket服務器端口,默認端口是1229
    'optimize'=>false,//是否顯示利於優化的參數,若是運行時間,消耗內存等,默認爲false
    'show_included_files'=>false,//是否顯示本次程序運行加載了哪些文件,默認爲false
    'error_handler'=>false,//是否接管程序錯誤,將程序錯誤顯示在console中,默認爲false
    'force_client_id'=>'',//日誌強制記錄到配置的client_id,默認爲空
    'allow_client_ids'=>array()////限制容許讀取日誌的client_id,默認爲空,表示全部人均可以得到日誌。
    )
    ,'set_config');
    ?>
  • optimize 參數若是設置爲true, 能夠在日誌中看見利於優化參數,如:[運行時間:0.081346035003662s][吞吐率:12.29req/s][內存消耗:346,910.45kb]
  • show_included_files 設置爲true,能顯示出程序運行時加載了哪些文件,好比咱們在分析開源程序時,若是不知道模板文件在那裏, 每每看一下加載文件列表就知道模板文件在哪裏了。
  • error_handler 設置爲true,能接管報錯,將錯誤信息顯示到瀏覽器console, 在開發程序時notice報錯能讓咱們快速發現bug,可是有些notice報錯是不可避免的,若是讓他們顯示在頁面中會影響網頁的正常佈局,那麼就設置error_handler,讓它顯示在瀏覽器console中吧。 另外此功能結合php taint也是極佳的。 taint能自動檢測出xss,sql注入, 若是隻用php taint, 它warning報錯只告訴了變量輸出的地方,並不知道變量在那裏賦值、怎麼傳遞。經過SocketLog, 能看到調用棧,輕鬆對有問題變量進行跟蹤。 更多taint的信息:http://www.laruence.com/2012/02/14/2544.html
  • 設置client_id: 在chrome瀏覽器中,能夠設置插件的Client_ID ,Client_ID是你任意指定的字符串。 enter image description here
  • 設置client_id後能實現如下功能:github

  • 1,配置allow_client_ids 配置項,讓指定的瀏覽器才能得到日誌,這樣就能夠把調試代碼帶上線。 普通用戶訪問不會觸發調試,不會發送日誌。 開發人員訪問就能看的調試日誌, 這樣利於找線上bug。 Client_ID 建議設置爲姓名拼命加上隨機字符串,這樣若是有員工離職能夠將其對應的client_id從配置項allow_client_ids中移除。 client_id除了姓名拼音,加上隨機字符串的目的,以防別人根據你公司員工姓名猜想出client_id,獲取線上的調試日誌。web

  • 設置allow_client_ids示例代碼:sql

    slog(array(
    'allow_client_ids'=>array('luofei_zfH5NbLn','easy_DJq0z80H')
    ),'set_config')
  • 2, 設置force_client_id配置項,讓後臺腳本也能輸出日誌到chrome。 網站有可能用了隊列,一些業務邏輯經過後臺腳本處理, 若是後臺腳本須要調試,你也能夠將日誌打印到瀏覽器的console中, 固然後臺腳本不和瀏覽器接觸,不知道當前觸發程序的是哪一個瀏覽器,因此咱們須要強制將日誌打印到指定client_id的瀏覽器上面。 咱們在後臺腳本中使用SocketLog時設置force_client_id 配置項指定要強制輸出瀏覽器的client_id 便可。chrome

  • 示例代碼:

    <?php
    include './php/SocketLog.class.php';
    slog(array(
    'force_client_id'=>'luofei_zfH5NbLn'
    ),'set_config');
    slog('test'); `

對數據庫進行調試

  • SocketLog還能對sql語句進行調試,自動對sql語句進行explain分析,顯示出有性能問題的sql語句。 以下圖所示。enter image description here
  • 圖中顯示出了三條sql語句 , 第一條sql語句字體較大,是由於它又性能問題, 在sql語句的後臺已經標註Using filesort。 咱們還能夠點擊某個sql語句看到sql執行的調用棧,清楚的知道sql語句是如何被執行的,方便咱們分析程序、方便作開源程序的二次開發。圖中第三條sql語句爲被點開的狀態。
  • 用slog函數打印sql語句是,第二個參數傳遞爲mysql或mysqli的對象便可。 示例代碼:

    $link=mysql_connect( 'localhost:3306' , 'root' , '123456' , true ) ;
    mysql_select_db('kuaijianli',$link);
    $sql="SELECT * FROM `user`";
    slog($sql,$link);

    後面會以OneThink爲實例再對數據庫調試進行演示。

經過上面的方法,socketlog還能自動爲你檢測沒有where語句的sql操做,而後自動提示你。

  • 注意,有時候在數據比較少的狀況下,mysql查詢不會使用索引,explain也會提示Using filesort等性能問題, 其實這時候並非真正有性能問題, 你須要自行進行判斷,或者增長更多的數據再測試。

對API進行調試

網站調用了API ,如何將API程序的調試信息也打印到瀏覽器的console中? 前面咱們講了一個配置 force_client_id, 能將日誌強制記錄到指定的瀏覽器。 用這種方式也能夠將API的調試信息打印到console中,可是force_client_id 只能指定一個client_id, 若是咱們的開發環境是多人共用,這種方式就不方便了。 其實只要將瀏覽器傳遞給網站的User-Agent 再傳遞給API, API程序中不用配置force_client_id, 也能識別當前訪問程序的瀏覽器, 將日誌打印到當前訪問程序的瀏覽器, 咱們須要將SDK代碼稍微作一下修改。 調用API的SDK,通常是用curl寫的,增長下面代碼能夠將瀏覽器的User-Agent傳遞到API 。

$headers=array();
    if(isset($_SERVER['HTTP_USER_AGENT']))
    {
        $headers[]='User-Agent: '.$_SERVER['HTTP_USER_AGENT'];
    }
    if(isset($_SERVER['HTTP_SOCKETLOG']))
    {
        $headers[]='Socketlog: '.$_SERVER['HTTP_SOCKETLOG'];
    }
    curl_setopt($ch,CURLOPT_HTTPHEADER,$headers);

區分正式和開發環境

進入chrome瀏覽器的「工具」-->「擴展程序」 , 點擊SocketLog的「選項」進行設置。

分析開源程序

有了SocketLog,咱們能很方便的分析開源程序,下面以OneThink爲例, 你們能夠在http://www.topthink.com/topic/2228.html 下載最新的OneThink程序。 安裝好OneThink後,按下面步驟增長SocketLog程序。

  • 將SocketLog.class.php複製到OneThink的程序目錄中,你若是沒有想好將文件放到哪一個子文件夾,暫且放到根目錄吧。
  • 編輯入口文件index.php, 再代碼的最前面加載SocketLog.class.php ,並設置SocketLog

    <?php
        include './SocketLog.class.php';
        slog(array(
         'error_handler'=>true,
         'optimize'=>true,
         'show_included_files'=>true
        ),'set_config');
  • 編輯ThinkPHP/Library/Think/Db/Driver.class.php 文件,在這個類中的execute 方法爲一個執行sql語句的方法,增長代碼:

    slog($this->queryStr,$this->_linkID);
  • 類中的query方法也是一個執行sql語句的地方, 一樣須要增長上面的代碼

  • 而後瀏覽網站看看效果:

    enter image description here

經過console的日誌,訪問每一頁咱們都知道程序幹了什麼,是一件很爽的事情。

  • 提示:另外一種更簡單的方法,由於OneThink每次執行完sql語句都會調用$this->debug, 因此咱們能夠把slog($this->queryStr,$this->_linkID); 直接寫在 Db.class.php文件的debug方法中。 這樣不論是mysqli仍是mysql驅動都有效
  • 轉自:http://blog.csdn.net/sanxian_li/article/details/43766349
  • zh
相關文章
相關標籤/搜索