Wildfly 8 transactions/traces not catched

Kibana version: 6.8

Elasticsearch version: 6.8

APM Server version: 6.8

APM Agent language and version: 1.6.1

Fresh install or upgraded from other version? fresh

Hi, i have setup java apm agent in our wildfly 8 ejb application.

I see transactions that i.e. will be created inside wildfly itself like startup or scheduled jobs:

But any transaction started via i.e. http-remoting ( methods called from webapps running in seperate tomcats ) or child transaction are not catched and gathered.

Is there a configuration missing ? Is remote invocation not supported ? Should we debug agent ?

If not support, can we start a transaction/ trace manually ?

Hi and thanks for your question :slight_smile:

These links should get you started: https://www.elastic.co/guide/en/apm/agent/java/current/supported-technologies-details.html
https://www.elastic.co/guide/en/apm/agent/java/current/public-api.html

What do you exactly mean with http-remoting? Do you have a link to the GitHub repo handy? Is it this one? http://jbossremoting.jboss.org/remoting-3.html https://github.com/jboss-remoting/jboss-remoting

Let me know if you have any further questions!

Thanks,
Felix

Thx. Felix for answering:

http-remoting is one of the ejb remote invocation methods. You found the newest version. Wildfly 8 is still working with that
https://github.com/wildfly/jboss-ejb-client/

Look here at method 2
https://blog.akquinet.de/2014/09/26/jboss-eap-wildfly-three-ways-to-invoke-remote-ejbs/

EJB invocation hits normally remote interface of ejb and all of its interceptors.

And of course wildfly 8 looks supported, but maybe only servlet 3.x api ? Wondering why i see pure ejb traces ( see above ) in apm ...

Yes, supporting WildFly 8 means in this case that the agent is continuously tested to instrument the Servlet API 3.x on WildFly. I agree that this should be a bit more clear from the supported technologies page.

Ok. Many thx.

If we start transaction manually via open api, will agent trace all sql queries and subcalls ?

yes!

@Frintrop maybe you already realized that, but worth the mention- you can add much more interesting support for you cross-tomcat ejb communication than just creating transactions on the server side. You can manually add capability to do distributed tracing, so that the transactions recorded separately on the client side and on the server side will be correlated into traces, representing actual application flows.
In order to do that, we have the injectTraceHeaders (client side) and startTransactionWithRemoteParent (server side) APIs.
Maybe you can use EJBClientInterceptor#handleInvocation together with EJBClientInvocationContext#getContextData in order to achieve that.

Many thx. But did somebody try to inject header in ejb client ? It looks not very easy.

Von unterwegs gesendet.

I never tried it this way :blush:
From a quick look, those APIs seems fit for the task, but I can't really tell without taking a deeper look and try. Generally speaking, if you have the ability to intercept calls on both sides and access to set/read metadata, you should be able to pull this off.
If you DO try it out, we will love to hear about it.
Good luck.

I will try it and give feedback.

I created an ejb interceptor which works for us now. An idea to better check for noop transactions ? instanceof is not working as NoopTransaction.class or NoopTransaction.INSTANCE will not exposed in eclipse.

	@AroundInvoke
	public Object profile(InvocationContext invocationContext) throws Exception
       {
		Object object = null;

		final long startTime = System.nanoTime();

		String target = preInvoke(invocationContext);

		Transaction transaction = ElasticApm.currentTransaction();

		if ("NoopTransaction".equals(transaction.getClass().getSimpleName())) // todo
																				// better
																				// check
																				// for
																				// noop;
		{
			transaction = ElasticApm.startTransaction();
			transaction.setName(target);
			transaction.setType(Transaction.TYPE_REQUEST);

			System.out.println("New apm transaction " + transaction.getId() + " with class " + transaction.getClass().getSimpleName());

			try (final Scope scope = transaction.activate())
			{
				object = invoke(invocationContext, target, startTime);
			}
			catch (Exception e)
			{
				transaction.captureException(e);
				throw e;
			}
			finally
			{
				transaction.end();
			}
		}
		else
		{
			System.out.println("Found apm transaction " + transaction.getId() + " with class " + transaction.getClass().getSimpleName());
			Span parentSpan = ElasticApm.currentSpan();

			Span span = parentSpan.startSpan("request", "subcall", null);
			span.setName(target);
			try (final Scope scope = span.activate())
			{
				object = invoke(invocationContext, target, startTime);
			}
			catch (Exception e)
			{
				span.captureException(e);
				throw e;
			}
			finally
			{
				span.end();
			}
		}

		return object;

	}

You can check whether transaction.getId or transaction.getTraceId returns a valid ID (meaning valid transaction) or an empty string (noop transactions).

BTW, since a Transaction is a kind of a Span, you can replace

        else
		{
			System.out.println("Found apm transaction " + transaction.getId() + " with class " + transaction.getClass().getSimpleName());
			Span parentSpan = ElasticApm.currentSpan();

			Span span = parentSpan.startSpan("request", "subcall", null);
			...

with

        else
		{
			System.out.println("Found apm transaction " + transaction.getId() + " with class " + transaction.getClass().getSimpleName());
			Span span = transaction.startSpan("request", "subcall", null);
			...

This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.