Skip to content

8359242: JFR: Missing help text for method trace and timing #25899

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: jdk25
Choose a base branch
from
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
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -107,6 +107,13 @@ final String getContent() {
return content;
}

final String getContentOrEmptyQuote() {
if (content == null || content.isEmpty()) {
return "\"\"";
}
return content;
}

final void addListener(XmlElement listener) {
listeners.add(listener);
listener.addProducer(this);
Expand Down
26 changes: 22 additions & 4 deletions src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/XmlText.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand All @@ -24,6 +24,8 @@
*/
package jdk.jfr.internal.jfc.model;

import jdk.jfr.internal.tracing.Filter;

// Corresponds to <text>
final class XmlText extends XmlInput {

Expand All @@ -35,7 +37,7 @@ public String getOptionSyntax() {
sb.append(getContentType().orElse("text"));
sb.append(">");
sb.append(" (");
String content = getContent();
String content = getContentOrEmptyQuote();
if (isTimespan()) {
// "20 ms" becomes "20ms"
content = content.replaceAll("\\s", "");
Expand All @@ -57,7 +59,7 @@ public void configure(String value) {
@Override
public void configure(UserInterface ui) throws AbortException {
ui.println();
ui.println(getLabel() + ": " + getContent() + " (default)");
ui.println(getLabel() + ": " + getContentOrEmptyQuote() + " (default)");
while (!readInput(ui)) {
;
}
Expand All @@ -71,9 +73,21 @@ protected Result evaluate() {
private boolean readInput(UserInterface ui) throws AbortException {
String line = ui.readLine();
if (line.isBlank()) {
ui.println("Using default: " + getContent());
ui.println("Using default: " + getContentOrEmptyQuote());
return true;
}
if (isMethodFilter()) {
if (!Filter.isValid(line)) {
ui.println("""
Not a valid method filter. A filter can be an annotation \
(@jakarta.ws.rs.GET), a full qualified class name (com.example.Foo), \
a fully qualified method reference (java.lang.HashMap::resize) or a \
class initializer (::<clinit>). Use <init> for constructors. \
Separate multiple filters with semicolon.\
""");
return false;
}
}
if (isTimespan()) {
try {
line = Utilities.parseTimespan(line);
Expand All @@ -90,4 +104,8 @@ private boolean readInput(UserInterface ui) throws AbortException {
private boolean isTimespan() {
return getContentType().orElse("text").equals("timespan");
}

private boolean isMethodFilter() {
return getContentType().orElse("text").equals("method-filter");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import jdk.jfr.internal.PlatformEventType;
import jdk.jfr.internal.Type;
import jdk.jfr.internal.tracing.Modification;
import jdk.jfr.internal.tracing.Filter;
import jdk.jfr.internal.tracing.PlatformTracer;

@MetadataDefinition
Expand All @@ -47,8 +48,9 @@ public MethodSetting(PlatformEventType eventType, Modification modification, Str
this.modification = modification;
}

@Override
public boolean isValid(String text) {
return PlatformTracer.isValidFilter(text);
return Filter.isValid(text);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@
* Class that represents the filter a user can specify for the MethodTrace and
* MethodTiming event.
*/
record Filter(String className, String methodName, String annotationName, Modification modification) {
public record Filter(String className, String methodName, String annotationName, Modification modification) {

public static boolean isValid(String filter) {
return of(filter, Modification.NONE) != null;
}

static Filter of(String filter, Modification modification) {
if (filter.startsWith("@")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,6 @@ public static void addTiming(long id, long duration) {
}
}

public static boolean isValidFilter(String text) {
return Filter.of(text, null) != null;
}

public static void setFilters(Modification modification, List<String> filters) {
ensureInitialized();
publishClasses(applyFilter(modification, filters));
Expand Down
6 changes: 4 additions & 2 deletions src/jdk.jfr/share/conf/jfr/default.jfc
Original file line number Diff line number Diff line change
Expand Up @@ -1189,9 +1189,11 @@

<text name="locking-threshold" label="Locking Threshold" contentType="timespan" minimum="0 s">20 ms</text>

<text name="method-timing" label="Method Timing" contentType="text"></text>
<text name="method-timing" label="Method Timing Filter" contentType="method-filter"
description="A filter can be an annotation (@jakarta.ws.rs.GET), a full qualified class name (com.example.Foo), a fully qualified method reference (java.lang.HashMap::resize) or a class initializer (::&lt;clinit&gt;). Use &lt;init&gt; for constructors. Separate multiple filters with semicolon."></text>

<text name="method-trace" label="Method Trace" contentType="text"></text>
<text name="method-trace" label="Method Trace Filter" contentType="method-filter"
description="A filter can be an annotation (@jakarta.ws.rs.GET), a full qualified class name (com.example.Foo), a fully qualified method reference (java.lang.HashMap::resize) or a class initializer (::&lt;clinit&gt;). Use &lt;init&gt; for constructors. Separate multiple filters with semicolon."></text>

<flag name="class-loading" label="Class Loading">false</flag>
</control>
Expand Down
6 changes: 4 additions & 2 deletions src/jdk.jfr/share/conf/jfr/profile.jfc
Original file line number Diff line number Diff line change
Expand Up @@ -1188,9 +1188,11 @@

<text name="locking-threshold" label="Locking Threshold" contentType="timespan" minimum="0 s">10 ms</text>

<text name="method-timing" label="Method Timing" contentType="text"></text>
<text name="method-timing" label="Method Timing Filter" contentType="method-filter"
description="A filter can be an annotation (@jakarta.ws.rs.GET), a full qualified class name (com.example.Foo), a fully qualified method reference (java.lang.HashMap::resize) or a class initializer (::&lt;clinit&gt;). Use &lt;init&gt; for constructors. Separate multiple filters with semicolon."></text>

<text name="method-trace" label="Method Trace" contentType="text"></text>
<text name="method-trace" label="Method Trace Filter" contentType="method-filter"
description="A filter can be an annotation (@jakarta.ws.rs.GET), a full qualified class name (com.example.Foo), a fully qualified method reference (java.lang.HashMap::resize) or a class initializer (::&lt;clinit&gt;). Use &lt;init&gt; for constructors. Separate multiple filters with semicolon."></text>

<flag name="class-loading" label="Class Loading">false</flag>
</control>
Expand Down