Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.vladsch.flexmark.util.sequence.Escaping;
import com.vladsch.flexmark.util.sequence.LineAppendable;
import com.vladsch.flexmark.util.sequence.TagRange;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.instrumentation.annotations.WithSpan;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
Expand Down Expand Up @@ -206,6 +207,10 @@ public void render(@NotNull Node node, @NotNull Appendable output) {
*/
@WithSpan("markdown.render")
public void render(@NotNull Node node, @NotNull Appendable output, int maxTrailingBlankLines) {
Span span = Span.current();
span.setAttribute("markdown.node.type", node.getClass().getSimpleName());
span.setAttribute("markdown.input.length", node.getChars().length());

HtmlWriter htmlWriter = new HtmlWriter(output, htmlOptions.indentSize, htmlOptions.formatFlags, !htmlOptions.htmlBlockOpenTagEol, !htmlOptions.htmlBlockCloseTagEol);
MainNodeRenderer renderer = new MainNodeRenderer(options, htmlWriter, node.getDocument());
if (renderer.htmlIdGenerator != HtmlIdGenerator.NULL && !(node instanceof Document)) {
Expand All @@ -218,6 +223,10 @@ public void render(@NotNull Node node, @NotNull Appendable output, int maxTraili
// resolve any unresolved tracked offsets that are outside elements which resolve their own
TrackedOffsetUtils.resolveTrackedOffsets(node.getChars(), htmlWriter, TRACKED_OFFSETS.get(renderer.getDocument()), maxTrailingBlankLines, SharedDataKeys.RUNNING_TESTS.get(options));
renderer.dispose();

if (output instanceof CharSequence) {
span.setAttribute("markdown.output.length", ((CharSequence) output).length());
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.vladsch.flexmark.util.sequence.BasedSequence;
import com.vladsch.flexmark.util.sequence.ReplacedBasedSequence;
import com.vladsch.flexmark.util.sequence.mappers.SpecialLeadInHandler;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.instrumentation.annotations.WithSpan;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
Expand Down Expand Up @@ -356,6 +357,8 @@ public static Builder builder(DataHolder options) {
*/
@WithSpan("markdown.parse")
public @NotNull Document parse(@NotNull BasedSequence input) {
Span.current().setAttribute("markdown.input.length", input.length());

// NOTE: parser can only handle contiguous sequences with no out of base characters
if (input instanceof ReplacedBasedSequence) {
throw new IllegalArgumentException("" +
Expand Down Expand Up @@ -383,6 +386,8 @@ public static Builder builder(DataHolder options) {
*/
@WithSpan("markdown.parse")
public @NotNull Document parse(@NotNull String input) {
Span.current().setAttribute("markdown.input.length", input.length());

DocumentParser documentParser = new DocumentParser(options
, blockParserFactories
, paragraphPreProcessorFactories
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
import com.vladsch.flexmark.util.dependency.DependencyResolver;
import com.vladsch.flexmark.util.dependency.DependentItem;
import com.vladsch.flexmark.util.dependency.DependentItemMap;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.StatusCode;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.annotations.WithSpan;

import java.util.*;
Expand Down Expand Up @@ -72,7 +76,16 @@ public Document postProcess(Document document) {
boolean hadGlobal = false;
for (PostProcessorFactory dependent : stage.dependents) {
if (dependent.affectsGlobalScope()) {
document = dependent.apply(document).processDocument(document);
PostProcessor postProcessor = dependent.apply(document);
Span span = startPostProcessorSpan(postProcessor);
try (Scope ignored = span.makeCurrent()) {
document = postProcessor.processDocument(document);
} catch (Throwable t) {
span.setStatus(StatusCode.ERROR, t.getClass().getSimpleName() + ": " + t.getMessage());
throw t;
} finally {
span.end();
}
hadGlobal = true;
// assume it no longer reflects reality;
classifyingNodeTracker = null;
Expand All @@ -94,28 +107,36 @@ public Document postProcess(Document document) {
}

ReversibleIterable<Node> nodes = classifyingNodeTracker.getCategoryItems(Node.class, dependentNodeTypes.keySet());
for (Node node : nodes) {
if (node.getParent() == null) continue; // was already removed
// now we need to get the bitset for the excluded ancestors of the node, then intersect it with the actual ancestors of this factory
int index;
BitSet nodeAncestors;
BitSet nodeExclusions;
Set<Class<?>> excluded = dependentNodeTypes.get(node.getClass());
if (excluded != null) {
index = classifyingNodeTracker.getItems().indexOf(node);
if (index != -1) {
nodeAncestors = classifyingNodeTracker.getNodeAncestryMap().get(index);
if (nodeAncestors != null) {
nodeExclusions = classifyingNodeTracker.getExclusionSet().indexBitSet(excluded);
nodeExclusions.and(nodeAncestors);
if (!nodeExclusions.isEmpty()) {
// has excluded ancestor
continue;
Span span = startPostProcessorSpan(postProcessor);
try (Scope ignored = span.makeCurrent()) {
for (Node node : nodes) {
if (node.getParent() == null) continue; // was already removed
// now we need to get the bitset for the excluded ancestors of the node, then intersect it with the actual ancestors of this factory
int index;
BitSet nodeAncestors;
BitSet nodeExclusions;
Set<Class<?>> excluded = dependentNodeTypes.get(node.getClass());
if (excluded != null) {
index = classifyingNodeTracker.getItems().indexOf(node);
if (index != -1) {
nodeAncestors = classifyingNodeTracker.getNodeAncestryMap().get(index);
if (nodeAncestors != null) {
nodeExclusions = classifyingNodeTracker.getExclusionSet().indexBitSet(excluded);
nodeExclusions.and(nodeAncestors);
if (!nodeExclusions.isEmpty()) {
// has excluded ancestor
continue;
}
}
}
}
postProcessor.process(classifyingNodeTracker, node);
}
postProcessor.process(classifyingNodeTracker, node);
} catch (Throwable t) {
span.setStatus(StatusCode.ERROR, t.getClass().getSimpleName() + ": " + t.getMessage());
throw t;
} finally {
span.end();
}
}
}
Expand All @@ -125,6 +146,14 @@ public Document postProcess(Document document) {
return document;
}

private static Span startPostProcessorSpan(PostProcessor postProcessor) {
// no-op span unless a Java agent (or the application) has wired GlobalOpenTelemetry
return GlobalOpenTelemetry.getTracer("com.vladsch.flexmark")
.spanBuilder("markdown.parse.post_processor")
.setAttribute("markdown.post_processor.class", postProcessor.getClass().getName())
.startSpan();
}

static DependentItemMap<PostProcessorFactory> prioritizePostProcessors(DependentItemMap<PostProcessorFactory> dependentMap) {
// put globals last
List<DependentItemMap.Entry<Class<?>, DependentItem<PostProcessorFactory>>> prioritized = dependentMap.entries();
Expand Down
Loading