Skip to content

Commit

Permalink
Remove Tracks-related networking code. Introduce AppsMetric networkin…
Browse files Browse the repository at this point in the history
…g contract.

Also, attach SHA-1 of user name.
  • Loading branch information
wzieba committed Oct 31, 2023
1 parent f676597 commit afc1a24
Show file tree
Hide file tree
Showing 12 changed files with 162 additions and 83 deletions.
1 change: 0 additions & 1 deletion example/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@ plugins {
tracks {
automatticProject.set(io.github.wzieba.tracks.plugin.TracksExtension.AutomatticProject.WooCommerce)
enabled.set(true)
customEventName.set("test_gradle_plugin")
}
1 change: 1 addition & 0 deletions example/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
appsMetricsToken = foobar
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,26 @@ class BuildReporter(
) {

@Suppress("TooGenericExceptionCaught")
fun report(buildData: BuildData, username: String?, customEventName: String?) {
fun report(buildData: BuildData, username: String) {
try {
reportMeasured(buildData, username, customEventName)
reportMeasured(buildData, username)
} catch (ex: Exception) {
logger.warn("$FAILURE_ICON Build time reporting failed: $ex")
}
}

private fun reportMeasured(buildData: BuildData, username: String?, customEventName: String?) {
private fun reportMeasured(buildData: BuildData, username: String) {
val start = nowMillis()

reportInternal(buildData, username, customEventName)
reportInternal(buildData, username)

val reportingOverhead = nowMillis() - start
logger.info("Reporting overhead: $reportingOverhead ms.")
}

private fun reportInternal(
buildData: BuildData,
username: String?,
customEventName: String?,
) {
private fun reportInternal(buildData: BuildData, username: String) {
runBlocking {
analyticsReporter.report(logger, buildData, username, customEventName)
analyticsReporter.report(logger, buildData, username)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.github.wzieba.tracks.plugin

import org.codehaus.groovy.runtime.EncodingGroovyMethods
import org.gradle.BuildListener
import org.gradle.BuildResult
import org.gradle.api.initialization.IncludedBuild
Expand Down Expand Up @@ -31,11 +32,13 @@ internal class BuildTimeListener(
tracksExtension.automatticProject.get(),
includedBuilds.map(IncludedBuild::getName)
)
val encodedUser = System.getProperty("user.name")?.let {
EncodingGroovyMethods.digest(it, "SHA-1")
}

buildReporter.report(
buildData,
tracksExtension.username.orNull,
tracksExtension.customEventName.orNull,
encodedUser.orEmpty()
)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.github.wzieba.tracks.plugin

import io.github.wzieba.tracks.plugin.analytics.networking.TracksReporter
import io.github.wzieba.tracks.plugin.analytics.networking.AppsMetricsReporter
import org.gradle.api.Plugin
import org.gradle.api.Project
import kotlin.time.ExperimentalTime
Expand All @@ -14,7 +14,7 @@ abstract class BuildTimePlugin : Plugin<Project> {

val buildTimeListener = BuildTimeListener(
buildDataFactory = BuildDataFactory,
buildReporter = BuildReporter(project.logger, TracksReporter()),
buildReporter = BuildReporter(project.logger, AppsMetricsReporter(project)),
tracksExtension = extension,
includedBuilds = project.gradle.includedBuilds
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,6 @@ abstract class TracksExtension @Inject constructor(project: Project) {

val enabled: Property<Boolean> = objects.property(Boolean::class.java)

@Optional
val username: Property<String> = objects.property(String::class.java)

@Optional
val customEventName: Property<String> = objects.property(String::class.java)

enum class AutomatticProject {
WooCommerce, WordPress, DayOne
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ interface AnalyticsReporter {
suspend fun report(
logger: Logger,
event: BuildData,
username: String?,
customEventName: String?,
user: String,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.github.wzieba.tracks.plugin.analytics.networking

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class GroupedAppsMetrics(
@SerialName("meta")
val meta: List<AppsMetric>,
@SerialName("metrics")
val metrics: List<AppsMetric>,
)

@Serializable
data class AppsMetric(
@SerialName("name")
val name: String,
@SerialName("value")
val value: String,
)
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,29 @@ import io.ktor.client.statement.HttpResponse
import io.ktor.client.statement.HttpStatement
import io.ktor.http.ContentType
import io.ktor.http.HttpHeaders
import io.ktor.http.HttpHeaders.Authorization
import io.ktor.http.HttpStatusCode
import io.ktor.http.contentType
import org.gradle.api.Project
import org.gradle.api.logging.Logger
import java.util.Locale
import java.util.concurrent.TimeUnit.MILLISECONDS
import java.util.concurrent.TimeUnit.MINUTES

class TracksReporter : AnalyticsReporter {
class AppsMetricsReporter(private val project: Project) : AnalyticsReporter {

override suspend fun report(
logger: Logger,
event: BuildData,
username: String?,
customEventName: String?,
user: String,
) {
val authToken: String? = project.properties["appsMetricsToken"] as String?

if (authToken.isNullOrBlank()) {
logger.warn("Did not find appsMetricsToken in gradle.properties. Skipping reporting.")
return
}

logger.debug("Reporting $event")

val client = HttpClient(CIO) {
Expand All @@ -46,26 +54,34 @@ class TracksReporter : AnalyticsReporter {
}
}

client.post<HttpStatement>("https://public-api.wordpress.com/rest/v1.1/tracks/record") {
client.post<HttpStatement>("https://seal-app-e8plp.ondigitalocean.app/api/grouped-metrics") {
headers {
append(HttpHeaders.UserAgent, "Gradle")
append(Authorization, "Bearer $authToken")
}
contentType(ContentType.Application.Json)
body = event.toTracksPayload(customEventName, username)
body = event.toAppsInfraPayload(user)
}.execute { response: HttpResponse ->
logger.debug(response.toString())

when (response.status) {
HttpStatusCode.Accepted -> {
HttpStatusCode.Created -> {
val buildTime = event.buildTime
val timeFormatted = String.format(
Locale.US,
"%dm %ds",
MILLISECONDS.toMinutes(buildTime),
MILLISECONDS.toSeconds(buildTime) - MINUTES.toSeconds(MILLISECONDS.toMinutes(buildTime))
MILLISECONDS.toSeconds(buildTime) - MINUTES.toSeconds(
MILLISECONDS.toMinutes(
buildTime
)
)
)
logger.lifecycle(
"$SUCCESS_ICON Build time report of $timeFormatted has been received by App Metrics."
)
logger.lifecycle("$SUCCESS_ICON Build time report of $timeFormatted has been received by Tracks.")
}

else -> {
logger.warn(
"$FAILURE_ICON Build time has not been uploaded. Add `debug` property to see more logs."
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package io.github.wzieba.tracks.plugin.analytics.networking

import io.github.wzieba.tracks.plugin.BuildData

@Suppress("LongMethod")
fun BuildData.toAppsInfraPayload(user: String) = GroupedAppsMetrics(
meta = listOf(
AppsMetric(
name = "User",
value = user
),
AppsMetric(
name = "Project",
value = this.forProject.name
)
),
metrics = listOf(
AppsMetric(
name = "Requested tasks",
value = this.tasks.joinToString(separator = ",")
),
AppsMetric(
name = "Performed Gradle action",
value = this.action
),
AppsMetric(
name = "Build time (ms)",
value = this.buildTime.toString()
),
AppsMetric(
name = "Build status",
value = if (this.failed) "Failure" else "Success"
),
AppsMetric(
name = "Failure message",
value = this.failure.toString()
),
AppsMetric(
name = "Number of running daemons",
value = this.daemonsRunning.toString()
),
AppsMetric(
name = "Daemon's build count",
value = this.thisDaemonBuilds.toString()
),
AppsMetric(
name = "Gradle version",
value = this.gradleVersion
),
AppsMetric(
name = "Operating system",
value = this.operatingSystem
),
AppsMetric(
name = "Environment",
value = this.environment.toString()
),
AppsMetric(
name = "Total number of tasks",
value = this.taskStatistics.total.toString()
),
AppsMetric(
name = "Up to date tasks",
value = this.taskStatistics.upToDate.toString()
),
AppsMetric(
name = "Tasks from cache",
value = this.taskStatistics.fromCache.toString()
),
AppsMetric(
name = "Executed tasks",
value = this.taskStatistics.executed.toString()
),
AppsMetric(
name = "Is configure on demand",
value = this.isConfigureOnDemand.toString()
),
AppsMetric(
name = "Is configuration cache",
value = this.isConfigurationCache.toString()
),
AppsMetric(
name = "Is build cache",
value = this.isBuildCache.toString()
),
AppsMetric(
name = "Max workers",
value = this.maxWorkers.toString()
),
AppsMetric(
name = "Build data collection overhead",
value = this.buildDataCollectionOverhead.toString()
),
AppsMetric(
name = "Included builds",
value = this.includedBuildsNames.joinToString(separator = ",").ifEmpty { "none" }
),
AppsMetric(
name = "Architecture",
value = this.architecture
),
)
)

This file was deleted.

This file was deleted.

0 comments on commit afc1a24

Please sign in to comment.