getTags() {
return Collections.unmodifiableMap(tags);
}
@@ -146,13 +148,12 @@ public class Span {
* @param key the given tag key.
* @return tag value.
*/
- public Object getTag(String key){
+ public Object getTag(String key) {
return tags.get(key);
}
/**
- * This method is from opentracing-java.
- * {@see https://github.com/opentracing/opentracing-java/blob/release-0.20.9/opentracing-api/src/main/java/io/opentracing/Span.java#L91}
+ * This method is from opentracing-java. {@see https://github.com/opentracing/opentracing-java/blob/release-0.20.9/opentracing-api/src/main/java/io/opentracing/Span.java#L91}
*
* Log key:value pairs to the Span with the current walltime timestamp.
*
@@ -161,40 +162,82 @@ public class Span {
*
* A contrived example (using Guava, which is not required):
*
{@code
- span.log(
- ImmutableMap.Builder()
- .put("event", "soft error")
- .put("type", "cache timeout")
- .put("waited.millis", 1500)
- .build());
- }
+ * span.log(
+ * ImmutableMap.Builder()
+ * .put("event", "soft error")
+ * .put("type", "cache timeout")
+ * .put("waited.millis", 1500)
+ * .build());
+ * }
*
* @param fields key:value log fields. Tracer implementations should support String, numeric, and boolean values;
- * some may also support arbitrary Objects.
+ * some may also support arbitrary Objects.
* @return the Span, for chaining
* @see Span#log(String)
*/
- public Span log(Map fields){
+ public Span log(Map fields) {
logs.add(new LogData(System.currentTimeMillis(), fields));
return this;
}
/**
- * This method is from opentracing-java.
- * {@see https://github.com/opentracing/opentracing-java/blob/release-0.20.9/opentracing-api/src/main/java/io/opentracing/Span.java#L120}
+ * Record an exception event of the current walltime timestamp.
+ *
+ * @param t any subclass of {@link Throwable}, which occurs in this span.
+ * @return the Span, for chaining
+ */
+ public Span log(Throwable t) {
+ Map exceptionFields = new HashMap();
+ exceptionFields.put("error.kind", t.getClass().getName());
+ exceptionFields.put("message", t.getMessage());
+ exceptionFields.put("stack", ThrowableTransformer.INSTANCE.convert2String(t, 4000));
+
+ logs.add(new LogData(System.currentTimeMillis(), exceptionFields));
+
+ return this;
+ }
+
+ private enum ThrowableTransformer {
+ INSTANCE;
+
+ private String convert2String(Throwable e, int maxLength) {
+ ByteArrayOutputStream buf = null;
+ StringBuilder expMessage = new StringBuilder();
+ try {
+ buf = new ByteArrayOutputStream();
+ Throwable causeException = e;
+ while (expMessage.length() < maxLength && causeException != null) {
+ causeException.printStackTrace(new java.io.PrintWriter(buf, true));
+ expMessage.append(buf.toString());
+ causeException = causeException.getCause();
+ }
+
+ } finally {
+ try {
+ buf.close();
+ } catch (IOException ioe) {
+ }
+ }
+
+ return (maxLength > expMessage.length() ? expMessage : expMessage.substring(0, maxLength)).toString();
+ }
+ }
+
+ /**
+ * This method is from opentracing-java. {@see https://github.com/opentracing/opentracing-java/blob/release-0.20.9/opentracing-api/src/main/java/io/opentracing/Span.java#L120}
*
* Record an event at the current walltime timestamp.
*
* Shorthand for
*
* {@code
- span.log(Collections.singletonMap("event", event));
- }
+ * span.log(Collections.singletonMap("event", event));
+ * }
*
* @param event the event value; often a stable identifier for a moment in the Span lifecycle
* @return the Span, for chaining
*/
- public Span log(String event){
+ public Span log(String event) {
log(Collections.singletonMap("event", event));
return this;
}
diff --git a/skywalking-commons/skywalking-trace/src/main/java/com/a/eye/skywalking/trace/tag/Tags.java b/skywalking-commons/skywalking-trace/src/main/java/com/a/eye/skywalking/trace/tag/Tags.java
index a0171e9f2..36909d46d 100644
--- a/skywalking-commons/skywalking-trace/src/main/java/com/a/eye/skywalking/trace/tag/Tags.java
+++ b/skywalking-commons/skywalking-trace/src/main/java/com/a/eye/skywalking/trace/tag/Tags.java
@@ -1,5 +1,7 @@
package com.a.eye.skywalking.trace.tag;
+import com.a.eye.skywalking.trace.Span;
+
/**
* The span tags are supported by sky-walking engine.
* As default, all tags will be stored, but these ones have particular meanings.
@@ -21,10 +23,16 @@ public final class Tags {
public static final IntTag HTTP_STATUS = new IntTag("http.status_code");
/**
- * SPAN_KIND hints at the relationship between spans.
- * e.g. cl = client; se = server.
+ * SPAN_KIND represents the kind of span.
+ * e.g. db=database,
*/
- public static final StringTag SPAN_KIND = new StringTag("span.kind");
+ public static final class SPAN_KIND{
+ private static StringTag SPAN_KIND_TAG = new StringTag("span.kind");
+
+ public static void asDBAccess(Span span){
+ SPAN_KIND_TAG.set(span, "db");
+ }
+ }
/**
* COMPONENT is a low-cardinality identifier of the module, library, or package that is instrumented.
diff --git a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/context/ContextManager.java b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/context/ContextManager.java
index 9c6e8f054..7c89f0cae 100644
--- a/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/context/ContextManager.java
+++ b/skywalking-sniffer/skywalking-api/src/main/java/com/a/eye/skywalking/context/ContextManager.java
@@ -30,7 +30,7 @@ public enum ContextManager implements TracerContextListener {
private static ThreadLocal CONTEXT = new ThreadLocal<>();
- public TracerContext get() {
+ private TracerContext get() {
TracerContext segment = CONTEXT.get();
if (segment == null) {
segment = new TracerContext();
diff --git a/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/PreparedStatementTracing.java b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/PreparedStatementTracing.java
index ec57bb8e5..464ea055d 100644
--- a/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/PreparedStatementTracing.java
+++ b/skywalking-sniffer/skywalking-sdk-plugin/jdbc-plugin/src/main/java/com/a/eye/skywalking/plugin/jdbc/PreparedStatementTracing.java
@@ -1,43 +1,36 @@
package com.a.eye.skywalking.plugin.jdbc;
-import com.a.eye.skywalking.model.Identification;
-import com.a.eye.skywalking.invoke.monitor.RPCClientInvokeMonitor;
-import com.a.eye.skywalking.plugin.jdbc.define.JDBCBuriedPointType;
-
+import com.a.eye.skywalking.context.ContextManager;
+import com.a.eye.skywalking.trace.Span;
+import com.a.eye.skywalking.trace.tag.Tags;
import java.sql.SQLException;
/**
* 连接级追踪,用于追踪用于Connection的操作追踪
- *
- * @author wusheng
*
+ * @author wusheng
*/
public class PreparedStatementTracing {
- private static RPCClientInvokeMonitor rpcClientInvokeMonitor = new RPCClientInvokeMonitor();
- public static R execute(java.sql.PreparedStatement realStatement,
- String connectInfo, String method, String sql, Executable exec)
- throws SQLException {
- try {
- rpcClientInvokeMonitor.beforeInvoke(Identification
- .newBuilder()
- .viewPoint(connectInfo)
- .businessKey(
- "preaparedStatement."
- + method
- + (sql == null || sql.length() == 0 ? ""
- : ":" + sql)).spanType(JDBCBuriedPointType.INSTANCE).build());
- return exec.exe(realStatement, sql);
- } catch (SQLException e) {
- rpcClientInvokeMonitor.occurException(e);
- throw e;
- } finally {
- rpcClientInvokeMonitor.afterInvoke();
- }
- }
+ public static R execute(java.sql.PreparedStatement realStatement,
+ String connectInfo, String method, String sql, Executable exec)
+ throws SQLException {
+ Span span = ContextManager.INSTANCE.createSpan("JDBC/PreparedStatement/" + method);
+ try {
+ Tags.SPAN_KIND.asDBAccess(span);
+ Tags.DB_URL.set(span, connectInfo);
+ Tags.DB_SQL.set(span, sql);
+ return exec.exe(realStatement, sql);
+ } catch (SQLException e) {
+ span.log(e);
+ throw e;
+ } finally {
+ ContextManager.INSTANCE.stopSpan(span);
+ }
+ }
- public interface Executable {
- public R exe(java.sql.PreparedStatement realConnection, String sql)
- throws SQLException;
- }
+ public interface Executable {
+ R exe(java.sql.PreparedStatement realConnection, String sql)
+ throws SQLException;
+ }
}