use of com.newrelic.agent.tracers.ClassMethodSignature in project newrelic-java-agent by newrelic.
the class InstrumentationImpl method createSqlTracer.
// I don't like having this method be a copy/paste of the createTracer method above but I do not
// want to introduce a performance hit for the default tracer path just to support sql tracers.
@Override
public ExitTracer createSqlTracer(Object invocationTarget, int signatureId, String metricName, int flags) {
try {
if (ServiceFactory.getServiceManager().isStopped()) {
return null;
}
if (ServiceFactory.getServiceManager().getCircuitBreakerService().isTripped()) {
return null;
}
TransactionActivity txa = TransactionActivity.get();
if (txa != null) {
if (txa.getRootTracer() != null && txa.getRootTracer().isAsync() && txa.getTransaction() == null) {
txa = null;
}
}
if (!Agent.canFastPath()) {
// legacy async instrumentation is in use
return oldCreateSqlTracer(txa, invocationTarget, signatureId, metricName, flags);
}
if (txa == null) {
AgentBridge.TokenAndRefCount tokenAndRefCount = AgentBridge.activeToken.get();
if (tokenAndRefCount != null && tokenAndRefCount.token != null) {
// Fast path for scala instrumentation (and potentially others in the future)
Transaction tx = Transaction.getTransaction(false);
if (tx == null) {
if (tokenAndRefCount.token.getTransaction() instanceof Transaction) {
tx = (Transaction) tokenAndRefCount.token.getTransaction();
} else {
return null;
}
}
txa = TransactionActivity.create(tx, Integer.MAX_VALUE);
flags = flags | TracerFlags.ASYNC;
ClassMethodSignature sig = ClassMethodSignatures.get().get(signatureId);
MetricNameFormat mnf = MetricNameFormats.getFormatter(invocationTarget, sig, metricName, flags);
Tracer tracer;
if (TracerFlags.isRoot(flags)) {
// Dispatcher || Async
tracer = new OtherRootSqlTracer(txa, sig, invocationTarget, mnf, flags);
} else if (overSegmentLimit(txa)) {
logger.log(Level.FINEST, "Transaction has exceeded tracer segment limit. Returning ultralight sql tracer.");
return UltraLightTracer.createClampedSegment(txa, sig);
} else {
tracer = new DefaultSqlTracer(txa, sig, invocationTarget, mnf, flags);
}
txa.tracerStarted(tracer);
Tracer initiatingTracer = (Tracer) tokenAndRefCount.tracedMethod.getAndSet(tracer);
tx.startFastAsyncWork(txa, initiatingTracer);
return tracer;
} else if (TracerFlags.isDispatcher(flags)) {
// Traditional first-time creation of a new transaction
com.newrelic.agent.Transaction.getTransaction(true);
txa = TransactionActivity.get();
} else if (TracerFlags.isAsync(flags)) {
// Create a transaction activity without a transaction
txa = TransactionActivity.create(null, Integer.MAX_VALUE);
}
if (txa == null) {
// or we are running on an Agent thread.
return null;
}
return startSqlTracer(txa, invocationTarget, signatureId, metricName, flags);
}
// traditional tracer creation code, we check it before creating any objects.
if (!TracerFlags.isRoot(flags) && !txa.isStarted()) {
return null;
}
Tracer result = null;
if (txa.checkTracerStart()) {
try {
ClassMethodSignature sig = ClassMethodSignatures.get().get(signatureId);
// Metric naming. When we come here from an @Trace that doesn't specify a metric name, a
// very common case, getFormatter() will return one of a couple of reusable instances of
// MetricNameFormat, so we avoid proliferating small objects. But when we come here from
// XML instrumentation, getFormatter() is forced to create a new MNF instance every time.
// This proved to be messy to optimize, so unfortunately has been left as-is. 2015-05.
MetricNameFormat mnf = MetricNameFormats.getFormatter(invocationTarget, sig, metricName, flags);
if (TracerFlags.isDispatcher(flags) || (TracerFlags.isAsync(flags) && txa.getTransaction() != null && !txa.isStarted())) {
result = new OtherRootSqlTracer(txa, sig, invocationTarget, mnf);
} else if (overSegmentLimit(txa)) {
logger.log(Level.FINEST, "Transaction has exceeded tracer segment limit. Returning ultralight sql tracer.");
result = UltraLightTracer.createClampedSegment(txa, sig);
} else {
result = new DefaultSqlTracer(txa, sig, invocationTarget, mnf, flags);
}
} finally {
txa.unlockTracerStart();
}
txa.tracerStarted(result);
}
return result;
} catch (Throwable t) {
logger.log(Level.FINEST, t, "createTracer({0}, {1}, {2}, {3})", invocationTarget, signatureId, metricName, flags);
return null;
}
}
use of com.newrelic.agent.tracers.ClassMethodSignature in project newrelic-java-agent by newrelic.
the class PointCutClassTransformer method evaluate.
public InvocationHandler evaluate(Class clazz, TracerService tracerService, Object className, Object methodName, Object methodDesc, boolean ignoreApdex, Object[] args) {
ClassMethodSignature classMethodSignature = new ClassMethodSignature(((String) className).replace('/', '.'), (String) methodName, (String) methodDesc);
for (PointCut pc : getPointcuts()) {
// code. Bummer for you!
if (pc.getClassMatcher().isMatch(clazz) && pc.getMethodMatcher().matches(MethodMatcher.UNSPECIFIED_ACCESS, classMethodSignature.getMethodName(), classMethodSignature.getMethodDesc(), MethodMatcher.UNSPECIFIED_ANNOTATIONS)) {
PointCutInvocationHandler invocationHandler = pc.getPointCutInvocationHandler();
return InvocationPoint.getInvocationPoint(invocationHandler, tracerService, classMethodSignature, ignoreApdex);
}
}
if (ignoreApdex) {
return IgnoreApdexInvocationHandler.INVOCATION_HANDLER;
}
Agent.LOG.log(Level.FINE, "No invocation handler was registered for {0}", classMethodSignature);
return NoOpInvocationHandler.INVOCATION_HANDLER;
}
use of com.newrelic.agent.tracers.ClassMethodSignature in project newrelic-java-agent by newrelic.
the class HeadersUtilTest method createDTHeadersSetsSpanIdEvenIfTxNotSampled.
@Test
public void createDTHeadersSetsSpanIdEvenIfTxNotSampled() {
ConfigService mockConfigService = new MockConfigService(AgentConfigImpl.createAgentConfig(ImmutableMap.of(AgentConfigImpl.APP_NAME, "Unit Test", AgentConfigImpl.DISTRIBUTED_TRACING, Collections.singletonMap(DistributedTracingConfig.ENABLED, true), AgentConfigImpl.SPAN_EVENTS, ImmutableMap.of(SpanEventsConfig.ENABLED, true, SpanEventsConfig.COLLECT_SPAN_EVENTS, true))));
MockServiceManager mockServiceManager = new MockServiceManager(mockConfigService);
mockServiceManager.setDistributedTraceService(new MockDistributedTraceService());
ServiceFactory.setServiceManager(mockServiceManager);
Transaction tx = Transaction.getTransaction();
tx.setPriorityIfNotNull(0F);
tx.startTransactionIfBeginning(new MockDispatcherTracer(tx));
Tracer mockTracer = new DefaultTracer(tx, new ClassMethodSignature(getClass().getName(), "tracerMethod", "()V"), this);
OutboundHeadersMap map = new OutboundHeadersMap(HeaderType.HTTP);
assertTrue("DT headers should have been set", HeadersUtil.createAndSetDistributedTraceHeaders(tx, mockTracer, map));
assertFalse(tx.sampled());
assertTrue("map should contain newrelic header", map.containsKey("newrelic"));
String decodedHeader = new String(Base64.decodeBase64(map.get("newrelic")), StandardCharsets.UTF_8);
JsonObject jsonObject = new Gson().fromJson(decodedHeader, JsonObject.class);
assertFalse("d.sa should be false because tx is not sampled", jsonObject.getAsJsonObject("d").get("sa").getAsBoolean());
assertEquals("d.pr should be zero", 0f, jsonObject.getAsJsonObject("d").get("pr").getAsFloat(), 0.0001);
assertNotNull("d.id should not be null", jsonObject.getAsJsonObject("d").get("id"));
assertEquals("d.id should be the span id.", mockTracer.getGuid(), jsonObject.getAsJsonObject("d").get("id").getAsString());
String traceParent = map.get("traceparent");
assertEquals("traceparent parentId field should match span id.", mockTracer.getGuid(), traceParent.split("-")[2]);
String traceState = map.get("tracestate");
assertEquals("tracestate spanId field should match span id.", mockTracer.getGuid(), traceState.split("-")[4]);
assertEquals("tracestate txId field should match tx id.", tx.getGuid(), traceState.split("-")[5]);
}
use of com.newrelic.agent.tracers.ClassMethodSignature in project newrelic-java-agent by newrelic.
the class AgentImplTest method testAsyncTracerShouldNotStartTxn.
@Test
public void testAsyncTracerShouldNotStartTxn() {
TransactionActivity txa = TransactionActivity.create(null, 0);
ClassMethodSignature sig = new ClassMethodSignature("class", "method", "methodDesc");
OtherRootTracer tracer = new OtherRootTracer(txa, sig, null, null, TracerFlags.ASYNC, System.nanoTime());
txa.tracerStarted(tracer);
Transaction txn = agentImpl.getTransaction();
Assert.assertTrue(txn instanceof NoOpTransaction);
Assert.assertFalse(txn instanceof com.newrelic.agent.Transaction);
}
use of com.newrelic.agent.tracers.ClassMethodSignature in project newrelic-java-agent by newrelic.
the class CrossProcessStateCatApiTest method testCatApiResponseExternalMetrics.
@Test
public void testCatApiResponseExternalMetrics() throws UnsupportedEncodingException {
Transaction transactionOne = Mockito.mock(Transaction.class);
Mockito.when(transactionOne.getAgentConfig()).thenReturn(ServiceFactory.getConfigService().getDefaultAgentConfig());
TransactionActivity txaOne = Mockito.mock(TransactionActivity.class);
CrossProcessConfig cpsOneConfig = getCrossProcessConfig("CrossProcessId", "");
setUpTransaction(transactionOne, txaOne, new Object(), new MockDispatcher(), cpsOneConfig, "guid");
MetricNameFormat nameFormat = new ClassMethodMetricNameFormat(new ClassMethodSignature("className", "methodName", "()V"), null, "");
CatTestCustomTracer requestTracer = new CatTestCustomTracer(transactionOne, new ClassMethodSignature("className", "methodName", "()V"), new Object(), nameFormat, TracerFlags.DISPATCHER);
when(txaOne.getLastTracer()).thenReturn(requestTracer);
CrossProcessTransactionStateImpl cpsOne = CrossProcessTransactionStateImpl.create(transactionOne);
Transaction transactionTwo = Mockito.mock(Transaction.class);
Mockito.when(transactionTwo.getAgentConfig()).thenReturn(ServiceFactory.getConfigService().getDefaultAgentConfig());
TransactionActivity txaTwo = Mockito.mock(TransactionActivity.class);
CrossProcessConfig cpsTwoConfig = getCrossProcessConfig("CrossProcessId", "");
setUpTransaction(transactionTwo, txaTwo, new Object(), new MockDispatcher(), cpsTwoConfig, "guid");
InboundHeaderState ihs = Mockito.mock(InboundHeaderState.class);
when(ihs.isTrustedCatRequest()).thenReturn(true);
when(transactionTwo.getInboundHeaderState()).thenReturn(ihs);
CrossProcessTransactionStateImpl cpsTwo = CrossProcessTransactionStateImpl.create(transactionTwo);
String requestMetadata = cpsOne.getRequestMetadata();
// Transaction one generates requestMetadata. This metadata is embedded in payload and sent to transaction two.
// Transaction two gets requestMetadata from payload and provides it to agent.
cpsTwo.processRequestMetadata(requestMetadata);
String responseMetadata = cpsTwo.getResponseMetadata();
// Transaction two generates responseMetadata and sends it to transaction one.
// Transaction one receives response.
cpsOne.processResponseMetadata(responseMetadata, null);
Set<String> rollupMetricNames = requestTracer.getRollupMetricNames();
assertTrue(rollupMetricNames.contains("External/all"));
assertTrue(rollupMetricNames.contains("External/allOther"));
assertTrue(rollupMetricNames.contains("External/Unknown/all"));
}
Aggregations