Skip to content

Commit

Permalink
[pinpoint-apm#4044] Add apdexScore in getServerMapDataV2
Browse files Browse the repository at this point in the history
  • Loading branch information
intr3p1d committed Feb 4, 2022
1 parent 204f334 commit 6d21b05
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.navercorp.pinpoint.web.applicationmap.histogram;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonValue;

import java.util.Objects;

public class ApdexScore {
private final double apdexScore;

public ApdexScore(Histogram histogram) {
Objects.requireNonNull(histogram, "histogram");
this.apdexScore = floor(calculateApdexScore(histogram));
}

private double calculateApdexScore(Histogram histogram) {
final long satisfiedCount = histogram.getFastCount();
final long toleratingCount = histogram.getNormalCount();
final long totalCount = histogram.getTotalCount();

if ((totalCount - (satisfiedCount + (toleratingCount >> 1))) < (totalCount >> 10) && (totalCount - (satisfiedCount + (toleratingCount >> 1))) > 0) {
return 0.999;
}

final double score = ((satisfiedCount + 0.5 * toleratingCount) / totalCount);

return score;
}

@JsonProperty
public double getApdexScore() {
return this.apdexScore;
}

private double floor(double value) {
return (Math.floor((value) * 1000) / 1000);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import com.navercorp.pinpoint.common.trace.ServiceType;
import com.navercorp.pinpoint.web.applicationmap.appender.metric.DBMetric;
import com.navercorp.pinpoint.web.applicationmap.histogram.ApdexScore;
import com.navercorp.pinpoint.web.applicationmap.histogram.TimeHistogramFormat;
import com.navercorp.pinpoint.web.applicationmap.histogram.NodeHistogram;
import com.navercorp.pinpoint.web.view.NodeSerializer;
Expand Down Expand Up @@ -53,7 +54,7 @@ public class Node {
private ServerInstanceList serverInstanceList = new ServerInstanceList();

private NodeHistogram nodeHistogram;

private boolean authorized = true;
private TimeHistogramFormat timeHistogramFormat = TimeHistogramFormat.V1;

Expand All @@ -62,7 +63,7 @@ public class Node {
public Node(Application application) {
this(NodeType.DETAILED, application);
}

public Node(NodeType nodeType, Application application) {
this.nodeType = Objects.requireNonNull(nodeType, "nodeType");
this.application = Objects.requireNonNull(application, "application");
Expand Down Expand Up @@ -119,7 +120,11 @@ public NodeHistogram getNodeHistogram() {
public void setNodeHistogram(NodeHistogram nodeHistogram) {
this.nodeHistogram = nodeHistogram;
}


public ApdexScore getApdexScore() {
return new ApdexScore(nodeHistogram.getApplicationHistogram());
}

public boolean isAuthorized() {
return authorized;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@

package com.navercorp.pinpoint.web.view;

import com.fasterxml.jackson.databind.util.NameTransformer;
import com.navercorp.pinpoint.bootstrap.plugin.request.NewTraceHeader;
import com.navercorp.pinpoint.common.trace.ServiceType;
import com.navercorp.pinpoint.web.applicationmap.appender.metric.DBMetric;
import com.navercorp.pinpoint.web.applicationmap.histogram.ApdexScore;
import com.navercorp.pinpoint.web.applicationmap.nodes.Node;
import com.navercorp.pinpoint.web.applicationmap.nodes.NodeType;
import com.navercorp.pinpoint.web.applicationmap.nodes.ServerInstanceList;
Expand All @@ -32,13 +35,17 @@
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
* @author emeroad
* @author minwoo.jung
* @author HyunGil Jeong
*/
public class NodeSerializer extends JsonSerializer<Node> {

private static SerializerProvider provider = null;

@Override
public void serialize(Node node, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
jgen.writeStartObject();
Expand All @@ -65,13 +72,22 @@ public void serialize(Node node, JsonGenerator jgen, SerializerProvider provider
jgen.writeBooleanField("isQueue", serviceType.isQueue());
jgen.writeBooleanField("isAuthorized", node.isAuthorized());

this.provider = provider;

writeHistogram(jgen, node);
writeServerInstanceList(jgen, node);
writeMetricDB(jgen, node);

jgen.writeEndObject();
}

private void writeUnwrappedObject(Object object, JsonGenerator jgen) throws IOException {
Objects.requireNonNull(provider, "SerializerProvider");
JsonSerializer<Object> beanSerializer = provider.findValueSerializer(object.getClass());
JsonSerializer<Object> unwrapping = beanSerializer.unwrappingSerializer(NameTransformer.NOP);
unwrapping.serialize(object, jgen, provider);
}

private void writeMetricDB(JsonGenerator jgen, Node node) throws IOException {
if (node.getDBMetricList().isEmpty()) {
writeEmptyArray(jgen, "DBMetric");
Expand Down Expand Up @@ -165,8 +181,11 @@ private void writeHistogram(JsonGenerator jgen, Node node) throws IOException {
jgen.writeObjectField(ResponseTimeStatics.RESPONSE_STATISTICS, responseTimeStatics);
if (applicationHistogram == null) {
writeEmptyObject(jgen, "histogram");
writeEmptyObject(jgen, "apdexScore");
} else {
jgen.writeObjectField("histogram", applicationHistogram);
//jgen.writeObjectField("apdexScore", node.getApdexScore());
writeUnwrappedObject(node.getApdexScore(), jgen);
}
if (NodeType.DETAILED == node.getNodeType()) {
Map<String, Histogram> agentHistogramMap = nodeHistogram.getAgentHistogramMap();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package com.navercorp.pinpoint.web.applicationmap.histogram;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.util.NameTransformer;
import com.navercorp.pinpoint.common.trace.ServiceType;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.Assert;
import org.junit.Test;

import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Objects;

public class ApdexScoreTest {

private static final ObjectMapper MAPPER = new ObjectMapper();
private final Logger logger = LogManager.getLogger(this.getClass());

@Test
public void getApdexScore() {
Histogram histogram = new Histogram(ServiceType.STAND_ALONE);

histogram.addCallCount((short) 1000, 100);
Assert.assertEquals(1.00, new ApdexScore(histogram).getApdexScore(), 0.001);

histogram.addCallCount((short) 100000, 100);
Assert.assertEquals(0.500, new ApdexScore(histogram).getApdexScore(), 0.001);
}

@Test
public void getApdexScore_floatingPoint() {
Histogram histogram = new Histogram(ServiceType.STAND_ALONE);
histogram.addCallCount((short) 1000, Long.MAX_VALUE - 1);
histogram.addCallCount((short) 100000, 1);

Assert.assertEquals(0.999, new ApdexScore(histogram).getApdexScore(), 0.001);
}

@Test
public void getApdexScore_format() throws IOException {
Writer jsonWriter = new StringWriter();
JsonGenerator jgen = new JsonFactory().createGenerator(jsonWriter);
ObjectMapper objectMapper = new ObjectMapper();
jgen.setCodec(objectMapper);
SerializerProvider provider = objectMapper.getSerializerProvider();

Histogram histogram = new Histogram(ServiceType.STAND_ALONE);
histogram.addCallCount((short) 1000, 100);

// jgen.writeStartObject();
jgen.writeObject(new ApdexScore(histogram));
// jgen.writeObjectField("apdexScore", new ApdexScore(histogram));
// jgen.writeEndObject();
jgen.close();

Assert.assertEquals("{\"apdexScore\":1.0}", jsonWriter.toString());
}

}

0 comments on commit 6d21b05

Please sign in to comment.