Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add basic metrics support #360

Merged
merged 11 commits into from
Dec 19, 2018
Merged

Conversation

felixbarny
Copy link
Member

No description provided.

@felixbarny felixbarny changed the title WIP: metrics Add basic metrics support Dec 13, 2018
@felixbarny
Copy link
Member Author

felixbarny commented Dec 13, 2018

Adds the following system metrics:

system.cpu.total.norm.pct
system.process.cpu.total.norm.pct
system.memory.total
system.memory.actual.free
system.process.memory.size

And some heap metrics:

jvm.memory.heap.used
jvm.memory.heap.committed
jvm.memory.heap.max
jvm.memory.non_heap.used
jvm.memory.non_heap.committed
jvm.memory.non_heap.max

@felixbarny
Copy link
Member Author

@kuisathaverat Do you know why pipeline Jenkins does not like this PR? I probably confused it with my wild force pushes 😬

@kuisathaverat
Copy link
Contributor

it looks like JENKINS-44598, probably is related to the force push, I never see it before.

Copy link
Contributor

@eyalkoren eyalkoren left a comment

Choose a reason for hiding this comment

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

Great!
Most importantly - used getNonHeapMemoryUsage twice.
Other than that, I am really missing some documentation about central classes role and data structures.
And some cosmetic suggestions.

}

public void serialize(long epochMicros, StringBuilder replaceBuilder, JsonWriter jw) {
jw.writeByte(JsonWriter.OBJECT_START);
Copy link
Contributor

Choose a reason for hiding this comment

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

Same - serialization better be colocated

import java.lang.management.MemoryUsage;
import java.util.Collections;

public class JvmMemoryMetrics implements LifecycleListener {
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure why this is a LifecycleListener if the MBeans are just registered on startup. Not very important but if there is no reason- consider changing.

Copy link
Member Author

Choose a reason for hiding this comment

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

We already have the concept of LifecycleListeners which provide a callback on application start and on shutdown. I did not create an SPI for metrics as I could just use the already existing one. If you think it would make things more clear, I can add a special SPI just for metrics.

* This implementation is based on io.micrometer.core.instrument.binder.system.ProcessorMetrics,
* under Apache License 2.0
*/
public class SystemMetrics implements LifecycleListener {
Copy link
Contributor

Choose a reason for hiding this comment

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

Same- consider not making a listener. I assume it is enough that the metrics collected thread is shut down when required.

@felixbarny
Copy link
Member Author

I have also added GC metrics:

jvm.gc.count [tags: name]
jvm.gc.time [tags: name]
jvm.gc.alloc

@felixbarny
Copy link
Member Author

I have manually checked that system.cpu.total.norm.pct returns similar values to the ones emitted by our Go agent.

Copy link
Contributor

@eyalkoren eyalkoren left a comment

Choose a reason for hiding this comment

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

Some minor comments-

  • Suggesting small serialization-dependency erasure
  • Can we remove PayloadSender?
  • It just occurred to me that the entire metrics harvesting is going to be done on the disruptor publishing thread. Do you think this may be problematic and be better done offline, so not to hold down other event publishing?

}

@Override
public String toString() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Moving the serialization code to the serialize package is great, so I think having this JsonWriter residual here is a shame. Sorry for nagging, I have future refactors in mind...
What do you say adding a static asString(MetricsRegistry) to the serializer?

Copy link
Member Author

Choose a reason for hiding this comment

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

do you want to create a separate module for serialization?

Copy link
Contributor

Choose a reason for hiding this comment

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

Not at the moment :)
I just think it makes sense to avoid dependency on serialization lib here.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm all about keeping package dependencies uni-directional!

registry.addUnlessNegative("jvm.gc.count", tags, new DoubleSupplier() {
@Override
public double get() {
return garbageCollectorMXBean.getCollectionCount();
Copy link
Contributor

@eyalkoren eyalkoren Dec 19, 2018

Choose a reason for hiding this comment

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

What would be more interesting - collection count or collection count since last measurement? For graphs, an ever increasing one is not as informative as a mostly-stagnant one where spikes are easier to spot. This is something that can be calculated in the server or Kibana as well, but since it is not a global metric, I don't think it would be.

Copy link
Member Author

Choose a reason for hiding this comment

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

It's quite common to report counters and use a derivative aggregation to graph the deltas.

registry.addUnlessNegative("jvm.gc.time", tags, new DoubleSupplier() {
@Override
public double get() {
return garbageCollectorMXBean.getCollectionTime();
Copy link
Contributor

Choose a reason for hiding this comment

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

same

@felixbarny
Copy link
Member Author

It just occurred to me that the entire metrics harvesting is going to be done on the disruptor publishing thread. Do you think this may be problematic and be better done offline, so not to hold down other event publishing?

I'd think that getting and serializing the metrics is not something that would hold down the reporter thread. I think the bottleneck there is the network anyway.

Do you think this may be problematic and be better done offline

Do you have an idea how to do this without serializing the metrics to a buffer which becomes garbage afterwards and without establishing another connection to the APM Server?

@eyalkoren
Copy link
Contributor

I am not talking about serialization, I am just talking about metrics collection from all MBeans. Anyway, as long as we don't have evidence that this is a problem - it is not.

@felixbarny felixbarny merged commit 8d31b40 into elastic:master Dec 19, 2018
@felixbarny felixbarny deleted the application-metrics branch December 19, 2018 14:09
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.

4 participants