Created
December 28, 2016 03:43
-
-
Save wu-sheng/0cf0aaa5d532b26b74e973cf80ed594a to your computer and use it in GitHub Desktop.
Transaction Trace
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Created by wusheng on 2016/12/21. | |
*/ | |
public class Transaction { | |
// 当前线程事务GUID | |
private java.lang.String traceId; | |
// 相关性上级GUID | |
private java.lang.String refTraceId; | |
// 全局 GUID | |
private java.lang.String tripId; | |
private List<Span> finishedSpan = new LinkedList<Span>(); | |
private SpanNodeStack activeSpanStack = new SpanNodeStack(); | |
private int spanIdGenerator = 0; | |
private TransactionContextHolder contextHolder = new TransactionContextHolder(); | |
Transaction() { | |
traceId = TransactionGuidFactory.generateGuid(); | |
} | |
public Span createSpan() { | |
Span parentSpan = activeSpanStack.peek(); | |
Span span; | |
if (parentSpan == null) { | |
span = new Span(this, spanIdGenerator++); | |
} else { | |
span = new Span(this, spanIdGenerator++, parentSpan); | |
} | |
activeSpanStack.push(span); | |
return span; | |
} | |
public Span activeSpan() { | |
Span span = activeSpanStack.peek(); | |
if (span == null) { | |
span = new NoopSpan(); | |
} | |
return span; | |
} | |
public void stopSpan(Span span) { | |
Span lastSpan = activeSpanStack.peek(); | |
if (lastSpan == span) { | |
finishedSpan.add(activeSpanStack.pop()); | |
} else { | |
throw new UnexpectedActiveSpanException(span); | |
} | |
if (activeSpanStack.isEmpty()) { | |
this.finish(); | |
} | |
} | |
public void setRefTraceId(java.lang.String refTraceId) { | |
this.refTraceId = refTraceId; | |
} | |
public void setTripId(java.lang.String tripId) { | |
this.tripId = tripId; | |
} | |
public String getTraceId() { | |
return traceId; | |
} | |
public String getRefTraceId() { | |
return refTraceId; | |
} | |
public String getTripId() { | |
return tripId; | |
} | |
public TransactionContextHolder getContextHolder() { | |
return contextHolder; | |
} | |
private void finish() { | |
ServiceFactory.getServiceManager().getTransactionDisruptorBufferService().finishTransaction(this); | |
TransactionManager.instance().finish(); | |
} | |
static class SpanNodeStack { | |
/** | |
* 单JVM的单线程,埋点数量一般不会超过20. | |
* 超过20会影响性能,不推荐使用 | |
*/ | |
private List<Span> spans = new ArrayList<Span>(20); | |
public Span pop() { | |
return spans.remove(getTopElementIdx()); | |
} | |
public void push(Span span) { | |
spans.add(spans.size(), span); | |
} | |
public Span peek() { | |
if (spans.isEmpty()) { | |
return null; | |
} | |
return spans.get(getTopElementIdx()); | |
} | |
private int getTopElementIdx() { | |
return spans.size() - 1; | |
} | |
boolean isEmpty() { | |
return spans.isEmpty(); | |
} | |
} | |
static class TransactionContextHolder { | |
private final Map<Connection, JdbcDataSourceConnectionFactory> connectionToFactory = new ConcurrentHashMap<Connection, JdbcDataSourceConnectionFactory>(); | |
private final Map<Statement, String> statementToSql = new ConcurrentHashMap<Statement, String>(); | |
public void putConnectionFactory(Connection connection, JdbcDataSourceConnectionFactory jdbcDataSourceConnectionFactory) { | |
connectionToFactory.put(connection, jdbcDataSourceConnectionFactory); | |
} | |
public JdbcDataSourceConnectionFactory getConnectionFactory(Connection connection) { | |
if (connection == null) | |
return null; | |
return connectionToFactory.get(connection); | |
} | |
public void putSql(Statement statement, String sql) { | |
statementToSql.put(statement, sql); | |
} | |
public String getSql(Statement statement) { | |
if (statement == null) | |
return null; | |
return statementToSql.get(statement); | |
} | |
} | |
public static class TransactionHolder{ | |
private Transaction instance; | |
public TransactionHolder(){ | |
} | |
public void setValue(Transaction transaction){ | |
this.instance = transaction; | |
} | |
public Transaction getValue(){ | |
return this.instance; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment