Module jdk.jfr
Package jdk.jfr

Class SettingControl



  • public abstract class SettingControl
    extends jdk.jfr.internal.Control
    Base class to extend to create setting controls.

    A naive implementation of a setting control for regular expressions could look like this:

     
     final class RegExpControl extends SettingControl {
       private Pattern pattern = Pattern.compile(".*");
    
       @Override
       public void setValue(String value) {
         this.pattern = Pattern.compile(value);
       }
    
       @Override
       public String combine(Set<String> values) {
         return String.join("|", values);
       }
    
       @Override
       public String getValue() {
         return pattern.toString();
       }
    
       public String matches(String s) {
         return pattern.matcher(s).find();
       }
     }
     
     
    The methods setValue(String), getValue() and combine(Set<String>) are invoked when a setting value changes, which typically happens when a recording is started or stopped. Purpose of the combine(Set<String>)-method is to resolve what value to use if there are multiple recordings going on at the same time.

    The setting control must have a default constructor that can be invoked when the event is being registered.

    To use a setting control with an event, add a method that returns a boolean and takes the setting control as a parameter. Annotate the method with @SettingDefinition. By default the method name will be used as the setting's name, but it can be set explicitly using @Name. If the method returns true, the event will be committed.

    It is recommended that the setValue(String) method updates an efficient data structure that can be checked quickly when the event is committed.

    Example,

     
     abstract class HTTPRequest extends Event {
       @Label("Request URI")
       protected String uri;
    
       @Label("Servlet URI Filter")
       @SettingDefinition
       protected boolean uriFilter(RegExpControl regExp) {
         return regExp.matches(uri);
       }
     }
    
     @Label("HTTP Get Request")
     class HTTPGetRequest extends HTTPRequest {
     }
    
     @Label("HTTP Post Request")
     class HTTPPostRequest extends HTTPRequest {
     }
    
     class ExampleServlet extends HTTPServlet {
       protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
         HTTPGetRequest request = new HTTPGetRequest();
         request.begin();
         request.uri = req.getRequestURI();
         ...
         request.commit();
       }
    
       protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
         HTTPPostRequest request = new HTTPPostRequest();
         request.begin();
         request.uri = req.getRequestURI();
         ...
         request.commit();
       }
     }
     
     
    The event can be filtered by assigning the setting "uriFilter" with the desired regular expressions, in a configuration file or programmatically like this:
     
     Recording r = new Recording();
     r.enable("HTTPGetRequest").with("uriFilter", "https://www.example.com/list/.*");
     r.enable("HTTPPostRequest").with("uriFilter", "https://www.example.com/login/.*");
     r.start();
     
     
    Since:
    9
    See Also:
    SettingDefinition
    • Constructor Detail

      • SettingControl

        protected SettingControl​()
        Constructor for invocation by subclass constructors.
    • Method Detail

      • combine

        public abstract String combine​(Set<String> settingValues)
        If multiple recordings are running at the same time, this method will combine setting values for all running recording into one value.

        The semantics of how setting values should be combined depends on the setting control that is being implemented, but the contract is that all recordings should get at least all the event they asked for.

        This method should have no side effects, since the caller might cache values. This method should never return null or throw an exception. If a value is not valid for this setting control, the value should be ignored.

        Examples,

        if the setting control represents a threshold and three recordings are running at the same time with the setting values "10 ms", "8 s" and "1 ms", this method should return "1 ms" since it means that all recordings would get at least all the data they requested.

        If the setting control represents a set of names and two recordings are running at the same time with the setting values "Hopper, Knuth" and "Knuth, Dijkstra" the returned value should be "Hopper, Knuth, Dijkstra" since it would mean all names would be accepted.

        If the setting control represents a boolean condition and four recordings are running at the same time with the following values "true", "false", "false", "incorrect", this method should return "true", since it would mean all recordings would get at least all the data they requested.

        Specified by:
        combine in class jdk.jfr.internal.Control
        Parameters:
        settingValues - set of values, not null
        Returns:
        the value to use, not null
      • setValue

        public abstract void setValue​(String settingValue)
        Sets the value for this setting.

        If a setting value is not valid for this setting control, this method should not throw an exception. Instead, the value should be ignored.

        Specified by:
        setValue in class jdk.jfr.internal.Control
        Parameters:
        settingValue - string value, not null
      • getValue

        public abstract String getValue​()
        Returns the currently used value for this setting, not null.

        The value returned by this method should be valid as an argument to both setValue(String) and combine(Set).

        This method will be invoked when an event is registered to obtain the default value. It is therefore important that a valid value can be returned right after an instance of this class has been created. It is not valid to return null

        Specified by:
        getValue in class jdk.jfr.internal.Control
        Returns:
        the setting value, not null