You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

EsJvmOptions.java 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2019 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. package org.sonar.application.command;
  21. import java.io.File;
  22. import java.io.IOException;
  23. import java.nio.charset.StandardCharsets;
  24. import java.nio.file.Files;
  25. import java.util.LinkedHashMap;
  26. import java.util.Map;
  27. import java.util.stream.Collectors;
  28. import org.sonar.process.System2;
  29. public class EsJvmOptions extends JvmOptions<EsJvmOptions> {
  30. private static final String ELASTICSEARCH_JVM_OPTIONS_HEADER = "# This file has been automatically generated by SonarQube during startup.\n" +
  31. "# Please use sonar.search.javaOpts and/or sonar.search.javaAdditionalOpts in sonar.properties to specify jvm options for Elasticsearch\n" +
  32. "\n" +
  33. "# DO NOT EDIT THIS FILE\n" +
  34. "\n";
  35. public EsJvmOptions(File tmpDir) {
  36. this(System2.INSTANCE, tmpDir);
  37. }
  38. EsJvmOptions(System2 system2, File tmpDir) {
  39. super(mandatoryOptions(system2, tmpDir));
  40. }
  41. // this basically writes down the content of jvm.options file distributed in vanilla Elasticsearch package
  42. // with some changes to fit running bundled in SQ
  43. private static Map<String, String> mandatoryOptions(System2 system2, File tmpDir) {
  44. Map<String, String> res = new LinkedHashMap<>(16);
  45. // GC configuration
  46. res.put("-XX:+UseConcMarkSweepGC", "");
  47. res.put("-XX:CMSInitiatingOccupancyFraction=", "75");
  48. res.put("-XX:+UseCMSInitiatingOccupancyOnly", "");
  49. // DNS cache policy
  50. // cache ttl in seconds for positive DNS lookups noting that this overrides the
  51. // JDK security property networkaddress.cache.ttl; set to -1 to cache forever
  52. res.put("-Des.networkaddress.cache.ttl=", "60");
  53. // cache ttl in seconds for negative DNS lookups noting that this overrides the
  54. // JDK security property networkaddress.cache.negative ttl; set to -1 to cache
  55. // forever
  56. res.put("-Des.networkaddress.cache.negative.ttl=", "10");
  57. // optimizations
  58. // pre-touch memory pages used by the JVM during initialization
  59. res.put("-XX:+AlwaysPreTouch", "");
  60. // basic
  61. // explicitly set the stack size
  62. res.put("-Xss1m", "");
  63. // set to headless, just in case
  64. res.put("-Djava.awt.headless=", "true");
  65. // ensure UTF-8 encoding by default (e.g. filenames)
  66. res.put("-Dfile.encoding=", "UTF-8");
  67. // use our provided JNA always versus the system one
  68. res.put("-Djna.nosys=", "true");
  69. // turn off a JDK optimization that throws away stack traces for common
  70. // exceptions because stack traces are important for debugging
  71. res.put("-XX:-OmitStackTraceInFastThrow", "");
  72. // flags to configure Netty
  73. res.put("-Dio.netty.noUnsafe=", "true");
  74. res.put("-Dio.netty.noKeySetOptimization=", "true");
  75. res.put("-Dio.netty.recycler.maxCapacityPerThread=", "0");
  76. // log4j 2
  77. res.put("-Dlog4j.shutdownHookEnabled=", "false");
  78. res.put("-Dlog4j2.disable.jmx=", "true");
  79. // (by default ES 6.6.1 uses variable ${ES_TMPDIR} which is replaced by start scripts. Since we start JAR file
  80. // directly on windows, we specify absolute file as URL (to support space in path) instead
  81. res.put("-Djava.io.tmpdir=", tmpDir.getAbsolutePath());
  82. // heap dumps (enable by default in ES 6.6.1, we don't enable them, no one will analyze them anyway)
  83. // generate a heap dump when an allocation from the Java heap fails
  84. // heap dumps are created in the working directory of the JVM
  85. // res.put("-XX:+HeapDumpOnOutOfMemoryError", "");
  86. // specify an alternative path for heap dumps; ensure the directory exists and
  87. // has sufficient space
  88. // res.put("-XX:HeapDumpPath", "data");
  89. // specify an alternative path for JVM fatal error logs (ES 6.6.1 default is "logs/hs_err_pid%p.log")
  90. res.put("-XX:ErrorFile=", "../logs/es_hs_err_pid%p.log");
  91. // JDK 8 GC logging (by default ES 6.6.1 enables them, we don't want to do that in SQ, no one will analyze them anyway)
  92. // res.put("8:-XX:+PrintGCDetails", "");
  93. // res.put("8:-XX:+PrintGCDateStamps", "");
  94. // res.put("8:-XX:+PrintTenuringDistribution", "");
  95. // res.put("8:-XX:+PrintGCApplicationStoppedTime", "");
  96. // res.put("8:-Xloggc:logs/gc.log", "");
  97. // res.put("8:-XX:+UseGCLogFileRotation", "");
  98. // res.put("8:-XX:NumberOfGCLogFiles", "32");
  99. // res.put("8:-XX:GCLogFileSize", "64m");
  100. // JDK 9+ GC logging
  101. // res.put("9-:-Xlog:gc*,gc+age=trace,safepoint:file=logs/gc.log:utctime,pid,tags:filecount=32,filesize=64m", "");
  102. // due to internationalization enhancements in JDK 9 Elasticsearch need to set the provider to COMPAT otherwise
  103. // time/date parsing will break in an incompatible way for some date patterns and locals
  104. if (system2.isJava9()) {
  105. res.put("-Djava.locale.providers=", "COMPAT");
  106. }
  107. if (system2.isJava10()) {
  108. // temporary workaround for C2 bug with JDK 10 on hardware with AVX-512
  109. res.put("-XX:UseAVX=", "2");
  110. }
  111. return res;
  112. }
  113. public void writeToJvmOptionFile(File file) {
  114. String jvmOptions = getAll().stream().collect(Collectors.joining("\n"));
  115. String jvmOptionsContent = ELASTICSEARCH_JVM_OPTIONS_HEADER + jvmOptions;
  116. try {
  117. Files.write(file.toPath(), jvmOptionsContent.getBytes(StandardCharsets.UTF_8));
  118. } catch (IOException e) {
  119. throw new IllegalStateException("Cannot write Elasticsearch jvm options file", e);
  120. }
  121. }
  122. }