diff --git a/client/.idea/deploymentTargetDropDown.xml b/client/.idea/deploymentTargetDropDown.xml
index 3fb2dab..1acd161 100644
--- a/client/.idea/deploymentTargetDropDown.xml
+++ b/client/.idea/deploymentTargetDropDown.xml
@@ -7,11 +7,11 @@
-
+
-
+
\ No newline at end of file
diff --git a/client/app/src/main/java/com/birdthedeveloper/prometheus/android/exporter/compose/Configuration.kt b/client/app/src/main/java/com/birdthedeveloper/prometheus/android/exporter/compose/Configuration.kt
index af287cb..0605434 100644
--- a/client/app/src/main/java/com/birdthedeveloper/prometheus/android/exporter/compose/Configuration.kt
+++ b/client/app/src/main/java/com/birdthedeveloper/prometheus/android/exporter/compose/Configuration.kt
@@ -17,6 +17,8 @@ private const val defaultPrometheusServerPort: Int = 10101
private const val defaultRemoteWriteScrapeInterval: Int = 30 // seconds
private const val defaultRemoteWriteMaxSamplesPerExport: Int = 60 // seconds
private const val defaultRemoteWriteExportInterval: Int = 120 // seconds
+private const val defaultRemoteWriteJobLabel: String = "test job"
+private const val defaultRemoteWriteInstanceLabel: String = "test instance"
// serialization classes for parsing YAML configuration file
@Serializable
@@ -41,6 +43,8 @@ data class PromConfigFile(
?: defaultRemoteWriteMaxSamplesPerExport).toString(),
remoteWriteExportInterval = (this.remote_write?.export_interval
?: defaultRemoteWriteExportInterval).toString(),
+ remoteWriteInstanceLabel = this.remote_write?.instance ?: defaultRemoteWriteInstanceLabel,
+ remoteWriteJobLabel = this.remote_write?.job ?: defaultRemoteWriteJobLabel,
)
}
}
@@ -65,6 +69,8 @@ data class RemoteWriteConfigFile(
val remote_write_endpoint: String? = null,
val max_samples_per_export: Int? = null,
val export_interval: Int? = null,
+ val job: String? = null,
+ val instance: String? = null,
)
// configuration of a work manager worker
@@ -81,6 +87,8 @@ data class PromConfiguration(
val remoteWriteEndpoint: String = "",
val remoteWriteExportInterval: String = defaultRemoteWriteExportInterval.toString(),
val remoteWriteMaxSamplesPerExport: String = defaultRemoteWriteMaxSamplesPerExport.toString(),
+ val remoteWriteInstanceLabel: String = defaultRemoteWriteInstanceLabel,
+ val remoteWriteJobLabel: String = defaultRemoteWriteJobLabel,
) {
fun toStructuredText(): String {
@@ -98,6 +106,8 @@ data class PromConfiguration(
export_interval: $remoteWriteExportInterval
max_samples_per_export: $remoteWriteMaxSamplesPerExport
remote_write_endpoint: "$remoteWriteEndpoint"
+ instance: "$remoteWriteInstanceLabel"
+ job: "$remoteWriteJobLabel"
""".trimIndent()
}
diff --git a/client/app/src/main/java/com/birdthedeveloper/prometheus/android/exporter/compose/HomeActivity.kt b/client/app/src/main/java/com/birdthedeveloper/prometheus/android/exporter/compose/HomeActivity.kt
index 00b2231..f0dbdcc 100644
--- a/client/app/src/main/java/com/birdthedeveloper/prometheus/android/exporter/compose/HomeActivity.kt
+++ b/client/app/src/main/java/com/birdthedeveloper/prometheus/android/exporter/compose/HomeActivity.kt
@@ -335,10 +335,10 @@ private fun RemoteWritePage(
)
TextField(
- value = uiState.promConfig.remoteWriteMaxSamplesPerExport,
+ value = uiState.promConfig.remoteWriteInstanceLabel,
singleLine = true,
onValueChange = {
- promViewModel.updatePromConfig(UpdatePromConfig.RemoteWriteMaxSamplesPerExport, it)
+ promViewModel.updatePromConfig(UpdatePromConfig.RemoteWriteInstanceLabel, it)
},
label = {
Text(text = "Target label instance")
@@ -347,10 +347,10 @@ private fun RemoteWritePage(
)
TextField(
- value = uiState.promConfig.remoteWriteExportInterval,
+ value = uiState.promConfig.remoteWriteJobLabel,
singleLine = true,
onValueChange = {
- promViewModel.updatePromConfig(UpdatePromConfig.RemoteWriteExportInterval, it)
+ promViewModel.updatePromConfig(UpdatePromConfig.RemoteWriteJobLabel, it)
},
label = {
Text(text = "Target label job")
diff --git a/client/app/src/main/java/com/birdthedeveloper/prometheus/android/exporter/compose/PromViewModel.kt b/client/app/src/main/java/com/birdthedeveloper/prometheus/android/exporter/compose/PromViewModel.kt
index 9efd146..43e6e66 100644
--- a/client/app/src/main/java/com/birdthedeveloper/prometheus/android/exporter/compose/PromViewModel.kt
+++ b/client/app/src/main/java/com/birdthedeveloper/prometheus/android/exporter/compose/PromViewModel.kt
@@ -42,6 +42,8 @@ enum class UpdatePromConfig {
RemoteWriteEndpoint,
RemoteWriteExportInterval,
RemoteWriteMaxSamplesPerExport,
+ RemoteWriteJobLabel,
+ RemoteWriteInstanceLabel,
}
enum class ExporterState {
@@ -388,6 +390,23 @@ class PromViewModel : ViewModel() {
)
)
}
+
+ UpdatePromConfig.RemoteWriteInstanceLabel -> _uiState.update {current ->
+ current.copy(
+ promConfig = current.promConfig.copy(
+ remoteWriteInstanceLabel = value as String
+ )
+ )
+ }
+
+ UpdatePromConfig.RemoteWriteJobLabel -> _uiState.update {current ->
+ current.copy(
+ promConfig = current.promConfig.copy(
+ remoteWriteJobLabel = value as String
+ )
+ )
+ }
+
}
}
}
diff --git a/client/app/src/main/java/com/birdthedeveloper/prometheus/android/exporter/worker/PromWorker.kt b/client/app/src/main/java/com/birdthedeveloper/prometheus/android/exporter/worker/PromWorker.kt
index e83428e..f8786de 100644
--- a/client/app/src/main/java/com/birdthedeveloper/prometheus/android/exporter/worker/PromWorker.kt
+++ b/client/app/src/main/java/com/birdthedeveloper/prometheus/android/exporter/worker/PromWorker.kt
@@ -74,6 +74,10 @@ class PromWorker(
collectorRegistry = collectorRegistry,
exportInterval = config.remoteWriteExportInterval.toInt(),
maxSamplesPerExport = config.remoteWriteMaxSamplesPerExport.toInt(),
+ targetLabels = mapOf(
+ "job" to config.remoteWriteJobLabel,
+ "instance" to config.remoteWriteInstanceLabel,
+ ),
) { context }
)
launch {
diff --git a/client/app/src/main/java/com/birdthedeveloper/prometheus/android/exporter/worker/PushProxClient.kt b/client/app/src/main/java/com/birdthedeveloper/prometheus/android/exporter/worker/PushProxClient.kt
index 170484e..9ce722f 100644
--- a/client/app/src/main/java/com/birdthedeveloper/prometheus/android/exporter/worker/PushProxClient.kt
+++ b/client/app/src/main/java/com/birdthedeveloper/prometheus/android/exporter/worker/PushProxClient.kt
@@ -142,6 +142,7 @@ class PushProxClient(private val pushProxConfig: PushProxConfig) {
Log.d(TAG, "Polling finished")
} else {
Log.d(TAG, "Skipping poll because network not available")
+ throw Exception("Device is not connected to any network")
}
}
@@ -177,24 +178,30 @@ class PushProxClient(private val pushProxConfig: PushProxConfig) {
}
// push metrics to pushprox
- try {
- val scrapeId: String = getIdFromResponseBody(pollResponseBody)
- val pushRequestBody: String = composeRequestBody(scrapedMetrics, scrapeId)
+ // only try to push metrics if device is connected to the network
+ if (Util.deviceIsConnectedToInternet(context.getContext())){
+ try {
+ val scrapeId: String = getIdFromResponseBody(pollResponseBody)
+ val pushRequestBody: String = composeRequestBody(scrapedMetrics, scrapeId)
- context.client.request(context.pushUrl) {
- method = HttpMethod.Post
- setBody(pushRequestBody)
- }
-
-
- pushProxConfig.countSuccessfulScrape()
- } catch (e: Exception) {
- if (e is CancellationException) {
- throw e
+ context.client.request(context.pushUrl) {
+ method = HttpMethod.Post
+ setBody(pushRequestBody)
+ }
+
+
+ pushProxConfig.countSuccessfulScrape()
+ } catch (e: Exception) {
+ if (e is CancellationException) {
+ throw e
+ }
+ counters.pushError()
+ Log.v(TAG, "Push exception $e")
+ return
}
+ }else{
counters.pushError()
- Log.v(TAG, "Push exception $e")
- return
+ Log.d(TAG, "device is not connected to any network")
}
}
diff --git a/client/app/src/main/java/com/birdthedeveloper/prometheus/android/exporter/worker/RemoteWriteSender.kt b/client/app/src/main/java/com/birdthedeveloper/prometheus/android/exporter/worker/RemoteWriteSender.kt
index 24f1ff7..5e33dc3 100644
--- a/client/app/src/main/java/com/birdthedeveloper/prometheus/android/exporter/worker/RemoteWriteSender.kt
+++ b/client/app/src/main/java/com/birdthedeveloper/prometheus/android/exporter/worker/RemoteWriteSender.kt
@@ -81,12 +81,13 @@ data class RemoteWriteConfiguration(
val collectorRegistry: CollectorRegistry,
val maxSamplesPerExport: Int,
val exportInterval: Int,
+ val targetLabels: Map,
val getContext: () -> Context,
)
class RemoteWriteSender(private val config: RemoteWriteConfiguration) {
private val lastTimeRingBuffer = LastTimeRingBuffer(config.scrapeInterval)
- private val storage: RemoteWriteSenderStorage = RemoteWriteSenderSimpleMemoryStorage()
+ private val storage: RemoteWriteSenderStorage = RemoteWriteSenderSimpleMemoryStorage(config.targetLabels)
private var scrapesAreBeingSent: Boolean = false
private lateinit var client: HttpClient
private var lastTimeRemoteWriteSent: Long = 0
@@ -228,33 +229,40 @@ class RemoteWriteSender(private val config: RemoteWriteConfiguration) {
private suspend fun sendRequestToRemoteWrite(body: ByteArray, numOfMetricScrapes: Int) {
Log.d(TAG, "Exporting remote write to prometheus now")
- val response = client.post(config.remoteWriteEndpoint) {
- setBody(body)
- headers {
- append(HttpHeaders.ContentEncoding, "snappy")
- append(HttpHeaders.ContentType, "application/protobuf")
- append(HttpHeaders.UserAgent, "Prometheus Android Exporter")
- header("X-Prometheus-Remote-Write-Version", "0.1.0")
- }
- }
- Log.d(TAG, "Response status: ${response.status}")
-
- when (response.status) {
- HttpStatusCode.NoContent -> {
- // this export was successful
- storage.removeNumberOfScrapedSamples(numOfMetricScrapes)
+ // only send the request if device is online, otherwise throw exception
+ // ExponentialBackoff will catch the exception
+ if (Util.deviceIsConnectedToInternet(config.getContext())){
+ val response = client.post(config.remoteWriteEndpoint) {
+ setBody(body)
+ headers {
+ append(HttpHeaders.ContentEncoding, "snappy")
+ append(HttpHeaders.ContentType, "application/protobuf")
+ append(HttpHeaders.UserAgent, "Prometheus Android Exporter")
+ header("X-Prometheus-Remote-Write-Version", "0.1.0")
+ }
}
- HttpStatusCode.BadRequest -> {
- // probably some error or race condition has occured
- // give up trying to send this data
- storage.removeNumberOfScrapedSamples(numOfMetricScrapes)
- }
+ Log.d(TAG, "Response status: ${response.status}")
- else -> {
- throw TryExportMetricsAgainException("Status code: ${response.status.description}")
+ when (response.status) {
+ HttpStatusCode.NoContent -> {
+ // this export was successful
+ storage.removeNumberOfScrapedSamples(numOfMetricScrapes)
+ }
+
+ HttpStatusCode.BadRequest -> {
+ // probably some error or race condition has occured
+ // give up trying to send this data
+ storage.removeNumberOfScrapedSamples(numOfMetricScrapes)
+ }
+
+ else -> {
+ throw TryExportMetricsAgainException("Status code: ${response.status.description}")
+ }
}
+ }else{
+ throw TryExportMetricsAgainException("Device is not connected to any network")
}
}
}
diff --git a/client/app/src/main/java/com/birdthedeveloper/prometheus/android/exporter/worker/RemoteWriteSenderMemStorage.kt b/client/app/src/main/java/com/birdthedeveloper/prometheus/android/exporter/worker/RemoteWriteSenderMemStorage.kt
index c24958b..3837ffa 100644
--- a/client/app/src/main/java/com/birdthedeveloper/prometheus/android/exporter/worker/RemoteWriteSenderMemStorage.kt
+++ b/client/app/src/main/java/com/birdthedeveloper/prometheus/android/exporter/worker/RemoteWriteSenderMemStorage.kt
@@ -12,7 +12,7 @@ private typealias ConverterHashMap = HashMap, MutableList<
private const val TAG: String = "REMOTE_WRITE_SENDER_MEMORY_SIMPLE_STORAGE"
-class RemoteWriteSenderSimpleMemoryStorage : RemoteWriteSenderStorage() {
+class RemoteWriteSenderSimpleMemoryStorage(val targetLabels: Map) : RemoteWriteSenderStorage() {
private val data: Queue = LinkedList()
private fun filterExpiredMetrics(metrics: MutableList) {
@@ -107,6 +107,17 @@ class RemoteWriteSenderSimpleMemoryStorage : RemoteWriteSenderStorage() {
return hashmapToProtobufWriteRequest(hashmap)
}
+ private fun addTargetLabels(labels: MutableList){
+ targetLabels.forEach {
+ val label = TimeSeriesLabel(
+ value = it.value,
+ name = it.key,
+ )
+
+ labels.add(label)
+ }
+ }
+
private fun processStorageTimeSeries(hashMap: ConverterHashMap, timeSeries: StorageTimeSeries) {
// add remote write label to labels
@@ -114,6 +125,7 @@ class RemoteWriteSenderSimpleMemoryStorage : RemoteWriteSenderStorage() {
// and those scraped by Remote Write
val labels: MutableList = timeSeries.labels.toMutableList()
labels.add(remoteWriteLabel)
+ addTargetLabels(labels)
val immutableLabels: List = labels.toList()
if (hashMap[immutableLabels] == null) {
diff --git a/config_file_structure.yaml b/config_file_structure.yaml
index 83dca41..109ee96 100644
--- a/config_file_structure.yaml
+++ b/config_file_structure.yaml
@@ -42,7 +42,7 @@ remote_write:
export_interval: 60 # default
- # instance and job target labels, no defaults are provided
+ # instance and job target labels, defaults are provided
# string values
- instance:
- job:
+ instance: "test instance"
+ job: "test job"