/** * Uses {@link ThreadLocalSpan} as there's no attribute namespace shared between callbacks, but * all callbacks happen on the same thread. * * <p>Uses {@link ThreadLocalSpan#CURRENT_TRACER} and this interceptor initializes before * tracing. */ @Override public <T extends Resultset> T preProcess(Supplier<String> sqlSupplier, Query interceptedQuery) { // Gets the next span (and places it in scope) so code between here and postProcess can read it Span span = ThreadLocalSpan.CURRENT_TRACER.next(); if (span == null || span.isNoop()) return null; String sql = sqlSupplier.get(); int spaceIndex = sql.indexOf(' '); // Allow span names of single-word statements like COMMIT span.kind(Span.Kind.CLIENT).name(spaceIndex == -1 ? sql : sql.substring(0, spaceIndex)); span.tag("sql.query", sql); parseServerIpAndPort(connection, span); span.start(); return null; }
@Override public void onAfterAnyExecute(StatementInformation info, long elapsed, SQLException e) { Span span = ThreadLocalSpan.CURRENT_TRACER.remove(); if (span == null || span.isNoop()) return; if (e != null) { span.tag("error", Integer.toString(e.getErrorCode())); } span.finish(); }
TracingChannelInterceptor(Tracing tracing, Propagation.Setter<MessageHeaderAccessor, String> setter, Propagation.Getter<MessageHeaderAccessor, String> getter) { this.tracing = tracing; this.tracer = tracing.tracer(); this.threadLocalSpan = ThreadLocalSpan.create(this.tracer); this.injector = tracing.propagation().injector(setter); this.extractor = tracing.propagation().extractor(getter); this.integrationObjectSupportPresent = ClassUtils.isPresent( "org.springframework.integration.context.IntegrationObjectSupport", null); this.hasDirectChannelClass = ClassUtils .isPresent("org.springframework.integration.channel.DirectChannel", null); this.directWithAttributesChannelClass = ClassUtils .isPresent(STREAM_DIRECT_CHANNEL, null) ? ClassUtils.resolveClassName(STREAM_DIRECT_CHANNEL, null) : null; }
/** * Returns the {@link Tracer#nextSpan(TraceContextOrSamplingFlags)} or null if {@link * #CURRENT_TRACER} and tracing isn't available. */ @Nullable public Span next(TraceContextOrSamplingFlags extracted) { Tracer tracer = tracer(); if (tracer == null) return null; Span next = tracer.nextSpan(extracted); Object[] spanAndScope = {next, tracer.withSpanInScope(next)}; getCurrentSpanInScopeStack().addFirst(spanAndScope); return next; }
public static ThreadLocalSpan create(Tracer tracer) { if (tracer == null) throw new NullPointerException("tracer == null"); return new ThreadLocalSpan(tracer); }
/** * Returns the {@link Tracer#nextSpan()} or null if {@link #CURRENT_TRACER} and tracing isn't * available. */ @Nullable public Span next() { Tracer tracer = tracer(); if (tracer == null) return null; Span next = tracer.nextSpan(); Object[] spanAndScope = {next, tracer.withSpanInScope(next)}; getCurrentSpanInScopeStack().addFirst(spanAndScope); return next; }
public static ThreadLocalSpan create(Tracer tracer) { if (tracer == null) throw new NullPointerException("tracer == null"); return new ThreadLocalSpan(tracer); }
/** * Uses {@link ThreadLocalSpan} as there's no attribute namespace shared between callbacks, but * all callbacks happen on the same thread. * * <p>Uses {@link ThreadLocalSpan#CURRENT_TRACER} and this interceptor initializes before tracing. */ @Override public void onBeforeAnyExecute(StatementInformation info) { String sql = includeParameterValues ? info.getSqlWithValues() : info.getSql(); // don't start a span unless there is SQL as we cannot choose a relevant name without it if (sql == null || sql.isEmpty()) return; // Gets the next span (and places it in scope) so code between here and postProcess can read it Span span = ThreadLocalSpan.CURRENT_TRACER.next(); if (span == null || span.isNoop()) return; span.kind(Span.Kind.CLIENT).name(sql.substring(0, sql.indexOf(' '))); span.tag("sql.query", sql); parseServerIpAndPort(info.getConnectionInformation().getConnection(), span); span.start(); }
@Override public <T extends Resultset> T postProcess(Supplier<String> sql, Query interceptedQuery, T originalResultSet, ServerSession serverSession) { if (interceptingExceptions && originalResultSet == null) { // Error case, the span will be finished in TracingExceptionInterceptor. return null; } Span span = ThreadLocalSpan.CURRENT_TRACER.remove(); if (span == null || span.isNoop()) return null; span.finish(); return null; }
/** * Returns the span set in scope via {@link #next()} or null if there was none. * * <p>When assertions are on, this will throw an assertion error if the span returned was not the * one currently in context. This could happen if someone called {@link * Tracer#withSpanInScope(Span)} or {@link CurrentTraceContext#newScope(TraceContext)} outside a * try/finally block. */ @Nullable public Span remove() { Tracer tracer = tracer(); Span currentSpan = tracer != null ? tracer.currentSpan() : null; Object[] spanAndScope = getCurrentSpanInScopeStack().pollFirst(); if (spanAndScope == null) return currentSpan; Span span = (Span) spanAndScope[0]; ((SpanInScope) spanAndScope[1]).close(); assert span.equals(currentSpan) : "Misalignment: scoped span " + span + " != current span " + currentSpan; return currentSpan; }
TracingChannelInterceptor(Tracing tracing, Propagation.Setter<MessageHeaderAccessor, String> setter, Propagation.Getter<MessageHeaderAccessor, String> getter) { this.tracing = tracing; this.tracer = tracing.tracer(); this.threadLocalSpan = ThreadLocalSpan.create(this.tracer); this.injector = tracing.propagation().injector(setter); this.extractor = tracing.propagation().extractor(getter); this.integrationObjectSupportPresent = ClassUtils.isPresent( "org.springframework.integration.context.IntegrationObjectSupport", null); this.hasDirectChannelClass = ClassUtils .isPresent("org.springframework.integration.channel.DirectChannel", null); this.directWithAttributesChannelClass = ClassUtils .isPresent(STREAM_DIRECT_CHANNEL, null) ? ClassUtils.resolveClassName(STREAM_DIRECT_CHANNEL, null) : null; }
/** * Uses {@link ThreadLocalSpan} as there's no attribute namespace shared between callbacks, but * all callbacks happen on the same thread. * * <p>Uses {@link ThreadLocalSpan#CURRENT_TRACER} and this interceptor initializes before * tracing. */ @Override public ResultSetInternalMethods preProcess(String sql, Statement interceptedStatement, Connection connection) { // Gets the next span (and places it in scope) so code between here and postProcess can read it Span span = ThreadLocalSpan.CURRENT_TRACER.next(); if (span == null || span.isNoop()) return null; // When running a prepared statement, sql will be null and we must fetch the sql from the statement itself if (interceptedStatement instanceof PreparedStatement) { sql = ((PreparedStatement) interceptedStatement).getPreparedSql(); } int spaceIndex = sql.indexOf(' '); // Allow span names of single-word statements like COMMIT span.kind(Span.Kind.CLIENT).name(spaceIndex == -1 ? sql : sql.substring(0, spaceIndex)); span.tag("sql.query", sql); parseServerIpAndPort(connection, span); span.start(); return null; }
void finishSpan(Exception error) { Span span = this.threadLocalSpan.remove(); if (span == null || span.isNoop()) return; if (error != null) { // an error occurred, adding error to span String message = error.getMessage(); if (message == null) message = error.getClass().getSimpleName(); span.tag("error", message); } span.finish(); }
/** * Returns the {@link Tracer#nextSpan()} or null if {@link #CURRENT_TRACER} and tracing isn't * available. */ @Nullable public Span next() { Tracer tracer = tracer(); if (tracer == null) return null; Span next = tracer.nextSpan(); Object[] spanAndScope = {next, tracer.withSpanInScope(next)}; getCurrentSpanInScopeStack().addFirst(spanAndScope); return next; }
TracingMessagingInterceptor(Tracing tracing, Propagation.Setter<MessageHeaderAccessor, String> setter, Propagation.Getter<MessageHeaderAccessor, String> getter) { this.tracing = tracing; this.tracer = tracing.tracer(); this.threadLocalSpan = ThreadLocalSpan.create(this.tracer); this.injector = tracing.propagation().injector(setter); this.extractor = tracing.propagation().extractor(getter); }
/** * Uses {@link ThreadLocalSpan} as there's no attribute namespace shared between callbacks, but * all callbacks happen on the same thread. * * <p>Uses {@link ThreadLocalSpan#CURRENT_TRACER} and this interceptor initializes before * tracing. */ @Override public <T extends Resultset> T preProcess(String sql, Statement interceptedStatement) { // Gets the next span (and places it in scope) so code between here and postProcess can read it Span span = ThreadLocalSpan.CURRENT_TRACER.next(); if (span == null || span.isNoop()) return null; // When running a prepared statement, sql will be null and we must fetch the sql from the statement itself if (interceptedStatement instanceof PreparedStatement) { sql = ((PreparedStatement) interceptedStatement).getPreparedSql(); } int spaceIndex = sql.indexOf(' '); // Allow span names of single-word statements like COMMIT span.kind(Span.Kind.CLIENT).name(spaceIndex == -1 ? sql : sql.substring(0, spaceIndex)); span.tag("sql.query", sql); parseServerIpAndPort(connection, span); span.start(); return null; }
@Override public ResultSetInternalMethods postProcess(String sql, Statement interceptedStatement, ResultSetInternalMethods originalResultSet, Connection connection, int warningCount, boolean noIndexUsed, boolean noGoodIndexUsed, SQLException statementException) { Span span = ThreadLocalSpan.CURRENT_TRACER.remove(); if (span == null || span.isNoop()) return null; if (statementException != null) { span.tag("error", Integer.toString(statementException.getErrorCode())); } span.finish(); return null; }
/** * Returns the {@link Tracer#nextSpan(TraceContextOrSamplingFlags)} or null if {@link * #CURRENT_TRACER} and tracing isn't available. */ @Nullable public Span next(TraceContextOrSamplingFlags extracted) { Tracer tracer = tracer(); if (tracer == null) return null; Span next = tracer.nextSpan(extracted); Object[] spanAndScope = {next, tracer.withSpanInScope(next)}; getCurrentSpanInScopeStack().addFirst(spanAndScope); return next; }
/** * This starts a consumer span as a child of the incoming message or the current trace * context, placing it in scope until the receive completes. */ @Override public Message<?> postReceive(Message<?> message, MessageChannel channel) { if (emptyMessage(message)) { return message; } MessageHeaderAccessor headers = mutableHeaderAccessor(message); TraceContextOrSamplingFlags extracted = this.extractor.extract(headers); Span span = this.threadLocalSpan.next(extracted); MessageHeaderPropagation.removeAnyTraceHeaders(headers, this.tracing.propagation().keys()); this.injector.inject(span.context(), headers); if (!span.isNoop()) { span.kind(Span.Kind.CONSUMER).name("receive").start(); span.remoteServiceName(REMOTE_SERVICE_NAME); addTags(message, span, channel); } if (log.isDebugEnabled()) { log.debug("Created a new span in post receive " + span); } headers.setImmutable(); return new GenericMessage<>(message.getPayload(), headers.getMessageHeaders()); }
@Override public <T extends Resultset> T postProcess(String sql, Statement interceptedStatement, T originalResultSet, int warningCount, boolean noIndexUsed, boolean noGoodIndexUsed, Exception statementException) { Span span = ThreadLocalSpan.CURRENT_TRACER.remove(); if (span == null || span.isNoop()) return null; if (statementException instanceof SQLException) { span.tag("error", Integer.toString(((SQLException) statementException).getErrorCode())); } span.finish(); return null; }