1. 程式人生 > >SocketLog-微信除錯、API除錯和AJAX的除錯的工具,能將日誌通過WebSocket輸出到Chrome瀏覽器的console中

SocketLog-微信除錯、API除錯和AJAX的除錯的工具,能將日誌通過WebSocket輸出到Chrome瀏覽器的console中

說明

SocketLog適合Ajax除錯和API除錯, 舉一個常見的場景,用SocketLog來做微信除錯, 我們在做微信API開發的時候,如果API有bug,微信只提示“改公眾賬號暫時無法提供服務,請稍候再試” ,我們根本不知道API出來什麼問題。 有了SocketLog就不一樣了, 我們可以知道微信給API傳遞了哪些引數, 程式有錯誤我們也能看見錯誤資訊(下方有張圖片,可能載入慢,請耐心等待一下)

微信除錯

  • 正在執行的API有bug,不能var_dump進行除錯,因為會影響client的呼叫。 將日誌寫到檔案,檢視也不方便,特別是帶呼叫棧或大資料結構的檔案日誌,檢視日誌十分困難。 這時候用SocketLog最好,SocketLog通過websocket將除錯日誌列印到瀏覽器的console中。你還可以用它來分析開源程式,分析SQL效能,結合taint分析程式漏洞。
  • 目錄結構:
  • 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 &
  • 在自己的程式中傳送日誌:

    <?php
    include './php/SocketLog.class.php';
    slog('hello world');
    ?>
    
  • 用slog函式傳送日誌, 支援多種日誌型別:

    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函式支援三個引數:

  • 第一個引數是日誌內容,日誌內容不光能支援字串喲,大家如果傳遞陣列,物件等一樣可以列印到console中。
  • 第二個引數是日誌型別,可選,如果沒有指定日誌型別預設型別為log, 第三個引數是自定樣式,在這裡寫上你自定義css樣式即可。

配置

  • 在載入SocketLog.class.php檔案後,還可以對SocketLog進行一些配置。
  • 例如:我們如果想將程式的報錯資訊頁輸出到console,可以配置

    <?php
    include './php/SocketLog.class.php';
    slog(array(
    'error_handler'=>true
    ),'set_config');
    echo notice;//製造一個notice報錯
    slog('這裡是輸出的一般日誌');
    ?>
    
  • 配置SocketLog也是用slog函式, 第一個引數傳遞配置項的陣列,第二個引數設定為set_config
  • 還支援其他配置項

    <?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後能實現以下功能:

  • 1,配置allow_client_ids 配置項,讓指定的瀏覽器才能獲得日誌,這樣就可以把除錯程式碼帶上線。 普通使用者訪問不會觸發除錯,不會發送日誌。 開發人員訪問就能看的除錯日誌, 這樣利於找線上bug。 Client_ID 建議設定為姓名拼命加上隨機字串,這樣如果有員工離職可以將其對應的client_id從配置項allow_client_ids中移除。 client_id除了姓名拼音,加上隨機字串的目的,以防別人根據你公司員工姓名猜測出client_id,獲取線上的除錯日誌。

  • 設定allow_client_ids示例程式碼:

    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 即可。

  • 示例程式碼:

    <?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驅動都有效。
下載地址:https://github.com/luofei614/SocketLog