/** * Tencent is pleased to support the open source community by making MSEC available. * * Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved. * * Licensed under the GNU General Public License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. You may * obtain a copy of the License at * * https://opensource.org/licenses/GPL-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific language governing permissions * and limitations under the License. */ package beans.service; import beans.dbaccess.BusinessLogResult; import beans.dbaccess.OddSecondLevelServiceIPInfo; import beans.request.BusinessLog; import beans.request.IPPortPair; import ngse.org.DBUtil; import ngse.org.JsonRPCHandler; import ngse.org.JsonRPCResponseBase; import ngse.org.ServletConfig; import org.apache.log4j.Logger; import org.graphviz.Graphviz; import org.json.JSONArray; import org.json.JSONObject; import javax.servlet.ServletOutputStream; import java.io.File; import java.io.OutputStream; import java.io.PrintWriter; import java.net.InetSocketAddress; import java.net.Socket; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.HashMap; /** * Created by Administrator on 2016/2/27. */ public class QueryBusinessLog extends JsonRPCHandler { public static final String BUSI_LOG_RESULT_IN_SESSION = "BusinessLogResult"; String log_srv_ip; int log_srv_port; public static ArrayList<IPPortPair> getBusiLogSrvIPPort() { DBUtil util = new DBUtil(); try { if (util.getConnection() == null) { return null; } String sql =sql = "select ip,port from t_second_level_service_ipinfo where second_level_service_name='log' " + "and first_level_service_name='RESERVED' and status='enabled'"; ArrayList<IPPortPair> list = util.findMoreRefResult(sql, null, IPPortPair.class); return list; } catch (Exception e ) { e.printStackTrace(); return null; } finally { util.releaseConn(); } } public static String getGraphFilename(String reqid) { return ServletConfig.fileServerRootDir + "/tmp/"+reqid+".png"; } //获取调用关系图 private String doGetCallRelationGraph( BusinessLog request) { Logger logger = Logger.getLogger(QueryBusinessLog.class); String dt; dt = request.getDt_begin(); if (dt == null || dt.length() < 14) { return "time field invalid";} String begin_dt = dt.substring(0, 4)+"-"+dt.substring(4,6)+"-"+dt.substring(6,8); String begin_tm = dt.substring(9); dt = request.getDt_end(); if (dt == null || dt.length() < 14) { return "time field invalid";} String end_dt = dt.substring(0, 4)+"-"+dt.substring(4,6)+"-"+dt.substring(6,8); String end_tm = dt.substring(9); String ReqID = request.getRequest_id(); String sJson = String.format("{\"callGraphReq\":{\"reqId\":\"%s\", \"filterFieldList\": null, \"startDate\":\"%s\","+ " \"endDate\":\"%s\", \"startTime\":\"%s\", \"endTime\":\"%s\"}}", ReqID, begin_dt, end_dt, begin_tm, end_tm); logger.info("request to log server:"+sJson); String lens = String.format("%10d", sJson.length()); ArrayList<IPPortPair> ipPortPairs = getBusiLogSrvIPPort(); if (ipPortPairs == null || ipPortPairs.size() < 1) { return "get log server ip failed"; } log_srv_ip = ipPortPairs.get(0).getIp(); log_srv_port = ipPortPairs.get(0).getPort(); Socket socket = new Socket(); try { socket.setSoTimeout(5000); socket.connect(new InetSocketAddress(log_srv_ip, log_srv_port), 3000); OutputStream outputStream = socket.getOutputStream(); outputStream.write(lens.getBytes()); outputStream.write(sJson.getBytes()); socket.shutdownOutput(); //收应答包 // length field 10bytes byte[] buf = new byte[1024*1024]; int total_len = 0; while (total_len < 10) { int len = socket.getInputStream().read(buf, total_len, 10-total_len); if (len <= 0) { return "receive json len failed."; } total_len += len; } int jsonLen = new Integer(new String(buf, 0, total_len).trim()).intValue(); logger.info(String.format("response json string len:%d", jsonLen)); if (jsonLen > buf.length) { return "response json is too long"; } total_len = 0; while ( total_len < jsonLen) { int len = socket.getInputStream().read(buf, total_len, jsonLen-total_len); if (len <= 0) { return "receive json string failed."; } total_len += len; } String jsonStr = new String(buf, 0, total_len); logger.info("the length of log json string:"+jsonStr.length()); logger.info("log resp:"+jsonStr); JSONObject jsonObject = new JSONObject(jsonStr); jsonObject = jsonObject.getJSONObject("callGraphRsp"); int status = jsonObject.getInt("ret"); if (status != 0) { String message = jsonObject.getString("errmsg"); return message; } String dotLang = jsonObject.getString("graph"); if ( !(dotLang == null || dotLang.equals("")) ) { String filename = getGraphFilename(ReqID); Graphviz.drawGraph(dotLang, filename); BusinessLogResult businessLogResult = (BusinessLogResult) (this.getHttpRequest().getSession().getAttribute(BUSI_LOG_RESULT_IN_SESSION)); if (businessLogResult == null) { return "failed to get log result from session."; } businessLogResult.setCall_relation_graph(ReqID); } return "success"; } catch (Exception e) { e.printStackTrace(); logger.error(e.getMessage()); return e.getMessage(); } finally { if (socket!=null) { try {socket.close();} catch (Exception e){}; } } } private String doQueryLog( BusinessLog request) { Logger logger = Logger.getLogger(QueryBusinessLog.class); String svcname = request.getService_name(); //if (svcname == null || svcname.length() < 1) { return "svcname field invalid";} String dt; dt = request.getDt_begin(); if (dt == null || dt.length() < 14) { return "time field invalid";} String begin_dt = dt.substring(0, 4)+"-"+dt.substring(4,6)+"-"+dt.substring(6,8); String begin_tm = dt.substring(9); dt = request.getDt_end(); if (dt == null || dt.length() < 14) { return "time field invalid";} String end_dt = dt.substring(0, 4)+"-"+dt.substring(4,6)+"-"+dt.substring(6,8); String end_tm = dt.substring(9); String where = ""; if (request.getRequest_id() != null && request.getRequest_id().length() > 0) { if (where.length() > 0) { where += " and ";} where += " ReqID='"+request.getRequest_id()+"'"; } if (request.getLog_ip() != null && request.getLog_ip().length() > 0) { if (where.length() > 0) { where += " and ";} where += " LocalIP='"+request.getLog_ip()+"' "; } if (request.getMore_condition() != null && request.getMore_condition().length() > 0) { if (where.length() > 0) { where += " and ";} where += request.getMore_condition(); } String sJson = String.format("{\"queryLogReq\":{\"appName\":\"%s\", \"logLevel\":\"DEBUG\","+ "\"filterFieldList\": null,\"maxRetNum\":1000, \"startDate\":\"%s\","+ " \"endDate\":\"%s\", \"startTime\":\"%s\", \"endTime\":\"%s\", "+ "\"whereCondition\":\"%s\"}}", svcname, begin_dt, end_dt, begin_tm, end_tm, where); logger.info("request to log server:"+sJson); String lens = String.format("%10d", sJson.length()); ArrayList<IPPortPair> ipPortPairs = getBusiLogSrvIPPort(); if (ipPortPairs == null || ipPortPairs.size() < 1) { return "get log server ip failed"; } log_srv_ip = ipPortPairs.get(0).getIp(); log_srv_port = ipPortPairs.get(0).getPort(); Socket socket = new Socket(); try { socket.setSoTimeout(5000); socket.connect(new InetSocketAddress(log_srv_ip, log_srv_port), 3000); OutputStream outputStream = socket.getOutputStream(); outputStream.write(lens.getBytes()); outputStream.write(sJson.getBytes()); socket.shutdownOutput(); //收应答包 // length field 10bytes byte[] buf = new byte[1024*1024]; int total_len = 0; while (total_len < 10) { int len = socket.getInputStream().read(buf, total_len, 10-total_len); if (len <= 0) { return "receive json len failed."; } total_len += len; } int jsonLen = new Integer(new String(buf, 0, total_len).trim()).intValue(); logger.info(String.format("response json string len:%d", jsonLen)); if (jsonLen > buf.length) { return "response json is too long"; } total_len = 0; while ( total_len < jsonLen) { int len = socket.getInputStream().read(buf, total_len, jsonLen-total_len); if (len <= 0) { return "receive json string failed."; } total_len += len; } String jsonStr = new String(buf, 0, total_len); //String jsonStr = "{'queryLogRsp':{'ret':0, 'errmsg':'ok', 'records':[ ['b\"i{e:r}s\\'on', '1122[8]490', '36岁'],['babamama', '2202020302', '37岁'] ],heads:['name', 'uin', 'age']}}"; logger.info("the length of log json string:"+jsonStr.length()); // logger.info("log resp:"+jsonStr); JSONObject jsonObject = new JSONObject(jsonStr); jsonObject = jsonObject.getJSONObject("queryLogRsp"); int status = jsonObject.getInt("ret"); if (status != 0) { String message = jsonObject.getString("errmsg"); return message; } ArrayList<String> columns = new ArrayList<String>(); ArrayList<HashMap<String, String>> record_map_list = new ArrayList<HashMap<String, String>>(); //返回的json字符串 // {queryLogRsp:{ret:0, errmsg:'ok', records:[ ['fieldvalue1', 'fieldvalue2', 'fieldvalue3'], ... ],heads:['ReqID', 'instime', ....]} } // 注意:引号要转义 // 例如:{'queryLogRsp':{'ret':0, 'errmsg':'ok', 'records':[ ['b"i{e:r}s\'on', '1122[8]490', '36岁'],['babamama', '2202030202', '37岁'] ],heads:['name', 'uin', 'age']}} // json array里元素的顺序是否在序列化前后或者反序列化前后保持不变呢? JSONArray heads = jsonObject.getJSONArray("heads"); StringBuffer logstr = new StringBuffer(); for (int i = 0; i < heads.length(); i++) { columns.add(heads.getString(i)); logstr.append(heads.getString(i)); logstr.append(";"); } logger.info("log head:"+logstr); JSONArray records = jsonObject.getJSONArray("records"); for (int i = 0; i < records.length(); ++i) { JSONArray values = records.getJSONArray(i); if (values.length() != columns.size()) { return "data returned by log serv is invalid."; } HashMap<String, String> record_map = new HashMap<String, String>(); for (int j = 0; j < values.length(); j++) { String value = values.getString(j); record_map.put(columns.get(j), value); } record_map_list.add(record_map); } logger.info("log record number:"+record_map_list.size()); BusinessLogResult businessLogResult = new BusinessLogResult(); businessLogResult.setColumn_names(columns); businessLogResult.setLog_records(record_map_list); this.getHttpRequest().getSession().setAttribute(BUSI_LOG_RESULT_IN_SESSION, businessLogResult ); return "success"; } catch (Exception e) { e.printStackTrace(); logger.error(e.getMessage()); return e.getMessage(); } finally { if (socket!=null) { try {socket.close();} catch (Exception e){}; } } } public JsonRPCResponseBase exec(BusinessLog request) { try { /* getHttpResponse().setContentType("text/html"); getHttpResponse().setCharacterEncoding("UTF-8"); ServletOutputStream out = getHttpResponse().getOutputStream(); out.println("<html>"); out.println("<head>"); out.println("<title>log result</title>"); out.println("</head>"); out.println("<body>"); out.println("<pre>");//这个标签用于原样输出 String result = doQueryLog(out, request); if (result == null || !result.equals("success")) { out.println(result); } out.println("</pre>"); out.println("</body>"); out.println("</html>"); out.close(); return null; */ JsonRPCResponseBase response = new JsonRPCResponseBase(); String result = checkIdentity(); if (!result.equals("success")) { response.setStatus(99); response.setMessage(result); return response; } result = doQueryLog(request); if ( !result.equals("success")) { response.setMessage(result); response.setStatus(100); return response; } String ReqID = request.getRequest_id(); if (ReqID != null && ReqID.length() > 0) { result = doGetCallRelationGraph(request); if ( !result.equals("success")) { response.setMessage(result); response.setStatus(100); return response; } } response.setMessage("success"); response.setStatus(0); return response; } catch (Exception e) { e.printStackTrace(); return null; } } }