Skip to content

Make StandardExports work with modules and/or IBM JVMs - #281

Merged
brian-brazil merged 7 commits into
prometheus:masterfrom
alin-amana:master
Jul 28, 2017
Merged

Make StandardExports work with modules and/or IBM JVMs#281
brian-brazil merged 7 commits into
prometheus:masterfrom
alin-amana:master

Conversation

@alin-amana

Copy link
Copy Markdown
Contributor

com.sun.management.UnixOperatingSystemMXBean is not available in IBM JVMs and not easily accessible in some environments, such as WildFly. Use reflection instead to collect file descriptor metrics.

…e com.sun.management.UnixOperatingSystemMXBean is not available. Use reflection instead to collect file descriptor metrics.
@brian-brazil

Copy link
Copy Markdown
Contributor

Please see #278, which I'd like to resolve first.

@alin-amana

Copy link
Copy Markdown
Contributor Author

Interesting. But I believe the instanceof operator in your code will result in a ClassNotFoundException in that case too. I wonder if there exists a programmatic approach to figuring out which interface actually declares that method and grab the method from there (whether it's com.sun, com.ibm or something else).

@brian-brazil

Copy link
Copy Markdown
Contributor

I'd be happy to have something that works with both, but if the choice is between Oracle and IBM JVMs then given this is the hotspot module we'll go with Oracle.

@alin-amana

Copy link
Copy Markdown
Contributor Author

Fair enough. All I'm saying is that the instanceof operator will throw an exception if running on an IBM JVM, so the else case is useless.

Anyway, I'll be looking into programmatically looking up the implementing interface and getting the method from there.

…lass then on all the interfaces it implements until either success or all attempts have failed
@alin-amana

Copy link
Copy Markdown
Contributor Author

Gave it another try. This should cover both process_cpu_seconds_total and the file descriptor metrics.

It tries to call the method directly on the concrete class, then recursively on all implemented interfaces until it either succeeds or has failed all options.

@alin-amana

Copy link
Copy Markdown
Contributor Author

Any opinion?

The code is somewhat generic, to be able to handle null return values. Since the getters we're calling all return long, it would be possible to drop the ReturnValue class and instead keep trying until we get a non-null value.

@brian-brazil

Copy link
Copy Markdown
Contributor

As I said, I wish for #278 to be resolved first to unbreak Java 9 before adding new things.

@alin-amana

Copy link
Copy Markdown
Contributor Author

Apologies for not making it clear enough, this change should also cover #278. It will traverse the tree of implemented interfaces and attempt to call the method on each of them until it either succeeds or runs out of interfaces.

Although I haven't tested it, this means it should work without issues under Java 9.

@alin-amana

Copy link
Copy Markdown
Contributor Author

Friendly ping.

mfs.add(new GaugeMetricFamily(
"process_max_fds", "Maximum number of open file descriptors.", maxFdCount));
} catch (Exception e) {
LOGGER.log(Level.FINE, "Could not access file descriptor metrics", e);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is going to be spammy on non-unix systems.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just replicated the behavior above for the CPU time metric. That, however is much less likely to log anything, particularly with the 2 known implementations.

Removed, replaced with a comment.

unixBean.getMaxFileDescriptorCount()));
// There exist at least 2 UnixOperatingSystemMXBean interfaces, in com.sun.management and
// com.ibm.lang.management. There are also environments (such as Wildfly) where access to these
// interfaces is restricted. Hence use reflection and recursively go through implemented

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think restricted is quite the right word, my understanding is that the way Wildfly does things breaks standard JMX usage.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. Looks like you need to define modules and dependencies between them, which is quite a bit of unnecessary overhead if you don't explicitly reference com.sun.something.

In the end, I dropped the reference to WildFly altogether, as it's too specific.

*/
static ReturnValue callMethod(Method method, Object obj) {
try {
method.setAccessible(true);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure this works on Java 9?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The call itself should work just fine. All the Java 9 AccessibleObject.setAccessible() documentation says in addition to the previous versions is that there is some logic preventing this working across module boundaries unless there is a direct module dependency and the method is public (essentially). Seeing how the two UnixOperatingSystemMXBeans are interfaces, the methods are definitely public. So in the worst case one would need to define a module dependency to make this work. Which, if necessary at all, would need to be defined for any kind of implementation to work.

To summarize, if any code will work in Java 9 then this should work too.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we still need this trick given the interface stuff below?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great point. Removed, as we don't need it for our current uses.

One observation though: if we ever want to invoke a method that's private/protected (because it's only declared in the concrete implementation, not an interface) it will be necessary to add it back.

/**
* Wraps a return value, similar to a Future but simplified.
*/
static class ReturnValue {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems unnecessary, we always return a Long.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

e);
}

for (Class<?> clazz : method.getDeclaringClass().getInterfaces()) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the "recursively visit all implemented interfaces" part.

A Method object refers to a specific class. So the first invocation of callMethod() will happen with method === SomeConcreteClass.getProcessCpuTime(), which will fail under Java 9. We then need to iterate over all interfaces implemented by SomeConcreteClass and eventually invoke callMethod() with method === UnixOperatingSystemMXBean.getProcessCpuTime(), which will then succeed.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you mention this in a comment?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@alin-amana

Copy link
Copy Markdown
Contributor Author

Addressed all your comments. Code is now more concise, there is no additional logging and the comments have been made more relevant.

Please take another look.

@alin-amana alin-amana changed the title Make StandardExports work in restricted environments or IBM JVMs Make StandardExports work with modules and/or IBM JVMs Jul 27, 2017
try {
interfaceMethod = clazz.getMethod(method.getName(), method.getParameterTypes());
Method interfaceMethod = clazz.getMethod(method.getName(), method.getParameterTypes());
Long result = callLongGetter(interfaceMethod, obj);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is recursive, do we need to worry about an infinite recursion?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. getInterfaces() will return exactly the list of interfaces implemented/extended, in the order they are listed in the class/interface definition. An interface cannot extend itself, so it follows this is a finite sized tree.

Also, we're not really going down all branches. If the method is not declared by one of the implemented interfaces, we don't go down that branch because then that method cannot be declared by any of that interface's ancestors either. I believe there is even a constraint about a method only being defined by a single interface (i.e. you can't implement 2 interfaces with a run() method each), meaning this recursion would only ever result in a simple path traversal.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently there is no constraint on implementing 2 interfaces defining the exact same method. The constraint is on 2 methods with the same parameters but different return types (obvious why that wouldn't work).

Still, the tree is finite and visiting more than a simple path is an edge case.

@brian-brazil brian-brazil left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That generally looks fine.

Have you tested this on both Java 9 and IBM's JVM?

* might happen with method === SomeConcreteClass.publicLongGetter() and will fail if
* SomeConcreteClass is not public. We then recurse over all interfaces implemented by
* SomeConcreteClass (or extended by those interfaces and so on) until we eventually invoke
* callMethod() with method === SomePublicInterface.publicLongGetter(), which will then succeed.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't JavaScript, just == will do

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

static Long callLongGetter(Method method, Object obj) {
try {
return (Long) method.invoke(obj);
} catch (Exception e) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would IllegalAccessException be sufficient here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced with IllegalAccessException and am now throwing InvocationTargetException when the invoked method throws, thus aborting the recursion if that happens.

@alin-amana

Copy link
Copy Markdown
Contributor Author

Have you tested this on both Java 9 and IBM's JVM?

Nope, not at all. But since I'm not using anything specific to a JVM implementation or other, that should mean the IBM JVM must work.

As for Java 9, the code no longer callis setAccessible(), which is what was failing. So if it is failing, it is failing for different reasons.

@brian-brazil

Copy link
Copy Markdown
Contributor

The change looks fine, but please test it on both those platforms as we're touching on implementation-specific stuff that has been problematic before.

@alin-amana

Copy link
Copy Markdown
Contributor Author

(Apologies for earlier post, wrong thread.)

OK, ran against both JVMs and the Simpleclient/Simpleclient Hotspot tests all passed.

However, FYI, I did get failures in the Spring Metrics client when running against Java 9:

$ JAVA_HOME=~/Work/jre/jre-9 ./mvnw test
[...]
Running io.prometheus.client.spring.web.MethodTimerTest
Tests run: 6, Failures: 0, Errors: 6, Skipped: 0, Time elapsed: 0.277 sec <<< FAILURE! - in io.prometheus.client.spring.web.MethodTimerTest
testOverloadedMethodName(io.prometheus.client.spring.web.MethodTimerTest)  Time elapsed: 0.186 sec  <<< ERROR!
java.lang.IllegalArgumentException: error at ::0 can't find referenced pointcut timeable
	at org.aspectj.weaver.tools.PointcutParser.parsePointcutExpression(PointcutParser.java:301)
	at org.springframework.aop.aspectj.AspectJExpressionPointcut.buildPointcutExpression(AspectJExpressionPointcut.java:217)
	at org.springframework.aop.aspectj.AspectJExpressionPointcut.checkReadyToMatch(AspectJExpressionPointcut.java:190)
	at org.springframework.aop.aspectj.AspectJExpressionPointcut.getClassFilter(AspectJExpressionPointcut.java:169)
	at org.springframework.aop.support.ComposablePointcut.<init>(ComposablePointcut.java:66)
	at org.springframework.aop.support.Pointcuts.union(Pointcuts.java:52)
	at org.springframework.aop.aspectj.annotation.InstantiationModelAwarePointcutAdvisorImpl.<init>(InstantiationModelAwarePointcutAdvisorImpl.java:92)
	at org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory.getAdvisor(ReflectiveAspectJAdvisorFactory.java:209)
	at org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory.getAdvisors(ReflectiveAspectJAdvisorFactory.java:136)
	at org.springframework.aop.aspectj.annotation.AspectJProxyFactory.addAdvisorsFromAspectInstanceFactory(AspectJProxyFactory.java:121)
	at org.springframework.aop.aspectj.annotation.AspectJProxyFactory.addAspect(AspectJProxyFactory.java:111)
	at io.prometheus.client.spring.web.MethodTimerTest.getProxy(MethodTimerTest.java:48)
	at io.prometheus.client.spring.web.MethodTimerTest.testOverloadedMethodName(MethodTimerTest.java:191)

testThrowWorks(io.prometheus.client.spring.web.MethodTimerTest)  Time elapsed: 0.005 sec  <<< ERROR!
java.lang.IllegalArgumentException: error at ::0 can't find referenced pointcut timeable
	at org.aspectj.weaver.tools.PointcutParser.parsePointcutExpression(PointcutParser.java:301)
	at org.springframework.aop.aspectj.AspectJExpressionPointcut.buildPointcutExpression(AspectJExpressionPointcut.java:217)
	at org.springframework.aop.aspectj.AspectJExpressionPointcut.checkReadyToMatch(AspectJExpressionPointcut.java:190)
	at org.springframework.aop.aspectj.AspectJExpressionPointcut.getClassFilter(AspectJExpressionPointcut.java:169)
	at org.springframework.aop.support.ComposablePointcut.<init>(ComposablePointcut.java:66)
	at org.springframework.aop.support.Pointcuts.union(Pointcuts.java:52)
	at org.springframework.aop.aspectj.annotation.InstantiationModelAwarePointcutAdvisorImpl.<init>(InstantiationModelAwarePointcutAdvisorImpl.java:92)
	at org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory.getAdvisor(ReflectiveAspectJAdvisorFactory.java:209)
	at org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory.getAdvisors(ReflectiveAspectJAdvisorFactory.java:136)
	at org.springframework.aop.aspectj.annotation.AspectJProxyFactory.addAdvisorsFromAspectInstanceFactory(AspectJProxyFactory.java:121)
	at org.springframework.aop.aspectj.annotation.AspectJProxyFactory.addAspect(AspectJProxyFactory.java:111)
	at io.prometheus.client.spring.web.MethodTimerTest.getProxy(MethodTimerTest.java:48)
	at io.prometheus.client.spring.web.MethodTimerTest.testThrowWorks(MethodTimerTest.java:121)

testSecondMethod(io.prometheus.client.spring.web.MethodTimerTest)  Time elapsed: 0.003 sec  <<< ERROR!
java.lang.IllegalArgumentException: error at ::0 can't find referenced pointcut timeable
	at org.aspectj.weaver.tools.PointcutParser.parsePointcutExpression(PointcutParser.java:301)
	at org.springframework.aop.aspectj.AspectJExpressionPointcut.buildPointcutExpression(AspectJExpressionPointcut.java:217)
	at org.springframework.aop.aspectj.AspectJExpressionPointcut.checkReadyToMatch(AspectJExpressionPointcut.java:190)
	at org.springframework.aop.aspectj.AspectJExpressionPointcut.getClassFilter(AspectJExpressionPointcut.java:169)
	at org.springframework.aop.support.ComposablePointcut.<init>(ComposablePointcut.java:66)
	at org.springframework.aop.support.Pointcuts.union(Pointcuts.java:52)
	at org.springframework.aop.aspectj.annotation.InstantiationModelAwarePointcutAdvisorImpl.<init>(InstantiationModelAwarePointcutAdvisorImpl.java:92)
	at org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory.getAdvisor(ReflectiveAspectJAdvisorFactory.java:209)
	at org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory.getAdvisors(ReflectiveAspectJAdvisorFactory.java:136)
	at org.springframework.aop.aspectj.annotation.AspectJProxyFactory.addAdvisorsFromAspectInstanceFactory(AspectJProxyFactory.java:121)
	at org.springframework.aop.aspectj.annotation.AspectJProxyFactory.addAspect(AspectJProxyFactory.java:111)
	at io.prometheus.client.spring.web.MethodTimerTest.getProxy(MethodTimerTest.java:48)
	at io.prometheus.client.spring.web.MethodTimerTest.testSecondMethod(MethodTimerTest.java:151)

timeMethod(io.prometheus.client.spring.web.MethodTimerTest)  Time elapsed: 0.003 sec  <<< ERROR!
java.lang.IllegalArgumentException: error at ::0 can't find referenced pointcut timeable
	at org.aspectj.weaver.tools.PointcutParser.parsePointcutExpression(PointcutParser.java:301)
	at org.springframework.aop.aspectj.AspectJExpressionPointcut.buildPointcutExpression(AspectJExpressionPointcut.java:217)
	at org.springframework.aop.aspectj.AspectJExpressionPointcut.checkReadyToMatch(AspectJExpressionPointcut.java:190)
	at org.springframework.aop.aspectj.AspectJExpressionPointcut.getClassFilter(AspectJExpressionPointcut.java:169)
	at org.springframework.aop.support.ComposablePointcut.<init>(ComposablePointcut.java:66)
	at org.springframework.aop.support.Pointcuts.union(Pointcuts.java:52)
	at org.springframework.aop.aspectj.annotation.InstantiationModelAwarePointcutAdvisorImpl.<init>(InstantiationModelAwarePointcutAdvisorImpl.java:92)
	at org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory.getAdvisor(ReflectiveAspectJAdvisorFactory.java:209)
	at org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory.getAdvisors(ReflectiveAspectJAdvisorFactory.java:136)
	at org.springframework.aop.aspectj.annotation.AspectJProxyFactory.addAdvisorsFromAspectInstanceFactory(AspectJProxyFactory.java:121)
	at org.springframework.aop.aspectj.annotation.AspectJProxyFactory.addAspect(AspectJProxyFactory.java:111)
	at io.prometheus.client.spring.web.MethodTimerTest.timeMethod(MethodTimerTest.java:36)

testValueParam(io.prometheus.client.spring.web.MethodTimerTest)  Time elapsed: 0.002 sec  <<< ERROR!
java.lang.IllegalArgumentException: error at ::0 can't find referenced pointcut timeable
	at org.aspectj.weaver.tools.PointcutParser.parsePointcutExpression(PointcutParser.java:301)
	at org.springframework.aop.aspectj.AspectJExpressionPointcut.buildPointcutExpression(AspectJExpressionPointcut.java:217)
	at org.springframework.aop.aspectj.AspectJExpressionPointcut.checkReadyToMatch(AspectJExpressionPointcut.java:190)
	at org.springframework.aop.aspectj.AspectJExpressionPointcut.getClassFilter(AspectJExpressionPointcut.java:169)
	at org.springframework.aop.support.ComposablePointcut.<init>(ComposablePointcut.java:66)
	at org.springframework.aop.support.Pointcuts.union(Pointcuts.java:52)
	at org.springframework.aop.aspectj.annotation.InstantiationModelAwarePointcutAdvisorImpl.<init>(InstantiationModelAwarePointcutAdvisorImpl.java:92)
	at org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory.getAdvisor(ReflectiveAspectJAdvisorFactory.java:209)
	at org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory.getAdvisors(ReflectiveAspectJAdvisorFactory.java:136)
	at org.springframework.aop.aspectj.annotation.AspectJProxyFactory.addAdvisorsFromAspectInstanceFactory(AspectJProxyFactory.java:121)
	at org.springframework.aop.aspectj.annotation.AspectJProxyFactory.addAspect(AspectJProxyFactory.java:111)
	at io.prometheus.client.spring.web.MethodTimerTest.getProxy(MethodTimerTest.java:48)
	at io.prometheus.client.spring.web.MethodTimerTest.testValueParam(MethodTimerTest.java:55)

testHelpParam(io.prometheus.client.spring.web.MethodTimerTest)  Time elapsed: 0.004 sec  <<< ERROR!
java.lang.IllegalArgumentException: error at ::0 can't find referenced pointcut timeable
	at org.aspectj.weaver.tools.PointcutParser.parsePointcutExpression(PointcutParser.java:301)
	at org.springframework.aop.aspectj.AspectJExpressionPointcut.buildPointcutExpression(AspectJExpressionPointcut.java:217)
	at org.springframework.aop.aspectj.AspectJExpressionPointcut.checkReadyToMatch(AspectJExpressionPointcut.java:190)
	at org.springframework.aop.aspectj.AspectJExpressionPointcut.getClassFilter(AspectJExpressionPointcut.java:169)
	at org.springframework.aop.support.ComposablePointcut.<init>(ComposablePointcut.java:66)
	at org.springframework.aop.support.Pointcuts.union(Pointcuts.java:52)
	at org.springframework.aop.aspectj.annotation.InstantiationModelAwarePointcutAdvisorImpl.<init>(InstantiationModelAwarePointcutAdvisorImpl.java:92)
	at org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory.getAdvisor(ReflectiveAspectJAdvisorFactory.java:209)
	at org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory.getAdvisors(ReflectiveAspectJAdvisorFactory.java:136)
	at org.springframework.aop.aspectj.annotation.AspectJProxyFactory.addAdvisorsFromAspectInstanceFactory(AspectJProxyFactory.java:121)
	at org.springframework.aop.aspectj.annotation.AspectJProxyFactory.addAspect(AspectJProxyFactory.java:111)
	at io.prometheus.client.spring.web.MethodTimerTest.getProxy(MethodTimerTest.java:48)
	at io.prometheus.client.spring.web.MethodTimerTest.testHelpParam(MethodTimerTest.java:85)


Results :

Tests in error: 
  MethodTimerTest.testOverloadedMethodName:191->getProxy:48 » IllegalArgument er...
  MethodTimerTest.testThrowWorks:121->getProxy:48 » IllegalArgument error at ::0...
  MethodTimerTest.testSecondMethod:151->getProxy:48 » IllegalArgument error at :...
  MethodTimerTest.timeMethod:36 » IllegalArgument error at ::0 can't find refere...
  MethodTimerTest.testValueParam:55->getProxy:48 » IllegalArgument error at ::0 ...
  MethodTimerTest.testHelpParam:85->getProxy:48 » IllegalArgument error at ::0 c...

Tests run: 6, Failures: 0, Errors: 6, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] 
[INFO] Prometheus Java Suite .............................. SUCCESS [  0.181 s]
[INFO] Prometheus Java Simpleclient ....................... SUCCESS [  4.100 s]
[INFO] Prometheus Java Simpleclient Common ................ SUCCESS [  0.377 s]
[INFO] Prometheus Java Simpleclient Caffeine .............. SUCCESS [  0.652 s]
[INFO] Prometheus Java Simpleclient Dropwizard ............ SUCCESS [  0.356 s]
[INFO] Prometheus Java Simpleclient Graphite Bridge ....... SUCCESS [  0.333 s]
[INFO] Prometheus Java Simpleclient Hibernate ............. SUCCESS [  0.985 s]
[INFO] Prometheus Java Simpleclient guava ................. SUCCESS [  0.499 s]
[INFO] Prometheus Java Simpleclient Servlet ............... SUCCESS [  0.901 s]
[INFO] Prometheus Java Simpleclient Hotspot ............... SUCCESS [  0.601 s]
[INFO] Prometheus Java Simpleclient Httpserver ............ SUCCESS [  0.437 s]
[INFO] Prometheus Java Simpleclient log4j ................. SUCCESS [  0.358 s]
[INFO] Prometheus Java Simpleclient log4j2 ................ SUCCESS [  0.453 s]
[INFO] Prometheus Java Simpleclient logback ............... SUCCESS [  0.386 s]
[INFO] Prometheus Java Simpleclient Pushgateway ........... SUCCESS [ 14.909 s]
[INFO] Prometheus Java Simpleclient Spring Metrics ........ FAILURE [  0.630 s]
[INFO] Prometheus Java Simpleclient Spring Boot Metric .... SKIPPED
[INFO] Prometheus Java Simpleclient Jetty ................. SKIPPED
[INFO] Prometheus Java Simpleclient Jetty JDK 8 ........... SKIPPED
[INFO] Prometheus Java Simpleclient Vert.x ................ SKIPPED
[INFO] Prometheus Java Client Benchmarks .................. SKIPPED
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 26.729 s
[INFO] Finished at: 2017-07-27T17:42:49+02:00
[INFO] Final Memory: 18M/60M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.15:test (default-test) on project simpleclient_spring_web: There are test failures.
[ERROR] 
[ERROR] Please refer to /home/alin/Work/prometheus_client_java/simpleclient_spring_web/target/surefire-reports for the individual test results.
[ERROR] -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
[ERROR] 
[ERROR] After correcting the problems, you can resume the build with the command
[ERROR]   mvn <goals> -rf :simpleclient_spring_web

@brian-brazil

Copy link
Copy Markdown
Contributor

Spring tends to do complicated stuff, so I wouldn't worry about that in this context.

Considering we're swallowing errors can you run something simple like https://github.com/RobustPerception/java_examples/tree/master/java_simple and verify the process stats are there?

@alin-amana

Copy link
Copy Markdown
Contributor Author

I have been running the code against my own WildFly deployed project and the stats are all there (CPU and file descriptor metrics in particular).

@brian-brazil

Copy link
Copy Markdown
Contributor

That gives confidence, but WildFly messes with JMX. Can you try it with something simple like the above?

@alin-amana

Copy link
Copy Markdown
Contributor Author

Tested. Works. On all 8, 9 and IBM.

@brian-brazil
brian-brazil merged commit ce76a49 into prometheus:master Jul 28, 2017
@brian-brazil

Copy link
Copy Markdown
Contributor

Great, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants