Skip to content
Closed
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) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
#
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
Expand Down Expand Up @@ -32,6 +32,6 @@
#
name=Subscriptions Tab
provider=Oracle Corporation
copyright=Copyright \u00A9 2018, 2022, Oracle and/or its affiliates.
copyright=Copyright \u00A9 2018, 2025, Oracle and/or its affiliates.
description=This feature adds a tab for monitoring existing subscriptions from within the JDK Mission Control Console.
descriptionUrl=http://www.oracle.com/missioncontrol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
#
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
Expand Down Expand Up @@ -32,6 +32,6 @@
#
name=JavaFX Page
provider=Oracle Corporation
copyright=Copyright \u00A9 2018, 2022, Oracle and/or its affiliates.
copyright=Copyright \u00A9 2018, 2025, Oracle and/or its affiliates.
description=This feature adds a page for viewing JDK Flight Recorder data produced by JavaFX.
descriptionUrl=http://www.oracle.com/missioncontrol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
Expand Down Expand Up @@ -451,6 +451,28 @@ protected Predicate<IItem> getPredicate(IMemberAccessor<? extends String, IItem>
}
}

public static class EndsWith extends AttributeValue<String> {
EndsWith(String substring, ICanonicalAccessorFactory<String> attribute) {
super(Kind.ENDS_WITH, attribute, substring);
}

@Override
protected Predicate<IItem> getPredicate(IMemberAccessor<? extends String, IItem> accessor, String substring) {
return PredicateToolkit.endsWith(accessor, substring);
}
}

public static class NotEndsWith extends AttributeValue<String> {
NotEndsWith(String substring, ICanonicalAccessorFactory<String> attribute) {
super(Kind.NOT_ENDS_WITH, attribute, substring);
}

@Override
protected Predicate<IItem> getPredicate(IMemberAccessor<? extends String, IItem> accessor, String substring) {
return PredicateToolkit.not(PredicateToolkit.endsWith(accessor, substring));
}
}

public static class Contains extends AttributeValue<String> {
Contains(String substring, ICanonicalAccessorFactory<String> attribute) {
super(Kind.CONTAINS, attribute, substring);
Expand Down Expand Up @@ -591,6 +613,14 @@ public static IItemFilter contains(ICanonicalAccessorFactory<String> attribute,
return new Contains(substring, attribute);
}

public static IItemFilter endsWith(ICanonicalAccessorFactory<String> attribute, String substring) {
return new EndsWith(substring, attribute);
}

public static IItemFilter notEndsWith(ICanonicalAccessorFactory<String> attribute, String substring) {
return new NotEndsWith(substring, attribute);
}

public static IItemFilter notMatches(ICanonicalAccessorFactory<String> attribute, String regexp) {
return new NotMatches(regexp, attribute);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
Expand Down Expand Up @@ -75,6 +75,8 @@ public enum Kind {
NOT_MATCHES(MATCHES),
CONTAINS,
NOT_CONTAINS(CONTAINS),
ENDS_WITH,
NOT_ENDS_WITH(ENDS_WITH),
LESS,
LESS_OR_EQUAL,
MORE(LESS_OR_EQUAL),
Expand Down Expand Up @@ -161,6 +163,10 @@ public static IItemFilter readFrom(IState memento) {
return ItemFilters.matches(readStringAttribute(memento), memento.getAttribute(KEY_VALUE));
case NOT_MATCHES:
return ItemFilters.notMatches(readStringAttribute(memento), memento.getAttribute(KEY_VALUE));
case ENDS_WITH:
return ItemFilters.endsWith(readStringAttribute(memento), memento.getAttribute(KEY_VALUE));
case NOT_ENDS_WITH:
return ItemFilters.notEndsWith(readStringAttribute(memento), memento.getAttribute(KEY_VALUE));
case CONTAINS:
return ItemFilters.contains(readStringAttribute(memento), memento.getAttribute(KEY_VALUE));
case NOT_CONTAINS:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
Expand Down Expand Up @@ -641,6 +641,29 @@ public boolean test(T o) {
};
}

/**
* Create a predicate that checks if a string value ends with a specified substring.
* <p>
* The predicate takes an input object as argument but the value that is checked is extracted
* from the input object using a member accessor.
*
* @param valueAccessor
* string accessor used to get the value to check from the input type
* @param substring
* the substring to look for
* @return a predicate that tests to {@code true} if the string value contains the substring
*/
public static <T> Predicate<T> endsWith(
final IMemberAccessor<? extends String, T> valueAccessor, final String substring) {
return new Predicate<T>() {
@Override
public boolean test(T o) {
String value = valueAccessor.getMember(o);
return value == null ? false : value.endsWith(substring);
}
};
}

/**
* Compile a regular expression into a pattern if possible. If the expression can't be compiled,
* return a valid pattern that will give 0 matches (at least for single lines).
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
Expand Down Expand Up @@ -32,6 +32,8 @@
*/
package org.openjdk.jmc.flightrecorder.rules.jdk.io;

import static org.openjdk.jmc.common.unit.UnitLookup.PLAIN_TEXT;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;
Expand All @@ -43,6 +45,7 @@
import org.openjdk.jmc.common.item.Aggregators;
import org.openjdk.jmc.common.item.IItem;
import org.openjdk.jmc.common.item.IItemCollection;
import org.openjdk.jmc.common.item.IItemFilter;
import org.openjdk.jmc.common.item.ItemFilters;
import org.openjdk.jmc.common.unit.IQuantity;
import org.openjdk.jmc.common.unit.UnitLookup;
Expand Down Expand Up @@ -72,9 +75,12 @@ public class FileReadRule implements IRule {
Messages.getString(Messages.FileReadRule_CONFIG_WARNING_LIMIT),
Messages.getString(Messages.FileReadRule_CONFIG_WARNING_LIMIT_LONG), UnitLookup.TIMESPAN,
UnitLookup.MILLISECOND.quantity(4000));

public static final TypedPreference<String> EXCLUDED_FILES = new TypedPreference<>("io.file.read.exclude.files", //$NON-NLS-1$
Messages.getString(Messages.FileReadRule_CONFIG_EXCLUDED_FILES),
Messages.getString(Messages.FileReadRule_CONFIG_EXCLUDED_FILES_LONG), PLAIN_TEXT.getPersister(),
".jfr,/proc/self/smaps"); //$NON-NLS-1$
private static final List<TypedPreference<?>> CONFIG_ATTRIBUTES = Arrays
.<TypedPreference<?>> asList(READ_WARNING_LIMIT);
.<TypedPreference<?>> asList(READ_WARNING_LIMIT, EXCLUDED_FILES);
private static final String RESULT_ID = "FileRead"; //$NON-NLS-1$

private static final Map<String, EventAvailability> REQUIRED_EVENTS = RequiredEventsBuilder.create()
Expand Down Expand Up @@ -103,8 +109,10 @@ public class FileReadRule implements IRule {
private IResult getResult(IItemCollection items, IPreferenceValueProvider vp, IResultValueProvider resultProvider) {
IQuantity warningLimit = vp.getPreferenceValue(READ_WARNING_LIMIT);
IQuantity infoLimit = warningLimit.multiply(0.5);
String excludedFiles = vp.getPreferenceValue(EXCLUDED_FILES);

IItemCollection fileReadEvents = items.apply(JdkFilters.FILE_READ);
IItemCollection fileReadEvents = items
.apply(ItemFilters.and(JdkFilters.FILE_READ, createExcludeFilter(excludedFiles)));
IItem longestEvent = fileReadEvents.getAggregate(Aggregators.itemWithMax(JfrAttributes.DURATION));

// Aggregate of all file read events - if null, then we had no events
Expand Down Expand Up @@ -143,6 +151,18 @@ private IResult getResult(IItemCollection items, IPreferenceValueProvider vp, IR
.addResult(LONGEST_READ_TIME, longestDuration).build();
}

private IItemFilter createExcludeFilter(String excludedFiles) {
if (excludedFiles.isBlank()) {
return ItemFilters.all();
}
String[] files = excludedFiles.split(",");
IItemFilter[] filters = new IItemFilter[files.length];
for (int i = 0; i < files.length; i++) {
filters[i] = ItemFilters.notEndsWith(JdkAttributes.IO_PATH, files[i].trim());
}
return ItemFilters.and(filters);
}

static String sanitizeFileName(String fileName) {
if (fileName == null || fileName.isEmpty()) {
return Encode.forHtml(Messages.getString(Messages.General_UNKNOWN_FILE_NAME));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
Expand Down Expand Up @@ -271,6 +271,8 @@ public class Messages {
public static final String FileReadRuleFactory_TEXT_WARN_LONG = "FileReadRuleFactory_TEXT_WARN_LONG"; //$NON-NLS-1$
public static final String FileReadRule_CONFIG_WARNING_LIMIT = "FileReadRule_CONFIG_WARNING_LIMIT"; //$NON-NLS-1$
public static final String FileReadRule_CONFIG_WARNING_LIMIT_LONG = "FileReadRule_CONFIG_WARNING_LIMIT_LONG"; //$NON-NLS-1$
public static final String FileReadRule_CONFIG_EXCLUDED_FILES = "FileReadRule_CONFIG_EXCLUDED_FILES"; //$NON-NLS-1$
public static final String FileReadRule_CONFIG_EXCLUDED_FILES_LONG = "FileReadRule_CONFIG_EXCLUDED_FILES_LONG"; //$NON-NLS-1$
public static final String FileWriteRuleFactory_RULE_NAME = "FileWriteRuleFactory_RULE_NAME"; //$NON-NLS-1$
public static final String FileWriteRuleFactory_TEXT_NO_EVENTS = "FileWriteRuleFactory_TEXT_NO_EVENTS"; //$NON-NLS-1$
public static final String FileWriteRuleFactory_TEXT_OK = "FileWriteRuleFactory_TEXT_OK"; //$NON-NLS-1$
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
#
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
Expand Down Expand Up @@ -271,6 +271,8 @@ FewSampledThreadsRule_TEXT_INFO=There are fewer sampled threads than the total n
FewSampledThreadsRule_TEXT_INFO_LONG={threadsWithEnoughSamples} threads with at least {min.sample.count.per.thread} method samples were found, but the machine has {hwThreads} hardware threads (cores). The application might benefit from a higher level of parallelism. This could also be caused by threads doing something else than running Java code, for example running native code or spending time in the JVM internals.
FileReadRule_CONFIG_WARNING_LIMIT=File read duration warning limit
FileReadRule_CONFIG_WARNING_LIMIT_LONG=The shortest file read duration that should trigger a warning
FileReadRule_CONFIG_EXCLUDED_FILES=Files to exclude
FileReadRule_CONFIG_EXCLUDED_FILES_LONG=The files to exclude. Will do an endsWith check, so can use extensions like .jfr.
FileReadRuleFactory_RULE_NAME=File Read Peak Duration
# {longestReadTime} is a time period
FileReadRuleFactory_TEXT_OK=No long file read pauses were found in this recording (the longest was {longestReadTime}).
Expand Down