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

[#9380] Supports Line number and location in Callstack #9450

Merged
merged 1 commit into from
Dec 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ public void insert(ApiMetaDataBo apiMetaData) {
buffer.putPrefixedString(api);
buffer.putInt(apiMetaData.getLineNumber());
buffer.putInt(apiMetaData.getMethodTypeEnum().getCode());
buffer.putPrefixedString(apiMetaData.getLocation());

final byte[] apiMetaDataBytes = buffer.getBuffer();
put.addColumn(description.getName(), description.QUALIFIER_SIGNATURE, apiMetaDataBytes);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public void handleRequest(ServerRequest<GeneratedMessageV3> serverRequest, Serve
}
}

private GeneratedMessageV3 handleApiMetaData(final PApiMetaData apiMetaData) {
GeneratedMessageV3 handleApiMetaData(final PApiMetaData apiMetaData) {
if (isDebug) {
logger.debug("Handle PApiMetaData={}", MessageFormatUtils.debugLog(apiMetaData));
}
Expand All @@ -76,8 +76,10 @@ private GeneratedMessageV3 handleApiMetaData(final PApiMetaData apiMetaData) {

final MethodTypeEnum type = MethodTypeEnum.defaultValueOf(apiMetaData.getType());

final ApiMetaDataBo apiMetaDataBo = new ApiMetaDataBo(agentId, agentStartTime, apiMetaData.getApiId(),
line, type, apiMetaData.getApiInfo());
final ApiMetaDataBo apiMetaDataBo = new ApiMetaDataBo.Builder(agentId, agentStartTime, apiMetaData.getApiId(),
line, type, apiMetaData.getApiInfo())
.setLocation(apiMetaData.getLocation())
.build();

this.apiMetaDataService.insert(apiMetaDataBo);
return PResult.newBuilder().setSuccess(true).build();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.navercorp.pinpoint.collector.dao.hbase;

import com.navercorp.pinpoint.common.hbase.HbaseColumnFamily;
import com.navercorp.pinpoint.common.hbase.HbaseOperations2;
import com.navercorp.pinpoint.common.hbase.TableNameProvider;
import com.navercorp.pinpoint.common.server.bo.ApiMetaDataBo;
import com.navercorp.pinpoint.common.server.bo.MethodTypeEnum;
import com.navercorp.pinpoint.common.server.hbase.DistributorConfiguration;
import com.sematext.hbase.wd.RowKeyDistributorByHashPrefix;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.client.Put;
import org.junit.jupiter.api.Test;

import java.util.List;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.assertj.core.api.Assertions.assertThat;

public class HbaseApiMetaDataDaoTest {

// from node: ApiMetaDataBo{agentId='express-node-sample-id', startTime=1669280767548, apiId=12, apiInfo='express.Function.proto.get(path, callback)', lineNumber=169, methodTypeEnum=DEFAULT, location='/Users/workspace/pinpoint/@pinpoint-naver-apm/pinpoint-agent-node/samples/express/src/routes/index.js'}
@Test
public void testInsert() {
HbaseOperations2 mockedHbaseTemplate = mock(HbaseOperations2.class);
TableNameProvider mockedProvider = mock(TableNameProvider.class);
DistributorConfiguration givenConfiguration = new DistributorConfiguration();
RowKeyDistributorByHashPrefix givenRowKeyDistributorByHashPrefix = givenConfiguration.getMetadataRowKeyDistributor();
HbaseApiMetaDataDao dut = new HbaseApiMetaDataDao(mockedHbaseTemplate, mockedProvider, givenRowKeyDistributorByHashPrefix);

doAnswer((invocation) -> {
Put actual = invocation.getArgument(1);
List<Cell> actualCells = actual.get(HbaseColumnFamily.API_METADATA_API.getName(), HbaseColumnFamily.API_METADATA_API.QUALIFIER_SIGNATURE);
assertThat(actualCells).hasSize(1);
return null;
}).when(mockedHbaseTemplate).put(any(), any(Put.class));

ApiMetaDataBo stub = new ApiMetaDataBo.Builder("express-node-sample-id", 1669280767548L, 12, 169, MethodTypeEnum.DEFAULT, "express.Function.proto.get(path, callback)")
.setLocation("/Users/workspace/pinpoint/@pinpoint-naver-apm/pinpoint-agent-node/samples/express/src/routes/index.js")
.build();
dut.insert(stub);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.navercorp.pinpoint.collector.handler.grpc;

import com.navercorp.pinpoint.collector.service.ApiMetaDataService;
import com.navercorp.pinpoint.common.server.bo.ApiMetaDataBo;
import com.navercorp.pinpoint.common.server.bo.MethodTypeEnum;
import com.navercorp.pinpoint.grpc.Header;
import com.navercorp.pinpoint.grpc.server.ServerContext;
import com.navercorp.pinpoint.grpc.trace.PApiMetaData;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import java.util.Collections;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.*;

public class GrpcApiMetaDataHandlerTest {
// ApiMetaDataBo{agentId='express-node-sample-id', startTime=1668495162817, apiId=11, apiInfo='express.Function.proto.get(path, callback)', lineNumber=177, methodTypeEnum=DEFAULT}
// from Node agent [11, 'express.Function.proto.get(path, callback)', 24, null, '/Users/workspace/pinpoint/@pinpoint-naver-apm/pinpoint-agent-node/samples/express/src/routes/index.js']
@Test
public void stubToApiMetaData() {
ApiMetaDataService mockedService = mock(ApiMetaDataService.class);
GrpcApiMetaDataHandler dut = new GrpcApiMetaDataHandler(mockedService);

PApiMetaData actualStub = PApiMetaData.newBuilder()
.setApiId(13)
.setApiInfo("express.Function.proto.get(path, callback)")
.setLine(177)
.setType(MethodTypeEnum.DEFAULT.getCode())
.setLocation("/Users/workspace/pinpoint/@pinpoint-naver-apm/pinpoint-agent-node/samples/express/src/routes/index.js")
.build();
try (MockedStatic<ServerContext> mocked = mockStatic(ServerContext.class)) {
mocked.when(ServerContext::getAgentInfo).thenReturn(new Header("name", "express-node-sample-id", "agentName", "applicationName", 0, 1668495162817L, 0, Collections.emptyList()));
doAnswer((invocation) -> {
ApiMetaDataBo actual = invocation.getArgument(0);
assertThat(actual).extracting("agentId", "startTime", "apiId", "apiInfo", "lineNumber", "methodTypeEnum", "location")
.contains("express-node-sample-id", 1668495162817L, 13, "express.Function.proto.get(path, callback)", 177, MethodTypeEnum.DEFAULT, "/Users/workspace/pinpoint/@pinpoint-naver-apm/pinpoint-agent-node/samples/express/src/routes/index.js");
return null;
}).when(mockedService).insert(any());

dut.handleApiMetaData(actualStub);

mocked.verify(ServerContext::getAgentInfo);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mock-maker-inline
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,26 @@ public String toString() {
", isAuthorized=" + isAuthorized +
'}';
}

public static class Builder {
private final int key;
private final Object value;
private boolean isAuthorized;

public Builder(int key, Object value) {
this.key = key;
this.value = value;
}

public Builder isAuthorized(boolean isAuthorized) {
this.isAuthorized = isAuthorized;
return this;
}

public AnnotationBo build() {
AnnotationBo result = new AnnotationBo(this.key, this.value);
result.setAuthorized(this.isAuthorized);
return result;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import com.navercorp.pinpoint.common.server.bo.serializer.metadata.MetaDataRowKey;
import com.navercorp.pinpoint.common.util.LineNumber;
import com.navercorp.pinpoint.common.util.StringUtils;

import java.util.Objects;

Expand All @@ -33,6 +34,7 @@ public class ApiMetaDataBo implements MetaDataRowKey {
private final String apiInfo;
private final int lineNumber;
private final MethodTypeEnum methodTypeEnum;
private String location;

public ApiMetaDataBo(String agentId, long startTime, int apiId, int lineNumber,
MethodTypeEnum methodTypeEnum, String apiInfo) {
Expand All @@ -42,6 +44,7 @@ public ApiMetaDataBo(String agentId, long startTime, int apiId, int lineNumber,
this.lineNumber = lineNumber;
this.apiInfo = apiInfo;
this.methodTypeEnum = Objects.requireNonNull(methodTypeEnum, "methodTypeEnum");
this.location = null;
}

@Override
Expand Down Expand Up @@ -71,6 +74,10 @@ public MethodTypeEnum getMethodTypeEnum() {
return methodTypeEnum;
}

public String getLocation() {
return location;
}

public String getDescription() {
if (LineNumber.isLineNumber(lineNumber)) {
return apiInfo + ":" + lineNumber;
Expand All @@ -82,14 +89,49 @@ public String getDescription() {

@Override
public String toString() {
final StringBuilder sb = new StringBuilder("ApiMetaDataBo{");
sb.append("agentId='").append(agentId).append('\'');
sb.append(", startTime=").append(startTime);
sb.append(", apiId=").append(apiId);
sb.append(", apiInfo='").append(apiInfo).append('\'');
sb.append(", lineNumber=").append(lineNumber);
sb.append(", methodTypeEnum=").append(methodTypeEnum);
sb.append('}');
return sb.toString();
return "ApiMetaDataBo{" +
"agentId='" + agentId + '\'' +
", startTime=" + startTime +
", apiId=" + apiId +
", apiInfo='" + apiInfo + '\'' +
", lineNumber=" + lineNumber +
", methodTypeEnum=" + methodTypeEnum +
", location='" + location + '\'' +
'}';
}

public static class Builder {
private final String agentId;
private final long startTime;
private final int apiId;
private final int lineNumber;
private final MethodTypeEnum methodTypeEnum;
private final String apiInfo;
private String location;

public Builder(String agentId, long startTime, int apiId, int lineNumber,
MethodTypeEnum methodTypeEnum, String apiInfo) {
this.agentId = agentId;
this.startTime = startTime;
this.apiId = apiId;
this.lineNumber = lineNumber;
this.methodTypeEnum = methodTypeEnum;
this.apiInfo = apiInfo;
this.location = null;
}

public Builder setLocation(String location) {
if (StringUtils.isEmpty(location)) {
return this;
}
this.location = location;
return this;
}

public ApiMetaDataBo build() {
ApiMetaDataBo result = new ApiMetaDataBo(this.agentId, this.startTime, this.apiId, this.lineNumber, this.methodTypeEnum, this.apiInfo);
result.location = this.location;
return result;
}
}
}
Loading