Commit 593635c8 authored by Nikita Kudrin's avatar Nikita Kudrin Committed by intellij-monorepo-bot
Browse files

[unit perf tests] AT-623 Init OpenTelemetry instance on the fly in the tests...

[unit perf tests] AT-623 Init OpenTelemetry instance on the fly in the tests without Test Application

GitOrigin-RevId: e6a71b357828caee96cd25cfa82d9cb4af07f7ec
parent 07de1703
Branches unavailable Tags unavailable
No related merge requests found
Showing with 67 additions and 18 deletions
+67 -18
......@@ -27,6 +27,7 @@ import kotlinx.coroutines.CoroutineName
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.annotations.TestOnly
import java.nio.file.Path
import java.util.concurrent.TimeUnit
import kotlin.coroutines.CoroutineContext
......@@ -38,7 +39,8 @@ import kotlin.coroutines.CoroutineContext
@ApiStatus.Experimental
@ApiStatus.Internal
class TelemetryManagerImpl(coroutineScope: CoroutineScope, isUnitTestMode: Boolean) : TelemetryManager {
// for the unit (performance) tests
// for the unit (performance) tests that use Application
@TestOnly
@Suppress("unused", "DEPRECATION")
constructor() : this(ApplicationManager.getApplication().coroutineScope, ApplicationManager.getApplication().isUnitTestMode)
......@@ -53,7 +55,14 @@ class TelemetryManagerImpl(coroutineScope: CoroutineScope, isUnitTestMode: Boole
init {
verboseMode = System.getProperty("idea.diagnostic.opentelemetry.verbose")?.toBooleanStrictOrNull() == true
val configurator = createOpenTelemetryConfigurator(appInfo = ApplicationInfoImpl.getShadowInstance())
val configurator: OpenTelemetryConfigurator = try {
createOpenTelemetryConfigurator(appInfo = ApplicationInfoImpl.getShadowInstance())
}
catch (e: Throwable) {
createOpenTelemetryConfiguratorForPerfTestWithoutApplication()
}
aggregatedMetricExporter = configurator.aggregatedMetricExporter
otlpService = OtlpService()
......@@ -214,12 +223,18 @@ private fun createSpanExporters(resource: Resource, isUnitTestMode: Boolean = fa
return spanExporters
}
private fun createOpenTelemetryConfigurator(appInfo: ApplicationInfo): OpenTelemetryConfigurator {
private fun createOpenTelemetryConfiguratorForPerfTestWithoutApplication(): OpenTelemetryConfigurator {
return createOpenTelemetryConfigurator("", "", "")
}
private fun createOpenTelemetryConfigurator(serviceName: String,
serviceVersion: String,
serviceNamespace: String): OpenTelemetryConfigurator {
return OpenTelemetryConfigurator(
sdkBuilder = OpenTelemetrySdk.builder(),
serviceName = ApplicationNamesInfo.getInstance().fullProductName,
serviceVersion = appInfo.build.asStringWithoutProductCode(),
serviceNamespace = appInfo.build.productCode,
serviceName = serviceName,
serviceVersion = serviceVersion,
serviceNamespace = serviceNamespace,
enableMetricsByDefault = true,
customResourceBuilder = {
// don't write username to file - it maybe private information
......@@ -228,4 +243,10 @@ private fun createOpenTelemetryConfigurator(appInfo: ApplicationInfo): OpenTelem
}
},
)
}
private fun createOpenTelemetryConfigurator(appInfo: ApplicationInfo): OpenTelemetryConfigurator {
return createOpenTelemetryConfigurator(serviceName = ApplicationNamesInfo.getInstance().fullProductName,
serviceVersion = appInfo.build.asStringWithoutProductCode(),
serviceNamespace = appInfo.build.productCode)
}
\ No newline at end of file
......@@ -109,7 +109,7 @@ private val instance = SynchronizedClearableLazy {
instance
}
internal class NoopTelemetryManager : TelemetryManager {
class NoopTelemetryManager : TelemetryManager {
override var verboseMode: Boolean = false
override fun getTracer(scope: Scope): IJTracer = IJNoopTracer
......
......@@ -3,9 +3,11 @@ package com.intellij.testFramework;
import com.intellij.concurrency.IdeaForkJoinWorkerThreadFactory;
import com.intellij.concurrency.JobSchedulerImpl;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.util.ThrowableComputable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.platform.diagnostic.telemetry.IJTracer;
import com.intellij.platform.diagnostic.telemetry.NoopTelemetryManager;
import com.intellij.platform.diagnostic.telemetry.Scope;
import com.intellij.platform.diagnostic.telemetry.TelemetryManager;
import com.intellij.platform.testFramework.diagnostic.MetricsPublisher;
......@@ -13,12 +15,14 @@ import com.intellij.util.ExceptionUtil;
import com.intellij.util.ThrowableRunnable;
import com.intellij.util.io.StorageLockContext;
import kotlin.reflect.KFunction;
import kotlinx.coroutines.*;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
......@@ -54,12 +58,46 @@ public class PerformanceTestInfo {
@NotNull
private final IJTracer tracer;
private static final CoroutineScope coroutineScope = CoroutineScopeKt.CoroutineScope(
SupervisorKt.SupervisorJob(null).plus(Dispatchers.getIO())
);
static {
// to use JobSchedulerImpl.getJobPoolParallelism() in tests which don't init application
IdeaForkJoinWorkerThreadFactory.setupForkJoinCommonPool(true);
}
/** In case if perf tests don't use Test Application we need to initialize OpenTelemetry without Application */
private static void initOpenTelemetryIfNeeded() {
// Open Telemetry file will be located at ../system/test/log/opentelemetry.json (alongside with open-telemetry-metrics.*.csv)
System.setProperty("idea.diagnostic.opentelemetry.file",
PathManager.getLogDir().resolve("opentelemetry.json").toAbsolutePath().toString());
var telemetryInstance = TelemetryManager.getInstance();
var isNoop = telemetryInstance instanceof NoopTelemetryManager;
// looks like telemetry manager is properly initialized
if (!isNoop) return;
try {
var telemetryClazz = Class.forName("com.intellij.platform.diagnostic.telemetry.impl.TelemetryManagerImpl");
var instance = Arrays.stream(telemetryClazz.getDeclaredConstructors())
.filter((it) -> it.getParameterCount() > 0).findFirst()
.get()
.newInstance(coroutineScope, true);
TelemetryManager.Companion.forceSetTelemetryManager((TelemetryManager)instance);
}
catch (Throwable e) {
System.err.println(
"Couldn't setup TelemetryManager without TestApplication. Either test should use TestApplication or somewhere is a bug");
e.printStackTrace();
}
}
PerformanceTestInfo(@NotNull ThrowableComputable<Integer, ?> test, int expectedMs, int expectedInputSize, @NotNull String what) {
initOpenTelemetryIfNeeded();
this.test = test;
this.expectedMs = expectedMs;
this.expectedInputSize = expectedInputSize;
......@@ -331,7 +369,7 @@ public class PerformanceTestInfo {
}
catch (Throwable t) {
System.err.println("Something unexpected happened during publishing performance metrics");
t.printStackTrace();
throw t;
}
}
}
......
......@@ -4,13 +4,11 @@ package com.intellij.tools.ide.metrics.benchmark
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.intellij.openapi.util.BuildNumber
import com.intellij.testFramework.PlatformTestUtil
import com.intellij.testFramework.TestApplicationManager
import com.intellij.tools.ide.metrics.collector.publishing.CIServerBuildInfo
import com.intellij.tools.ide.metrics.collector.publishing.PerformanceMetricsDto
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInfo
import java.nio.file.Files
......@@ -30,14 +28,6 @@ class SpanExtractionFromUnitPerfTest {
Paths.get(this::class.java.classLoader.getResource("opentelemetry")!!.toURI())
}
companion object {
@JvmStatic
@BeforeAll
fun initTestApplication() {
TestApplicationManager.getInstance()
}
}
@Test
fun unitPerfTestsMetricsExtraction(testInfo: TestInfo) {
val mainMetricName = "simple perf test"
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment