This commit is contained in:
Martin Ptáček
2023-06-14 22:18:31 +02:00
parent 8df013745a
commit 766297a741
4 changed files with 46 additions and 9 deletions

View File

@ -38,6 +38,8 @@ class ExponentialBackoff {
} }
} }
Log.d(TAG, "Exception caught")
onException() onException()
// calculate new delay // calculate new delay

View File

@ -11,6 +11,7 @@ import androidx.work.WorkerParameters
import com.birdthedeveloper.prometheus.android.prometheus.android.exporter.R import com.birdthedeveloper.prometheus.android.prometheus.android.exporter.R
import com.birdthedeveloper.prometheus.android.prometheus.android.exporter.compose.PromConfiguration import com.birdthedeveloper.prometheus.android.prometheus.android.exporter.compose.PromConfiguration
import io.prometheus.client.CollectorRegistry import io.prometheus.client.CollectorRegistry
import io.prometheus.client.exemplars.ExemplarConfig
import io.prometheus.client.exporter.common.TextFormat import io.prometheus.client.exporter.common.TextFormat
import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
@ -38,6 +39,7 @@ class PromWorker(
init { init {
val androidCustomExporter = AndroidCustomExporter(metricsEngine) val androidCustomExporter = AndroidCustomExporter(metricsEngine)
androidCustomExporter.register<AndroidCustomExporter>(collectorRegistry) androidCustomExporter.register<AndroidCustomExporter>(collectorRegistry)
ExemplarConfig.disableExemplars() // prometheus client library configuration
} }
//TODO foreground notification //TODO foreground notification

View File

@ -12,6 +12,7 @@ import io.ktor.client.request.post
import io.ktor.client.request.setBody import io.ktor.client.request.setBody
import io.ktor.http.HttpHeaders import io.ktor.http.HttpHeaders
import io.ktor.http.HttpStatusCode import io.ktor.http.HttpStatusCode
import io.prometheus.client.Collector.MetricFamilySamples
import io.prometheus.client.CollectorRegistry import io.prometheus.client.CollectorRegistry
import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.channels.BufferOverflow
@ -86,16 +87,26 @@ class RemoteWriteSender(private val config: RemoteWriteConfiguration) {
private suspend fun performScrapeAndSaveIt(channel: Channel<Unit>) { private suspend fun performScrapeAndSaveIt(channel: Channel<Unit>) {
Log.d(TAG, "performScrapeAndSaveIt start") Log.d(TAG, "performScrapeAndSaveIt start")
val scrapedMetrics = config.collectorRegistry.metricFamilySamples() val scrapedMetrics = config.collectorRegistry.metricFamilySamples()
storage.writeScrapedSample(scrapedMetrics) val metricsScrape : MetricsScrape = MetricsScrape.fromMfs(scrapedMetrics)
storage.writeScrapedSample(metricsScrape)
channel.send(Unit) channel.send(Unit)
Log.d(TAG, "performScrapeAndSaveIt end") Log.d(TAG, "performScrapeAndSaveIt end")
} }
private fun insertInitialDummyScrape(){
lastTimeRingBuffer.setLastTime(System.currentTimeMillis())
}
private suspend fun scraper(channel: Channel<Unit>) { private suspend fun scraper(channel: Channel<Unit>) {
val checkDelay = 1000L val checkDelay : Long = 1000L
insertInitialDummyScrape()
while (true) { while (true) {
if (lastTimeRingBuffer.checkScrapeDidNotHappenInTime()) { if (lastTimeRingBuffer.checkScrapeDidNotHappenInTime()) {
remoteWriteOn = true remoteWriteOn = true
Log.d(TAG, "Turning remote write on")
performScrapeAndSaveIt(channel) performScrapeAndSaveIt(channel)
delay(config.scrapeInterval * 1000L) delay(config.scrapeInterval * 1000L)
@ -105,8 +116,10 @@ class RemoteWriteSender(private val config: RemoteWriteConfiguration) {
performScrapeAndSaveIt(channel) performScrapeAndSaveIt(channel)
} }
Log.d(TAG, "Turning remote write off")
remoteWriteOn = false remoteWriteOn = false
} }
delay(checkDelay) delay(checkDelay)
} }
} }
@ -140,7 +153,7 @@ class RemoteWriteSender(private val config: RemoteWriteConfiguration) {
} }
private suspend fun exportToRemoteWriteEndpoint() { private suspend fun exportToRemoteWriteEndpoint() {
Log.d(TAG, "sendAll") Log.d(TAG, "export To Remote Write Endpoint")
if (!scrapesAreBeingSent) { if (!scrapesAreBeingSent) {
scrapesAreBeingSent = true scrapesAreBeingSent = true
@ -190,10 +203,12 @@ class RemoteWriteSender(private val config: RemoteWriteConfiguration) {
coroutineScope { //TODO this could be a problem coroutineScope { //TODO this could be a problem
launch { launch {
// check for outage in scrapes, save scrapes to storage // check for outage in scrapes, save scrapes to storage
Log.d(TAG, "Launching scraper")
scraper(channel) scraper(channel)
} }
launch { launch {
// send saved scrapes to remote write endpoint // send saved scrapes to remote write endpoint
Log.d(TAG, "Launching senderManager")
senderManager(channel) senderManager(channel)
} }
} }
@ -207,7 +222,6 @@ class RemoteWriteSender(private val config: RemoteWriteConfiguration) {
} }
fun countSuccessfulScrape() { fun countSuccessfulScrape() {
Log.d(TAG, "Counting successful scrape")
lastTimeRingBuffer.setLastTime(System.currentTimeMillis()) lastTimeRingBuffer.setLastTime(System.currentTimeMillis())
} }

View File

@ -18,12 +18,27 @@ private const val TAG: String = "REMOTE_WRITE_SENDER_STORAGE"
// No need for locks as all operations are run on a single thread, defined in PromWorker // No need for locks as all operations are run on a single thread, defined in PromWorker
// This class defines contract for RemoteWriteSender storage // This class defines contract for RemoteWriteSender storage
typealias MetricsScrape = Enumeration<MetricFamilySamples> // the same structure as MetricFamilySamples
data class MetricsScrape(
val timeSeriesList : List<TimeSeries>
){
companion object {
fun fromMfs(input : Enumeration<MetricFamilySamples>) : MetricsScrape{
for (family in input){
for (sample in family.samples){
}
}
}
}
}
// HashMap<List of labels including name, List of TimeSeries samples to this TimeSeries> data class TimeSeries(
private typealias ConverterHashMap = HashMap<List<TimeSeriesLabel>, MutableList<TimeSeriesSample>> val sample : TimeSeriesSample,
val labels : List<TimeSeriesLabel>,
)
private data class TimeSeriesLabel( data class TimeSeriesLabel(
val name: String, val name: String,
val value: String, val value: String,
) { ) {
@ -35,7 +50,7 @@ private data class TimeSeriesLabel(
} }
} }
private data class TimeSeriesSample( data class TimeSeriesSample(
val timeStampMs: Long, val timeStampMs: Long,
val value: Double, val value: Double,
) { ) {
@ -47,6 +62,10 @@ private data class TimeSeriesSample(
} }
} }
// HashMap<List of labels including name, List of TimeSeries samples to this TimeSeries>
private typealias ConverterHashMap = HashMap<List<TimeSeriesLabel>, MutableList<TimeSeriesSample>>
abstract class RemoteWriteSenderStorage { abstract class RemoteWriteSenderStorage {
private val remoteWriteLabel: TimeSeriesLabel = TimeSeriesLabel( private val remoteWriteLabel: TimeSeriesLabel = TimeSeriesLabel(
name = "backfill", name = "backfill",