package com.taobao.top.analysis.util; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.jar.Attributes; import java.util.jar.Manifest; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.taobao.top.analysis.node.job.Job; /** * Analyzer中的一些公共方法 * AnalyzerUtil.java * @author yunzhan.jtq * * @since 2012-2-8 下午01:30:45 */ public class AnalyzerUtil { private static final Log logger = LogFactory.getLog(AnalyzerUtil.class); private static long buildDate=-1; private static final String report2MapFile = "report2Map"; private static ThreadPoolExecutor alertThreadPool = new ThreadPoolExecutor( 2, 5, 0, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new NamedThreadFactory("Sendder_worker")); private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); /** * 获取MANIFEST.MF文件中的属性 * @param attr * @return */ public static String getManifestAttr(String attr){ try { InputStream is=Thread.currentThread().getContextClassLoader().getResourceAsStream("META-INF/MANIFEST.MF"); Manifest mani=new Manifest(); mani.read(is); Attributes atr=mani.getMainAttributes(); String val=atr.getValue(attr); return val; } catch (Throwable e) { logger.error(e); } return null; } /** * 获取MANIFEST.MF文件的创建时间作为打包时间 * @return */ public static long getManifestBuildDate(){ if(buildDate!=-1) return buildDate; String str=getManifestAttr("BuildDate"); try{ return Long.parseLong(str); }catch(Throwable t){ return buildDate; } } public static void sendOutAlert(final Calendar calendar, final String alertURL, final String alertFrom, final String alertModel, final String alertWangwang, final String content) { alertThreadPool.execute(new Runnable() { @Override public void run() { StringBuilder urlStr = new StringBuilder(alertURL); urlStr.append("?"); urlStr.append("from="); urlStr.append(alertFrom); urlStr.append("&"); urlStr.append("alertModel="); urlStr.append(alertModel); urlStr.append("&"); urlStr.append("wangwang="); String temp = "error!"; String temp1 = "error!"; try { String date = sdf.format(java.util.Calendar.getInstance().getTime()); temp = java.net.URLEncoder.encode(alertWangwang, "UTF-8"); temp1 = java.net.URLEncoder.encode(content + "(" + date + "," + ReportUtil.getIp() + ")", "UTF-8"); } catch (UnsupportedEncodingException e) { logger.error(e.getMessage(), e); } urlStr.append(temp); urlStr.append("&"); urlStr.append("content="); urlStr.append(temp1); HttpURLConnection con = null; InputStream is = null; try { java.net.URL url = new java.net.URL(urlStr.toString()); con = HttpURLConnection.class.cast(url.openConnection()); con.setRequestMethod("GET"); con.setRequestProperty("Content-Type", "text/html; charset=UTF-8"); con.connect(); is = con.getInputStream(); } catch (Throwable e) { logger.error(urlStr.toString(), e); } finally { try { if (is != null) is.close(); if (con != null) con.disconnect(); } catch (Throwable e) { logger.error(e.getMessage(), e); } } } }); } /** * 将NULL转为空字符串 * @param str * @return */ public static String covertNullToEmpty(String str) { if (str == null) return ""; return str; } /** * 临时使用方法 * 将report2Master进行备份 * 下次加载规则时,如果存在该文件,则优先加载该文件 * 加载该文件后,再根据配置进行调整,没有的report和master从该配置中去除 * @return */ public static boolean exportReportToMaster(Map<String, String> report2Master, final Job job) { if (report2Master == null || report2Master.size() <= 0) return true; BufferedWriter bwriter = null; String _fileSuffix = AnalysisConstants.INNER_DATAFILE_SUFFIX; String _bckSuffix = AnalysisConstants.IBCK_DATAFILE_SUFFIX; String destfile = null; try { String dir = getDir(job.getJobConfig().getOutput()); File dest = new File(dir); if (!dest.exists() || (dest.exists() && !dest.isDirectory())) dest.mkdirs(); if (!dir.endsWith(File.separator)) dir += File.separator; destfile = new StringBuilder(dir).append(job.getJobName()).append("-").append(report2MapFile).append("-") .append(ReportUtil.getIp()).append(_fileSuffix).toString(); File bckFile = new File(destfile.replace(_fileSuffix, _bckSuffix)); if (bckFile.exists()) bckFile.delete(); File f = new File(destfile); if (f.exists()) f.renameTo(new File(destfile.replace(_fileSuffix, _bckSuffix))); else f.createNewFile(); bwriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f.getAbsolutePath(), false))); // 写个开头 Iterator<String> keys = report2Master.keySet().iterator(); while (keys.hasNext()) { String key = keys.next(); bwriter.write(key); bwriter.write(AnalysisConstants.EXPORT_RECORD_SPLIT); String value = report2Master.get(key); bwriter.write(value); bwriter.write(ReportUtil.getSeparator()); } bwriter.flush(); if(logger.isInfoEnabled()) logger.info("export report2Map into file : " + destfile); return true; } catch (Throwable ex) { logger.error(ex); throw new RuntimeException(ex); } finally { if (bwriter != null) { try { bwriter.close(); } catch (IOException e) { logger.error(e); } } } } /** * 临时策略 * 将report2Master文件load进内存,并与按照分配策略所产生的Map进行合并 * 合并策略为: * 1、首先去除所load报表中没有的 * 2、其次取出所load配置中不存在的master * 3、将剩余的覆盖进按照分配策略所产生的map,覆盖时info级别打点 * @return */ public static Map<String, String> loadReportToMaster(List<String> masters, List<String> reports, Map<String, String> report2Master, final Job job) { BufferedReader breader = null; Map<String, String> resultPool = null; String _fileSuffix = AnalysisConstants.INNER_DATAFILE_SUFFIX; String destfile = null; long beg = System.currentTimeMillis(); String dir = getDir(job.getJobConfig().getOutput()); File dest = new File(dir); if (!dest.exists() || (dest.exists() && !dest.isDirectory())) return report2Master; if (!dir.endsWith(File.separator)) dir += File.separator; destfile = new StringBuilder(dir).append(job.getJobName()).append("-").append(report2MapFile).append("-") .append(ReportUtil.getIp()).append(_fileSuffix).toString(); File f = new File(destfile); if (!f.exists()) return report2Master; try { breader = new BufferedReader(new InputStreamReader(new FileInputStream(f))); String line; while ((line = breader.readLine()) != null) { if (resultPool == null) resultPool = new HashMap<String, String>(); String[] contents = StringUtils.splitByWholeSeparator(line, AnalysisConstants.EXPORT_RECORD_SPLIT); if (contents == null || contents.length != 2) continue; if (masters != null && !masters.contains(contents[1])) continue; if (reports != null && !reports.contains(contents[0])) continue; resultPool.put(contents[0], contents[1]); } if (logger.isWarnEnabled()) logger.warn("Load file " + f.getAbsolutePath() + " Success , use : " + String.valueOf(System.currentTimeMillis() - beg)); if(resultPool == null) return report2Master; for (String key : resultPool.keySet()) { report2Master.put(key, resultPool.get(key)); } } catch (Exception ex) { logger.error("Load file " + f.getAbsolutePath() + " Error", ex); throw new RuntimeException("Load file " + f.getAbsolutePath() + " Error", ex); } finally { if (breader != null) { try { breader.close(); } catch (IOException e) { logger.error(e.getMessage(), e); } } } return report2Master; } /** * 将string转为map简单实现 * @param string * @param recordSplit * @param mapSplit * @return */ public static Map<String, String> convertStringToMap(String string, String recordSplit, String mapSplit) { if(string == null) return new HashMap<String, String>(); String[] records = StringUtils.splitByWholeSeparator(string, recordSplit); if(records == null || records.length <= 0) return new HashMap<String, String>(); Map<String, String> result = new HashMap<String, String>(); for(String record : records) { String ss[] = StringUtils.splitByWholeSeparator(record, mapSplit); if(ss == null || ss.length != 2) continue; result.put(ss[0], ss[1]); } return result; } private static String getDir(String dir) { String rootDir = dir; //去掉前缀,主要用于协议的前缀 if (rootDir.indexOf(":") > 0) rootDir = rootDir.substring(rootDir.indexOf(":") +1); if (!rootDir.endsWith(File.separator)) rootDir = new StringBuilder(rootDir).append(File.separator).toString(); return rootDir; } }