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中。
使用方法
- 首先,請在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是你任意指定的字串。
-
設定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語句。 如下圖所示。
- 圖中顯示出了三條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語句的地方, 同樣需要增加上面的程式碼
-
然後瀏覽網站看看效果:
通過console的日誌,訪問每一頁我們都知道程式幹了什麼,是一件很爽的事情。
- 提示:另一種更簡單的方法,因為OneThink每次執行完sql語句都會呼叫$this->debug, 所以我們可以把slog($this->queryStr,$this->_linkID); 直接寫在 Db.class.php檔案的debug方法中。 這樣不管是mysqli還是mysql驅動都有效。