From 24fd3ff1be0eeb09d03756735c6e1a7b58105b48 Mon Sep 17 00:00:00 2001 From: zhangxin10 Date: Thu, 14 Jan 2016 19:55:57 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E5=AE=8C=E6=88=90ViewPoint=E7=9A=84?= =?UTF-8?q?=E9=93=BE=202.=20=E5=AE=8C=E6=88=90=E5=A4=84=E7=90=86=E9=80=BB?= =?UTF-8?q?=E8=BE=91=E7=9A=84=E9=93=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- skywalking-analysis/pom.xml | 66 +++++++++++ .../analysis/AnalysisServerDriver.java | 58 ++++++++++ .../skywalking/analysis/config/Config.java | 7 ++ .../analysis/config/ConfigInitializer.java | 85 ++++++++++++++ .../config/ViewPointFilterFactory.java | 79 +++++++++++++ .../analysis/filter/ChainNodeFilter.java | 9 ++ .../skywalking/analysis/filter/NodeChain.java | 37 ++++++ .../filter/impl/CopyAttrNodeFilter.java | 26 +++++ .../analysis/filter/impl/CostNodeFilter.java | 24 ++++ .../filter/impl/ViewPointNodeFilter.java | 20 ++++ .../analysis/mapper/CallChainMapper.java | 79 +++++++++++++ .../skywalking/analysis/model/ChainInfo.java | 105 ++++++++++++++++++ .../skywalking/analysis/model/ChainNode.java | 97 ++++++++++++++++ .../skywalking/analysis/model/CostMap.java | 20 ++++ .../analysis/reduce/ChainInfoReduce.java | 15 +++ .../analysis/util/TokenGenerator.java | 36 ++++++ .../analysis/viewpoint/ViewPointFilter.java | 18 +++ .../impl/AppendBusinessKeyFilter.java | 15 +++ .../viewpoint/impl/ReplaceIPPortFilter.java | 22 ++++ .../src/main/resources/config.properties | 0 .../src/main/resources/log4j.xml | 19 ++++ .../src/main/resources/log4j2.xml | 13 +++ .../src/main/resources/viewpointfilter.conf | 3 + 23 files changed, 853 insertions(+) create mode 100644 skywalking-analysis/pom.xml create mode 100644 skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/AnalysisServerDriver.java create mode 100644 skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/config/Config.java create mode 100644 skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/config/ConfigInitializer.java create mode 100644 skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/config/ViewPointFilterFactory.java create mode 100644 skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/filter/ChainNodeFilter.java create mode 100644 skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/filter/NodeChain.java create mode 100644 skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/filter/impl/CopyAttrNodeFilter.java create mode 100644 skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/filter/impl/CostNodeFilter.java create mode 100644 skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/filter/impl/ViewPointNodeFilter.java create mode 100644 skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/mapper/CallChainMapper.java create mode 100644 skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/model/ChainInfo.java create mode 100644 skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/model/ChainNode.java create mode 100644 skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/model/CostMap.java create mode 100644 skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/reduce/ChainInfoReduce.java create mode 100644 skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/util/TokenGenerator.java create mode 100644 skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/viewpoint/ViewPointFilter.java create mode 100644 skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/viewpoint/impl/AppendBusinessKeyFilter.java create mode 100644 skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/viewpoint/impl/ReplaceIPPortFilter.java create mode 100644 skywalking-analysis/src/main/resources/config.properties create mode 100644 skywalking-analysis/src/main/resources/log4j.xml create mode 100644 skywalking-analysis/src/main/resources/log4j2.xml create mode 100644 skywalking-analysis/src/main/resources/viewpointfilter.conf diff --git a/skywalking-analysis/pom.xml b/skywalking-analysis/pom.xml new file mode 100644 index 000000000..c74aeb101 --- /dev/null +++ b/skywalking-analysis/pom.xml @@ -0,0 +1,66 @@ + + 4.0.0 + + com.ai.cloud + skywalking-analysis + 1.0-SNAPSHOT + jar + + skywalking-analysis + http://maven.apache.org + + + UTF-8 + + + + + junit + junit + 3.8.1 + test + + + org.apache.hbase + hbase-client + 1.1.2 + + + org.apache.hbase + hbase-server + 1.1.2 + + + org.apache.logging.log4j + log4j-core + 2.4.1 + + + com.ai.cloud + skywalking-protocol + 1.0-SNAPSHOT + + + + + + + maven-compiler-plugin + + 1.6 + 1.6 + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-resources-plugin + 2.4.3 + + ${project.build.sourceEncoding} + + + + + diff --git a/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/AnalysisServerDriver.java b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/AnalysisServerDriver.java new file mode 100644 index 000000000..651b60d04 --- /dev/null +++ b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/AnalysisServerDriver.java @@ -0,0 +1,58 @@ +package com.ai.cloud.skywalking.analysis; + +import com.ai.cloud.skywalking.analysis.config.Config; +import com.ai.cloud.skywalking.analysis.mapper.CallChainMapper; +import com.ai.cloud.skywalking.analysis.model.ChainInfo; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.conf.Configured; +import org.apache.hadoop.hbase.client.Scan; +import org.apache.hadoop.hbase.mapreduce.TableMapReduceUtil; +import org.apache.hadoop.mapreduce.Job; +import org.apache.hadoop.util.GenericOptionsParser; +import org.apache.hadoop.util.Tool; +import org.apache.hadoop.util.ToolRunner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class AnalysisServerDriver extends Configured implements Tool { + + private static Logger logger = LoggerFactory.getLogger(AnalysisServerDriver.class.getName()); + + public static void main(String[] args) throws Exception { + logger.info("Begin to analysis call chain."); + int res = ToolRunner.run(new AnalysisServerDriver(), args); + System.exit(res); + } + + @Override + public int run(String[] args) throws Exception { + Configuration conf = new Configuration(); + String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs(); + if (otherArgs.length != 2) { + System.err.println("Usage: AnalysisServer yyyy-MM-dd/HH:mm:ss yyyy-MM-dd/HH:mm:ss"); + System.exit(2); + } + Job job = Job.getInstance(conf); + job.setJarByClass(AnalysisServerDriver.class); + Scan scan = buildHBaseScan(args); + + TableMapReduceUtil.initTableMapperJob(Config.HBase.TABLE_NAME, scan, CallChainMapper.class, + String.class, ChainInfo.class, job); + //TableMapReduceUtil.initTableReducerJob("sw-call-chain-model", CallChainReducer.class, job); + return job.waitForCompletion(true) ? 0 : 1; + } + + private Scan buildHBaseScan(String[] args) throws ParseException, IOException { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd/HH:mm:ss"); + Date startDate = simpleDateFormat.parse(args[0]); + Date endDate = simpleDateFormat.parse(args[1]); + Scan scan = new Scan(); + scan.setTimeRange(startDate.getTime(), endDate.getTime()); + return scan; + } +} diff --git a/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/config/Config.java b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/config/Config.java new file mode 100644 index 000000000..9dbff39a4 --- /dev/null +++ b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/config/Config.java @@ -0,0 +1,7 @@ +package com.ai.cloud.skywalking.analysis.config; + +public class Config { + public static class HBase { + public static String TABLE_NAME; + } +} diff --git a/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/config/ConfigInitializer.java b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/config/ConfigInitializer.java new file mode 100644 index 000000000..bd3305b17 --- /dev/null +++ b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/config/ConfigInitializer.java @@ -0,0 +1,85 @@ +package com.ai.cloud.skywalking.analysis.config; + +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.LinkedList; +import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class ConfigInitializer { + private static Logger logger = Logger.getLogger(ConfigInitializer.class.getName()); + + public static void initialize() { + InputStream inputStream = ConfigInitializer.class.getResourceAsStream("/config.properties"); + if (inputStream == null) { + logger.log(Level.ALL, "No provider sky-walking certification documents, sky-walking api auto shutdown."); + } else { + try { + Properties properties = new Properties(); + properties.load(inputStream); + initNextLevel(properties, Config.class, new ConfigDesc()); + } catch (IllegalAccessException e) { + logger.log(Level.ALL, "Parsing certification file failed, sky-walking api auto shutdown."); + } catch (IOException e) { + logger.log(Level.ALL, "Failed to read the certification file, sky-walking api auto shutdown."); + } + } + } + + private static void initNextLevel(Properties properties, Class recentConfigType, ConfigDesc parentDesc) throws NumberFormatException, IllegalArgumentException, IllegalAccessException { + for (Field field : recentConfigType.getFields()) { + if (Modifier.isPublic(field.getModifiers()) && Modifier.isStatic(field.getModifiers())) { + String configKey = (parentDesc + "." + + field.getName()).toLowerCase(); + String value = properties.getProperty(configKey); + if (value != null) { + if (field.getType().equals(int.class)) + field.set(null, Integer.valueOf(value)); + if (field.getType().equals(String.class)) + field.set(null, value); + if (field.getType().equals(long.class)) + field.set(null, Long.valueOf(value)); + if (field.getType().equals(boolean.class)) + field.set(null, Boolean.valueOf(value)); + } + } + } + for (Class innerConfiguration : recentConfigType.getClasses()) { + parentDesc.append(innerConfiguration.getSimpleName()); + initNextLevel(properties, innerConfiguration, parentDesc); + parentDesc.removeLastDesc(); + } + } +} + +class ConfigDesc { + private LinkedList descs = new LinkedList(); + + void append(String currentDesc) { + descs.addLast(currentDesc); + } + + void removeLastDesc() { + descs.removeLast(); + } + + @Override + public String toString() { + if (descs.size() == 0) { + return ""; + } + StringBuilder ret = new StringBuilder(descs.getFirst()); + boolean first = true; + for (String desc : descs) { + if (first) { + first = false; + continue; + } + ret.append(".").append(desc); + } + return ret.toString(); + } +} diff --git a/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/config/ViewPointFilterFactory.java b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/config/ViewPointFilterFactory.java new file mode 100644 index 000000000..b9bdb9bef --- /dev/null +++ b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/config/ViewPointFilterFactory.java @@ -0,0 +1,79 @@ +package com.ai.cloud.skywalking.analysis.config; + +import com.ai.cloud.skywalking.analysis.viewpoint.ViewPointFilter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +public class ViewPointFilterFactory { + + private static Logger logger = LoggerFactory.getLogger(ViewPointFilterFactory.class.getName()); + + private static Map filterType; + + private ViewPointFilterFactory() { + //Non + } + + private static void initFilterChain() { + Properties properties = new Properties(); + try { + properties.load(ViewPointFilterFactory.class.getResourceAsStream("/viewpointfilter.conf")); + } catch (IOException e) { + logger.error("Failed to found the conf file[viewpointfilter.conf]", e); + System.exit(-1); + } + + Set> entries = properties.entrySet(); + + for (Map.Entry entry : entries) { + String types = (String) entry.getKey(); + String filters = (String) entry.getValue(); + + String[] filterClasses = filters.split(">"); + ViewPointFilter filter = null; + for (int i = filterClasses.length - 1; i >= 0; i--) { + try { + Class filterClass = Class.forName(filterClasses[i]); + ViewPointFilter newFilter = (ViewPointFilter) filterClass.newInstance(); + newFilter.setViewPointFilter(filter); + filter = newFilter; + } catch (ClassNotFoundException e) { + logger.error("Failed to found class[" + filterClasses[i] + "].", e); + System.exit(-1); + } catch (InstantiationException e) { + logger.error("Failed to instance class[" + filterClasses[i] + "].", e); + System.exit(-1); + } catch (IllegalAccessException e) { + logger.error("Failed to access class[" + filterClasses[i] + "].", e); + System.exit(-1); + } + } + + filterType = new HashMap(); + String[] type = types.split(","); + for (int i = 0; i < type.length; i++) { + filterType.put(type[i], filter); + } + } + } + + public static ViewPointFilter getFilter(String type) { + if (filterType == null) { + initFilterChain(); + } + + ViewPointFilter filter = filterType.get(type); + if (filter == null) { + throw new RuntimeException("Failed to found the filter[" + type + "]"); + } + + return filter; + } + +} diff --git a/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/filter/ChainNodeFilter.java b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/filter/ChainNodeFilter.java new file mode 100644 index 000000000..cb5db2a09 --- /dev/null +++ b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/filter/ChainNodeFilter.java @@ -0,0 +1,9 @@ +package com.ai.cloud.skywalking.analysis.filter; + +import com.ai.cloud.skywalking.analysis.model.ChainNode; +import com.ai.cloud.skywalking.analysis.model.CostMap; +import com.ai.cloud.skywalking.protocol.Span; + +public interface ChainNodeFilter { + void doFilter(Span span, ChainNode node, CostMap costMap, NodeChain chain); +} diff --git a/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/filter/NodeChain.java b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/filter/NodeChain.java new file mode 100644 index 000000000..4403b94a1 --- /dev/null +++ b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/filter/NodeChain.java @@ -0,0 +1,37 @@ +package com.ai.cloud.skywalking.analysis.filter; + +import com.ai.cloud.skywalking.analysis.filter.impl.CopyAttrNodeFilter; +import com.ai.cloud.skywalking.analysis.filter.impl.CostNodeFilter; +import com.ai.cloud.skywalking.analysis.filter.impl.ViewPointNodeFilter; +import com.ai.cloud.skywalking.analysis.model.ChainNode; +import com.ai.cloud.skywalking.analysis.model.CostMap; +import com.ai.cloud.skywalking.protocol.Span; + +import java.util.ArrayList; +import java.util.List; + +public class NodeChain { + + private int stage = 0; + + private static List filters = null; + + public void doChain(Span span, ChainNode chainNode, CostMap costMap) { + if (filters == null) { + filters = new ArrayList(); + init(); + } + + int subscript = stage; + stage = stage + 1; + if (subscript < filters.size()) { + filters.get(subscript).doFilter(span, chainNode, costMap, this); + } + } + + private static void init() { + filters.add(new CostNodeFilter()); + filters.add(new CopyAttrNodeFilter()); + filters.add(new ViewPointNodeFilter()); + } +} diff --git a/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/filter/impl/CopyAttrNodeFilter.java b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/filter/impl/CopyAttrNodeFilter.java new file mode 100644 index 000000000..ed7e225fb --- /dev/null +++ b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/filter/impl/CopyAttrNodeFilter.java @@ -0,0 +1,26 @@ +package com.ai.cloud.skywalking.analysis.filter.impl; + +import com.ai.cloud.skywalking.analysis.filter.ChainNodeFilter; +import com.ai.cloud.skywalking.analysis.filter.NodeChain; +import com.ai.cloud.skywalking.analysis.model.ChainNode; +import com.ai.cloud.skywalking.analysis.model.CostMap; +import com.ai.cloud.skywalking.protocol.Span; + +public class CopyAttrNodeFilter implements ChainNodeFilter { + + @Override + public void doFilter(Span span, ChainNode node, CostMap costMap, NodeChain chain) { + node.setCost(span.getCost()); + node.setLevelId(span.getLevelId()); + node.setParentLevelId(span.getParentLevel()); + node.setCallType(span.getCallType()); + + if (span.getExceptionStack() == null || span.getExceptionStack().length() == 0) { + node.setStatus(ChainNode.NodeStatus.NORMAL); + } else { + node.setStatus(ChainNode.NodeStatus.ABNORMAL); + } + + chain.doChain(span, node, costMap); + } +} diff --git a/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/filter/impl/CostNodeFilter.java b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/filter/impl/CostNodeFilter.java new file mode 100644 index 000000000..be48b5468 --- /dev/null +++ b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/filter/impl/CostNodeFilter.java @@ -0,0 +1,24 @@ +package com.ai.cloud.skywalking.analysis.filter.impl; + +import com.ai.cloud.skywalking.analysis.filter.ChainNodeFilter; +import com.ai.cloud.skywalking.analysis.filter.NodeChain; +import com.ai.cloud.skywalking.analysis.model.ChainNode; +import com.ai.cloud.skywalking.analysis.model.CostMap; +import com.ai.cloud.skywalking.protocol.Span; + +public class CostNodeFilter implements ChainNodeFilter { + + @Override + public void doFilter(Span span, ChainNode node, CostMap costMap, NodeChain chain) { + if (span.isReceiver()) { + costMap.put(span.getParentLevel() + "." + span.getLevelId() + "-S", node.getCost()); + } else { + if (costMap.exists(span.getParentLevel())) { + costMap.put(span.getParentLevel(), costMap.get(span.getParentLevel()) + span.getCost()); + } else { + costMap.put(span.getParentLevel(), span.getCost()); + } + chain.doChain(span, node, costMap); + } + } +} diff --git a/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/filter/impl/ViewPointNodeFilter.java b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/filter/impl/ViewPointNodeFilter.java new file mode 100644 index 000000000..93fccaad8 --- /dev/null +++ b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/filter/impl/ViewPointNodeFilter.java @@ -0,0 +1,20 @@ +package com.ai.cloud.skywalking.analysis.filter.impl; + +import com.ai.cloud.skywalking.analysis.config.ViewPointFilterFactory; +import com.ai.cloud.skywalking.analysis.filter.ChainNodeFilter; +import com.ai.cloud.skywalking.analysis.filter.NodeChain; +import com.ai.cloud.skywalking.analysis.model.ChainNode; +import com.ai.cloud.skywalking.analysis.model.CostMap; +import com.ai.cloud.skywalking.analysis.viewpoint.ViewPointFilter; +import com.ai.cloud.skywalking.protocol.Span; + +public class ViewPointNodeFilter implements ChainNodeFilter { + @Override + public void doFilter(Span span, ChainNode node, CostMap costMap, NodeChain chain) { + ViewPointFilter viewPointFilter = ViewPointFilterFactory.getFilter(span.getSpanType()); + String viewPoint = span.getViewPointId(); + viewPointFilter.doFilter(span, viewPoint); + node.setViewPoint(viewPoint); + chain.doChain(span, node, costMap); + } +} diff --git a/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/mapper/CallChainMapper.java b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/mapper/CallChainMapper.java new file mode 100644 index 000000000..e366a32e0 --- /dev/null +++ b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/mapper/CallChainMapper.java @@ -0,0 +1,79 @@ +package com.ai.cloud.skywalking.analysis.mapper; + +import com.ai.cloud.skywalking.analysis.model.ChainInfo; +import com.ai.cloud.skywalking.analysis.model.ChainNode; +import com.ai.cloud.skywalking.protocol.CallType; +import com.ai.cloud.skywalking.protocol.Span; +import org.apache.hadoop.hbase.Cell; +import org.apache.hadoop.hbase.client.Result; +import org.apache.hadoop.hbase.io.ImmutableBytesWritable; +import org.apache.hadoop.hbase.mapreduce.TableMapper; +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.hadoop.io.Text; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +public class CallChainMapper extends TableMapper { + private Logger logger = LoggerFactory.getLogger(CallChainMapper.class.getName()); + + @Override + protected void map(ImmutableBytesWritable key, Result value, Context context) throws IOException, + InterruptedException { + Map costMap = new HashMap(); + + ChainInfo chainInfo = new ChainInfo(); + String traceId = key.toString(); + logger.info("Begin to deal Trace[" + traceId + "]..."); + for (Cell cell : value.rawCells()) { + ChainNode node = new ChainNode(); + Span span = new Span(Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength())); + + node.setLevelId(span.getLevelId()); + node.setParentLevelId(span.getParentLevel()); + node.setViewPoint(convertViewPoint(span)); + node.setCost(span.getCost()); + node.setCallType(span.getCallType()); + if (span.isReceiver()) { + costMap.put(span.getParentLevel() + "." + span.getLevelId() + "-S", span.getCost()); + continue; + } + + if (costMap.containsKey(span.getParentLevel())) { + costMap.put(span.getParentLevel(), costMap.get(span.getParentLevel()).longValue() + span.getCost()); + } else { + costMap.put(span.getParentLevel(), 0L); + } + + chainInfo.getNodes().add(node); + } + + for (ChainNode node : chainInfo.getNodes()) { + CallType callType = CallType.valueOf(node.getCallType()); + switch (callType) { + case ASYNC: + + break; + case SYNC: + + break; + case LOCAL: + + break; + } + } + + //入Mysql库 + //入HBase库 + //找到首个Node的MD5 + //拼接MR任务的Key + context.write(new Text(""), chainInfo); + } + + private String convertViewPoint(Span span) { + return null; + } +} diff --git a/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/model/ChainInfo.java b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/model/ChainInfo.java new file mode 100644 index 000000000..4361cd43d --- /dev/null +++ b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/model/ChainInfo.java @@ -0,0 +1,105 @@ +package com.ai.cloud.skywalking.analysis.model; + +import org.apache.hadoop.io.Writable; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class ChainInfo implements Writable { + private String chainToken; + private ChainStatus chainStatus; + private List nodes; + + public ChainInfo() { + this.nodes = new ArrayList(); + } + + @Override + public void write(DataOutput out) throws IOException { + out.write(chainToken.getBytes()); + out.writeChar(chainStatus.getValue()); + + out.writeInt(nodes.size()); + for (ChainNode chainNode : nodes) { + out.write(chainNode.getNodeToken().getBytes()); + out.write(chainNode.getViewPoint().getBytes()); + out.writeChar(chainNode.getStatus().getValue()); + out.writeLong(chainNode.getCost()); + out.write(chainNode.getParentLevelId().getBytes()); + out.writeInt(chainNode.getLevelId()); + } + } + + @Override + public void readFields(DataInput in) throws IOException { + chainToken = in.readLine(); + chainStatus = ChainStatus.convert(in.readChar()); + + int nodeSize = in.readInt(); + this.nodes = new ArrayList(); + for (int i = 0; i < nodeSize; i++) { + ChainNode chainNode = new ChainNode(); + chainNode.setNodeToken(in.readLine()); + chainNode.setViewPoint(in.readLine()); + chainNode.setStatus(ChainNode.NodeStatus.convert(in.readChar())); + chainNode.setCost(in.readLong()); + chainNode.setParentLevelId(in.readLine()); + chainNode.setLevelId(in.readInt()); + nodes.add(chainNode); + } + } + + + public String getChainToken() { + return chainToken; + } + + public void setChainToken(String chainToken) { + this.chainToken = chainToken; + } + + public ChainStatus getChainStatus() { + return chainStatus; + } + + public void setChainStatus(ChainStatus chainStatus) { + this.chainStatus = chainStatus; + } + + public List getNodes() { + return nodes; + } + + public void setNodes(List nodes) { + this.nodes = nodes; + } + + public enum ChainStatus { + NORMAL('N'), ABNORMAL('A'); + private char value; + + ChainStatus(char value) { + this.value = value; + } + + public char getValue() { + return value; + } + + public static ChainStatus convert(char value) { + switch (value) { + case 'N': + return NORMAL; + case 'A': + return ABNORMAL; + default: + throw new IllegalStateException("Failed to convert[" + value + "]"); + } + } + } +} + + diff --git a/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/model/ChainNode.java b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/model/ChainNode.java new file mode 100644 index 000000000..715e04e83 --- /dev/null +++ b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/model/ChainNode.java @@ -0,0 +1,97 @@ +package com.ai.cloud.skywalking.analysis.model; + +public class ChainNode { + + private String nodeToken; + + private String viewPoint; + //TODO + private String businessKey; + + private long cost; + private NodeStatus status; + private String parentLevelId; + private int levelId; + private String callType; + + public String getNodeToken() { + return nodeToken; + } + + public void setNodeToken(String nodeToken) { + this.nodeToken = nodeToken; + } + + public String getViewPoint() { + return viewPoint; + } + + public void setViewPoint(String viewPoint) { + this.viewPoint = viewPoint; + } + + public long getCost() { + return cost; + } + + public void setCost(long cost) { + this.cost = cost; + } + + public NodeStatus getStatus() { + return status; + } + + public void setStatus(NodeStatus status) { + this.status = status; + } + + public String getParentLevelId() { + return parentLevelId; + } + + public void setParentLevelId(String parentLevelId) { + this.parentLevelId = parentLevelId; + } + + public int getLevelId() { + return levelId; + } + + public void setLevelId(int levelId) { + this.levelId = levelId; + } + + public void setCallType(String callType) { + this.callType = callType; + } + + public String getCallType() { + return callType; + } + + public enum NodeStatus { + NORMAL('N'), ABNORMAL('A'); + private char value; + + NodeStatus(char value) { + this.value = value; + } + + public char getValue() { + return value; + } + + public static NodeStatus convert(char value) { + switch (value) { + case 'N': + return NORMAL; + case 'A': + return ABNORMAL; + default: + throw new IllegalStateException("Failed to convert[" + value + "]"); + } + } + } + +} diff --git a/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/model/CostMap.java b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/model/CostMap.java new file mode 100644 index 000000000..835c3a2ae --- /dev/null +++ b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/model/CostMap.java @@ -0,0 +1,20 @@ +package com.ai.cloud.skywalking.analysis.model; + +import java.util.HashMap; +import java.util.Map; + +public class CostMap { + private Map costs = new HashMap(); + + public void put(String parentLevel, Long cost) { + costs.put(parentLevel, cost); + } + + public boolean exists(String parentLevel) { + return costs.containsKey(parentLevel); + } + + public long get(String parentLevel) { + return costs.get(parentLevel); + } +} diff --git a/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/reduce/ChainInfoReduce.java b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/reduce/ChainInfoReduce.java new file mode 100644 index 000000000..d47aa1283 --- /dev/null +++ b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/reduce/ChainInfoReduce.java @@ -0,0 +1,15 @@ +package com.ai.cloud.skywalking.analysis.reduce; + +import com.ai.cloud.skywalking.analysis.model.ChainInfo; +import org.apache.hadoop.hbase.client.Put; +import org.apache.hadoop.hbase.mapreduce.TableReducer; +import org.apache.hadoop.io.Text; + +import java.io.IOException; + +public class ChainInfoReduce extends TableReducer { + @Override + protected void reduce(Text key, Iterable values, Context context) throws IOException, InterruptedException { + super.reduce(key, values, context); + } +} diff --git a/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/util/TokenGenerator.java b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/util/TokenGenerator.java new file mode 100644 index 000000000..73c3200e1 --- /dev/null +++ b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/util/TokenGenerator.java @@ -0,0 +1,36 @@ +package com.ai.cloud.skywalking.analysis.util; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +public class TokenGenerator { + private static Logger logger = LoggerFactory.getLogger(TokenGenerator.class.getName()); + + private TokenGenerator() { + //Non + } + + public static String generate(String originData) { + StringBuilder result = new StringBuilder(); + if (originData != null) { + try { + MessageDigest md = MessageDigest.getInstance("MD5"); + byte bytes[] = md.digest(originData.getBytes()); + for (int i = 0; i < bytes.length; i++) { + String str = Integer.toHexString(bytes[i] & 0xFF); + if (str.length() == 1) { + str += "F"; + } + result.append(str); + } + } catch (NoSuchAlgorithmException e) { + logger.error("Cannot found algorithm.", e); + System.exit(-1); + } + } + return result.toString().toUpperCase(); + } +} diff --git a/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/viewpoint/ViewPointFilter.java b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/viewpoint/ViewPointFilter.java new file mode 100644 index 000000000..a81d9377d --- /dev/null +++ b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/viewpoint/ViewPointFilter.java @@ -0,0 +1,18 @@ +package com.ai.cloud.skywalking.analysis.viewpoint; + +import com.ai.cloud.skywalking.protocol.Span; + +public abstract class ViewPointFilter { + private ViewPointFilter viewPointFilter; + + public abstract void doFilter(Span viewPoint, String span); + + public ViewPointFilter getViewPointFilter() { + return viewPointFilter; + } + + public void setViewPointFilter(ViewPointFilter viewPointFilter) { + this.viewPointFilter = viewPointFilter; + } + +} diff --git a/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/viewpoint/impl/AppendBusinessKeyFilter.java b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/viewpoint/impl/AppendBusinessKeyFilter.java new file mode 100644 index 000000000..86da43c86 --- /dev/null +++ b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/viewpoint/impl/AppendBusinessKeyFilter.java @@ -0,0 +1,15 @@ +package com.ai.cloud.skywalking.analysis.viewpoint.impl; + +import com.ai.cloud.skywalking.analysis.viewpoint.ViewPointFilter; +import com.ai.cloud.skywalking.protocol.Span; + +public class AppendBusinessKeyFilter extends ViewPointFilter { + @Override + public void doFilter(Span span, String viewPoint) { + viewPoint += span.getBusinessKey(); + + if (getViewPointFilter() != null) { + getViewPointFilter().doFilter(span, viewPoint); + } + } +} diff --git a/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/viewpoint/impl/ReplaceIPPortFilter.java b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/viewpoint/impl/ReplaceIPPortFilter.java new file mode 100644 index 000000000..5d03362a5 --- /dev/null +++ b/skywalking-analysis/src/main/java/com/ai/cloud/skywalking/analysis/viewpoint/impl/ReplaceIPPortFilter.java @@ -0,0 +1,22 @@ +package com.ai.cloud.skywalking.analysis.viewpoint.impl; + +import com.ai.cloud.skywalking.analysis.viewpoint.ViewPointFilter; +import com.ai.cloud.skywalking.protocol.Span; + +public class ReplaceIPPortFilter extends ViewPointFilter { + + //ip:port regex + private static String IP_PORT_REGEX = "^([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\\." + + "([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\\.([0-9]|[1-9][0-9]|1([0-9][0-9])" + + "|2([0-4][0-9]|5[0-5]))\\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5])):" + + "([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$"; + + @Override + public void doFilter(Span span, String viewPoint) { + viewPoint = viewPoint.replaceAll(IP_PORT_REGEX, span.getApplicationId()); + + if (getViewPointFilter() != null) { + getViewPointFilter().doFilter(span, viewPoint); + } + } +} diff --git a/skywalking-analysis/src/main/resources/config.properties b/skywalking-analysis/src/main/resources/config.properties new file mode 100644 index 000000000..e69de29bb diff --git a/skywalking-analysis/src/main/resources/log4j.xml b/skywalking-analysis/src/main/resources/log4j.xml new file mode 100644 index 000000000..0da28a6d5 --- /dev/null +++ b/skywalking-analysis/src/main/resources/log4j.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + diff --git a/skywalking-analysis/src/main/resources/log4j2.xml b/skywalking-analysis/src/main/resources/log4j2.xml new file mode 100644 index 000000000..025d5b2fb --- /dev/null +++ b/skywalking-analysis/src/main/resources/log4j2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/skywalking-analysis/src/main/resources/viewpointfilter.conf b/skywalking-analysis/src/main/resources/viewpointfilter.conf new file mode 100644 index 000000000..7009d68dd --- /dev/null +++ b/skywalking-analysis/src/main/resources/viewpointfilter.conf @@ -0,0 +1,3 @@ +# +D,M=com.ai.cloud.skywalking.analysis.viewpoint.impl.ReplaceIPPortFilter +J=com.ai.cloud.skywalking.analysis.viewpoint.impl.AppendBusinessKeyFilter \ No newline at end of file