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

WIP : DW-issue-2096: Add metrics showing the number of events evaluated #16

Closed
wants to merge 16 commits into from
Closed
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
9 changes: 7 additions & 2 deletions api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<relativePath>../../../microservice-parent/pom.xml</relativePath>
</parent>
<artifactId>query-metric-api</artifactId>
<version>3.0.9-SNAPSHOT</version>
<version>3.0.10-SNAPSHOT</version>
<url>https://code.nsa.gov/datawave-query-metric-service</url>
<scm>
<connection>scm:git:https://github.com/NationalSecurityAgency/datawave-query-metric-service.git</connection>
Expand All @@ -23,7 +23,7 @@
<version.base-rest-responses>3.0.0</version.base-rest-responses>
<version.commons-lang3>3.12.0</version.commons-lang3>
<version.commons-text>1.9</version.commons-text>
<version.datawave>6.9.1</version.datawave>
<version.datawave>6.9.3</version.datawave>
<version.glassfish>2.3.6</version.glassfish>
<version.guava>31.1-jre</version.guava>
<version.jackson>2.12.5</version.jackson>
Expand Down Expand Up @@ -189,6 +189,11 @@
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.21</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,18 @@
package datawave.microservice.querymetric;

import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlTransient;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.StringEscapeUtils;
import org.springframework.web.servlet.ModelAndView;

import com.fasterxml.jackson.annotation.JsonIgnore;

import datawave.microservice.querymetric.BaseQueryMetric.PageMetric;
import datawave.webservice.HtmlProvider;
import datawave.webservice.result.BaseResponse;

public abstract class BaseQueryMetricListResponse<T extends BaseQueryMetric> extends BaseResponse implements HtmlProvider {
public abstract class BaseQueryMetricListResponse<T extends BaseQueryMetric> extends BaseResponse {

private static final long serialVersionUID = 1L;
private static final String TITLE = "Query Metrics";
private static final String EMPTY = "";
@XmlElementWrapper(name = "queryMetrics")
@XmlElement(name = "queryMetric")
protected List<T> result = null;
Expand All @@ -35,22 +22,16 @@ public abstract class BaseQueryMetricListResponse<T extends BaseQueryMetric> ext
protected boolean isGeoQuery = false;
@XmlTransient
private boolean administratorMode = false;
private String JQUERY_INCLUDES;
protected String BASE_URL = "/DataWave/Query/Metrics";

public BaseQueryMetricListResponse() {
setHtmlIncludePaths(new HashMap<>());
}
@XmlTransient
protected String header;
@XmlTransient
protected String footer;

public void setHtmlIncludePaths(Map<String,String> pathMap) {
// @formatter:off
JQUERY_INCLUDES =
"<script type='text/javascript' src='" + pathMap.getOrDefault("jquery", "") + "/jquery.min.js'></script>\n";
// @formatter:on
}
protected String basePath = "/querymetric";
protected String viewName = "querymetric";

public void setBaseUrl(String baseUrl) {
this.BASE_URL = baseUrl;
public void setBasePath(String basePath) {
this.basePath = basePath;
}

private static String numToString(long number) {
Expand Down Expand Up @@ -90,131 +71,17 @@ public void setGeoQuery(boolean geoQuery) {
isGeoQuery = geoQuery;
}

@JsonIgnore
@XmlTransient
@Override
public String getTitle() {
return TITLE;
public void setViewName(String viewName) {
this.viewName = viewName;
}

@JsonIgnore
@XmlTransient
@Override
public String getPageHeader() {
return getTitle();
}
abstract public ModelAndView createModelAndView();

@JsonIgnore
@XmlTransient
@Override
public String getHeadContent() {
if (isGeoQuery) {
// @formatter:off
return JQUERY_INCLUDES +
"<script type='text/javascript'>" +
"$(document).ready(function() {" +
" var currentUrl = window.location.href.replace(/\\/+$/, '');" +
" var queryHeader = document.getElementById(\"query-header\").innerHTML;" +
" queryHeader = queryHeader + '<br>(<a href=\"' + currentUrl + '/map\">map</a>)';" +
" document.getElementById(\"query-header\").innerHTML = queryHeader;" +
"});" +
"</script>";
// @formatter: on
} else {
return EMPTY;
}
public void setHeader(String header) {
this.header = header;
}

@JsonIgnore
@XmlTransient
@Override
public String getMainContent() {
StringBuilder builder = new StringBuilder();

builder.append("<table>\n");
builder.append("<tr>\n");
builder.append("<th>Visibility</th><th>Query Date</th><th>User</th><th>UserDN</th><th>Proxy Server(s)</th><th>Query ID</th><th>Query Type</th>");
builder.append("<th>Query Logic</th><th id=\"query-header\">Query</th><th>Begin Date</th><th>End Date</th><th>Query Auths</th><th>Server</th>");
builder.append("<th>Query Setup Time (ms)</th><th>Query Setup Call Time (ms)</th><th>Number Pages</th><th>Number Results</th>");
builder.append("<th>Total Page Time (ms)</th><th>Total Page Call Time (ms)</th><th>Total Page Serialization Time (ms)</th>");
builder.append("<th>Total Page Bytes Sent (uncompressed)</th><th>Lifecycle</th><th>Elapsed Time</th><th>Error Code</th><th>Error Message</th>");
builder.append("\n</tr>\n");

TreeMap<Date,T> metricMap = new TreeMap<Date,T>(Collections.reverseOrder());

for (T metric : this.getResult()) {
metricMap.put(metric.getCreateDate(), metric);
}

SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HHmmss");

int x = 0;
for (T metric : metricMap.values()) {
// highlight alternating rows
if (x % 2 == 0) {
builder.append("<tr class=\"highlight\" style=\"vertical-align:top;\">\n");
} else {
builder.append("<tr style=\"vertical-align:top;\">\n");
}
x++;

builder.append("<td>").append(metric.getColumnVisibility()).append("</td>");
builder.append("<td style=\"min-width:125px !important;\">").append(sdf.format(metric.getCreateDate())).append("</td>");
builder.append("<td>").append(metric.getUser()).append("</td>");
String userDN = metric.getUserDN();
builder.append("<td style=\"min-width:500px !important;\">").append(userDN == null ? "" : userDN).append("</td>");
String proxyServers = metric.getProxyServers() == null ? "" : StringUtils.join(metric.getProxyServers(), "<BR/>");
builder.append("<td>").append(proxyServers).append("</td>");
if (this.isAdministratorMode()) {
builder.append("<td><a href=\"/DataWave/Query/Metrics/user/").append(metric.getUser()).append("/").append(metric.getQueryId()).append("/")
.append("\">").append(metric.getQueryId()).append("</a></td>");
} else {
builder.append("<td><a href=\"/DataWave/Query/Metrics/id/").append(metric.getQueryId()).append("/").append("\">").append(metric.getQueryId())
.append("</a></td>");
}
builder.append("<td>").append(metric.getQueryType()).append("</td>");
builder.append("<td>").append(metric.getQueryLogic()).append("</td>");
builder.append("<td style=\"word-wrap: break-word;\">").append(StringEscapeUtils.escapeHtml4(metric.getQuery())).append("</td>");

String beginDate = metric.getBeginDate() == null ? "" : sdf.format(metric.getBeginDate());
builder.append("<td style=\"min-width:125px !important;\">").append(beginDate).append("</td>");
String endDate = metric.getEndDate() == null ? "" : sdf.format(metric.getEndDate());
builder.append("<td style=\"min-width:125px !important;\">").append(endDate).append("</td>");
String queryAuths = metric.getQueryAuthorizations() == null ? "" : metric.getQueryAuthorizations().replaceAll(",", " ");
builder.append("<td style=\"word-wrap: break-word; min-width:300px !important;\">").append(queryAuths).append("</td>");

builder.append("<td>").append(metric.getHost()).append("</td>");
builder.append("<td>").append(numToString(metric.getSetupTime())).append("</td>");
builder.append("<td>").append(numToString(metric.getCreateCallTime())).append("</td>\n");
builder.append("<td>").append(metric.getNumPages()).append("</td>");
builder.append("<td>").append(metric.getNumResults()).append("</td>");
long count = 0l;
long callTime = 0l;
long serializationTime = 0l;
long bytesSent = 0l;
for (PageMetric p : metric.getPageTimes()) {
count += p.getReturnTime();
callTime += (p.getCallTime()) == -1 ? 0 : p.getCallTime();
serializationTime += (p.getSerializationTime()) == -1 ? 0 : p.getSerializationTime();
bytesSent += (p.getBytesWritten()) == -1 ? 0 : p.getBytesWritten();
}
builder.append("<td>").append(count).append("</td>\n");
builder.append("<td>").append(numToString(callTime)).append("</td>\n");
builder.append("<td>").append(numToString(serializationTime)).append("</td>\n");
builder.append("<td>").append(numToString(bytesSent)).append("</td>\n");
builder.append("<td>").append(metric.getLifecycle()).append("</td>");
builder.append("<td>").append(metric.getElapsedTime()).append("</td>");
String errorCode = metric.getErrorCode();
builder.append("<td style=\"word-wrap: break-word;\">").append((errorCode == null) ? "" : StringEscapeUtils.escapeHtml4(errorCode)).append("</td>");
String errorMessage = metric.getErrorMessage();
builder.append("<td style=\"word-wrap: break-word;\">").append((errorMessage == null) ? "" : StringEscapeUtils.escapeHtml4(errorMessage))
.append("</td>");

builder.append("\n</tr>\n");
}

builder.append("</table>\n");

return builder.toString();

public void setFooter(String footer) {
this.footer = footer;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package datawave.microservice.querymetric;

import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

public class PageMetricModel extends BaseQueryMetric.PageMetric {

private NumberFormat nf = NumberFormat.getIntegerInstance();
private SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HHmmss");

public PageMetricModel(BaseQueryMetric.PageMetric pageMetric) {
super(pageMetric);
}

public String getPageNumberStr() {
return numToString(getPageNumber(), 1);
}

public String getPageRequestedStr() {
return getPageRequested() > 0 ? sdf.format(new Date(getPageRequested())) : "";
}

public String getPageReturnedStr() {
return getPageReturned() > 0 ? sdf.format(new Date(getPageReturned())) : "";
}

public String getReturnTimeStr() {
return nf.format(getReturnTime());
}

public String getPageSizeStr() {
return nf.format(getPagesize());
}

public String getCallTimeStr() {
return numToString(getCallTime(), 0);
}

public String getLoginTimeStr() {
return numToString(getLoginTime(), 0);
}

public String getSerializationTimeStr() {
return numToString(getSerializationTime(), 0);
}

public String getBytesWrittenStr() {
return numToString(getBytesWritten(), 0);
}

private String numToString(long number, long minValue) {
return number < minValue ? "" : nf.format(number);
}
}
Loading