mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-15 02:59:33 +07:00
Provide method for extracting startup metrics
GitOrigin-RevId: 723e10d55e4128785ad46f266995934cbcd76231
This commit is contained in:
committed by
intellij-monorepo-bot
parent
f8f5f0df90
commit
8bf1ee0f74
@@ -7,7 +7,7 @@ import com.intellij.tools.ide.util.common.withRetry
|
||||
import java.io.File
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
|
||||
class OpentelemetryJsonParser(private val spanFilter: SpanFilter) {
|
||||
open class OpentelemetryJsonParser(private val spanFilter: SpanFilter) {
|
||||
|
||||
private fun getSpans(file: File): JsonNode {
|
||||
val spanData: JsonNode? = withRetry(messageOnFailure = "Failure during spans extraction from OpenTelemetry json file",
|
||||
@@ -58,7 +58,7 @@ class OpentelemetryJsonParser(private val spanFilter: SpanFilter) {
|
||||
return result.asSequence()
|
||||
}
|
||||
|
||||
private fun processChild(result: MutableSet<SpanElement>, parent: SpanElement, index: Map<String, Collection<SpanElement>>) {
|
||||
protected open fun processChild(result: MutableSet<SpanElement>, parent: SpanElement, index: Map<String, Collection<SpanElement>>) {
|
||||
index[parent.spanId]?.forEach {
|
||||
if (parent.isWarmup) {
|
||||
it.isWarmup = true
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.intellij.tools.ide.metrics.collector.telemetry
|
||||
|
||||
class OpentelemetryJsonParserWithChildrenFiltering(spanFilter: SpanFilter, private val childFilter: SpanFilter) : OpentelemetryJsonParser(spanFilter){
|
||||
override fun processChild(result: MutableSet<SpanElement>, parent: SpanElement, index: Map<String, Collection<SpanElement>>) {
|
||||
index[parent.spanId]?.forEach {
|
||||
if (parent.isWarmup) {
|
||||
it.isWarmup = true
|
||||
}
|
||||
if (!childFilter.filter(it)) {
|
||||
return@forEach
|
||||
}
|
||||
result.add(it)
|
||||
processChild(result, it, index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,6 +86,27 @@ fun getSpansMetricsMap(file: File,
|
||||
return spanToMetricMap
|
||||
}
|
||||
|
||||
fun getMetricsForStartup(file: File): List<Metric> {
|
||||
val spansToPublish = listOf("bootstrap", "startApplication", "ProjectImpl container")
|
||||
val spansSuffixesToIgnore = listOf(": scheduled", ": completing")
|
||||
val filter = SpanFilter.containsIn(spansToPublish)
|
||||
val childFilter = SpanFilter { span -> spansSuffixesToIgnore.none { span.name.endsWith(it) } }
|
||||
|
||||
val spanElements = OpentelemetryJsonParserWithChildrenFiltering(filter, childFilter).getSpanElements(file)
|
||||
val startTime = spanElements.first { it.name == "bootstrap" }.startTimestamp
|
||||
val spansWithoutDuplicatedNames = spanElements.groupBy { it.name }.filter { it.value.size == 1 }.flatMap { it.value }
|
||||
|
||||
val metricSpanProcessor = MetricSpanProcessor()
|
||||
val spanToMetricMap = spansWithoutDuplicatedNames.mapNotNull { metricSpanProcessor.process(it) }.groupBy { it.metric.id.name }
|
||||
|
||||
val spanElementsWithoutRoots = spansWithoutDuplicatedNames.filterNot { it.name in spansToPublish }
|
||||
val startMetrics = spanElementsWithoutRoots.map { span -> Metric(Duration(span.name + ".start"), span.startTimestamp - startTime) }
|
||||
val endMetrics = spanElementsWithoutRoots.map { span ->
|
||||
Metric(Duration(span.name + ".end"), span.startTimestamp - startTime + span.duration)
|
||||
}
|
||||
return combineMetrics(spanToMetricMap) + startMetrics + endMetrics
|
||||
}
|
||||
|
||||
private fun combineMetrics(metrics: Map<String, List<MetricWithAttributes>>): List<Metric> {
|
||||
val result = mutableListOf<Metric>()
|
||||
metrics.forEach { entry ->
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -3,11 +3,14 @@ package com.intellij.tools.ide.metrics.collector
|
||||
import com.intellij.tools.ide.metrics.collector.metrics.PerformanceMetrics.Metric
|
||||
import com.intellij.tools.ide.metrics.collector.metrics.PerformanceMetrics.MetricId.Counter
|
||||
import com.intellij.tools.ide.metrics.collector.metrics.PerformanceMetrics.MetricId.Duration
|
||||
import com.intellij.tools.ide.metrics.collector.telemetry.getMetricsBasedOnDiffBetweenSpans
|
||||
import com.intellij.tools.ide.metrics.collector.telemetry.getMetricsFromSpanAndChildren
|
||||
import com.intellij.tools.ide.metrics.collector.telemetry.SpanFilter
|
||||
import com.intellij.tools.ide.metrics.collector.telemetry.getMetricsBasedOnDiffBetweenSpans
|
||||
import com.intellij.tools.ide.metrics.collector.telemetry.getMetricsForStartup
|
||||
import com.intellij.tools.ide.metrics.collector.telemetry.getMetricsFromSpanAndChildren
|
||||
import io.kotest.matchers.collections.shouldContain
|
||||
import io.kotest.matchers.collections.shouldContainAll
|
||||
import io.kotest.matchers.collections.shouldContainExactlyInAnyOrder
|
||||
import io.kotest.matchers.collections.shouldHaveSize
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.nio.file.Paths
|
||||
import kotlin.io.path.div
|
||||
@@ -19,6 +22,20 @@ class OpenTelemetryTest {
|
||||
Paths.get(this::class.java.classLoader.getResource("opentelemetry")!!.toURI())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun startupMetricsCollected(){
|
||||
val file = (openTelemetryReports / "startup.json").toFile()
|
||||
val result = getMetricsForStartup(file)
|
||||
result.shouldHaveSize(560)
|
||||
result.shouldContain(Metric(Duration("bootstrap"), 58))
|
||||
result.shouldContain(Metric(Duration("startApplication"), 3036))
|
||||
result.shouldContain(Metric(Duration("status bar pre-init"), 136))
|
||||
result.shouldContain(Metric(Duration("status bar pre-init.start"), 1584))
|
||||
result.shouldContain(Metric(Duration("status bar pre-init.end"), 1584 + 136))
|
||||
result.filter { it.id.name.contains(": scheduling") }.shouldHaveSize(0)
|
||||
result.filter { it.id.name.contains(": completing") }.shouldHaveSize(0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testContainsInFilter() {
|
||||
val spanNames = listOf("%findUsages", "run activity")
|
||||
|
||||
Reference in New Issue
Block a user