@Get
    @Post
    @Path("/api/v1/labels")
    public HttpResponse labels(
        @Param("match[]") Optional<String> match,
        @Param("start") Optional<String> start,
        @Param("end") Optional<String> end,
        @Param("limit") Optional<Integer> limit) throws IOException {
        LabelsQueryRsp response = new LabelsQueryRsp();
        long endTS = System.currentTimeMillis();
        if (end.isPresent()) {
            endTS = formatTimestamp2Millis(end.get());
        }
        int limitNum = limit.orElse(100);
        Duration duration = getDayDurationFromTimestamp(endTS);
        if (match.isPresent()) {
            MatcherSetResult parseResult;
            try {
                parseResult = getMatcherSetResult(match.get());
            } catch (ParseCancellationException e) {
                response.setStatus(ResultStatus.ERROR);
                response.setErrorType(ErrorType.BAD_DATA);
                response.setError(e.getMessage());
                return jsonResponse(response);
            }
            String metricName = parseResult.getMetricName();
            Optional<ValueColumnMetadata.ValueColumn> valueColumn = ValueColumnMetadata.INSTANCE.readValueColumnDefinition(
                metricName);
            if (valueColumn.isPresent()) {
                ValueColumnMetadata.ValueColumn metaData = valueColumn.get();
                Scope scope = Scope.Finder.valueOf(metaData.getScopeId());
                response.getData().addAll(buildLabelNames(scope, metaData));
                if (Column.ValueDataType.LABELED_VALUE == valueColumn.get().getDataType()) {
                    List<MetricsValues> matchedMetrics = getMatcherMetricsValues(parseResult, duration);
                    response.getData().addAll(buildLabelNamesFromQuery(matchedMetrics));
                }
                if (metaData.isMultiIntValues()) {
                    response.getData().remove(DataLabel.GENERAL_LABEL_NAME);
                }
            } else if (ServiceTraffic.INDEX_NAME.equals(metricName) || InstanceTraffic.INDEX_NAME.equals(metricName)
                || EndpointTraffic.INDEX_NAME.equals(metricName)) {
                response.getData().addAll(buildLabelNamesForTraffic(metricName));
            }
        } else {
            Arrays.stream(LabelName.values()).forEach(label -> {
                response.getData().add(label.getLabel());
            });
        }
        List<String> result = response.getData().stream().limit(limitNum).collect(Collectors.toList());
        response.setData(result);
        response.setStatus(ResultStatus.SUCCESS);
        return jsonResponse(response);
    }
If match[] is not present, return general labels.
If end time is not present, use current time as default end time.
The start param will be ignored, reserve this param to keep consistent with API protocol.
Always query with day step.
oap-server/server-query-plugin/promql-plugin/src/main/java/org/apache/skywalking/oap/query/promql/handler/PromQLApiHandler.java