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

[SCB-327] Update metrics publish data module (Re-organized) #555

Merged
merged 7 commits into from Feb 26, 2018

Conversation

zhengyangyong
Copy link

@zhengyangyong zhengyangyong commented Feb 12, 2018

Follow this checklist to help us incorporate your contribution quickly and easily:

  • Make sure there is a JIRA issue filed for the change (usually before you start working on it). Trivial changes like typos do not require a JIRA issue. Your pull request should address just this issue, without pulling in other changes.
  • Each commit in the pull request should have a meaningful subject line and body.
  • Format the pull request title like [SCB-XXX] Fixes bug in ApproximateQuantiles, where you replace SCB-XXX with the appropriate JIRA issue.
  • Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
  • Run mvn clean install to make sure basic checks pass. A more thorough check will be performed on your pull request automatically.
  • If this contribution is large, please file an Apache Individual Contributor License Agreement.

Re-organize commits of PR : #550

Adjust metrics publish format to spring cloud netflix style
Before:
servicecomb.instance.system.cpu.load
servicecomb.instance.system.cpu.runningThreads
servicecomb.instance.system.heap.init
servicecomb.instance.system.heap.max
servicecomb.instance.system.heap.commit
servicecomb.instance.system.heap.used
servicecomb.instance.system.nonHeap.init
servicecomb.instance.system.nonHeap.max
servicecomb.instance.system.nonHeap.commit
servicecomb.instance.system.nonHeap.used
servicecomb.instance | operationName.producer.waitInQueue.count
servicecomb.instance | operationName.producer.lifeTimeInQueue.average
servicecomb.instance | operationName.producer.lifeTimeInQueue.max
servicecomb.instance | operationName.producer.lifeTimeInQueue.min
servicecomb.instance | operationName.producer.executionTime.average
servicecomb.instance | operationName.producer.executionTime.max
servicecomb.instance | operationName.producer.executionTime.min
servicecomb.instance | operationName.producer.producerLatency.average
servicecomb.instance | operationName.producer.producerLatency.max
servicecomb.instance | operationName.producer.producerLatency.min
servicecomb.instance | operationName.producer.producerCall.total
servicecomb.instance | operationName.producer.producerCall.tps
servicecomb.instance | operationName.consumer.consumerLatency.average
servicecomb.instance | operationName.consumer.consumerLatency.max
servicecomb.instance | operationName.consumer.consumerLatency.min
servicecomb.instance | operationName.consumer.consumerCall.total
servicecomb.instance | operationName.consumer.consumerCall.tps

Current:
jvm(statistic=gauge,name={name})
{name} include :
cpuLoad,cpuRunningThreads,heapInit,heapMax,heapCommit,
heapUsed,nonHeapInit,nonHeapMax,nonHeapCommit,nonHeapUsed

servicecomb.invocation(operation={operationName},role={role},stage={stage},statistic={statistic},status={status},unit={unit})

TagName TagValue
operation Operation Name
role consume,producer
stage queue,execution,total
statistic tps,count,max,waitInQueue,latency
status statusCode like 200, 404 ... etc
unit time unit like MILLISECONDS etc

@zhengyangyong zhengyangyong changed the title [SCB-327] Update metrics publish data module [SCB-327] Update metrics publish data module (Re-organized) Feb 12, 2018
@coveralls
Copy link

coveralls commented Feb 12, 2018

Coverage Status

Coverage increased (+0.08%) to 87.208% when pulling f7f3843 on zhengyangyong:SCB-327-2 into b0f8224 on apache:master.

this.invocationType, finishedTime - startProcessingTime,
finishedTime - startTime, statusCode, success));
.triggerEvent(new InvocationFinishedEvent(operationMeta.getMicroserviceQualifiedName(), this.invocationType,
startProcessingTime - startTime,
Copy link
Member

Choose a reason for hiding this comment

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

Can you explain the meaning of startTime, startProcessingTime?

Copy link
Author

Choose a reason for hiding this comment

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

On producer side , startTime is when invocation received,startProcessingTime is when invocation fetch from queue and start execute;

@@ -15,7 +15,7 @@
* limitations under the License.
*/

package org.apache.servicecomb.metrics.common;
package org.apache.servicecomb.foundation.metrics.publish;

public class DefaultHealthCheckExtraData {
Copy link
Member

Choose a reason for hiding this comment

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

What's the relationship between the DefaultHealthCheckExtraData and HealthCheckResult.extraData?
We don't need to use the String to store result, it's easy to use toString method to turn the instance of HealthCheckExtraData into a string.

Copy link
Author

Choose a reason for hiding this comment

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

We may no need provider this default health check because :
1.make some confusion
2.Service Center had same function

Copy link
Author

Choose a reason for hiding this comment

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

Had removed


import org.apache.servicecomb.foundation.metrics.MetricsConst;

public class MetricNode {
Copy link
Member

Choose a reason for hiding this comment

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

Can you show me the unit test of MetricNode?

Copy link
Author

Choose a reason for hiding this comment

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

Added

if (metrics.containsKey(id)) {
return new MetricNode(metrics.get(id), groupTagKeys);
}
return null;
Copy link
Member

Choose a reason for hiding this comment

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

I'm not a big fan of null, you can throw exception or using Option return the value.

Copy link
Author

Choose a reason for hiding this comment

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

Done

@@ -43,7 +43,6 @@ public void process(Event data) {
if (InvocationType.PRODUCER.equals(event.getInvocationType())) {
ProducerInvocationMonitor monitor = registryMonitor.getProducerInvocationMonitor(event.getOperationName());
monitor.getWaitInQueue().increment(-1);
monitor.getLifeTimeInQueue().update(event.getInQueueNanoTime());
Copy link
Member

Choose a reason for hiding this comment

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

Why did you remove this line?

Copy link
Author

Choose a reason for hiding this comment

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

queue stage latency had move from this event to finish event


public class ConsumerInvocationMonitor extends InvocationMonitor {
public class ConsumerInvocationMonitor {
Copy link
Member

Choose a reason for hiding this comment

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

What we should do if we want to change the ConsumerInvocationMonitor into ProducerInvocationMonitor?We don't need to write lots Classes here, please use abstraction to reduce the number of the class.

Copy link
Author

Choose a reason for hiding this comment

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

I had use DefaultMonitorRegistry as monitor container replace it;
In order to update monitor,I had add a group of basic wrapped monitor extends from AbstractMonitor;
Measure metrics will direct from DefaultMonitorRegistry.getInstance().getRegisteredMonitors() then getValue()

public RegistryMetric toRegistryMetric(int windowTimeIndex) {
Map<String, ConsumerInvocationMetric> consumerInvocationMetrics = new HashMap<>();
public Map<String, Double> measure(int windowTimeIndex, boolean calculateLatency) {
Map<String, Double> measurements = new HashMap<>(systemMonitor.measure());
Copy link
Member

Choose a reason for hiding this comment

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

If we want measure the invocation monitor, we don't need to know if it consumerInvocationMonitor or producerInvocationMonitor.

Copy link
Author

Choose a reason for hiding this comment

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

Done

@@ -114,8 +113,8 @@ public String getContext(String key) {
protected void scheduleInvocation() {
OperationMeta operationMeta = restOperationMeta.getOperationMeta();

InvocationStartedEvent startedEvent = new InvocationStartedEvent(operationMeta.getMicroserviceQualifiedName(),
InvocationType.PRODUCER, System.nanoTime());
ProducerInvocationStartedEvent startedEvent = new ProducerInvocationStartedEvent(
Copy link
Member

Choose a reason for hiding this comment

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

Why do you introduce the ProducerInvocationStartedEvent?

@@ -130,7 +129,7 @@ protected void scheduleInvocation() {
return;
}

runOnExecutor(startedEvent);
runOnExecutor(startedEvent.getStartedTime());
Copy link
Member

Choose a reason for hiding this comment

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

Using the Event could be easy for the user to extend.

}
}
}
} catch (ServiceCombException ignored) {
Copy link
Member

Choose a reason for hiding this comment

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

Why did you ignored the exception.

@@ -40,7 +42,7 @@ public MetricNode getMetricTree(String id, String... groupTagKeys) {
if (metrics.containsKey(id)) {
return new MetricNode(metrics.get(id), groupTagKeys);
}
return null;
throw new ServiceCombException("no such id");
Copy link
Member

Choose a reason for hiding this comment

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

Please keep the id in the exception for the developer to find out the failed reason.

* limitations under the License.
*/

package org.apache.servicecomb.metrics.core.event.servo;
Copy link
Member

Choose a reason for hiding this comment

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

Listener is application level code, it should not bind to the servo implementation.

public void triggerStartExecutionEvent() {
if (InvocationType.PRODUCER.equals(invocationType)) {
this.startExecutionTime = System.nanoTime();
EventUtils.triggerEvent(new InvocationStartExecutionEvent(operationMeta.getMicroserviceQualifiedName()));
Copy link
Member

Choose a reason for hiding this comment

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

This EventUtils is more like a singleton.

Copy link
Author

Choose a reason for hiding this comment

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

OK , delete EventUtils and make EventBus as a singleton

TestMgr.check(true, metrics.size() > 0);
TestMgr.check(true, metrics.get(
"servicecomb.invocation(operation=springmvc.codeFirst.saySomething,role=producer,stage=whole,statistic=count,status=200)")
"servicecomb.invocation(operation=springmvc.codeFirst.saySomething,role=PRODUCER,stage=total,statistic=count,status=200)")
Copy link
Member

Choose a reason for hiding this comment

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

the PRODUCER is upper case, but other tags are lower case.

Copy link
Author

Choose a reason for hiding this comment

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

Done,add toLowerCase()

}
//before receive any request,there are no MetricsConst.SERVICECOMB_INVOCATION,so getMetricTree will throw ServiceCombException
catch (ServiceCombException ignored) {
return;
Copy link
Member

Choose a reason for hiding this comment

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

We need to log the exception for trace the issue

Copy link
Author

Choose a reason for hiding this comment

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

add a containsId method and no need throw exception any more

zhengyangyong added 4 commits February 24, 2018 09:27
Signed-off-by: zhengyangyong <yangyong.zheng@huawei.com>
Signed-off-by: zhengyangyong <yangyong.zheng@huawei.com>
Signed-off-by: zhengyangyong <yangyong.zheng@huawei.com>
Signed-off-by: zhengyangyong <yangyong.zheng@huawei.com>

public class TestMetricNode {
@Test
public void test() {
Copy link
Member

Choose a reason for hiding this comment

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

The unit test method is not generic one, it should has some meaning which can help us to find out the key reason of failed test.

Copy link
Author

Choose a reason for hiding this comment

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

Ok ,add comments for explain check reason

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Author

Choose a reason for hiding this comment

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

OK

System.getProperties().setProperty("servo.pollers", time > 0 ? String.valueOf(time) : "5000");
}

public Counter getCounter(boolean isStepCounter, String name, String... tags) {
Copy link
Member

Choose a reason for hiding this comment

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

This method exposes the counter detail which is not right way.

Copy link
Author

Choose a reason for hiding this comment

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

separate into two method named getCounter and getStepCounter

@CrossOrigin
public HealthCheckResult healthWithName(@PathVariable(name = "name") String name) {
return manager.check(name);
public Map<String, HealthCheckResult> checkHealthDetail() {
Copy link
Member

Choose a reason for hiding this comment

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

Details

Copy link
Author

Choose a reason for hiding this comment

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

Fixed

Signed-off-by: zhengyangyong <yangyong.zheng@huawei.com>
Signed-off-by: zhengyangyong <yangyong.zheng@huawei.com>
@@ -66,6 +47,6 @@ public boolean checkHealth() {
@RequestMapping(path = "/detail", method = RequestMethod.GET)
Copy link
Member

Choose a reason for hiding this comment

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

The path name need to updated.

Copy link
Author

Choose a reason for hiding this comment

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

change to details

Copy link
Author

Choose a reason for hiding this comment

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

finnal path is /health/details

@@ -30,8 +30,7 @@

@Test
public void test() {
HealthCheckerManager manager = new HealthCheckerManager();
manager.register(new HealthChecker() {
HealthCheckerManager.getInstance().register(new HealthChecker() {
Copy link
Member

Choose a reason for hiding this comment

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

Here you just check one HealthChecker. The test should test at least zero,one and two HealthChecker.

Copy link
Author

Choose a reason for hiding this comment

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

Done

Copy link
Author

Choose a reason for hiding this comment

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

zero,one and two HealthChecker check logic had added in TestHealthCheckerManager

Signed-off-by: zhengyangyong <yangyong.zheng@huawei.com>
@RequestMapping(path = "/health")
public class HealthCheckerPublisher {
@RequestMapping(path = "/", method = RequestMethod.GET)
@CrossOrigin
Copy link
Contributor

Choose a reason for hiding this comment

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

This annotation may not work

@WillemJiang WillemJiang merged commit f55177e into apache:master Feb 26, 2018
@zhengyangyong zhengyangyong deleted the SCB-327-2 branch March 27, 2018 06:29
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.

None yet

4 participants