remote write UI

This commit is contained in:
Martin Ptáček
2023-06-13 14:23:21 +02:00
parent 31829184ed
commit 9fc3df5ca9
6 changed files with 107 additions and 30 deletions

View File

@ -14,8 +14,8 @@ private const val TAG: String = "CONFIGURATION"
//TODO register within prometheus foundation //TODO register within prometheus foundation
private const val defaultPrometheusServerPort: Int = 10101 private const val defaultPrometheusServerPort: Int = 10101
private const val defaultRemoteWriteScrapeInterval: Int = 30 // seconds private const val defaultRemoteWriteScrapeInterval: Int = 30 // seconds
private const val defaultRemoteWriteMaxSamplesPerSend : Int = 60 // seconds private const val defaultRemoteWriteMaxSamplesPerExport : Int = 60 // seconds
private const val defaultRemoteWriteSendInterval : Int = 120 // seconds private const val defaultRemoteWriteExportInterval : Int = 120 // seconds
// serialization classes for parsing YAML configuration file // serialization classes for parsing YAML configuration file
@Serializable @Serializable
@ -35,8 +35,8 @@ data class PromConfigFile(
remoteWriteEndpoint = this.remote_write?.remote_write_endpoint ?: "", remoteWriteEndpoint = this.remote_write?.remote_write_endpoint ?: "",
prometheusServerEnabled = this.prometheus_server?.enabled ?: true, prometheusServerEnabled = this.prometheus_server?.enabled ?: true,
prometheusServerPort = this.prometheus_server?.port ?: defaultPrometheusServerPort, prometheusServerPort = this.prometheus_server?.port ?: defaultPrometheusServerPort,
remoteWriteMaxSamplesPerSend = this.remote_write?.max_samples_per_send ?: defaultRemoteWriteMaxSamplesPerSend, remoteWriteMaxSamplesPerExport = this.remote_write?.max_samples_per_export ?: defaultRemoteWriteMaxSamplesPerExport,
remoteWriteSendInterval = this.remote_write?.send_interval ?: defaultRemoteWriteSendInterval, remoteWriteExportInterval = this.remote_write?.export_interval ?: defaultRemoteWriteExportInterval,
) )
} }
} }
@ -59,8 +59,8 @@ data class RemoteWriteConfigFile(
val enabled: Boolean?, val enabled: Boolean?,
val scrape_interval: Int?, val scrape_interval: Int?,
val remote_write_endpoint: String?, val remote_write_endpoint: String?,
val max_samples_per_send: Int?, val max_samples_per_export: Int?,
val send_interval: Int?, val export_interval: Int?,
) )
// configuration of a work manager worker // configuration of a work manager worker
@ -75,8 +75,8 @@ data class PromConfiguration(
val remoteWriteEnabled: Boolean = false, val remoteWriteEnabled: Boolean = false,
val remoteWriteScrapeInterval: Int = defaultRemoteWriteScrapeInterval, val remoteWriteScrapeInterval: Int = defaultRemoteWriteScrapeInterval,
val remoteWriteEndpoint: String = "", val remoteWriteEndpoint: String = "",
val remoteWriteSendInterval : Int = 60, val remoteWriteExportInterval : Int = defaultRemoteWriteExportInterval,
val remoteWriteMaxSamplesPerSend : Int = 500, val remoteWriteMaxSamplesPerExport : Int = defaultRemoteWriteMaxSamplesPerExport,
) { ) {
fun toStructuredText(): String { fun toStructuredText(): String {
@ -91,8 +91,8 @@ data class PromConfiguration(
remote_write: remote_write:
enabled: $remoteWriteEnabled enabled: $remoteWriteEnabled
scrape_interval: $remoteWriteScrapeInterval scrape_interval: $remoteWriteScrapeInterval
send_interval: $remoteWriteSendInterval export_interval: $remoteWriteExportInterval
max_samples_per_send: $remoteWriteMaxSamplesPerSend max_samples_per_export: $remoteWriteMaxSamplesPerExport
remote_write_endpoint: "$remoteWriteEndpoint" remote_write_endpoint: "$remoteWriteEndpoint"
""".trimIndent() """.trimIndent()
} }

View File

@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.AlertDialog import androidx.compose.material.AlertDialog
import androidx.compose.material.Button import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults import androidx.compose.material.ButtonDefaults
@ -34,6 +35,7 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
@ -84,7 +86,7 @@ fun HomePage(
ConfigFileState.SUCCESS -> ConfigFileSuccessPage(promViewModel = promViewModel) ConfigFileState.SUCCESS -> ConfigFileSuccessPage(promViewModel = promViewModel)
ConfigFileState.LOADING -> LoadingPage(Modifier) ConfigFileState.LOADING -> LoadingPage(Modifier)
ConfigFileState.MISSING -> TabPage(promViewModel, navController) ConfigFileState.MISSING -> TabPage(promViewModel)
} }
} }
@ -174,7 +176,6 @@ private fun StartStopButton(
@Composable @Composable
private fun TabPage( private fun TabPage(
promViewModel: PromViewModel, promViewModel: PromViewModel,
navController: NavHostController,
) { ) {
val tabs = mapOf(0 to "Prom Server", 1 to "PushProx", 2 to "Remote write") val tabs = mapOf(0 to "Prom Server", 1 to "PushProx", 2 to "Remote write")
val uiState: PromUiState by promViewModel.uiState.collectAsState() val uiState: PromUiState by promViewModel.uiState.collectAsState()
@ -188,7 +189,7 @@ private fun TabPage(
} }
} }
when (uiState.tabIndex) { when (uiState.tabIndex) {
0 -> PrometheusServerPage(promViewModel, Modifier) 0 -> PrometheusServerPage(promViewModel)
1 -> PushProxPage(promViewModel) 1 -> PushProxPage(promViewModel)
2 -> RemoteWritePage(promViewModel) 2 -> RemoteWritePage(promViewModel)
} }
@ -198,7 +199,6 @@ private fun TabPage(
@Composable @Composable
private fun PrometheusServerPage( private fun PrometheusServerPage(
promViewModel: PromViewModel, promViewModel: PromViewModel,
modifier: Modifier
) { ) {
val uiState: PromUiState by promViewModel.uiState.collectAsState() val uiState: PromUiState by promViewModel.uiState.collectAsState()
@ -300,6 +300,7 @@ private fun PushProxPage(
} }
} }
//TODO implement this
@Composable @Composable
private fun RemoteWritePage( private fun RemoteWritePage(
promViewModel: PromViewModel, promViewModel: PromViewModel,
@ -307,10 +308,72 @@ private fun RemoteWritePage(
val uiState: PromUiState by promViewModel.uiState.collectAsState() val uiState: PromUiState by promViewModel.uiState.collectAsState()
Column( Column(
modifier = Modifier, modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
) { ) {
//TODO implement this Text("Remote write configuration:")
Text("Remote write configuration")
TextField(
value = uiState.promConfig.remoteWriteEndpoint,
singleLine = true,
onValueChange = {
promViewModel.updatePromConfig(UpdatePromConfig.PushproxFqdn, it)
},
label = {
Text(text = "Remote write endpoint")
},
modifier = Modifier.padding(bottom = 12.dp)
)
TextField(
value = uiState.promConfig.remoteWriteScrapeInterval.toString(),
singleLine = true,
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
onValueChange = {
promViewModel.updatePromConfig(UpdatePromConfig.RemoteWriteScrapeInterval, it.toInt())
},
label = {
Text(text = "Scrape interval in seconds")
},
)
TextField(
value = uiState.promConfig.remoteWriteMaxSamplesPerExport.toString(),
singleLine = true,
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
onValueChange = {
promViewModel.updatePromConfig(
UpdatePromConfig.RemoteWriteMaxSamplesPerExport,
it.toInt(),
)
},
label = {
Text(text = "Max number of samples per export")
},
)
TextField(
value = uiState.promConfig.remoteWriteExportInterval.toString(),
singleLine = true,
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
onValueChange = {
promViewModel.updatePromConfig(UpdatePromConfig.PushproxProxyUrl, it.toInt())
},
label = {
Text(text = "Export interval in seconds")
},
)
Switch(
checked = uiState.promConfig.remoteWriteEnabled,
onCheckedChange = { value: Boolean? ->
if (value != null) {
promViewModel.updatePromConfig(UpdatePromConfig.RemoteWriteEnabled, value)
}
}
)
} }
} }

View File

@ -5,7 +5,6 @@ import android.util.Log
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.work.Constraints import androidx.work.Constraints
import androidx.work.Data import androidx.work.Data
import androidx.work.ExistingWorkPolicy import androidx.work.ExistingWorkPolicy
@ -20,7 +19,6 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update import kotlinx.coroutines.flow.update
import java.util.UUID
private val TAG: String = "PROMVIEWMODEL" private val TAG: String = "PROMVIEWMODEL"
@ -40,6 +38,8 @@ enum class UpdatePromConfig {
RemoteWriteEnabled, RemoteWriteEnabled,
RemoteWriteScrapeInterval, RemoteWriteScrapeInterval,
RemoteWriteEndpoint, RemoteWriteEndpoint,
RemoteWriteexportInterval,
RemoteWriteMaxSamplesPerExport,
} }
enum class ExporterState { enum class ExporterState {
@ -57,7 +57,6 @@ data class PromUiState(
val configValidationException: String? = null, val configValidationException: String? = null,
) )
class PromViewModel() : ViewModel() { class PromViewModel() : ViewModel() {
private val _uiState = MutableStateFlow(PromUiState()) private val _uiState = MutableStateFlow(PromUiState())
@ -338,6 +337,22 @@ class PromViewModel() : ViewModel() {
) )
) )
} }
UpdatePromConfig.RemoteWriteexportInterval -> _uiState.update {current ->
current.copy(
promConfig = current.promConfig.copy(
remoteWriteExportInterval = value as Int
)
)
}
UpdatePromConfig.RemoteWriteMaxSamplesPerExport -> _uiState.update { current ->
current.copy(
promConfig = current.promConfig.copy(
remoteWriteMaxSamplesPerExport = value as Int
)
)
}
} }
} }
} }

View File

@ -2,7 +2,6 @@ package com.birdthedeveloper.prometheus.android.prometheus.android.exporter.work
import android.app.NotificationManager import android.app.NotificationManager
import android.content.Context import android.content.Context
import android.util.Log
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import androidx.work.CoroutineWorker import androidx.work.CoroutineWorker
import androidx.work.ForegroundInfo import androidx.work.ForegroundInfo
@ -60,8 +59,8 @@ class PromWorker(
scrapeInterval = config.remoteWriteScrapeInterval, scrapeInterval = config.remoteWriteScrapeInterval,
remoteWriteEndpoint = config.remoteWriteEndpoint, remoteWriteEndpoint = config.remoteWriteEndpoint,
collectorRegistry = collectorRegistry, collectorRegistry = collectorRegistry,
sendInterval = config.remoteWriteSendInterval, exportInterval = config.remoteWriteExportInterval,
maxSamplesPerSend = config.remoteWriteMaxSamplesPerSend, maxSamplesPerExport = config.remoteWriteMaxSamplesPerExport,
) { context } ) { context }
) )
launch { launch {

View File

@ -68,8 +68,8 @@ data class RemoteWriteConfiguration(
val scrapeInterval: Int, val scrapeInterval: Int,
val remoteWriteEndpoint: String, val remoteWriteEndpoint: String,
val collectorRegistry: CollectorRegistry, val collectorRegistry: CollectorRegistry,
val maxSamplesPerSend: Int, val maxSamplesPerExport: Int,
val sendInterval : Int, val exportInterval : Int,
val getContext : () -> Context, val getContext : () -> Context,
) )
@ -107,7 +107,7 @@ class RemoteWriteSender(private val config: RemoteWriteConfiguration) {
private suspend fun sendAll(){ private suspend fun sendAll(){
scrapesAreBeingSent = true scrapesAreBeingSent = true
while (!storage.isEmpty()){ while (!storage.isEmpty()){
val body = storage.getScrapedSamplesCompressedProtobuf(config.maxSamplesPerSend) val body = storage.getScrapedSamplesCompressedProtobuf(config.maxSamplesPerExport)
ExponentialBackoff.runWithBackoff( {sendRequestToRemoteWrite(body)}, {}, false) ExponentialBackoff.runWithBackoff( {sendRequestToRemoteWrite(body)}, {}, false)
} }
lastTimeRemoteWriteSent = System.currentTimeMillis() lastTimeRemoteWriteSent = System.currentTimeMillis()
@ -128,7 +128,7 @@ class RemoteWriteSender(private val config: RemoteWriteConfiguration) {
} }
private fun timeHasPassed() : Boolean { private fun timeHasPassed() : Boolean {
return lastTimeRemoteWriteSent < System.currentTimeMillis() - config.sendInterval * 1000 return lastTimeRemoteWriteSent < System.currentTimeMillis() - config.exportInterval * 1000
} }
private fun conditionsForRemoteWrite() : Boolean { private fun conditionsForRemoteWrite() : Boolean {
@ -136,7 +136,7 @@ class RemoteWriteSender(private val config: RemoteWriteConfiguration) {
} }
private fun enoughSamplesScraped() : Boolean { private fun enoughSamplesScraped() : Boolean {
return storage.getLength() > config.maxSamplesPerSend return storage.getLength() > config.maxSamplesPerExport
} }
private suspend fun senderManager(channel : Channel<Unit>){ private suspend fun senderManager(channel : Channel<Unit>){

View File

@ -36,6 +36,6 @@ remote_write:
remote_write_endpoint: remote_write_endpoint:
# default value is 500 scrapes # default value is 500 scrapes
max_samples_per_send: 500 max_samples_per_export: 500
send_interval: 60 # default export_interval: 60 # default