2012年11月30日 星期五

苦惱訂單系統沒有額外LOG記錄,Stingray幫你通通記下來

當LoadBalancer不再只有流量重導與負載平衡時候,您也可以透過LB來做一些特殊的事情...
這邊展示從HTTP協定著手,將LB所負載之WEB上的Log做一個額外的紀錄...

[系統URL或API URI範例]
[POST] https://your.ip.address:port/cloudstore/simonsu/order/OD-01346

Create Body:(當post上面url時候,實際是送這邊的資料出去)
{"order_id":"OD-01346","username":"simonsu","price":"1000"}
Response Body:(當post完成時候,系統回傳資訊)
{"status":"OK"}

這邊透過一個Request Rule與一個Response Rule來組成這個服務,
其中Request部分記錄使用者傳入參數
而Response部分記錄系統回傳完成訂購之資訊
回傳部分,可以透過某些檢查機制來確認是否要進行Log動作...

[RULE_CREATEORDER_LOG_REQ]
$rawurl = http.getRawURL(); # ex: /cloudstore/simonsu/order/OD-01346
$method = http.getMethod(); # ex: POST
$post = http.getBody(); # ex:
{"order_id":"OD-01346","username":"simonsu","price":"1000"}
$arr = string.split($rawurl,'/'); $ want to get user
$user = '';
if ( array.length($arr) >= 2 ) {
  $user = $arr[1];
}
if ( string.startsWith( $rawurl,"/cloudstore") &&
    string.regexmatch($method, 'POST') ) {
  log.info('>>>>>>>YES GOT CREATE ACTION!!!!');
  # pass the parameter to response rule
  connection.data.set("post", $post);
  connection.data.set("user", $user);
}


[RULE_CREATEORDER_LOG_RESP]
$user = connection.data.get("user");
$post = connection.data.get("post");
$resp = http.getResponseBody();
# Query the mapi2 for record the post and the response
# All things in url can process from node.js using req.params.[name]
# All thinsg in POST column can process from node.js using req.body
$new_url = "http://log.server.ip.address:port/logOrder/".$user."/".string.urlencode( $post );
if($resp != '{"status":"Failed"}'){ $result = http.request.post($new_url, $resp,"Content-Type: application/json");
log.info('>>>create order result='.$result);
}

接收Log的程式,也相當簡單,這邊展示使用Node.js的接值方式
至於儲存部分,則依據自己實作啦∼

[Node.js Server (Using ExpressJS)]
# app.js
app.get('/logOrder/:user/:post', route.createOrderLog);
# route/index.js
exports.createOrderLog = function(req, res){
//post data取值,直接接回body取值
 var order = req.body;
 res.writeHead(200, {'Content-Type': 'application/json'});
//url列的參數取值,使用req.params.[name]取值
 order.user=req.params.user;
 order.post=JSON.parse(req.params.post);

  //TODO: 使用您prefer的儲存方式存檔
 console.log('Get create order request...., %s', JSON.stringify(order));
//回應狀態
 res.end(JSON.stringify(order));
}

已上面的範例,做後可以看到console的Log

[LOG]
Get create order request...., {"status":"OK","user":"simonsu","post":{"order_id":"OD-01346","username":"simonsu","price":"1000"}}