use of com.newrelic.agent.tracers.metricname.MetricNameFormat in project newrelic-java-agent by newrelic.
the class InstrumentationImpl method createTracer.
/**
* Optimized createTracer call for weaved and XML instrumentation. We do not know if either a TransactionActivity or
* a Transaction is present on the thread. If present, we do not know if the Transaction has been started.
*/
@Override
public ExitTracer createTracer(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 oldCreateTracer(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 OtherRootTracer(txa, sig, invocationTarget, mnf, flags);
} else {
tracer = new DefaultTracer(txa, sig, invocationTarget, mnf, flags);
}
txa.tracerStarted(tracer);
Tracer initiatingTracer = (Tracer) AgentBridge.activeToken.get().tracedMethod.getAndSet(tracer);
tx.startFastAsyncWork(txa, initiatingTracer);
return noticeTracer(signatureId, flags, 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 noticeTracer(signatureId, flags, null);
}
return noticeTracer(signatureId, flags, startTracer(txa, invocationTarget, signatureId, metricName, flags));
}
// traditional tracer creation code, we check it before creating any objects.
if (!TracerFlags.isRoot(flags) && !txa.isStarted()) {
return noticeTracer(signatureId, flags, 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 OtherRootTracer(txa, sig, invocationTarget, mnf);
} else {
result = new DefaultTracer(txa, sig, invocationTarget, mnf, flags);
}
} finally {
txa.unlockTracerStart();
}
txa.tracerStarted(result);
}
return noticeTracer(signatureId, flags, 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.metricname.MetricNameFormat in project newrelic-java-agent by newrelic.
the class InstrumentationImpl method startSqlTracer.
private Tracer startSqlTracer(TransactionActivity txa, Object target, int signatureId, String metricName, int flags) {
ClassMethodSignature sig = ClassMethodSignatures.get().get(signatureId);
MetricNameFormat mnf = MetricNameFormats.getFormatter(target, sig, metricName, flags);
Tracer tracer;
if (TracerFlags.isRoot(flags)) {
// Dispatcher || Async
tracer = new OtherRootSqlTracer(txa, sig, target, mnf, flags, System.nanoTime());
} else {
tracer = new DefaultSqlTracer(txa, sig, target, mnf, flags);
}
txa.tracerStarted(tracer);
return tracer;
}
use of com.newrelic.agent.tracers.metricname.MetricNameFormat 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.metricname.MetricNameFormat in project newrelic-java-agent by newrelic.
the class DefaultTracer method setMetricNameFormatInfo.
@Override
public void setMetricNameFormatInfo(String metricName, String transactionSegmentName, String transactionSegmentUri) {
MetricNameFormat format = new SimpleMetricNameFormat(metricName, transactionSegmentName, transactionSegmentUri);
setMetricNameFormat(format);
}
use of com.newrelic.agent.tracers.metricname.MetricNameFormat in project newrelic-java-agent by newrelic.
the class AbstractExternalComponentTracer method finish.
@Override
public void finish(Throwable throwable) {
if (throwable instanceof UnknownHostException) {
host = UNKNOWN_HOST;
MetricNameFormat metricNameFormat = getMetricNameFormat();
if (metricNameFormat instanceof ExternalComponentNameFormat) {
setMetricNameFormat(((ExternalComponentNameFormat) metricNameFormat).cloneWithNewHost(UNKNOWN_HOST));
}
}
super.finish(throwable);
}
Aggregations