Skip to content

Commit 84ea314

Browse files
committed
[pinpoint-apm#12195] Add new agent list using uid
1 parent 837d2f7 commit 84ea314

File tree

16 files changed

+606
-4
lines changed

16 files changed

+606
-4
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.navercorp.pinpoint.collector.dao;
2+
3+
import com.navercorp.pinpoint.common.server.uid.ApplicationUid;
4+
import com.navercorp.pinpoint.common.server.uid.ServiceUid;
5+
6+
public interface AgentListDao {
7+
void insert(ServiceUid serviceUid, ApplicationUid applicationUid, String agentId, long agentStartTime, String agentName);
8+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.navercorp.pinpoint.collector.dao.hbase;
2+
3+
import com.navercorp.pinpoint.collector.dao.AgentListDao;
4+
import com.navercorp.pinpoint.common.hbase.HbaseColumnFamily;
5+
import com.navercorp.pinpoint.common.hbase.HbaseOperations;
6+
import com.navercorp.pinpoint.common.hbase.HbaseTables;
7+
import com.navercorp.pinpoint.common.hbase.TableNameProvider;
8+
import com.navercorp.pinpoint.common.server.uid.ApplicationUid;
9+
import com.navercorp.pinpoint.common.server.uid.ServiceUid;
10+
import com.navercorp.pinpoint.common.server.util.AgentListRowKeyUtils;
11+
import org.apache.hadoop.hbase.TableName;
12+
import org.apache.hadoop.hbase.client.Put;
13+
import org.apache.hadoop.hbase.util.Bytes;
14+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
15+
import org.springframework.stereotype.Repository;
16+
17+
import java.util.Objects;
18+
19+
@Repository
20+
@ConditionalOnProperty(name = "pinpoint.collector.application.uid.enable", havingValue = "true")
21+
public class HbaseAgentListDao implements AgentListDao {
22+
23+
private static final HbaseColumnFamily DESCRIPTOR = HbaseTables.AGENT_LIST;
24+
25+
private final HbaseOperations hbaseOperations;
26+
private final TableNameProvider tableNameProvider;
27+
28+
public HbaseAgentListDao(HbaseOperations hbaseOperations, TableNameProvider tableNameProvider) {
29+
this.hbaseOperations = Objects.requireNonNull(hbaseOperations, "hbaseOperations");
30+
this.tableNameProvider = Objects.requireNonNull(tableNameProvider, "tableNameProvider");
31+
}
32+
33+
@Override
34+
public void insert(ServiceUid serviceUid, ApplicationUid applicationUid, String agentId, long agentStartTime, String agentName) {
35+
byte[] rowKey = AgentListRowKeyUtils.agentListRowKey(serviceUid, applicationUid, agentId, agentStartTime);
36+
byte[] value = Bytes.toBytes(agentName);
37+
38+
Put put = new Put(rowKey, true);
39+
put.addColumn(DESCRIPTOR.getName(), DESCRIPTOR.getName(), value);
40+
41+
final TableName agentListTableName = tableNameProvider.getTableName(DESCRIPTOR.getTable());
42+
hbaseOperations.put(agentListTableName, put);
43+
}
44+
}

collector/src/main/java/com/navercorp/pinpoint/collector/handler/grpc/GrpcAgentInfoHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ private PResult handleAgentInfo(ServerHeader header, PAgentInfo agentInfo) {
9191
try {
9292
// agent info
9393
final AgentInfoBo agentInfoBo = this.agentInfoBoMapper.map(agentInfo, header);
94-
this.agentInfoService.insert(agentInfoBo);
94+
this.agentInfoService.insert(header.getServiceUid(), header.getApplicationUid(), agentInfoBo);
9595
return PResult.newBuilder().setSuccess(true).build();
9696
} catch (Exception e) {
9797
logger.warn("Failed to handle. agentInfo={}", MessageFormatUtils.debugLog(agentInfo), e);

collector/src/main/java/com/navercorp/pinpoint/collector/service/AgentInfoService.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,21 @@
1717
package com.navercorp.pinpoint.collector.service;
1818

1919
import com.navercorp.pinpoint.collector.dao.AgentInfoDao;
20+
import com.navercorp.pinpoint.collector.dao.AgentListDao;
2021
import com.navercorp.pinpoint.collector.dao.ApplicationIndexDao;
2122
import com.navercorp.pinpoint.common.server.bo.AgentInfoBo;
23+
import com.navercorp.pinpoint.common.server.uid.ApplicationUid;
24+
import com.navercorp.pinpoint.common.server.uid.ServiceUid;
2225
import jakarta.validation.Valid;
2326
import jakarta.validation.constraints.NotBlank;
2427
import jakarta.validation.constraints.PositiveOrZero;
28+
import org.springframework.beans.factory.annotation.Value;
2529
import org.springframework.stereotype.Service;
2630
import org.springframework.validation.annotation.Validated;
2731

2832
import java.util.Objects;
33+
import java.util.Optional;
34+
import java.util.function.Supplier;
2935

3036
/**
3137
* @author emeroad
@@ -40,14 +46,23 @@ public class AgentInfoService {
4046

4147
private final ApplicationIndexDao applicationIndexDao;
4248

43-
public AgentInfoService(AgentInfoDao agentInfoDao, ApplicationIndexDao applicationIndexDao) {
49+
private final AgentListDao agentListDao;
50+
private final boolean agentListEnable;
51+
52+
public AgentInfoService(AgentInfoDao agentInfoDao, ApplicationIndexDao applicationIndexDao, Optional<AgentListDao> agentListDao,
53+
@Value("${pinpoint.collector.uid.agent.list.insert:false}") boolean agentListEnable) {
4454
this.agentInfoDao = Objects.requireNonNull(agentInfoDao, "agentInfoDao");
4555
this.applicationIndexDao = Objects.requireNonNull(applicationIndexDao, "applicationIndexDao");
56+
this.agentListDao = Objects.requireNonNull(agentListDao, "agentListDao").orElse(null);
57+
this.agentListEnable = agentListEnable;
4658
}
4759

48-
public void insert(@Valid final AgentInfoBo agentInfoBo) {
60+
public void insert(Supplier<ServiceUid> serviceUid, Supplier<ApplicationUid> applicationUid, @Valid final AgentInfoBo agentInfoBo) {
4961
agentInfoDao.insert(agentInfoBo);
5062
applicationIndexDao.insert(agentInfoBo);
63+
if (agentListEnable && agentListDao != null) {
64+
agentListDao.insert(serviceUid.get(), applicationUid.get(), agentInfoBo.getAgentId(), agentInfoBo.getStartTime(), agentInfoBo.getAgentName());
65+
}
5166
}
5267

5368
public AgentInfoBo getSimpleAgentInfo(@NotBlank final String agentId, @PositiveOrZero final long timestamp) {

commons-hbase/src/main/java/com/navercorp/pinpoint/common/hbase/HbaseTable.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public enum HbaseTable {
3232
APPLICATION_INDEX("ApplicationIndex"),
3333
APPLICATION_UID("ApplicationUid"),
3434
APPLICATION_NAME("ApplicationName"),
35+
AGENT_LIST("AgentList"),
3536
APPLICATION_TRACE_INDEX("ApplicationTraceIndex"),
3637
HOST_APPLICATION_MAP_VER2("HostApplicationMap_Ver2"),
3738
MAP_STATISTICS_CALLEE_VER2("ApplicationMapStatisticsCallee_Ver2"),

commons-hbase/src/main/java/com/navercorp/pinpoint/common/hbase/HbaseTables.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ private ApiMetadata(HbaseTable hBaseTable, byte[] columnFamilyName) {
4444

4545
public static final HbaseColumnFamily APPLICATION_NAME = new HbaseColumnFamily(HbaseTable.APPLICATION_NAME, Bytes.toBytes("N"));
4646

47+
public static final HbaseColumnFamily AGENT_LIST = new HbaseColumnFamily(HbaseTable.AGENT_LIST, Bytes.toBytes("A"));
4748

4849
public static final HbaseColumnFamily APPLICATION_INDEX_AGENTS = new HbaseColumnFamily(HbaseTable.APPLICATION_INDEX, Bytes.toBytes("Agents"));
4950

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package com.navercorp.pinpoint.common.server.util;
2+
3+
import com.navercorp.pinpoint.common.buffer.Buffer;
4+
import com.navercorp.pinpoint.common.buffer.FixedBuffer;
5+
import com.navercorp.pinpoint.common.hbase.HbaseTableConstants;
6+
import com.navercorp.pinpoint.common.server.uid.ApplicationUid;
7+
import com.navercorp.pinpoint.common.server.uid.ServiceUid;
8+
import com.navercorp.pinpoint.common.util.BytesUtils;
9+
import com.navercorp.pinpoint.common.util.TimeUtils;
10+
11+
public class AgentListRowKeyUtils {
12+
private static final int AGENT_ID_OFFSET = BytesUtils.INT_BYTE_LENGTH + BytesUtils.LONG_BYTE_LENGTH;
13+
private static final int AGENT_START_TIME_OFFSET = AGENT_ID_OFFSET + HbaseTableConstants.AGENT_ID_MAX_LEN;
14+
15+
private AgentListRowKeyUtils() {
16+
}
17+
18+
19+
public static byte[] agentListRowKey(ServiceUid serviceUid, ApplicationUid applicationUid, String agentId, long agentStartTime) {
20+
Buffer buffer = new FixedBuffer(AGENT_START_TIME_OFFSET + BytesUtils.LONG_BYTE_LENGTH);
21+
22+
buffer.putInt(serviceUid.getUid());
23+
buffer.putLong(applicationUid.getUid());
24+
buffer.putPadString(agentId, HbaseTableConstants.AGENT_ID_MAX_LEN);
25+
buffer.putLong(TimeUtils.reverseTimeMillis(agentStartTime));
26+
27+
return buffer.getBuffer();
28+
}
29+
30+
public static byte[] createScanPrefix(ServiceUid serviceUid, ApplicationUid applicationUid, String agentId) {
31+
Buffer buffer = new FixedBuffer(AGENT_START_TIME_OFFSET);
32+
buffer.putInt(serviceUid.getUid());
33+
buffer.putLong(applicationUid.getUid());
34+
buffer.putPadString(agentId, HbaseTableConstants.AGENT_ID_MAX_LEN);
35+
return buffer.getBuffer();
36+
}
37+
38+
public static byte[] createScanPrefix(ServiceUid serviceUid, ApplicationUid applicationUid) {
39+
Buffer buffer = new FixedBuffer(AGENT_ID_OFFSET);
40+
buffer.putInt(serviceUid.getUid());
41+
buffer.putLong(applicationUid.getUid());
42+
return buffer.getBuffer();
43+
}
44+
45+
public static String getAgentId(byte[] rowKey) {
46+
Buffer buffer = new FixedBuffer(rowKey);
47+
buffer.setOffset(AGENT_ID_OFFSET);
48+
return buffer.readPadStringAndRightTrim(HbaseTableConstants.AGENT_ID_MAX_LEN);
49+
}
50+
51+
public static long getAgentStartTime(byte[] rowKey) {
52+
Buffer buffer = new FixedBuffer(rowKey);
53+
buffer.setOffset(AGENT_START_TIME_OFFSET);
54+
return TimeUtils.recoveryTimeMillis(buffer.readLong());
55+
}
56+
}

hbase/scripts/hbase-create.hbase

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,11 @@ create 'HostApplicationMap_Ver2', { NAME => 'M', TTL => 5184000, VERSIONS => 1,
3030
=end
3131

3232
=begin
33-
# The two tables below are not currently in use.
33+
# The tables below are not currently in use.
3434
#create 'ApplicationUid', { NAME => 'I', DATA_BLOCK_ENCODING => 'PREFIX' }
3535
#create 'ApplicationName', { NAME => 'N', DATA_BLOCK_ENCODING => 'PREFIX' }
36+
37+
#create 'AgentList', { NAME => 'A', TTL => 5184000, VERSIONS => 1, DATA_BLOCK_ENCODING => 'PREFIX' }
3638
=end
3739

3840
list
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
package com.navercorp.pinpoint.web.authorization.controller;
2+
3+
4+
import com.navercorp.pinpoint.common.server.response.Response;
5+
import com.navercorp.pinpoint.common.server.response.SimpleResponse;
6+
import com.navercorp.pinpoint.common.server.uid.ApplicationUid;
7+
import com.navercorp.pinpoint.common.server.uid.ServiceUid;
8+
import com.navercorp.pinpoint.common.server.util.time.Range;
9+
import com.navercorp.pinpoint.web.service.AgentListService;
10+
import com.navercorp.pinpoint.web.uid.service.ApplicationUidService;
11+
import com.navercorp.pinpoint.web.vo.agent.AgentListEntryAndStatus;
12+
import jakarta.validation.constraints.NotBlank;
13+
import jakarta.validation.constraints.PositiveOrZero;
14+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
15+
import org.springframework.web.bind.annotation.DeleteMapping;
16+
import org.springframework.web.bind.annotation.GetMapping;
17+
import org.springframework.web.bind.annotation.RequestMapping;
18+
import org.springframework.web.bind.annotation.RequestParam;
19+
import org.springframework.web.bind.annotation.RestController;
20+
21+
import java.util.Collections;
22+
import java.util.Comparator;
23+
import java.util.List;
24+
import java.util.Map;
25+
import java.util.Objects;
26+
import java.util.stream.Collectors;
27+
import java.util.stream.Stream;
28+
29+
@RestController
30+
@RequestMapping("/api/uid/agentList")
31+
@ConditionalOnProperty(name = "pinpoint.web.application.uid.enable", havingValue = "true")
32+
public class UidAgentListController {
33+
34+
private final AgentListService agentListService;
35+
private final ApplicationUidService applicationUidService;
36+
37+
public UidAgentListController(AgentListService agentListService, ApplicationUidService applicationUidService) {
38+
this.agentListService = Objects.requireNonNull(agentListService, "agentListService");
39+
this.applicationUidService = Objects.requireNonNull(applicationUidService, "applicationUidService");
40+
}
41+
42+
43+
@GetMapping()
44+
public List<AgentListEntryAndStatus> getAgentList(@RequestParam(value = "serviceUid", required = false, defaultValue = "0") int serviceUid,
45+
@RequestParam(value = "applicationName") @NotBlank String applicationName,
46+
@RequestParam(value = "orderBy", required = false, defaultValue = "NO_OP") String orderBy) {
47+
ServiceUid serviceUidObject = ServiceUid.of(serviceUid);
48+
49+
ApplicationUid applicationUid = applicationUidService.getApplicationUid(serviceUidObject, applicationName);
50+
if (applicationUid == null) {
51+
return Collections.emptyList();
52+
}
53+
54+
return agentListService.getAgentList(serviceUidObject, applicationUid).stream()
55+
.sorted(OrderBy.of(orderBy))
56+
.collect(Collectors.toList());
57+
}
58+
59+
@GetMapping(params = {"from", "to"})
60+
public List<AgentListEntryAndStatus> getAgentList(@RequestParam(value = "serviceUid", required = false, defaultValue = "0") int serviceUid,
61+
@RequestParam(value = "applicationName") @NotBlank String applicationName,
62+
@RequestParam("from") @PositiveOrZero long from,
63+
@RequestParam("to") @PositiveOrZero long to,
64+
@RequestParam(value = "orderBy", required = false, defaultValue = "NO_OP") String orderBy) {
65+
ServiceUid serviceUidObject = ServiceUid.of(serviceUid);
66+
Range range = Range.between(from, to);
67+
68+
ApplicationUid applicationUid = applicationUidService.getApplicationUid(serviceUidObject, applicationName);
69+
if (applicationUid == null) {
70+
return Collections.emptyList();
71+
}
72+
return agentListService.getActiveAgentList(serviceUidObject, applicationUid, range).stream()
73+
.sorted(OrderBy.of(orderBy))
74+
.collect(Collectors.toList());
75+
}
76+
77+
@DeleteMapping()
78+
public Response deleteAgents(@RequestParam(value = "serviceUid", required = false, defaultValue = "0") int serviceUid,
79+
@RequestParam(value = "applicationName") @NotBlank String applicationName) {
80+
ServiceUid serviceUidObject = ServiceUid.of(serviceUid);
81+
82+
ApplicationUid applicationUid = applicationUidService.getApplicationUid(serviceUidObject, applicationName);
83+
if (applicationUid == null) {
84+
return SimpleResponse.ok();
85+
}
86+
agentListService.deleteAgents(serviceUidObject, applicationUid);
87+
return SimpleResponse.ok();
88+
}
89+
90+
@DeleteMapping(params = {"agentId"})
91+
public Response deleteAgent(@RequestParam(value = "serviceUid", required = false, defaultValue = "0") int serviceUid,
92+
@RequestParam(value = "applicationName") @NotBlank String applicationName,
93+
@RequestParam(value = "agentId") @NotBlank String agentId) {
94+
ServiceUid serviceUidObject = ServiceUid.of(serviceUid);
95+
96+
ApplicationUid applicationUid = applicationUidService.getApplicationUid(serviceUidObject, applicationName);
97+
if (applicationUid == null) {
98+
return SimpleResponse.ok();
99+
}
100+
agentListService.deleteAgent(serviceUidObject, applicationUid, agentId);
101+
return SimpleResponse.ok();
102+
}
103+
104+
private enum OrderBy implements Comparator<AgentListEntryAndStatus> {
105+
NO_OP(Comparator.comparing(o -> 0)),
106+
NAME_ASC(Comparator.comparing(o -> o.getAgentListEntry().getAgentName())),
107+
NAME_DESC(NAME_ASC.reversed()),
108+
ID_ASC(Comparator.comparing(o -> o.getAgentListEntry().getAgentId())),
109+
ID_DESC(ID_ASC.reversed()),
110+
START_TIME_ASC(Comparator.comparingLong(o -> o.getAgentListEntry().getStartTimestamp())),
111+
START_TIME_DESC(START_TIME_ASC.reversed());
112+
113+
private static final Map<String, OrderBy> MAP =
114+
Stream.of(values()).collect(Collectors.toMap(Enum::name, e -> e));
115+
116+
public static OrderBy of(String value) {
117+
return MAP.getOrDefault(value.toUpperCase(), NO_OP);
118+
}
119+
120+
private final Comparator<AgentListEntryAndStatus> comparator;
121+
122+
OrderBy(Comparator<AgentListEntryAndStatus> comparator) {
123+
this.comparator = comparator;
124+
}
125+
126+
@Override
127+
public int compare(AgentListEntryAndStatus o1, AgentListEntryAndStatus o2) {
128+
return comparator.compare(o1, o2);
129+
}
130+
}
131+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.navercorp.pinpoint.web.dao;
2+
3+
import com.navercorp.pinpoint.common.server.uid.ApplicationUid;
4+
import com.navercorp.pinpoint.common.server.uid.ServiceUid;
5+
import com.navercorp.pinpoint.web.vo.agent.AgentListEntry;
6+
7+
import java.util.List;
8+
9+
public interface AgentListDao {
10+
11+
List<AgentListEntry> selectAgentListEntry(ServiceUid serviceUid, ApplicationUid applicationUid);
12+
13+
List<AgentListEntry> selectAgentListEntry(ServiceUid serviceUid, ApplicationUid applicationUid, String agentId);
14+
15+
void deleteAgents(ServiceUid serviceUid, ApplicationUid applicationUid, List<AgentListEntry> agentList);
16+
}

0 commit comments

Comments
 (0)