forked from pinpoint-apm/pinpoint
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[pinpoint-apm#7375] Add Channelz monitoring API for Collector
- Loading branch information
Showing
24 changed files
with
1,297 additions
and
40 deletions.
There are no files selected for viewing
131 changes: 131 additions & 0 deletions
131
collector/src/main/java/com/navercorp/pinpoint/collector/controller/ChannelzController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
package com.navercorp.pinpoint.collector.controller; | ||
|
||
import com.fasterxml.jackson.core.JsonProcessingException; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import com.navercorp.pinpoint.common.util.Assert; | ||
import com.navercorp.pinpoint.grpc.channelz.ChannelzRegistry; | ||
import com.navercorp.pinpoint.grpc.channelz.ChannelzUtils; | ||
import io.grpc.InternalChannelz; | ||
import io.grpc.InternalInstrumented; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.stereotype.Controller; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.ResponseBody; | ||
|
||
import java.util.List; | ||
|
||
|
||
@Controller | ||
@RequestMapping("/channelz") | ||
public class ChannelzController { | ||
|
||
private final ChannelzRegistry channelzRegistry; | ||
private final InternalChannelz channelz = InternalChannelz.instance(); | ||
private final ObjectMapper mapper; | ||
|
||
@Autowired | ||
public ChannelzController(ChannelzRegistry channelzRegistry, ObjectMapper objectMapper) { | ||
this.channelzRegistry = Assert.requireNonNull(channelzRegistry, "channelzRegistry"); | ||
this.mapper = Assert.requireNonNull(objectMapper, "objectMapper"); | ||
} | ||
|
||
@RequestMapping("/getSocket") | ||
@ResponseBody | ||
public String getSocket(long logId) throws JsonProcessingException { | ||
InternalChannelz.SocketStats stats = getSocket0(logId); | ||
|
||
return mapper.writeValueAsString(stats); | ||
} | ||
|
||
@RequestMapping("/html/getSocket") | ||
@ResponseBody | ||
public String getSocketToHtml(long logId) { | ||
InternalChannelz.SocketStats stats = getSocket0(logId); | ||
|
||
return new HTMLBuilder().build(stats); | ||
} | ||
|
||
private InternalChannelz.SocketStats getSocket0(long logId) { | ||
InternalInstrumented<InternalChannelz.SocketStats> socket = channelz.getSocket(logId); | ||
if (socket == null) { | ||
return null; | ||
} | ||
return ChannelzUtils.getResult("Socket", socket); | ||
} | ||
|
||
@RequestMapping("/findSocket") | ||
@ResponseBody | ||
public String findSocket(String remoteAddress, int localPort) throws JsonProcessingException { | ||
String target = remoteAddress + ":" + localPort; | ||
|
||
InternalChannelz.SocketStats stats = findSocket(target); | ||
if (stats == null) { | ||
return notFound("remoteAddress:" + remoteAddress +" localPort:" + localPort); | ||
} | ||
|
||
return mapper.writeValueAsString(stats); | ||
} | ||
|
||
@RequestMapping("/html/findSocket") | ||
@ResponseBody | ||
public String findSocketStatToHtml(String remoteAddress, int localPort) { | ||
String target = remoteAddress + ":" + localPort; | ||
|
||
InternalChannelz.SocketStats stats = findSocket(target); | ||
if (stats == null) { | ||
return notFound("remoteAddress:" + remoteAddress +" localPort:" + localPort); | ||
} | ||
|
||
return new HTMLBuilder().build(stats); | ||
} | ||
|
||
private InternalChannelz.SocketStats findSocket(String targetAddress) { | ||
Long logId = channelzRegistry.getSocketLogId(targetAddress); | ||
InternalInstrumented<InternalChannelz.SocketStats> socket = channelz.getSocket(logId); | ||
if (socket == null) { | ||
return null; | ||
} | ||
return ChannelzUtils.getResult("Socket", socket); | ||
} | ||
|
||
@RequestMapping("/html/getServer") | ||
@ResponseBody | ||
public String getServerStatToHtml(String serverName) { | ||
List<InternalChannelz.ServerStats> stats = getServer(serverName); | ||
if (stats == null) { | ||
return notFound("serverName=" + serverName); | ||
} | ||
StringBuilder buffer = new StringBuilder(); | ||
for (InternalChannelz.ServerStats stat : stats) { | ||
String html = new HTMLBuilder().build(stat); | ||
buffer.append(html); | ||
|
||
buffer.append("<br>"); | ||
} | ||
return buffer.toString(); | ||
} | ||
|
||
@RequestMapping("/html/getSpanReceiver") | ||
@ResponseBody | ||
public String getSpanReceiverl() { | ||
return getServerStatToHtml("grpcSpanReceiver"); | ||
} | ||
|
||
|
||
private List<InternalChannelz.ServerStats> getServer(String serverName) { | ||
Long logId = channelzRegistry.getServerLogId(serverName); | ||
|
||
InternalChannelz.ServerList serverList = channelz.getServers(logId, 10000); | ||
|
||
List<InternalChannelz.ServerStats> serverStats = ChannelzUtils.getResults("ServerStats", serverList.servers); | ||
return serverStats; | ||
} | ||
|
||
|
||
|
||
private String notFound(String target) { | ||
return target + " not Found"; | ||
} | ||
|
||
|
||
} |
86 changes: 86 additions & 0 deletions
86
collector/src/main/java/com/navercorp/pinpoint/collector/controller/HTMLBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package com.navercorp.pinpoint.collector.controller; | ||
|
||
import org.apache.commons.lang3.builder.ReflectionToStringBuilder; | ||
import org.apache.commons.lang3.builder.ToStringStyle; | ||
|
||
import java.util.Comparator; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.Stream; | ||
|
||
/** | ||
* source : http://scrumbucket.org/converting-a-pojo-into-html/ | ||
*/ | ||
public class HTMLBuilder { | ||
|
||
|
||
public static class HTMLStyle extends ToStringStyle { | ||
|
||
public static final String[] toStringClass = {"java.lang", "java.net"}; | ||
|
||
public HTMLStyle() { | ||
setFieldSeparator("</td></tr>" + System.lineSeparator() + "<tr><td>"); | ||
|
||
setContentStart("<table border=\"1\" style=\"border-collapse:collapse\">" + System.lineSeparator() + | ||
"<thead><tr><th>Field</th><th>Data</th></tr></thead>" + | ||
"<tbody><tr><td>"); | ||
|
||
setFieldNameValueSeparator("</td><td>"); | ||
|
||
setContentEnd("</td></tr>" + System.lineSeparator() + "</tbody></table>"); | ||
|
||
setArrayContentDetail(true); | ||
setUseShortClassName(true); | ||
setUseClassName(false); | ||
setUseIdentityHashCode(false); | ||
|
||
} | ||
|
||
@Override | ||
public void appendDetail(StringBuffer buffer, String fieldName, Object value) { | ||
for (String prefix : toStringClass) { | ||
if (value.getClass().getName().startsWith(prefix)) { | ||
super.appendDetail(buffer, fieldName, value); | ||
return; | ||
} | ||
} | ||
buffer.append(ReflectionToStringBuilder.toString(value, this)); | ||
} | ||
|
||
@Override | ||
public void append(StringBuffer buffer, String fieldName, Object value, Boolean fullDetail) { | ||
super.append(buffer, fieldName, value, fullDetail); | ||
} | ||
|
||
@Override | ||
protected void appendDetail(StringBuffer buffer, String fieldName, Map<?, ?> map) { | ||
if (fieldName.equals("others")) { | ||
|
||
List<? extends Map.Entry<?, ?>> list = sort(map); | ||
appendContentStart(buffer); | ||
for (Map.Entry<?, ?> entry : list) { | ||
String key = (String) entry.getKey(); | ||
Object value = entry.getValue().toString(); | ||
|
||
append(buffer, key, value, true); | ||
} | ||
removeLastFieldSeparator(buffer); | ||
appendContentEnd(buffer); | ||
return; | ||
} | ||
super.appendDetail(buffer, fieldName, map); | ||
} | ||
|
||
private List<? extends Map.Entry<?, ?>> sort(Map<?, ?> map) { | ||
Stream<? extends Map.Entry<?, ?>> stream = map.entrySet().stream(); | ||
return stream.sorted(Comparator.comparing(anotherString -> (String) anotherString.getKey())) | ||
.collect(Collectors.toList()); | ||
} | ||
} | ||
|
||
public String build(Object object) { | ||
ReflectionToStringBuilder builder = new ReflectionToStringBuilder(object, new HTMLStyle()); | ||
return builder.toString(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.