Skip to content
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 @@ -50,6 +50,7 @@
import org.apache.accumulo.core.client.admin.TabletInformation;
import org.apache.accumulo.core.client.admin.servers.ServerId;
import org.apache.accumulo.core.data.TableId;
import org.apache.accumulo.core.process.thrift.MetricResponse;
import org.apache.accumulo.core.util.compaction.RunningCompactionInfo;
import org.apache.accumulo.monitor.Monitor;
import org.apache.accumulo.monitor.next.InformationFetcher.InstanceSummary;
Expand Down Expand Up @@ -185,6 +186,36 @@ public TableData getServerProcessView(@MatrixParam("table") TableDataFactory.Tab
return view;
}

@GET
@Path("servers/detail/{type}/{resourceGroup}/{server}")
@Produces(MediaType.APPLICATION_JSON)
@Description("Returns a UI-ready metric table for one server process")
public TableData getServerDetail(@PathParam("type") ServerId.Type type,
@PathParam("resourceGroup") String resourceGroup, @PathParam("server") String server) {
if (type == null) {
throw new BadRequestException("A 'type' parameter is required");
}
if (resourceGroup == null || resourceGroup.isBlank()) {
throw new BadRequestException("A 'resourceGroup' parameter is required");
}
if (server == null || server.isBlank()) {
throw new BadRequestException("A 'server' parameter is required");
}

MetricResponse response;
try {
response = monitor.getInformationFetcher().getSummaryForEndpoint()
.getServerMetricResponse(type, resourceGroup, server);
} catch (IllegalArgumentException e) {
throw new BadRequestException("Invalid server metrics parameters", e);
}
if (response == null) {
throw new NotFoundException("Server " + type.name() + " " + server + " in resource group "
+ resourceGroup + " not found");
}
return TableDataFactory.forServer(response);
}

@GET
@Path("compactions/running")
@Produces(MediaType.APPLICATION_JSON)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -889,7 +889,9 @@ public Object getRowData(ServerId sid, MetricResponse mr,

if (!qm.isEmpty()) {
// Create a ServersView object from the MetricResponse for each queue
return TableDataFactory.forColumns(qm.keySet(), qm, cols);
TableData tableData = TableDataFactory.forColumns(qm.keySet(), qm, cols);
tableData.data().forEach(row -> row.put(TableDataFactory.LINK_RG_COL_KEY, ""));
return tableData;
}
return TableDataFactory.forColumns(Set.of(), Map.of(), cols);
}
Expand Down Expand Up @@ -1639,6 +1641,16 @@ public TableData getServerProcessView(TableDataFactory.TableName table) {
return null;
}

public MetricResponse getServerMetricResponse(ServerId.Type type, String resourceGroup,
String serverAddress) {
HostAndPort address = HostAndPort.fromString(serverAddress);
if (!address.hasPort()) {
throw new IllegalArgumentException("Server address must be host:port");
}
return allMetrics.getIfPresent(new ServerId(type, ResourceGroupId.of(resourceGroup),
address.getHost(), address.getPort()));
}

public static Number getMetricValue(FMetric metric) {
if (metric.ivalue() != 0) {
return metric.ivalue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import org.apache.accumulo.core.metrics.flatbuffers.FTag;
import org.apache.accumulo.core.process.thrift.MetricResponse;
import org.apache.accumulo.core.util.threads.ThreadPoolNames;
import org.apache.accumulo.monitor.next.SystemInformation;
import org.apache.accumulo.monitor.next.views.TableData.Column;
import org.apache.accumulo.server.metrics.MetricResponseWrapper;

Expand All @@ -53,14 +54,30 @@ public class TableDataFactory {

public static final String RG_COL_KEY = "resourceGroup";
public static final String ADDR_COL_KEY = "serverAddress";
public static final String TYPE_COL_KEY = "serverType";
public static final String LINK_RG_COL_KEY = "serverLinkResourceGroup";
public static final String TIME_COL_KEY = "lastContact";
public static final String METRIC_NAME_COL_KEY = "metricName";
public static final String METRIC_VALUE_COL_KEY = "metricValue";
public static final String METRIC_TYPE_COL_KEY = "metricType";
public static final String METRIC_TAGS_COL_KEY = "metricTags";
public static final String METRIC_DESCRIPTION_COL_KEY = "metricDescription";
public static final String METRIC_SECTION_COL_KEY = "metricSection";

public static final Column LAST_CONTACT_COLUMN = new Column(TIME_COL_KEY, "Last Contact",
"Time since the server last responded to the monitor", "duration");
public static final Column RG_COLUMN =
new Column(RG_COL_KEY, "Resource Group", "Resource Group", "");
public static final Column ADDR_COLUMN =
new Column(ADDR_COL_KEY, "Server Address", "Server address", "");
new Column(ADDR_COL_KEY, "Server Address", "Server address", "server-address");

private static final List<Column> SERVER_DETAIL_COLUMNS =
List.of(new Column(METRIC_NAME_COL_KEY, "Metric", "Metric name", ""),
new Column(METRIC_VALUE_COL_KEY, "Value", "Metric value", ""),
new Column(METRIC_TYPE_COL_KEY, "Type", "Metric type", ""),
new Column(METRIC_TAGS_COL_KEY, "Tags", "Metric tags", ""),
new Column(METRIC_SECTION_COL_KEY, "Section", "Metric documentation section", ""),
new Column(METRIC_DESCRIPTION_COL_KEY, "Description", "Metric description", ""));

/**
* Server-process table identifiers accepted by /rest-v2/servers/view. These enum names are used
Expand Down Expand Up @@ -146,6 +163,8 @@ public static TableData forColumns(final Set<ServerId> servers,
List<Map<String,Object>> data = new ArrayList<>();
serverMetricRows.forEach(serverMetricRow -> {
Map<String,Object> row = new LinkedHashMap<>();
row.put(TYPE_COL_KEY, serverMetricRow.server().getType().name());
row.put(LINK_RG_COL_KEY, serverMetricRow.server().getResourceGroup().canonical());
for (ColumnFactory colf : requestedColumns) {
row.put(colf.getColumn().key(), colf.getRowData(serverMetricRow.server(),
serverMetricRow.response(), serverMetricRow.metrics()));
Expand All @@ -157,6 +176,45 @@ public static TableData forColumns(final Set<ServerId> servers,

}

public static TableData forServer(final MetricResponse metricResponse) {
if (!hasMetricData(metricResponse)) {
return new TableData(SERVER_DETAIL_COLUMNS, List.of());
}

List<Map<String,Object>> data = new ArrayList<>();
FMetric metric = new FMetric();
for (var binary : metricResponse.getMetrics()) {
metric = FMetric.getRootAsFMetric(binary, metric);
Map<String,Object> row = new LinkedHashMap<>();
row.put(METRIC_NAME_COL_KEY, metric.name());
row.put(METRIC_VALUE_COL_KEY, SystemInformation.getMetricValue(metric));
row.put(METRIC_TYPE_COL_KEY, metric.type());
row.put(METRIC_TAGS_COL_KEY, formatTags(metric));

try {
Metric metricDefinition = Metric.fromName(metric.name());
row.put(METRIC_SECTION_COL_KEY, metricDefinition.getDocSection().getSectionTitle());
row.put(METRIC_DESCRIPTION_COL_KEY, metricDefinition.getDescription());
} catch (IllegalArgumentException e) {
row.put(METRIC_SECTION_COL_KEY, "");
row.put(METRIC_DESCRIPTION_COL_KEY, "");
}
data.add(row);
}

return new TableData(SERVER_DETAIL_COLUMNS, data);
}

private static String formatTags(FMetric metric) {
List<String> tags = new ArrayList<>();
FTag tag = new FTag();
for (int i = 0; i < metric.tagsLength(); i++) {
tag = metric.tags(tag, i);
tags.add(tag.key() + "=" + tag.value());
}
return String.join(", ", tags);
}

public static TableData forTable(final TableName table, final Set<ServerId> servers,
final Map<ServerId,MetricResponse> allMetrics) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ public class WebViews {
*/
private static final String TSERVER_PARAM_KEY = "s";

private static final String SERVER_TYPE_PARAM_KEY = "type";

private static final String RESOURCE_GROUP_PARAM_KEY = "resourceGroup";

private static final Logger log = LoggerFactory.getLogger(WebViews.class);

@Inject
Expand Down Expand Up @@ -195,16 +199,44 @@ public Map<String,Object> getTabletServers(
Map<String,Object> model = getModel();
model.put("title", "Tablet Server Status");
if (server != null && !server.isBlank()) {
model.put("title", "Server Metrics");
model.put("template", "server.ftl");
model.put("js", "server.js");
model.put("server", server);
model.put("serverType", "TABLET_SERVER");
model.put("resourceGroup", "");
return model;
}
model.put("template", "tservers.ftl");
model.put("js", "tservers.js");
return model;
}

/**
* Returns the server metrics template
*
* @param serverType Accumulo server process type
* @param resourceGroup server resource group
* @param server server address
* @return server metrics model
*/
@GET
@Path("server")
@Template(name = "/default.ftl")
public Map<String,Object> getServerMetrics(@QueryParam(SERVER_TYPE_PARAM_KEY) String serverType,
@QueryParam(RESOURCE_GROUP_PARAM_KEY) String resourceGroup,
@QueryParam(TSERVER_PARAM_KEY) @Pattern(regexp = HOSTNAME_PORT_REGEX) String server) {

Map<String,Object> model = getModel();
model.put("title", "Server Metrics");
model.put("template", "server.ftl");
model.put("js", "server.js");
model.put("server", server);
model.put("serverType", serverType);
model.put("resourceGroup", resourceGroup == null ? "" : resourceGroup);
return model;
}

/**
* Returns the scan servers template
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ $(function () {
"type": "html",
"render": function (data, type, row, meta) {
if (type === 'display') {
data = '<a class="link-body-emphasis" href="tservers?s=' + row.server + '">' + row.server + '</a>';
data = renderServerMetricsLink('COMPACTOR', '', row.server);
}
return data;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const ALERT_COUNTS = 'alertCounts';
const RECOVERY = 'recovery';
const INSTANCE_OVERVIEW = 'instanceOverview';
const SCANS = 'scans';
const SERVER_METRICS = 'serverMetrics';
const LAST_UPDATE = 'lastUpdate';

var STATUS_REQUEST = null;
Expand Down Expand Up @@ -311,6 +312,31 @@ function sanitize(url) {
return url.split('+').join('%2B');
}

function escapeHtml(value) {
if (value === null || value === undefined) {
return '';
}
return $('<div>').text(value).html();
}

function serverMetricsHref(serverType, resourceGroup, serverAddress) {
var href = 'server?type=' + encodeURIComponent(serverType) +
'&s=' + encodeURIComponent(serverAddress);
if (resourceGroup !== null && resourceGroup !== undefined && resourceGroup !== '') {
href += '&resourceGroup=' + encodeURIComponent(resourceGroup);
}
return href;
}

function renderServerMetricsLink(serverType, resourceGroup, serverAddress) {
if (!serverType || !resourceGroup || !serverAddress) {
return escapeHtml(serverAddress);
}
return '<a class="link-body-emphasis" href="' +
serverMetricsHref(serverType, resourceGroup, serverAddress) + '">' +
escapeHtml(serverAddress) + '</a>';
}

/**
* Creates a string with the value to sort and the value to display
* Options are 0 = firstcell left, 1 = right, 2 = center, 3 = left
Expand Down Expand Up @@ -606,6 +632,12 @@ function getServerProcessView(table, storageKey) {
return getJSONForTable(url, storageKey);
}

function getServerMetrics(serverType, resourceGroup, serverAddress) {
var url = REST_V2_PREFIX + '/servers/detail/' + encodeURIComponent(serverType) + '/' +
encodeURIComponent(resourceGroup) + '/' + encodeURIComponent(serverAddress);
return getJSONForTable(url, SERVER_METRICS);
}

function getCompactorsView() {
return getServerProcessView('COMPACTORS', COMPACTOR_SERVER_PROCESS_VIEW);
}
Expand Down
Loading