wip logging

This commit is contained in:
Martin Ptáček
2023-06-14 00:49:37 +02:00
parent 91e16d5c43
commit 89884172f7
11 changed files with 63 additions and 44 deletions

View File

@ -11,7 +11,6 @@ import java.io.File
private const val TAG: String = "CONFIGURATION"
//TODO register within prometheus foundation
private const val defaultPrometheusServerPort: Int = 10101
private const val defaultRemoteWriteScrapeInterval: Int = 30 // seconds
private const val defaultRemoteWriteMaxSamplesPerExport: Int = 60 // seconds
@ -118,7 +117,7 @@ data class PromConfiguration(
}
fun loadFromConfigFile(context: Context): PromConfiguration {
Log.v(TAG, context.filesDir.absolutePath)
Log.d(TAG, "Loading configuration file now")
val file = File(context.filesDir, filename)
val alternativeFile = File(context.filesDir, alternativeFilename)
@ -135,7 +134,7 @@ data class PromConfiguration(
fileContents
)
Log.v(TAG, parsedConfig.prometheus_server?.port.toString())
Log.d(TAG, "Configuration file loaded")
return parsedConfig.toPromConfiguration()
}

View File

@ -37,7 +37,7 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
private val TAG = "HOMEPAGE"
private const val TAG : String = "HOMEPAGE"
@Composable
fun HomePage(
@ -206,13 +206,14 @@ private fun PrometheusServerPage(
) {
TextField(
value = uiState.promConfig.prometheusServerPort.toString(),
value = uiState.promConfig.prometheusServerPort,
singleLine = true,
onValueChange = {
promViewModel.updatePromConfig(UpdatePromConfig.PrometheusServerPort, it)
},
label = { Text("Prometheus HTTP port") },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
enabled = uiState.exporterState == ExporterState.NotRunning,
)
Spacer(modifier = Modifier.height(20.dp))
@ -226,7 +227,8 @@ private fun PrometheusServerPage(
if (value != null) {
promViewModel.updatePromConfig(UpdatePromConfig.PrometheusServerEnabled, value)
}
}
},
enabled = uiState.exporterState == ExporterState.NotRunning,
)
}
}
@ -260,7 +262,8 @@ private fun PushProxPage(
label = {
Text(text = "Fully Qualified Domain Name")
},
modifier = Modifier.padding(bottom = 12.dp)
modifier = Modifier.padding(bottom = 12.dp),
enabled = uiState.exporterState == ExporterState.NotRunning,
)
TextField(
@ -272,6 +275,7 @@ private fun PushProxPage(
label = {
Text(text = "PushProx proxy URL")
},
enabled = uiState.exporterState == ExporterState.NotRunning,
)
Switch(
@ -280,7 +284,8 @@ private fun PushProxPage(
if (value != null) {
promViewModel.updatePromConfig(UpdatePromConfig.PushproxEnabled, value)
}
}
},
enabled = uiState.exporterState == ExporterState.NotRunning,
)
}
@ -310,7 +315,8 @@ private fun RemoteWritePage(
label = {
Text(text = "Remote write endpoint")
},
modifier = Modifier.padding(bottom = 12.dp)
modifier = Modifier.padding(bottom = 12.dp),
enabled = uiState.exporterState == ExporterState.NotRunning,
)
TextField(
@ -323,6 +329,7 @@ private fun RemoteWritePage(
label = {
Text(text = "Scrape interval in seconds")
},
enabled = uiState.exporterState == ExporterState.NotRunning,
)
TextField(
@ -335,6 +342,7 @@ private fun RemoteWritePage(
label = {
Text(text = "Max number of samples per export")
},
enabled = uiState.exporterState == ExporterState.NotRunning,
)
TextField(
@ -347,6 +355,7 @@ private fun RemoteWritePage(
label = {
Text(text = "Export interval in seconds")
},
enabled = uiState.exporterState == ExporterState.NotRunning,
)
Switch(
@ -355,7 +364,8 @@ private fun RemoteWritePage(
if (value != null) {
promViewModel.updatePromConfig(UpdatePromConfig.RemoteWriteEnabled, value)
}
}
},
enabled = uiState.exporterState == ExporterState.NotRunning,
)
}
}

View File

@ -66,6 +66,7 @@ class PromViewModel : ViewModel() {
private var workerLiveData: LiveData<List<WorkInfo>>? = null
private val workerLiveDataObserver: Observer<List<WorkInfo>> = Observer {
Log.d(TAG, "Observing change in worker state")
if (it.isEmpty()) {
updateExporterStateWith(ExporterState.NotRunning)
} else {
@ -85,9 +86,8 @@ class PromViewModel : ViewModel() {
}
private fun loadConfigurationFile() {
Log.v(TAG, "Checking for configuration file")
Log.d(TAG, "Checking for configuration file")
Log.v(TAG, getContext().filesDir.absolutePath)
val fileExists = PromConfiguration.configFileExists(context = getContext())
if (fileExists) {
val tempPromConfiguration: PromConfiguration
@ -101,7 +101,10 @@ class PromViewModel : ViewModel() {
)
}
Log.d(TAG, "Configuration file parsed successfully")
} catch (e: Exception) {
Log.d(TAG, "Configuration file parsing failed")
_uiState.update { current ->
current.copy(
configFileState = ConfigFileState.ERROR,
@ -202,6 +205,7 @@ class PromViewModel : ViewModel() {
}
private fun validatePromConfiguration(): Boolean {
Log.d(TAG, "Validating PromConfiguration now")
val config: PromConfiguration = uiState.value.promConfig
// check either pushprox or prometheus server is turned on
@ -244,7 +248,6 @@ class PromViewModel : ViewModel() {
"Scrape interval must be smaller than Export interval!"
)
}
}
// validate settings for prometheus server
@ -261,10 +264,12 @@ class PromViewModel : ViewModel() {
// no need to validate anything for pushprox
Log.d(TAG, "PromConfiguration validated")
return true
}
private fun startWorker() {
Log.d(TAG, "Starting worker")
if (validatePromConfiguration()) {
Log.v(TAG, "Enqueuing work")
val workManagerInstance = WorkManager.getInstance(getContext())
@ -290,22 +295,13 @@ class PromViewModel : ViewModel() {
ExistingWorkPolicy.KEEP,
workerRequest,
).enqueue()
// set UI state
_uiState.update { current ->
current.copy(exporterState = ExporterState.Running)
}
}
}
private fun stopWorker() {
Log.d(TAG, "Stopping worker")
val workerManagerInstance = WorkManager.getInstance(getContext())
workerManagerInstance.cancelUniqueWork(PROM_UNIQUE_WORK)
// update UI state
_uiState.update { current ->
current.copy(exporterState = ExporterState.NotRunning)
}
}
fun updatePromConfig(part: UpdatePromConfig, value: Any) {

View File

@ -18,8 +18,6 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
private val TAG = "SETTINGS_PAGE"
@Composable
fun SettingsPage(
promViewModel: PromViewModel,

View File

@ -4,18 +4,19 @@ import android.util.Log
import io.prometheus.client.Collector
import io.prometheus.client.GaugeMetricFamily
private val TAG = "ANDROID_EXPORTER"
private const val TAG = "ANDROID_EXPORTER"
class AndroidCustomExporter(metricEngine: MetricsEngine) : Collector() {
private val metricsEngineRef = metricEngine
override fun collect(): List<MetricFamilySamples> {
Log.v(TAG, "collecting")
Log.d(TAG, "Collecting metrics now")
val mfs: MutableList<MetricFamilySamples> = ArrayList()
// metrics definitions
collectBatteryStatus(mfs)
Log.d(TAG, "Metrics collected")
return mfs
}

View File

@ -5,11 +5,10 @@ import android.content.Intent
import android.content.IntentFilter
import android.os.BatteryManager
class MetricsEngine(context: Context) {
private val contextRef = context
class MetricsEngine(private val context: Context) {
public fun getBatteryPercentage(): Float {
val batteryStatus: Intent? = IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { intFilter ->
contextRef.registerReceiver(null, intFilter)
context.registerReceiver(null, intFilter)
}
//val status: Int = batteryStatus?.getIntExtra(BatteryManager.EXTRA_STATUS, -1) ?: -1

View File

@ -2,6 +2,7 @@ package com.birdthedeveloper.prometheus.android.prometheus.android.exporter.work
import android.app.NotificationManager
import android.content.Context
import android.util.Log
import androidx.core.app.NotificationCompat
import androidx.work.CoroutineWorker
import androidx.work.ForegroundInfo
@ -18,20 +19,24 @@ import kotlinx.coroutines.newSingleThreadContext
import kotlinx.coroutines.withContext
import java.io.StringWriter
private const val TAG = "Worker"
private const val TAG : String = "Worker"
class PromWorker(
val context: Context,
private val context: Context,
parameters: WorkerParameters,
) : CoroutineWorker(context, parameters) {
private val collectorRegistry = CollectorRegistry()
private val metricsEngine: MetricsEngine = MetricsEngine(context)
private val androidCustomExporter: AndroidCustomExporter =
AndroidCustomExporter(metricsEngine).register(collectorRegistry)
private lateinit var pushProxClient: PushProxClient
private var remoteWriteSender: RemoteWriteSender? = null
init {
val androidCustomExporter = AndroidCustomExporter(metricsEngine)
androidCustomExporter.register<AndroidCustomExporter>(collectorRegistry)
}
//TODO foreground notification
private val notificationManager =
context.getSystemService(Context.NOTIFICATION_SERVICE) as
@ -44,6 +49,7 @@ class PromWorker(
}
private suspend fun countSuccessfulScrape() {
Log.d(TAG, "Counting successful scrape")
remoteWriteSender?.countSuccessfulScrape()
}
@ -65,12 +71,14 @@ class PromWorker(
) { context }
)
launch {
Log.d(TAG, "Remote Write launched")
remoteWriteSender?.start()
}
}
if (config.prometheusServerEnabled) {
launch {
Log.d(TAG, "Prometheus server launched")
PrometheusServer.start(
PrometheusServerConfig(
config.prometheusServerPort.toInt(),
@ -92,6 +100,7 @@ class PromWorker(
)
)
launch {
Log.d(TAG, "PushProx launched")
pushProxClient.start()
}
}

View File

@ -24,12 +24,11 @@ data class PrometheusServerConfig(
val countSuccessfulScrape: suspend () -> Unit,
)
// Expose metrics on given port using Ktor http server
class PrometheusServer() {
companion object {
suspend fun start(config: PrometheusServerConfig) {
Log.v(TAG, "Starting prometheus server")
Log.d(TAG, "Starting prometheus server")
val server = configureServer(config)
@ -38,7 +37,7 @@ class PrometheusServer() {
delay(Long.MAX_VALUE)
} finally {
withContext(NonCancellable) {
Log.v(TAG, "Canceling Prometheus server")
Log.d(TAG, "Canceling Prometheus server")
server.stop()
}
}
@ -69,7 +68,6 @@ class PrometheusServer() {
}
private fun configureServer(config: PrometheusServerConfig): ApplicationEngine {
//TODO testing of different providers (CIO, netty, jetty ... for performance)
return embeddedServer(CIO, port = config.port) {
install(StatusPages) {
status(HttpStatusCode.NotFound) { call, status ->
@ -89,6 +87,7 @@ class PrometheusServer() {
get("/metrics") {
call.respondText(config.performScrape())
config.countSuccessfulScrape()
Log.d(TAG, "Successful scrape")
}
}
}

View File

@ -163,7 +163,7 @@ class PushProxClient(private val pushProxConfig: PushProxConfig) {
pushProxConfig.countSuccessfulScrape()
} catch (e: Exception) {
counters.pushError()
Log.v(TAG, "Push exception ${e.toString()}")
Log.v(TAG, "Push exception $e")
return
}
}

View File

@ -83,9 +83,11 @@ class RemoteWriteSender(private val config: RemoteWriteConfiguration) {
private var remoteWriteOn: Boolean = false
private suspend fun performScrapeAndSaveIt(channel: Channel<Unit>) {
Log.d(TAG, "performScrapeAndSaveIt start")
val scrapedMetrics = config.collectorRegistry.metricFamilySamples()
storage.writeScrapedSample(scrapedMetrics)
channel.send(Unit)
Log.d(TAG, "performScrapeAndSaveIt end")
}
private suspend fun scraper(channel: Channel<Unit>) {
@ -106,6 +108,7 @@ class RemoteWriteSender(private val config: RemoteWriteConfiguration) {
}
private suspend fun sendAll() {
Log.d(TAG, "sendAll")
scrapesAreBeingSent = true
while (!storage.isEmpty()) {
val body = storage.getScrapedSamplesCompressedProtobuf(config.maxSamplesPerExport)
@ -145,7 +148,9 @@ class RemoteWriteSender(private val config: RemoteWriteConfiguration) {
if (storage.isEmpty()) {
// channel is conflated, one receive is enough
// suspend here until sending remote write is needed
Log.d(TAG, "Sender manager: waiting on channel receive")
channel.receive()
Log.d(TAG, "Sender Manager: channel received")
}
while (remoteWriteOn || !storage.isEmpty()) {
@ -176,20 +181,20 @@ class RemoteWriteSender(private val config: RemoteWriteConfiguration) {
}
} finally {
withContext(NonCancellable) {
Log.d(TAG, "Canceling Remote Write Sender")
channel.close()
client.close()
Log.v(TAG, "Canceling Remote Write Sender")
}
}
}
fun countSuccessfulScrape() {
Log.v(TAG, "Counting successful scrape")
Log.d(TAG, "Counting successful scrape")
lastTimeRingBuffer.setLastTime(System.currentTimeMillis())
}
private suspend fun sendRequestToRemoteWrite(body: ByteArray) {
Log.v(TAG, "sending to prometheus remote write now")
Log.d(TAG, "Exporting remote write to prometheus now")
val response = client.post(config.remoteWriteEndpoint) {
setBody(body)
headers {
@ -200,7 +205,6 @@ class RemoteWriteSender(private val config: RemoteWriteConfiguration) {
}
}
Log.v(TAG, "Response status: ${response.status}")
Log.v(TAG, "body: ${response.body<String>()}")
Log.d(TAG, "Response status: ${response.status}")
}
}

View File

@ -175,6 +175,7 @@ class RemoteWriteSenderSimpleMemoryStorage : RemoteWriteSenderStorage() {
private val data: Queue<MetricsScrape> = LinkedList()
override fun getScrapedSamplesCompressedProtobuf(howMany: Int): ByteArray {
Log.d(TAG, "Getting scraped samples: $howMany samples")
if (howMany < 1) {
throw IllegalArgumentException("howMany must be bigger than zero")
}
@ -194,7 +195,9 @@ class RemoteWriteSenderSimpleMemoryStorage : RemoteWriteSenderStorage() {
return this.encodeWithSnappy(bytes)
}
//TODO use this thing
override fun removeNumberOfScrapedSamples(number: Int) {
Log.d(TAG, "Removing number of scraped samples: $number samples")
if (number > 0) {
for (i in 1..number) {
data.remove()
@ -205,6 +208,7 @@ class RemoteWriteSenderSimpleMemoryStorage : RemoteWriteSenderStorage() {
}
override fun writeScrapedSample(metricsScrape: MetricsScrape) {
Log.d(TAG, "Writing scraped sample to storage")
data.add(metricsScrape)
}