Repository: elastic/rally

Issue:
Adjust flight recorder flags for JDK 11
The [open-source release of Java flight recorder](http://openjdk.java.net/jeps/328) is targeted for JDK 11. As a consequence, the JVM flags to activate Java flight recorder will change (it's not a commercial feature anymore). Also, we can remove the licensing warning that we issue (but only from JDK 11 onwards!) and we should change our documentation accordingly (no need for an Oracle JDK anymore to use Java flight recorder)

Discussion:

Patch:
diff --git a/docs/install.rst b/docs/install.rst
index 1add0799..0389cb11 100644
--- a/docs/install.rst
+++ b/docs/install.rst
@@ -101,9 +101,7 @@ In all other cases, Rally requires ``git 1.9`` or better. Verify with ``git --ve
 JDK
 ~~~
 
-A JDK is required on all machines where you want to launch Elasticsearch. If you use Rally just as a load generator to :doc:`benchmark remote clusters </recipes>`, no JDK is required.
-
-We recommend to use Oracle JDK but you are free to use OpenJDK as well. For details on how to install a JDK check your operating system's documentation pages.
+A JDK is required on all machines where you want to launch Elasticsearch. If you use Rally just as a load generator to :doc:`benchmark remote clusters </recipes>`, no JDK is required. For details on how to install a JDK check your operating system's documentation pages.
 
 To find the JDK, Rally expects the environment variable ``JAVA_HOME`` to be set on all targeted machines. To have more specific control, for example when you want to benchmark across a wide range of Elasticsearch releases, you can also set ``JAVAx_HOME`` where ``x``  is the major version of a JDK (e.g. ``JAVA8_HOME`` would point to a JDK 8 installation). Rally will then choose the highest supported JDK per version of Elasticsearch that is available.
 
diff --git a/docs/telemetry.rst b/docs/telemetry.rst
index d24f0d22..01a7b220 100644
--- a/docs/telemetry.rst
+++ b/docs/telemetry.rst
@@ -31,7 +31,7 @@ You can attach one or more of these telemetry devices to the benchmarked cluster
 jfr
 ---
 
-The ``jfr`` telemetry device enables the `Java Flight Recorder <http://docs.oracle.com/javacomponents/jmc-5-5/jfr-runtime-guide/index.html>`_ on the benchmark candidate. Java Flight Recorder ships only with Oracle JDK, so Rally assumes that Oracle JDK is used for benchmarking.
+The ``jfr`` telemetry device enables the `Java Flight Recorder <http://docs.oracle.com/javacomponents/jmc-5-5/jfr-runtime-guide/index.html>`_ on the benchmark candidate. Up to JDK 11, Java flight recorder ships only with Oracle JDK, so Rally assumes that Oracle JDK is used for benchmarking. If you run benchmarks on JDK 11 or later, Java flight recorder is also available on OpenJDK.
 
 To enable ``jfr``, invoke Rally with ``esrally --telemetry jfr``. ``jfr`` will then write a flight recording file which can be opened in `Java Mission Control <http://www.oracle.com/technetwork/java/javaseproducts/mission-control/java-mission-control-1998576.html>`_. Rally prints the location of the flight recording file on the command line.
 
@@ -44,7 +44,7 @@ Supported telemetry parameters:
 
 .. note::
 
-   The licensing terms of Java flight recorder do not allow you to run it in production environments without a valid license (for details, refer to the `Oracle Java SE Advanced & Suite Products page <http://www.oracle.com/technetwork/java/javaseproducts/overview/index.html>`_). However, running in a QA environment is fine.
+   Up to JDK 11 Java flight recorder ship only with Oracle JDK and the licensing terms do not allow you to run it in production environments without a valid license (for details, refer to the `Oracle Java SE Advanced & Suite Products page <http://www.oracle.com/technetwork/java/javaseproducts/overview/index.html>`_). However, running in a QA environment is fine.
 
 jit
 ---
diff --git a/esrally/mechanic/telemetry.py b/esrally/mechanic/telemetry.py
index e1d750ec..e5f5316f 100644
--- a/esrally/mechanic/telemetry.py
+++ b/esrally/mechanic/telemetry.py
@@ -143,7 +143,7 @@ class FlightRecorder(TelemetryDevice):
     internal = False
     command = "jfr"
     human_name = "Flight Recorder"
-    help = "Enables Java Flight Recorder (requires an Oracle JDK)"
+    help = "Enables Java Flight Recorder (requires an Oracle JDK or OpenJDK 11+)"
 
     def __init__(self, telemetry_params, log_root, java_major_version):
         super().__init__()
@@ -155,15 +155,17 @@ class FlightRecorder(TelemetryDevice):
         io.ensure_dir(self.log_root)
         log_file = "%s/%s-%s.jfr" % (self.log_root, car.safe_name, candidate_id)
 
-        console.println("\n***************************************************************************\n")
-        console.println("[WARNING] Java flight recorder is a commercial feature of the Oracle JDK.\n")
-        console.println("You are using Java flight recorder which requires that you comply with\nthe licensing terms stated in:\n")
-        console.println(console.format.link("http://www.oracle.com/technetwork/java/javase/terms/license/index.html"))
-        console.println("\nBy using this feature you confirm that you comply with these license terms.\n")
-        console.println("Otherwise, please abort and rerun Rally without the \"jfr\" telemetry device.")
-        console.println("\n***************************************************************************\n")
+        # JFR was integrated into OpenJDK 11 and is not a commercial feature anymore.
+        if self.java_major_version < 11:
+            console.println("\n***************************************************************************\n")
+            console.println("[WARNING] Java flight recorder is a commercial feature of the Oracle JDK.\n")
+            console.println("You are using Java flight recorder which requires that you comply with\nthe licensing terms stated in:\n")
+            console.println(console.format.link("http://www.oracle.com/technetwork/java/javase/terms/license/index.html"))
+            console.println("\nBy using this feature you confirm that you comply with these license terms.\n")
+            console.println("Otherwise, please abort and rerun Rally without the \"jfr\" telemetry device.")
+            console.println("\n***************************************************************************\n")
 
-        time.sleep(3)
+            time.sleep(3)
 
         console.info("%s: Writing flight recording to [%s]" % (self.human_name, log_file), logger=self.logger)
 
@@ -174,7 +176,10 @@ class FlightRecorder(TelemetryDevice):
 
     def java_opts(self, log_file):
         recording_template = self.telemetry_params.get("recording-template")
-        java_opts = "-XX:+UnlockDiagnosticVMOptions -XX:+UnlockCommercialFeatures -XX:+DebugNonSafepoints "
+        java_opts = "-XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints "
+
+        if self.java_major_version < 11:
+            java_opts += "-XX:+UnlockCommercialFeatures "
 
         if self.java_major_version < 9:
             java_opts += "-XX:+FlightRecorder "


Test patch:
diff --git a/tests/mechanic/telemetry_test.py b/tests/mechanic/telemetry_test.py
index 82a30ad4..8cc9344f 100644
--- a/tests/mechanic/telemetry_test.py
+++ b/tests/mechanic/telemetry_test.py
@@ -166,14 +166,21 @@ class JfrTests(TestCase):
     def test_sets_options_for_pre_java_9_default_recording_template(self):
         jfr = telemetry.FlightRecorder(telemetry_params={}, log_root="/var/log", java_major_version=random.randint(0, 8))
         java_opts = jfr.java_opts("/var/log/test-recording.jfr")
-        self.assertEqual("-XX:+UnlockDiagnosticVMOptions -XX:+UnlockCommercialFeatures -XX:+DebugNonSafepoints -XX:+FlightRecorder "
+        self.assertEqual("-XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints -XX:+UnlockCommercialFeatures -XX:+FlightRecorder "
                          "-XX:FlightRecorderOptions=disk=true,maxage=0s,maxsize=0,dumponexit=true,"
                          "dumponexitpath=/var/log/test-recording.jfr -XX:StartFlightRecording=defaultrecording=true", java_opts)
 
-    def test_sets_options_for_java_9_or_above_default_recording_template(self):
-        jfr = telemetry.FlightRecorder(telemetry_params={}, log_root="/var/log", java_major_version=random.randint(9, 999))
+    def test_sets_options_for_java_9_or_10_default_recording_template(self):
+        jfr = telemetry.FlightRecorder(telemetry_params={}, log_root="/var/log", java_major_version=random.randint(9, 10))
         java_opts = jfr.java_opts("/var/log/test-recording.jfr")
-        self.assertEqual("-XX:+UnlockDiagnosticVMOptions -XX:+UnlockCommercialFeatures -XX:+DebugNonSafepoints "
+        self.assertEqual("-XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints -XX:+UnlockCommercialFeatures "
+                         "-XX:StartFlightRecording=maxsize=0,maxage=0s,disk=true,dumponexit=true,filename=/var/log/test-recording.jfr",
+                         java_opts)
+
+    def test_sets_options_for_java_11_or_above_default_recording_template(self):
+        jfr = telemetry.FlightRecorder(telemetry_params={}, log_root="/var/log", java_major_version=random.randint(11, 999))
+        java_opts = jfr.java_opts("/var/log/test-recording.jfr")
+        self.assertEqual("-XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints "
                          "-XX:StartFlightRecording=maxsize=0,maxage=0s,disk=true,dumponexit=true,filename=/var/log/test-recording.jfr",
                          java_opts)
 
@@ -182,17 +189,27 @@ class JfrTests(TestCase):
                                        log_root="/var/log",
                                        java_major_version=random.randint(0, 8))
         java_opts = jfr.java_opts("/var/log/test-recording.jfr")
-        self.assertEqual("-XX:+UnlockDiagnosticVMOptions -XX:+UnlockCommercialFeatures -XX:+DebugNonSafepoints -XX:+FlightRecorder "
+        self.assertEqual("-XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints -XX:+UnlockCommercialFeatures -XX:+FlightRecorder "
                          "-XX:FlightRecorderOptions=disk=true,maxage=0s,maxsize=0,dumponexit=true,"
                          "dumponexitpath=/var/log/test-recording.jfr -XX:StartFlightRecording=defaultrecording=true,settings=profile",
                          java_opts)
 
-    def test_sets_options_for_java_9_or_above_custom_recording_template(self):
+    def test_sets_options_for_java_9_or_10_custom_recording_template(self):
+        jfr = telemetry.FlightRecorder(telemetry_params={"recording-template": "profile"},
+                                       log_root="/var/log",
+                                       java_major_version=random.randint(9, 10))
+        java_opts = jfr.java_opts("/var/log/test-recording.jfr")
+        self.assertEqual("-XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints -XX:+UnlockCommercialFeatures "
+                         "-XX:StartFlightRecording=maxsize=0,maxage=0s,disk=true,dumponexit=true,"
+                         "filename=/var/log/test-recording.jfr,settings=profile",
+                         java_opts)
+
+    def test_sets_options_for_java_11_or_above_custom_recording_template(self):
         jfr = telemetry.FlightRecorder(telemetry_params={"recording-template": "profile"},
                                        log_root="/var/log",
-                                       java_major_version=random.randint(9, 999))
+                                       java_major_version=random.randint(11, 999))
         java_opts = jfr.java_opts("/var/log/test-recording.jfr")
-        self.assertEqual("-XX:+UnlockDiagnosticVMOptions -XX:+UnlockCommercialFeatures -XX:+DebugNonSafepoints "
+        self.assertEqual("-XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints "
                          "-XX:StartFlightRecording=maxsize=0,maxage=0s,disk=true,dumponexit=true,"
                          "filename=/var/log/test-recording.jfr,settings=profile",
                          java_opts)