Skip to content

Commit

Permalink
chore: replace GA
Browse files Browse the repository at this point in the history
  • Loading branch information
slandelle committed Jul 1, 2022
1 parent 7ccb78c commit 492e77a
Show file tree
Hide file tree
Showing 17 changed files with 205 additions and 114 deletions.
124 changes: 124 additions & 0 deletions gatling-app/src/main/scala/io/gatling/app/Analytics.scala
@@ -0,0 +1,124 @@
/*
* Copyright 2011-2022 GatlingCorp (https://gatling.io)
*
* 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 io.gatling.app

import java.net.{ HttpURLConnection, URL }
import java.nio.charset.StandardCharsets.UTF_8

import scala.util.{ Try, Using }
import scala.util.control.NonFatal

import io.gatling.commons.util.{ GatlingVersion, Java }

object Analytics {

private val ApiKeyDev = "c942a452709b79a25f792ea63b60f2b1"
private val ApiKeyProd = "c82eb1f1552d655a799501ecc8181fca"

def send(simulationClass: SimulationClass, explicitLauncher: Option[String], buildToolVersion: Option[String]): Unit = {

val apiKey = if (GatlingVersion.ThisVersion.isSnapshot) ApiKeyDev else ApiKeyProd
val programmingLanguage = simulationClass match {
case SimulationClass.Java(_) =>
Try {
getClass.getClassLoader.loadClass("kotlin.KotlinVersion")
"kotlin"
}.toOption.getOrElse("java")

case SimulationClass.Scala(_) => "scala"
}
val launcher = explicitLauncher
.orElse(
if (sys.props.get("java.class.path").exists(_.contains("idea"))) {
Some("idea")
} else if (
// eclipse on MacOS
sys.env.get("__CFBundleIdentifier").exists(_.contains("eclipse")) ||
// eclipse on Windows with bundle JRE
sys.props.get("java.library.path").exists(_.contains("eclipse"))
) {
Some("eclipse")
} else {
None
}
)

val userPropertiesBase = Map(
"java_version_major" -> Java.MajorVersion.toString,
"gatling_version_major" -> GatlingVersion.ThisVersion.majorVersion,
"gatling_version_minor" -> GatlingVersion.ThisVersion.minorVersion,
"gatling_version_full" -> GatlingVersion.ThisVersion.fullVersion,
"gatling_version_enterprise" -> GatlingVersion.ThisVersion.isEnterprise,
"programming_language" -> programmingLanguage
)

val launcherProperties = launcher.fold(Map.empty[String, String])(l => Map("launcher" -> l))
val buildToolVersionProperties = buildToolVersion.fold(Map.empty[String, String])(btv => Map("build-tool-version" -> btv))

val jsonUserProperties =
(userPropertiesBase ++ launcherProperties ++ buildToolVersionProperties).map { case (key, value) => s""""$key": "$value"""" }.toSeq.sorted.mkString(",\n")

val bodyBytes =
s"""{
| "api_key":"$apiKey",
| "events":[
| {
| "user_id":"gatling",
| "event_type":"gatling_run",
| "ip":"$$remote",
| "user_properties":{
| $jsonUserProperties
| }
| }
| ]
|}""".stripMargin
.getBytes(UTF_8)

val url = new URL("https://api.eu.amplitude.com/2/httpapi")

val thread = new Thread(() =>
try {
val conn = url.openConnection().asInstanceOf[HttpURLConnection]

try {
conn.setReadTimeout(2000)
conn.setConnectTimeout(2000)
conn.setDoInput(true)
conn.setDoOutput(true)
conn.setUseCaches(false)
conn.setRequestMethod("POST")
conn.setRequestProperty("Connection", "close")
conn.setRequestProperty("Content-Length", bodyBytes.length.toString)

Using.resource(conn.getOutputStream) { os =>
os.write(bodyBytes)
os.flush()

// wait for the response (at least one byte) before closing
conn.getInputStream.read()
}
} finally {
conn.disconnect()
}
} catch {
case NonFatal(_) =>
}
)
thread.setDaemon(true)
thread.start()
}
}
2 changes: 1 addition & 1 deletion gatling-app/src/main/scala/io/gatling/app/Gatling.scala
Expand Up @@ -40,7 +40,7 @@ object Gatling extends StrictLogging {
sys.exit(fromArgs(args, None))
}

// used by maven archetype
// used by Engine
def fromMap(overrides: ConfigOverrides): Int = start(overrides, None)

// used by sbt-test-framework
Expand Down
6 changes: 3 additions & 3 deletions gatling-app/src/main/scala/io/gatling/app/Runner.scala
Expand Up @@ -54,15 +54,15 @@ private[gatling] class Runner(system: ActorSystem, eventLoopGroup: EventLoopGrou

val selection = Selection(forcedSimulationClass, configuration)

if (configuration.http.enableGA) Ga.send(GatlingVersion.ThisVersion.number)
if (configuration.data.enableAnalytics) Analytics.send(selection.simulationClass, configuration.data.launcher, configuration.data.buildToolVersion)

val simulationParams = selection.simulationClass.params(configuration)
logger.trace("Simulation params built")

simulationParams.before()
logger.trace("Before hook executed")

val runMessage = RunMessage(simulationParams.name, selection.simulationId, clock.nowMillis, selection.description, GatlingVersion.ThisVersion.number)
val runMessage = RunMessage(simulationParams.name, selection.simulationId, clock.nowMillis, selection.description, GatlingVersion.ThisVersion.fullVersion)
val statsEngine = newStatsEngine(simulationParams, runMessage)
val throttler = Throttler.newThrottler(system, simulationParams)
val injector = Injector(system, eventLoopGroup, statsEngine, clock)
Expand Down Expand Up @@ -107,7 +107,7 @@ private[gatling] class Runner(system: ActorSystem, eventLoopGroup: EventLoopGrou
protected def displayVersionWarning(): Unit =
GatlingVersion.LatestRelease.foreach { latest =>
if (latest.releaseDate.isAfter(GatlingVersion.ThisVersion.releaseDate)) {
println(s"Gatling ${latest.number} is available! (you're using ${GatlingVersion.ThisVersion.number})")
println(s"Gatling ${latest.fullVersion} is available! (you're using ${GatlingVersion.ThisVersion.fullVersion})")
}
}
}
Expand Up @@ -46,6 +46,12 @@ private[app] class ArgsParser(args: Array[String]) {

opt[String](RunDescription)
.foreach(props.runDescription)

opt[String](Launcher)
.foreach(props.launcher)

opt[String](BuildToolVersion)
.foreach(props.buildToolVersion)
}

def parseArguments: Either[ConfigOverrides, StatusCode] =
Expand Down
Expand Up @@ -42,4 +42,6 @@ private[gatling] object CommandLineConstants {
)
val Simulation = new CommandLineConstant("simulation", "s", "Runs <className> simulation", Some("<className>"))
val RunDescription = new CommandLineConstant("run-description", "rd", "A short <description> of the run to include in the report", Some("<description>"))
val Launcher = new CommandLineConstant("launcher", "l", "The program that launched Gatling", None)
val BuildToolVersion = new CommandLineConstant("build-tool-version", "btv", "The version of the build tool used to launch Gatling", None)
}
Expand Up @@ -25,6 +25,7 @@ import scala.jdk.StreamConverters._
import scala.util.control.NoStackTrace

import io.gatling.bundle.{ BundleIO, CommandArguments }
import io.gatling.commons.util.Java
import io.gatling.plugin.util.Fork

private[commands] object CommandHelper {
Expand All @@ -48,15 +49,6 @@ private[commands] object CommandHelper {
case _ => "java"
}

val javaVersion: Int = {
val javaSpecVersion = System.getProperty("java.specification.version")
(javaSpecVersion.split("\\.").toList match {
case "1" :: major :: _ => major
case major :: _ => major
case _ => throw new IllegalArgumentException(s"Malformed java.specification.version System property value: $javaSpecVersion")
}).toInt
}

def gatlingHome: String = optionEnv("GATLING_HOME").getOrElse {
try {
Paths.get(getClass.getProtectionDomain.getCodeSource.getLocation.toURI).getParent.getParent.toAbsolutePath.toString
Expand All @@ -76,9 +68,9 @@ private[commands] object CommandHelper {
"-XX:MaxInlineLevel=20",
"-XX:MaxTrivialSize=12"
) ++
(if (javaVersion < 9) List("-XX:+UseG1GC") else Nil) ++
(if (javaVersion < 11) List("-XX:+ParallelRefProcEnabled") else Nil) ++
(if (javaVersion < 15) List("-XX:-UseBiasedLocking") else Nil)
(if (Java.MajorVersion < 9) List("-XX:+UseG1GC") else Nil) ++
(if (Java.MajorVersion < 11) List("-XX:+ParallelRefProcEnabled") else Nil) ++
(if (Java.MajorVersion < 15) List("-XX:-UseBiasedLocking") else Nil)

if (Files.notExists(Paths.get(gatlingHome))) {
throw new InvalidGatlingHomeException
Expand Down Expand Up @@ -117,8 +109,8 @@ private[commands] object CommandHelper {
val classPath = gatlingLibs ++ userLibs ++ gatlingConfFiles

val extraJavacOptions = maxJavaVersion match {
case Some(maxVersion) if javaVersion > maxVersion =>
println(s"Currently running on unsupported Java version $javaVersion; Java code will be compiled with the '--release $maxVersion' option")
case Some(maxVersion) if Java.MajorVersion > maxVersion =>
println(s"Currently running on unsupported Java version ${Java.MajorVersion}; Java code will be compiled with the '--release $maxVersion' option")
List("-ejo", s"--release,$maxVersion")
case _ =>
Nil
Expand Down
Expand Up @@ -39,7 +39,7 @@ class OpenSourceRunCommand(config: CommandArguments, args: List[String]) {
"io.gatling.app.Gatling",
classPath.asJava,
runJavaOptions.asJava,
args.asJava,
(args ::: List("-l", "bundle")).asJava,
java,
true,
BundleIO.getLogger,
Expand Down
Expand Up @@ -49,7 +49,7 @@ private[charts] final class SimulationCardComponent(runInfo: RunInfo) extends Co
| <span class="simulation-information-title">Gatling Version</span>
| <span class="simulation-information-item">
| <span class="simulation-information-label">Version: </span>
| <span>${GatlingVersion.ThisVersion.number}</span>
| <span>${GatlingVersion.ThisVersion.fullVersion}</span>
| </span>
| <span class="simulation-information-item">
| <span class="simulation-information-label">Released: </span>
Expand Down
Expand Up @@ -66,12 +66,12 @@ private[charts] abstract class PageTemplate(
val deprecationMessage = GatlingVersion.LatestRelease match {
case Some(GatlingVersion(number, releaseDate)) if releaseDate.isAfter(thisReleaseDatePlus1Year) =>
s"""
|You are using Gatling ${GatlingVersion.ThisVersion.number}
|You are using Gatling ${GatlingVersion.ThisVersion.fullVersion}
| released on ${thisReleaseDate.toLocalDate.toString}, more than 1 year ago.
| Gatling $number is available since ${releaseDate.toLocalDate.toString}.
|""".stripMargin
case None if ZonedDateTime.now(ZoneOffset.UTC).isAfter(thisReleaseDatePlus1Year) =>
s"""You are using Gatling ${GatlingVersion.ThisVersion.number}
s"""You are using Gatling ${GatlingVersion.ThisVersion.fullVersion}
| released on ${thisReleaseDate.toLocalDate.toString}, more than 1 year ago.
|""".stripMargin
case _ =>
Expand Down
83 changes: 0 additions & 83 deletions gatling-commons/src/main/scala/io/gatling/commons/util/Ga.scala

This file was deleted.

Expand Up @@ -43,7 +43,12 @@ object GatlingVersion {
lazy val LatestRelease: Option[GatlingVersion] = LatestGatlingRelease.load()
}

final case class GatlingVersion(number: String, releaseDate: ZonedDateTime)
final case class GatlingVersion(fullVersion: String, releaseDate: ZonedDateTime) {
val minorVersion: String = fullVersion.split("\\.").take(2).mkString(".")
val majorVersion: String = fullVersion.substring(fullVersion.indexOf('.'))
def isSnapshot: Boolean = fullVersion.endsWith("-SNAPSHOT")
def isEnterprise: Boolean = fullVersion.contains(".FL")
}

private object LatestGatlingRelease extends StrictLogging {

Expand Down Expand Up @@ -91,7 +96,7 @@ private object LatestGatlingRelease extends StrictLogging {
lastCheck match {
case FetchResult.Success(_, latestRelease) =>
Prefs.putBoolean(LastCheckSuccessPref, true)
Prefs.put(LatestReleaseNumberPref, latestRelease.number)
Prefs.put(LatestReleaseNumberPref, latestRelease.fullVersion)
Prefs.putLong(LastCheckSuccessPref, latestRelease.releaseDate.toInstant.toEpochMilli)

case _ =>
Expand Down
29 changes: 29 additions & 0 deletions gatling-commons/src/main/scala/io/gatling/commons/util/Java.scala
@@ -0,0 +1,29 @@
/*
* Copyright 2011-2022 GatlingCorp (https://gatling.io)
*
* 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 io.gatling.commons.util

import scala.util.Properties

object Java {
val MajorVersion: Int = {
(Properties.javaSpecVersion.split("\\.").toList match {
case "1" :: major :: _ => major
case major :: _ => major
case _ => throw new IllegalArgumentException(s"Malformed java.specification.version System property value: ${Properties.javaSpecVersion}")
}).toInt
}
}

0 comments on commit 492e77a

Please sign in to comment.