public ExpressionResult visitMetric()

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);
        }
    }