diff --git a/client/app/src/main/java/com/birdthedeveloper/prometheus/android/prometheus/android/exporter/compose/Configuration.kt b/client/app/src/main/java/com/birdthedeveloper/prometheus/android/prometheus/android/exporter/compose/Configuration.kt index f74e600..1f8467c 100644 --- a/client/app/src/main/java/com/birdthedeveloper/prometheus/android/prometheus/android/exporter/compose/Configuration.kt +++ b/client/app/src/main/java/com/birdthedeveloper/prometheus/android/prometheus/android/exporter/compose/Configuration.kt @@ -27,16 +27,15 @@ data class PromConfigFile( fun toPromConfiguration(): PromConfiguration { return PromConfiguration( pushproxProxyUrl = this.pushprox?.proxy_url ?: "", - remoteWriteScrapeInterval = this.remote_write?.scrape_interval - ?: defaultRemoteWriteScrapeInterval, + remoteWriteScrapeInterval = (this.remote_write?.scrape_interval ?: defaultRemoteWriteScrapeInterval).toString(), pushproxEnabled = this.pushprox?.enabled ?: false, pushproxFqdn = this.pushprox?.fqdn ?: "", remoteWriteEnabled = this.remote_write?.enabled ?: false, remoteWriteEndpoint = this.remote_write?.remote_write_endpoint ?: "", prometheusServerEnabled = this.prometheus_server?.enabled ?: true, - prometheusServerPort = this.prometheus_server?.port ?: defaultPrometheusServerPort, - remoteWriteMaxSamplesPerExport = this.remote_write?.max_samples_per_export ?: defaultRemoteWriteMaxSamplesPerExport, - remoteWriteExportInterval = this.remote_write?.export_interval ?: defaultRemoteWriteExportInterval, + prometheusServerPort = (this.prometheus_server?.port ?: defaultPrometheusServerPort).toString(), + remoteWriteMaxSamplesPerExport = (this.remote_write?.max_samples_per_export ?: defaultRemoteWriteMaxSamplesPerExport).toString(), + remoteWriteExportInterval = (this.remote_write?.export_interval ?: defaultRemoteWriteExportInterval).toString(), ) } } @@ -68,15 +67,15 @@ data class RemoteWriteConfigFile( data class PromConfiguration( // the following are default values for various configuration settings val prometheusServerEnabled: Boolean = true, - val prometheusServerPort: Int = defaultPrometheusServerPort, + val prometheusServerPort: String = defaultPrometheusServerPort.toString(), val pushproxEnabled: Boolean = false, val pushproxFqdn: String = "", val pushproxProxyUrl: String = "", val remoteWriteEnabled: Boolean = false, - val remoteWriteScrapeInterval: Int = defaultRemoteWriteScrapeInterval, + val remoteWriteScrapeInterval: String = defaultRemoteWriteScrapeInterval.toString(), val remoteWriteEndpoint: String = "", - val remoteWriteExportInterval : Int = defaultRemoteWriteExportInterval, - val remoteWriteMaxSamplesPerExport : Int = defaultRemoteWriteMaxSamplesPerExport, + val remoteWriteExportInterval : String = defaultRemoteWriteExportInterval.toString(), + val remoteWriteMaxSamplesPerExport : String = defaultRemoteWriteMaxSamplesPerExport.toString(), ) { fun toStructuredText(): String { diff --git a/client/app/src/main/java/com/birdthedeveloper/prometheus/android/prometheus/android/exporter/compose/HomeActivity.kt b/client/app/src/main/java/com/birdthedeveloper/prometheus/android/prometheus/android/exporter/compose/HomeActivity.kt index 5405217..047d75a 100644 --- a/client/app/src/main/java/com/birdthedeveloper/prometheus/android/prometheus/android/exporter/compose/HomeActivity.kt +++ b/client/app/src/main/java/com/birdthedeveloper/prometheus/android/prometheus/android/exporter/compose/HomeActivity.kt @@ -212,7 +212,7 @@ private fun PrometheusServerPage( value = uiState.promConfig.prometheusServerPort.toString(), singleLine = true, onValueChange = { - promViewModel.updatePromConfig(UpdatePromConfig.PrometheusServerPort, it.toInt()) + promViewModel.updatePromConfig(UpdatePromConfig.PrometheusServerPort, it) }, label = { Text("Prometheus HTTP port") }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), @@ -301,12 +301,14 @@ private fun RemoteWritePage( horizontalAlignment = Alignment.CenterHorizontally, ) { Text("Remote write configuration:") + + Spacer(modifier = Modifier.padding(bottom = 12.dp)) TextField( value = uiState.promConfig.remoteWriteEndpoint, singleLine = true, onValueChange = { - promViewModel.updatePromConfig(UpdatePromConfig.PushproxFqdn, it) + promViewModel.updatePromConfig(UpdatePromConfig.RemoteWriteEndpoint, it) }, label = { Text(text = "Remote write endpoint") @@ -315,14 +317,11 @@ private fun RemoteWritePage( ) TextField( - value = scrapeIntervalState.value, + value = uiState.promConfig.remoteWriteScrapeInterval, singleLine = true, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), onValueChange = { - val converted : Int? = it.toIntOrNull() - if (converted != null) { - promViewModel.updatePromConfig(UpdatePromConfig.RemoteWriteScrapeInterval, converted) - } + promViewModel.updatePromConfig(UpdatePromConfig.RemoteWriteScrapeInterval, it) }, label = { Text(text = "Scrape interval in seconds") @@ -330,14 +329,11 @@ private fun RemoteWritePage( ) TextField( - value = uiState.promConfig.remoteWriteMaxSamplesPerExport.toString(), + value = uiState.promConfig.remoteWriteMaxSamplesPerExport, singleLine = true, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), onValueChange = { - promViewModel.updatePromConfig( - UpdatePromConfig.RemoteWriteMaxSamplesPerExport, - it.toInt(), - ) + promViewModel.updatePromConfig(UpdatePromConfig.RemoteWriteMaxSamplesPerExport, it) }, label = { Text(text = "Max number of samples per export") @@ -345,11 +341,11 @@ private fun RemoteWritePage( ) TextField( - value = uiState.promConfig.remoteWriteExportInterval.toString(), + value = uiState.promConfig.remoteWriteExportInterval, singleLine = true, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), onValueChange = { - promViewModel.updatePromConfig(UpdatePromConfig.PushproxProxyUrl, it.toInt()) + promViewModel.updatePromConfig(UpdatePromConfig.RemoteWriteExportInterval, it) }, label = { Text(text = "Export interval in seconds") diff --git a/client/app/src/main/java/com/birdthedeveloper/prometheus/android/prometheus/android/exporter/compose/PromViewModel.kt b/client/app/src/main/java/com/birdthedeveloper/prometheus/android/prometheus/android/exporter/compose/PromViewModel.kt index 5a39dd6..bf5b36f 100644 --- a/client/app/src/main/java/com/birdthedeveloper/prometheus/android/prometheus/android/exporter/compose/PromViewModel.kt +++ b/client/app/src/main/java/com/birdthedeveloper/prometheus/android/prometheus/android/exporter/compose/PromViewModel.kt @@ -20,7 +20,7 @@ import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update -private val TAG: String = "PROMVIEWMODEL" +private const val TAG: String = "PROMVIEWMODEL" enum class ConfigFileState { LOADING, // parsing configuration file now @@ -29,36 +29,6 @@ enum class ConfigFileState { SUCCESS, } -class PromUiConfiguration private constructor( - val prometheusServerEnabled: Boolean, - val prometheusServerPort: String, - val pushproxEnabled: Boolean, - val pushproxFqdn: String, - val pushproxProxyUrl: String, - val remoteWriteEnabled: Boolean, - val remoteWriteScrapeInterval: String, - val remoteWriteEndpoint: String, - val remoteWriteExportInterval : String, - val remoteWriteMaxSamplesPerExport : String, -){ - companion object { - fun default() : PromUiConfiguration{ - val template = PromConfiguration() - - return PromUiConfiguration( - remoteWriteEndpoint = template.remoteWriteEndpoint, - prometheusServerPort = template.prometheusServerPort.toString(), - prometheusServerEnabled = //TODO asap - ) - } - } - - // Throws exception when values are illegal - fun toPromConfiguration() : PromConfiguration { - //TODO - } -} - enum class UpdatePromConfig { PrometheusServerEnabled, PrometheusServerPort, @@ -68,7 +38,7 @@ enum class UpdatePromConfig { RemoteWriteEnabled, RemoteWriteScrapeInterval, RemoteWriteEndpoint, - RemoteWriteexportInterval, + RemoteWriteExportInterval, RemoteWriteMaxSamplesPerExport, } @@ -87,7 +57,7 @@ data class PromUiState( val configValidationException: String? = null, ) -class PromViewModel() : ViewModel() { +class PromViewModel : ViewModel() { private val _uiState = MutableStateFlow(PromUiState()) val uiState: StateFlow = _uiState.asStateFlow() @@ -215,45 +185,80 @@ class PromViewModel() : ViewModel() { return false } + private fun somePushProxVariableUnset(config : PromConfiguration) : Boolean { + return config.pushproxFqdn.isBlank() || config.pushproxProxyUrl.isBlank() + } + + private fun somePrometheusServerVariableUnset(config : PromConfiguration) : Boolean { + return config.prometheusServerPort.isBlank() + } + + private fun someRemoteWriteVariableUnset(config : PromConfiguration) : Boolean { + return config.remoteWriteEndpoint.isBlank() + || config.remoteWriteScrapeInterval.isBlank() + || config.remoteWriteExportInterval.isBlank() + || config.remoteWriteMaxSamplesPerExport.isBlank() + } + private fun validatePromConfiguration(): Boolean { val config: PromConfiguration = uiState.value.promConfig - // check eather pushprox or prometheus server is on + // check either pushprox or prometheus server is turned on if (!config.pushproxEnabled && !config.prometheusServerEnabled) { return displayConfigValidationDialog("Please enable PushProx or Prometheus server!") } - // check port boundaries - val minPort = 1024 - val maxPort = 65535 - if (config.prometheusServerPort < minPort || config.prometheusServerPort > maxPort) { - return displayConfigValidationDialog("Prometheus exporter port out of bounds!") + // check for empty configuration + if(config.pushproxEnabled && somePushProxVariableUnset(config)){ + return displayConfigValidationDialog("Please set all PushProx configuration settings!") + } + if(config.prometheusServerEnabled && somePrometheusServerVariableUnset(config)){ + return displayConfigValidationDialog("Set all Prometheus Server config settings!") + } + if(config.remoteWriteEnabled && someRemoteWriteVariableUnset(config)){ + return displayConfigValidationDialog("Set all Remote Write configuration settings!") } - // check scrape interval boundaries - val minScrapeInterval = 1 - val maxScrapeInterval = 3600 / 4 - val scrapeInterval = config.remoteWriteScrapeInterval - if (scrapeInterval > maxScrapeInterval || scrapeInterval < minScrapeInterval) { - return displayConfigValidationDialog("Remote write scrape interval out of bounds!") + // validate settings for remote write + if(config.remoteWriteEnabled){ + // check scrape interval boundaries + val minScrapeInterval = 1 + val maxScrapeInterval = 3600 / 4 + val scrapeInterval : Int = config.remoteWriteScrapeInterval.toIntOrNull() + ?: return displayConfigValidationDialog("Scrape interval must be a number!") + + if (scrapeInterval > maxScrapeInterval || scrapeInterval < minScrapeInterval) { + return displayConfigValidationDialog("Remote write scrape interval out of bounds!") + } + + // check max samples per export + config.remoteWriteMaxSamplesPerExport.toIntOrNull() + ?: return displayConfigValidationDialog("Max Samples Per Export must be a number!") + + // check export interval + val exportInterval : Int = config.remoteWriteExportInterval.toIntOrNull() + ?: return displayConfigValidationDialog("Export interval must be a number!") + if (scrapeInterval > exportInterval){ + return displayConfigValidationDialog( + "Scrape interval must be smaller than Export interval!" + ) + } + } - // if remote write enabled, remote_write_endpoint is set - if (config.remoteWriteEnabled && config.remoteWriteEndpoint.isBlank()) { - return displayConfigValidationDialog("Please set remote write endpoint!") + // validate settings for prometheus server + if(config.prometheusServerEnabled){ + // check port boundaries + val minPort = 1024 + val maxPort = 65535 + val prometheusServerPort : Int = config.prometheusServerPort.toIntOrNull() + ?: return displayConfigValidationDialog("Prometheus Server Port must be a number!") + if (prometheusServerPort < minPort || prometheusServerPort > maxPort) { + return displayConfigValidationDialog("Prometheus exporter port out of bounds!") + } } - // if pushprox is enabled, fqdn is set - if (config.pushproxEnabled && config.pushproxFqdn.isBlank()) { - return displayConfigValidationDialog( - "Please set proxy fqdn! For example: test.example.com" - ) - } - - // if pushprox is enabled, proxy_url is set - if (config.pushproxEnabled && config.pushproxProxyUrl.isBlank()) { - return displayConfigValidationDialog("Please set proxy_url!") - } + // no need to validate anything for pushprox return true } @@ -315,7 +320,7 @@ class PromViewModel() : ViewModel() { UpdatePromConfig.PrometheusServerPort -> _uiState.update { current -> current.copy( promConfig = current.promConfig.copy( - prometheusServerPort = value as Int, + prometheusServerPort = value as String, ) ) } @@ -355,7 +360,7 @@ class PromViewModel() : ViewModel() { UpdatePromConfig.RemoteWriteScrapeInterval -> _uiState.update { current -> current.copy( promConfig = current.promConfig.copy( - remoteWriteScrapeInterval = value as Int, + remoteWriteScrapeInterval = value as String, ) ) } @@ -368,10 +373,10 @@ class PromViewModel() : ViewModel() { ) } - UpdatePromConfig.RemoteWriteexportInterval -> _uiState.update {current -> + UpdatePromConfig.RemoteWriteExportInterval -> _uiState.update { current -> current.copy( promConfig = current.promConfig.copy( - remoteWriteExportInterval = value as Int + remoteWriteExportInterval = value as String ) ) } @@ -379,7 +384,7 @@ class PromViewModel() : ViewModel() { UpdatePromConfig.RemoteWriteMaxSamplesPerExport -> _uiState.update { current -> current.copy( promConfig = current.promConfig.copy( - remoteWriteMaxSamplesPerExport = value as Int + remoteWriteMaxSamplesPerExport = value as String ) ) } diff --git a/client/app/src/main/java/com/birdthedeveloper/prometheus/android/prometheus/android/exporter/worker/PromWorker.kt b/client/app/src/main/java/com/birdthedeveloper/prometheus/android/prometheus/android/exporter/worker/PromWorker.kt index 16ff306..4015f2c 100644 --- a/client/app/src/main/java/com/birdthedeveloper/prometheus/android/prometheus/android/exporter/worker/PromWorker.kt +++ b/client/app/src/main/java/com/birdthedeveloper/prometheus/android/prometheus/android/exporter/worker/PromWorker.kt @@ -56,11 +56,11 @@ class PromWorker( if (config.remoteWriteEnabled) { remoteWriteSender = RemoteWriteSender( RemoteWriteConfiguration( - scrapeInterval = config.remoteWriteScrapeInterval, + scrapeInterval = config.remoteWriteScrapeInterval.toInt(), remoteWriteEndpoint = config.remoteWriteEndpoint, collectorRegistry = collectorRegistry, - exportInterval = config.remoteWriteExportInterval, - maxSamplesPerExport = config.remoteWriteMaxSamplesPerExport, + exportInterval = config.remoteWriteExportInterval.toInt(), + maxSamplesPerExport = config.remoteWriteMaxSamplesPerExport.toInt(), ) { context } ) launch { @@ -72,7 +72,7 @@ class PromWorker( launch { PrometheusServer.start( PrometheusServerConfig( - config.prometheusServerPort, + config.prometheusServerPort.toInt(), ::performScrape, ::countSuccessfulScrape, ),