org.gradle.performance.fixture.YourKitProfiler.groovy Maven / Gradle / Ivy
Show all versions of gradle-api Show documentation
/*
* Copyright 2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gradle.performance.fixture
import groovy.transform.CompileDynamic
import groovy.transform.CompileStatic
import org.gradle.internal.os.OperatingSystem
/**
*
* Helper class for adding Yourkit Java Profiler (YJP) agent start up arguments for builds launched in performance tests.
*
* Currently, YJP_HOME environment variable or YJP_AGENT_PATH environment variable is used to locate the agent library file. This is not needed if you install YJP in /opt/yjp on Linux
* or rename the application as "yjp" on Mac OS X (directory: /Applications/yjp.app). These locations are searched by default.
*
*
* Examples of specifying YJP_HOME
*
* export YJP_HOME="/opt/yjp" # on linux
* export YJP_HOME="/Applications/yjp.app/Contents/Resources" # on Mac OS X
*
*
*
* Examples of specifying YJP_AGENT_PATH directly
*
* export YJP_AGENT_PATH="/opt/yjp/bin/linux-x86-64/libyjpagent.so" # on linux
* export YJP_AGENT_PATH="/Applications/yjp.app/Contents/Resources/bin/mac/libyjpagent.jnilib" # on Mac OS X
*
*
*
* If you profile on Windows, you will have to add YJP_AGENT_PATH environment variable pointing to the yjpagent.dll file (YJP installation directory\bin\win64\yjpagent.dll).
*
*
* Performance tests extending {@link org.gradle.performance.AbstractCrossBuildPerformanceTest} or {@link org.gradle.performance.AbstractCrossVersionPerformanceTest} will add
* YJP agent parameters to the Gradle build process when you add {@code -Porg.gradle.performance.use_yourkit } parameter to the command line. You can also enable the YourKit
* profiler by adding -Dorg.gradle.performance.use_yourkit=1 to the VM options from IntelliJ.
*
*
* Example of running a single performance test with YJP agent options:
*
* ./gradlew performance:performanceTest -Porg.gradle.performance.use_yourkit -D:performance:performanceTest.single=NativePreCompiledHeaderPerformanceTest
*
*
*
* By default, YJP will create a snapshot in ~/Snapshots when the profiled process terminates. The file name contains the test project name and display name from the performance test.
*
*
* This integration reads YourKit agent options from {@code ~/.gradle/yourkit.properties} file. YourKit startup options
*
*
* Example settings for tracing profiling
*
* tracing=true
* disablealloc=true
* monitors=true
* probe_disable=*
* delay=0
*
*
* Tweak tracing settings in {@code ~/.yjp/tracing.txt}, tracing.txt reference
* useful setting is "adaptive=false" to trace all method calls.
*
* Example settings for sampling profiling
*
* sampling=true
* disablealloc=true
* monitors=true
* probe_disable=*
* delay=0
*
*
* Tweak sampling settings in {@code ~/.yjp/sampling.txt}, sampling.txt reference
* useful setting is "sampling_period_ms", which is 20 ms by default.
*
* Example settings for call counting profiling
*
* call_counting=true
* disablealloc=true
* monitors=true
* probe_disable=*
* delay=0
*
*
*
* Defaults are currently:
*
* sampling=true
* disablealloc=true
* monitors=true
* probe_disable=*
* delay=0
*
*/
@CompileStatic
class YourKitProfiler implements Profiler {
private static final String USE_YOURKIT = "org.gradle.performance.use_yourkit"
private static final Set NO_ARGS_OPTIONS =
['onlylocal', 'united_log', 'sampling', 'tracing', 'call_counting', 'allocsampled', 'monitors', 'disablestacktelemetry', 'disableexceptiontelemetry', 'disableoomedumper', 'disablealloc', 'disabletracing', 'disableall'] as Set
private static final File DEFAULT_YOURKIT_PROPERTIES_FILE = new File(System.getProperty("user.home"), ".gradle/yourkit.properties")
private String yjpAgentPath
private String yjpHome
private OperatingSystem operatingSystem
public YourKitProfiler() {
this(System.getenv("YJP_AGENT_PATH"), System.getenv("YJP_HOME"), OperatingSystem.current())
}
public YourKitProfiler(String yjpAgentPath, String yjpHome, OperatingSystem operatingSystem) {
this.yjpAgentPath = yjpAgentPath
this.yjpHome = yjpHome
this.operatingSystem = operatingSystem
}
@CompileDynamic
public static Map loadProperties(File yourkitPropertiesFile) {
Map yourkitOptions
if (yourkitPropertiesFile.exists()) {
Properties yourkitProperties = new Properties()
yourkitPropertiesFile.withInputStream {
yourkitProperties.load(it)
}
yourkitOptions = [:] + yourkitProperties
} else {
yourkitOptions = [sampling : true,
disablealloc : true,
monitors : true,
probe_disable: '*']
}
yourkitOptions
}
@Override
void addProfilerDefaults(GradleInvocationSpec.InvocationBuilder invocation) {
if (System.getProperty(USE_YOURKIT)) {
invocation.useProfiler().profilerOpts(loadProperties())
}
}
@Override
List profilerArguments(Map yourkitOptions) {
String resolvedYjpAgentPath = locateYjpAgent()
String yjpAgentOptions = buildYjpAgentOptionsString(yourkitOptions)
return [ "-agentpath:$resolvedYjpAgentPath=$yjpAgentOptions".toString() ]
}
public Map loadProperties() {
loadProperties(DEFAULT_YOURKIT_PROPERTIES_FILE)
}
private String buildYjpAgentOptionsString(Map yourkitOptions) {
def yjpOptionsStringBuilder = new StringBuilder()
if (yourkitOptions) {
yourkitOptions.each { k, v ->
String optionName = k.toString()
String optionValue = v?.toString()
if (yjpOptionsStringBuilder.length() > 0) {
yjpOptionsStringBuilder.append(',')
}
yjpOptionsStringBuilder.append(optionName)
if (!NO_ARGS_OPTIONS.contains(optionName)) {
yjpOptionsStringBuilder.append('=')
yjpOptionsStringBuilder.append(optionValue)
}
}
}
if (yjpOptionsStringBuilder.length() == 0) {
throw new IllegalArgumentException("You must specify some YourKit agent options.")
}
yjpOptionsStringBuilder.toString()
}
private String locateYjpAgent() {
String resolvedYjpAgentPath = yjpAgentPath
if (!resolvedYjpAgentPath) {
def resolvedYjpHome = yjpHome
if (!resolvedYjpHome) {
if (operatingSystem.isMacOsX()) {
resolvedYjpHome = "/Applications/yjp.app/Contents/Resources"
} else {
resolvedYjpHome = "/opt/yjp"
}
}
if (operatingSystem.isMacOsX()) {
resolvedYjpAgentPath = "$resolvedYjpHome/bin/mac/libyjpagent.jnilib"
} else {
resolvedYjpAgentPath = "$resolvedYjpHome/bin/linux-x86-64/libyjpagent.so"
}
}
if (!resolvedYjpAgentPath || !new File(resolvedYjpAgentPath).isFile()) {
throw new IllegalStateException("Cannot find YourKit agent library ($resolvedYjpAgentPath). Add YJP_AGENT_PATH environment variable that points to Yourkit JVM agent library or add YJP_HOME environment variable that points to Yourkit installation directory.")
}
resolvedYjpAgentPath
}
}