private void appendMetrics(final Collection<? extends Metrics> metrics, final StringBuilder sb, final int indent) {
        // Append each StepMetric's row. indexToLabelMap values are ordered by index.
        for (Metrics m : metrics) {
            final StringBuilder metricName = new StringBuilder();

            // Handle indentation
            for (int ii = 0; ii < indent; ii++) {
                metricName.append("  ");
            }
            metricName.append(m.getName());
            // Abbreviate if necessary
            final StringBuilder rowName = new StringBuilder(StringUtils.abbreviate(metricName.toString(), 50));

            // Grab the values
            final Long itemCount = m.getCount(ELEMENT_COUNT_ID);
            final Long traverserCount = m.getCount(TRAVERSER_COUNT_ID);
            final Double percentDur = (Double) m.getAnnotation(PERCENT_DURATION_KEY);

            // Build the row string

            sb.append(String.format("%n%-50s", rowName.toString()));

            if (itemCount != null) {
                sb.append(String.format(" %21d", itemCount));
            } else {
                sb.append(String.format(" %21s", ""));
            }

            if (traverserCount != null) {
                sb.append(String.format(" %11d", traverserCount));
            } else {
                sb.append(String.format(" %11s", ""));
            }

            sb.append(String.format(" %15.3f", m.getDuration(TimeUnit.MICROSECONDS) / 1000.0));

            if (percentDur != null) {
                sb.append(String.format(" %8.2f", percentDur));
            }

            // process any annotations
            final Map<String,Object> annotations = m.getAnnotations();
            if (!annotations.isEmpty()) {
                // ignore the PERCENT_DURATION_KEY as that is a TinkerPop annotation that is displayed by default
                annotations.entrySet().stream().filter(kv -> !kv.getKey().equals(PERCENT_DURATION_KEY)).forEach(kv -> {
                    final StringBuilder prefixBuilder = new StringBuilder("  ");
                    for (int i = 0; i < indent; i++) {
                        prefixBuilder.append("  ");
                    }
                    final String prefix = prefixBuilder.append("\\_").toString();
                    final String separator = "=";
                    final String k = prefix + StringUtils.abbreviate(kv.getKey(), 30);
                    final int valueIndentLen = separator.length() + k.length() + indent;
                    final int leftover = 110 - valueIndentLen;

                    final String[] splitValues = splitOnSize(kv.getValue().toString(), leftover);
                    for (int ix = 0; ix < splitValues.length; ix++) {
                        // the first lines gets the annotation prefix. the rest are indented to the separator
                        if (ix == 0) {
                            sb.append(String.format("%n%s", k + separator + splitValues[ix]));
                        } else {
                            sb.append(String.format("%n%s", padLeft(splitValues[ix], valueIndentLen - 1)));
                        }
                    }
                });
            }

            appendMetrics(m.getNested(), sb, indent + 1);
        }
    }
Extracts metrics from the provided {@link Traversal} and computes metrics. Calling this method finalizes the
metrics such that their values can no longer be modified.
gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/util/DefaultTraversalMetrics.java