New Relic

classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

New Relic

corey
This post was updated on .
Greetings,

I'm the UI Architect at Chrome River Technologies a 100-200 employee company.  

We are happily using Thymeleaf to render our upcoming single page HTML5 application.

However, the vendor we are looking into, New Relic, does not support Thymeleaf for its browser product and claims it's due to the way the javascript is inlined/injected on the Thymeleaf side.

My question, is this true?  

And if it can work then how?

http://newrelic.com/real-user-monitoring
https://docs.newrelic.com/docs/java/real-user-monitoring-in-java#manual_instrumentation

Let us know how we can help in any way.

Cheers,

Corey
Reply | Threaded
Open this post in threaded view
|

Re: New Relic

Emanuel
Administrator
Glad to hear you're liking Thymeleaf :)

As for using it with New Relic, this is the first I've heard of it (I'll see if Daniel knows a bit more - it's more likely he's been in touch with them if they've contacted us at all).  Looking at that documentation page, I'm guessing the trouble with getting their timing code into Thymeleaf templates is the way they want their code inserted into pages; all their examples are using 'write arbitrary strings into an HTML page' methods as per the various view technologies they've shown, whereas with Thymeleaf you mostly need well-formed XML which also includes a lot of escaping rules around inline scripts.

So there's likely some kind of clash between the scripts they want to insert, and the scripts our XML output engine will allow.

This is just a guess based on that page - I've not used New Relic, nor do I know what their timing code looks like.  If I knew a little more about the resulting string they're trying to output, I might be able to offer some workarounds.
Reply | Threaded
Open this post in threaded view
|

Re: New Relic

Zemi
Administrator
Hello,

could you just try the following and see if it works? (if not, tell us the error or paste the generated source)

<head>
   ...
   <div th:remove="tag" th:utext="${T(com.newrelic.api.agent.NewRelic).getBrowserTimingHeader()}"></div>
</head>
<body>
   ...
   <div th:utext="${T(com.newrelic.api.agent.NewRelic).getBrowserTimingFooter()}"></div>
</body>

Regards,
   Zemi

Reply | Threaded
Open this post in threaded view
|

Re: New Relic

danielfernandez
Administrator
In reply to this post by corey
Hello corey,

I definitely know New Relic, but unfortunately I'm not a user myself and never had the opportunity to test it on a thymeleaf-based site.

JavaScript inlining is an optional feature in Thymeleaf, enabled exclusively on dev request, so I'm pretty sure that is not the problem. New Relic has classes for including an entire fragment of markup which handles the monitoring, so in theory Zemi's solution should work. Even if they include non-XMLized markup or scripts, th:utext should treat New Relic's code as a Macro and not try to parse it (as long as we are talking about Thymeleaf 2.1 - not 2.0), so at first sight this does look like your best option.

If that doesn't work, would you be so kind to send to us the specific piece of markup that those New Relic classes generate so that we can better diagnose? You can send them directly to us ( http://www.thymeleaf.org/team.html ) or open a new ticket on GitHub http://github.com/thymeleaf/thymeleaf/issues 

Thanks,
Daniel.
Reply | Threaded
Open this post in threaded view
|

Re: New Relic

corey
Thanks!

Gonna try it and report back.
Reply | Threaded
Open this post in threaded view
|

Re: New Relic

corey
It worked.  New Relic is getting the data.

Had to update versions of Thymeleaf/Spring from 2.0 to 2.1 in our gradle.build, etc. And had to change a couple classes for fragment usage.

Good to go.

Thanks everyone for the help!

We really appreciate it!
Reply | Threaded
Open this post in threaded view
|

Re: New Relic

Zemi
Administrator
Hello,

I'm glad to hear that.

If you contacted New Relic support before, please tell them that it works OK with Thymeleaf 2.1 following the same method as JSP inclusion.

Kind regards,
   Zemi

Reply | Threaded
Open this post in threaded view
|

Re: New Relic

corey
Will do.  Cheers.
Reply | Threaded
Open this post in threaded view
|

Re: New Relic

corey
Hi All,

New Relic's Engineering Director received the request to add Thymeleaf to the supported templates page.

One more question:

Is there a way to have Thymeleaf not throw an exception if com.newrelic.api.agent.NewRelic doesn't exist?

Reason is we can then test the New Relic analitics in dev environment and not worry about breaking other environments if they dont have the New Relic jars.

Cheers,

Corey

============ERROR OUTPUT============
org.springframework.expression.spel.SpelEvaluationException: EL1005E:(pos 0): Type cannot be found 'com.newrelic.api.agent.NewRelic'
 org.springframework.expression.spel.support.StandardTypeLocator.findType(StandardTypeLocator.java:79)
 org.springframework.expression.spel.ExpressionState.findType(ExpressionState.java:137)
 org.springframework.expression.spel.ast.TypeReference.getValueInternal(TypeReference.java:56)
 org.springframework.expression.spel.ast.CompoundExpression.getValueRef(CompoundExpression.java:48)
 org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:81)
 org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:93)
 org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:94)
 org.thymeleaf.spring3.expression.SpelVariableExpressionEvaluator.evaluate(SpelVariableExpressionEvaluator.java:139)
 org.thymeleaf.standard.expression.VariableExpression.executeVariable(VariableExpression.java:149)
 org.thymeleaf.standard.expression.SimpleExpression.executeSimple(SimpleExpression.java:59)
 org.thymeleaf.standard.expression.Expression.execute(Expression.java:103)
 org.thymeleaf.standard.expression.Expression.execute(Expression.java:133)
 org.thymeleaf.standard.processor.attr.AbstractStandardUnescapedTextChildModifierAttrProcessor.getText(AbstractStandardUnescapedTextChildModifierAttrProcessor.java:69)
 org.thymeleaf.processor.attr.AbstractUnescapedTextChildModifierAttrProcessor.getModifiedChildren(AbstractUnescapedTextChildModifierAttrProcessor.java:60)
 org.thymeleaf.processor.attr.AbstractChildrenModifierAttrProcessor.processAttribute(AbstractChildrenModifierAttrProcessor.java:58)
 org.thymeleaf.processor.attr.AbstractAttrProcessor.doProcess(AbstractAttrProcessor.java:87)
 org.thymeleaf.processor.AbstractProcessor.process(AbstractProcessor.java:212)
 org.thymeleaf.dom.Node.applyNextProcessor(Node.java:1016)
 org.thymeleaf.dom.Node.processNode(Node.java:971)
Reply | Threaded
Open this post in threaded view
|

Re: New Relic

corey
New Relic added the Thymeleaf info to their supported frameworks page.

Here is the link: https://docs.newrelic.com/docs/agents/java-agent/instrumentation/page-load-timing-java#manual_instrumentation

I would recommend them, try them out.

Cheers,

Corey
Reply | Threaded
Open this post in threaded view
|

Re: New Relic

corey
In reply to this post by Zemi
Why doesn't this work?

  <div th:if="${T(com.newrelic.api.agent.NewRelic) != null}" th:utext="${T(com.newrelic.api.agent.NewRelic).getBrowserTimingFooter()}"></div>

I would like it only to output if the object exists.  

Thanks.
Reply | Threaded
Open this post in threaded view
|

Re: New Relic

Emanuel
Administrator
Not sure, but I think the check you're doing ends-up trying to load the NewRelic class, which will fail if the NewRelic libraries/JAR isn't in the classpath.  To do dynamic lookups of that sort, you usually have to do a query using the classloader, and then handle the failure case with a catch...

try {
  Class.forName("com.newrelic.api.agent.NewRelic")
}
catch (ClassNotFoundException ex) {
  ...
}

...which you can't easily do with a plain expression.  You might need to create a util class for that.