in oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/mqe/rt/MQEVisitor.java [110:221]
public ExpressionResult visitMetric(MQEParser.MetricContext ctx) {
DebuggingTraceContext traceContext = TRACE_CONTEXT.get();
DebuggingSpan span = traceContext.createSpan("MQE Metric OP: " + ctx.getText());
try {
ExpressionResult result = new ExpressionResult();
String metricName = ctx.metricName().getText();
Optional<ValueColumnMetadata.ValueColumn> valueColumn = ValueColumnMetadata.INSTANCE.readValueColumnDefinition(
metricName);
if (valueColumn.isEmpty()) {
result.setType(ExpressionResultType.UNKNOWN);
result.setError("Metric: [" + metricName + "] does not exist.");
return result;
}
Column.ValueDataType dataType = valueColumn.get().getDataType();
try {
if (Column.ValueDataType.COMMON_VALUE == dataType) {
if (ctx.parent instanceof MQEParser.TopNContext) {
MQEParser.TopNContext parent = (MQEParser.TopNContext) ctx.parent;
int topN = Integer.parseInt(parent.INTEGER().getText());
if (topN <= 0) {
throw new IllegalExpressionException("TopN value must be > 0.");
}
List<AttrCondition> attrConditions = new ArrayList<>();
if (parent.attributeList() != null) {
for (MQEParser.AttributeContext attributeContext : parent.attributeList().attribute()) {
String attrName = attributeContext.attributeName().getText();
String attrValue = attributeContext.VALUE_STRING().getText();
if (StringUtil.isNotBlank(attrValue)) {
String attrValueTrim = attrValue.substring(1, attrValue.length() - 1);
if (attributeContext.EQ() != null) {
attrConditions.add(new AttrCondition(attrName, attrValueTrim, true));
} else if (attributeContext.NEQ() != null) {
attrConditions.add(new AttrCondition(attrName, attrValueTrim, false));
}
}
}
}
querySortMetrics(metricName, Integer.parseInt(parent.INTEGER().getText()),
Order.valueOf(parent.order().getText().toUpperCase()), attrConditions, result);
} else if (ctx.parent instanceof MQEParser.TrendOPContext) {
//trend query requires get previous data according to the trend range
MQEParser.TrendOPContext parent = (MQEParser.TrendOPContext) ctx.parent;
int trendRange = Integer.parseInt(parent.INTEGER().getText());
queryMetrics(metricName, getTrendQueryDuration(trendRange), result);
} else if (ctx.parent instanceof MQEParser.BaselineOPContext) {
MQEParser.BaselineOPContext parent = (MQEParser.BaselineOPContext) ctx.parent;
ArrayList<String> times = new ArrayList<>();
for (PointOfTime pointOfTime : duration.assembleDurationPoints()) {
times.add(Long.toString(pointOfTime.getPoint()));
}
List<MQEValues> valuesList = super.queryBaseline(
entity.getServiceName(), metricName, times,
parent.baseline_type().getStart().getType()
);
result.setResults(valuesList);
result.setType(ExpressionResultType.TIME_SERIES_VALUES);
} else {
queryMetrics(metricName, this.duration, result);
}
} else if (Column.ValueDataType.LABELED_VALUE == dataType) {
if (ctx.parent instanceof MQEParser.TopNOPContext) {
throw new IllegalExpressionException(
"Metric: [" + metricName + "] is labeled value, does not support top_n query.");
}
List<KeyValue> queryLabels = super.buildLabels(ctx.labelList());
if (ctx.parent instanceof MQEParser.TrendOPContext) {
MQEParser.TrendOPContext parent = (MQEParser.TrendOPContext) ctx.parent;
int trendRange = Integer.parseInt(parent.INTEGER().getText());
queryLabeledMetrics(metricName, queryLabels, getTrendQueryDuration(trendRange), result);
} else if (ctx.parent instanceof MQEParser.BaselineOPContext) {
MQEParser.BaselineOPContext parent = (MQEParser.BaselineOPContext) ctx.parent;
ArrayList<String> times = new ArrayList<>();
for (PointOfTime pointOfTime : duration.assembleDurationPoints()) {
times.add(Long.toString(pointOfTime.getPoint()));
}
List<MQEValues> valuesList = super.queryLabeledBaseline(
entity.getServiceName(), metricName, queryLabels, times, parent.baseline_type()
.getStart()
.getType());
result.setResults(valuesList);
result.setType(ExpressionResultType.TIME_SERIES_VALUES);
} else {
queryLabeledMetrics(metricName, queryLabels, this.duration, result);
}
} else if (Column.ValueDataType.SAMPLED_RECORD == dataType) {
if (ctx.parent instanceof MQEParser.TopNContext) {
MQEParser.TopNContext parent = (MQEParser.TopNContext) ctx.parent;
int topN = Integer.parseInt(parent.INTEGER().getText());
if (topN <= 0) {
throw new IllegalExpressionException("TopN value must be > 0.");
}
queryRecords(metricName, Integer.parseInt(parent.INTEGER().getText()),
Order.valueOf(parent.order().getText().toUpperCase()), result);
} else {
throw new IllegalExpressionException(
"Metric: [" + metricName + "] is topN record, need top_n function for query.");
}
}
} catch (IllegalExpressionException e) {
return getErrorResult(e.getMessage());
} catch (IOException e) {
ExpressionResult errorResult = getErrorResult("Internal IO exception, query metrics error.");
log.error("Query metrics from backend error.", e);
return errorResult;
}
return result;
} finally {
traceContext.stopSpan(span);
}
}