@Override public void setup(ProfilerPluginSetupContext context) { final OkHttpPluginConfig config = new OkHttpPluginConfig(context.getConfig()); logger.debug("[OkHttp] Initialized config={}", config); logger.debug("[OkHttp] Add Call class."); addCall(context, config); logger.debug("[OkHttp] Add Dispatcher class."); addDispatcher(context, config); logger.debug("[OkHttp] Add AsyncCall class."); addAsyncCall(context, config); addHttpEngine(context, config); addRequestBuilder(context, config); }
private void deleteUserIncludeTrace(final Trace trace) { if (isDebug) { logger.debug("Delete user include trace={}, sampled={}", trace, trace.canSampled()); } traceContext.removeTraceObject(); trace.close(); }
@Override public void after(Object target, Object result, Throwable throwable, Object[] args) { if (isDebug) { logger.afterInterceptor( target, methodDescriptor.getClassName(), methodDescriptor.getMethodName(), "", args, result, throwable); } final Trace trace = traceContext.currentTraceObject(); if (trace == null) { return; } InterceptorGroupInvocation invocation = interceptorGroup.getCurrentInvocation(); if (invocation != null && invocation.getAttachment() != null) { HttpCallContext callContext = (HttpCallContext) invocation.getAttachment(); if (methodDescriptor.getMethodName().equals("doSendRequest")) { callContext.setWriteEndTime(System.currentTimeMillis()); callContext.setWriteFail(throwable != null); } else { callContext.setReadEndTime(System.currentTimeMillis()); callContext.setReadFail(throwable != null); } logger.debug("Set call context {}", callContext); } }
@Override public void before(Object target, Object[] args) { if (isDebug) { logger.beforeInterceptor(target, args); } final Trace trace = traceContext.currentTraceObject(); if (trace == null) { return; } SpanEventRecorder recorder = trace.traceBlockBegin(); try { // set asynchronous trace final AsyncTraceId asyncTraceId = trace.getAsyncTraceId(); recorder.recordNextAsyncId(asyncTraceId.getAsyncId()); // set async id. InterceptorGroupInvocation transaction = interceptorGroup.getCurrentInvocation(); if (transaction != null) { transaction.setAttachment(asyncTraceId); if (isDebug) { logger.debug("Set asyncTraceId metadata {}", asyncTraceId); } } } catch (Throwable t) { logger.warn("Failed to before process. {}", t.getMessage(), t); } }
private boolean validate(Object target) { if (!(target instanceof UserRequestGetter)) { logger.debug("Invalid target object. Need field accessor({}).", FIELD_USER_REQUEST); return false; } if (!(target instanceof UserResponseGetter)) { logger.debug("Invalid target object. Need field accessor({}).", FIELD_USER_RESPONSE); return false; } if (!(target instanceof ConnectionGetter)) { logger.debug("Invalid target object. Need field accessor({}).", FIELD_CONNECTION); return false; } return true; }
@Override public void before(Object target, Object[] args) { if (isDebug) { logger.beforeInterceptor(target, args); } if (!validate(target, args)) { return; } final Trace trace = this.traceContext.currentRawTraceObject(); if (trace == null) { return; } try { ThriftRequestProperty parentTraceInfo = new ThriftRequestProperty(); final boolean shouldSample = trace.canSampled(); if (!shouldSample) { if (isDebug) { logger.debug("set Sampling flag=false"); } parentTraceInfo.setShouldSample(shouldSample); } else { SpanEventRecorder recorder = trace.traceBlockBegin(); Object asyncMethodCallObj = args[0]; // inject async trace info to AsyncMethodCall object final AsyncTraceId asyncTraceId = injectAsyncTraceId(asyncMethodCallObj, trace); recorder.recordServiceType(THRIFT_CLIENT_INTERNAL); // retrieve connection information String remoteAddress = getRemoteAddress(asyncMethodCallObj); final TraceId nextId = asyncTraceId.getNextTraceId(); // Inject nextSpanId as the actual sending of data will be handled asynchronously. final long nextSpanId = nextId.getSpanId(); parentTraceInfo.setSpanId(nextSpanId); parentTraceInfo.setTraceId(nextId.getTransactionId()); parentTraceInfo.setParentSpanId(nextId.getParentSpanId()); parentTraceInfo.setFlags(nextId.getFlags()); parentTraceInfo.setParentApplicationName(this.traceContext.getApplicationName()); parentTraceInfo.setParentApplicationType(this.traceContext.getServerTypeCode()); parentTraceInfo.setAcceptorHost(remoteAddress); this.asyncCallRemoteAddressAccessor.set(asyncMethodCallObj, remoteAddress); this.asyncNextSpanIdAccessor.set(asyncMethodCallObj, nextSpanId); } InterceptorGroupInvocation currentTransaction = this.group.getCurrentInvocation(); currentTransaction.setAttachment(parentTraceInfo); } catch (Throwable t) { logger.warn("before error. Caused:{}", t.getMessage(), t); } }
private AsyncTraceId injectAsyncTraceId(final Object asyncMethodCallObj, final Trace trace) { final AsyncTraceId asyncTraceId = trace.getAsyncTraceId(); SpanEventRecorder recorder = trace.currentSpanEventRecorder(); recorder.recordNextAsyncId(asyncTraceId.getAsyncId()); this.asyncTraceIdAccessor.set(asyncMethodCallObj, asyncTraceId); if (isDebug) { logger.debug("Set asyncTraceId metadata {}", asyncTraceId); } return asyncTraceId; }
private boolean validate(Object target) { if (!(target instanceof AsyncMarkerFlagFieldAccessor)) { if (isDebug) { logger.debug( "Invalid target object. Need field accessor({}).", AsyncMarkerFlagFieldAccessor.class.getName()); } return false; } return true; }
private boolean validate(final Object target, final Object[] args) { if (args.length != 1) { return false; } Object asyncMethodCallObj = args[0]; if (asyncMethodCallObj == null) { if (isDebug) { logger.debug("Metadata injection target object is null."); } return false; } if (!this.asyncTraceIdAccessor.isApplicable(asyncMethodCallObj)) { if (isDebug) { logger.debug("Invalid target object. Need metadata accessor({})", METADATA_ASYNC_TRACE_ID); } return false; } if (!this.asyncNextSpanIdAccessor.isApplicable(asyncMethodCallObj)) { if (isDebug) { logger.debug( "Invalid target object. Need metadata accessor({})", METADATA_ASYNC_NEXT_SPAN_ID); } return false; } if (!this.asyncCallRemoteAddressAccessor.isApplicable(asyncMethodCallObj)) { if (isDebug) { logger.debug( "Invalid target object. Need metadata accessor({})", METADATA_ASYNC_CALL_REMOTE_ADDRESS); } return false; } return true; }
private boolean validateInputProtocol(Object iprot) { if (iprot instanceof TProtocol) { if (!(iprot instanceof ServerMarkerFlagFieldAccessor)) { if (isDebug) { logger.debug( "Invalid target object. Need field accessor({}).", ServerMarkerFlagFieldAccessor.class.getName()); } return false; } if (!(iprot instanceof AsyncMarkerFlagFieldAccessor)) { if (isDebug) { logger.debug( "Invalid target object. Need field accessor({}).", AsyncMarkerFlagFieldAccessor.class.getName()); } return false; } return true; } return false; }
private String getRemoteAddress(Object asyncMethodCallObj) { if (!this.nonblockingSocketAddressAccessor.isApplicable(asyncMethodCallObj)) { if (isDebug) { logger.debug( "Invalid TAsyncMethodCall object. Need metadata accessor({})", METADATA_NONBLOCKING_SOCKET_ADDRESS); } return UNKNOWN_ADDRESS; } Object socketAddress = this.nonblockingSocketAddressAccessor.get(asyncMethodCallObj); if (socketAddress instanceof SocketAddress) { return ThriftUtils.getHostPort((SocketAddress) socketAddress); } return UNKNOWN_ADDRESS; }
@Override public void before(Object target, Object[] args) { InterceptorGroupInvocation transaction = group.getCurrentInvocation(); if (transaction.tryEnter(policy)) { if (before != null) { before.before(target, args); } } else { if (debugEnabled) { logger.debug( "tryBefore() returns false: interceptorGroupTransaction: {}, executionPoint: {}. Skip interceptor {}", new Object[] {transaction, policy, before == null ? null : before.getClass()}); } } }
@Override public void setup(ProfilerPluginSetupContext context) { final UserPluginConfig config = new UserPluginConfig(context.getConfig()); // add user include methods for (String fullQualifiedMethodName : config.getIncludeList()) { try { addUserIncludeClass(context, fullQualifiedMethodName); if (logger.isDebugEnabled()) { logger.debug("Add user include class interceptor {}", fullQualifiedMethodName); } } catch (Exception e) { logger.warn("Failed to add user include class(" + fullQualifiedMethodName + ").", e); } } }
@Override public void after(Object target, Object[] args, Object result, Throwable throwable) { InterceptorGroupInvocation transaction = group.getCurrentInvocation(); if (transaction.canLeave(policy)) { if (after != null) { after.after(target, args, result, throwable); } transaction.leave(policy); } else { if (debugEnabled) { logger.debug( "tryAfter() returns false: interceptorGroupTransaction: {}, executionPoint: {}. Skip interceptor {}", new Object[] {transaction, policy, after == null ? null : after.getClass()}); } } }
private Trace createUserIncludeTrace() { final Trace trace = traceContext.newTraceObject(); if (isDebug) { logger.debug("New user include trace {} and sampled {}", trace, trace.canSampled()); } // add user scope. TraceScope oldScope = trace.addScope(SCOPE_NAME); if (oldScope != null) { // delete corrupted trace. logger.warn("Duplicated user include trace scope={}.", oldScope.getName()); deleteUserIncludeTrace(trace); return null; } if (trace.canSampled()) { // record root span. final SpanRecorder recorder = trace.getSpanRecorder(); recorder.recordServiceType(ServiceType.STAND_ALONE); recorder.recordApi(USER_INCLUDE_METHOD_DESCRIPTOR); } return trace; }