prometheus server and pushprox working

This commit is contained in:
Martin Ptáček
2023-05-02 15:54:33 +02:00
parent d9e8cbf5b9
commit 5b8132b750
6 changed files with 144 additions and 6 deletions

View File

@@ -1,11 +1,29 @@
# prometheus-android-exporter
Prometheus exporter for android
Prometheus exporter for android phones. Can traverse NAT by leveraging PushProx proxy. Not intended
to run as ROOT. Exposes various hardware sensor metrics.
# Repository contents
- Folder ./client contains Jetpack Compose android Prometheus exporter written in kotlin.
- Folder ./server contains ansible playbook for simple deployment of prometheus monitoring stack
on a virtual private server, that is deployment of prometheus database itself, grafana
monitoring dashboard and pushprox, a prometheus proxy used to traverse NAT while still following
the pull model.
- Folder ./local contains simple docker-compose.yaml to spin up prometheus database on localhost
quickly.
# Not public
143.42.59.63:9090 - prometheus
# Client
Android app written in kotlin using Jetpack Compose.
### ADB port forwarding
ADB port forwarding is usefull when running the client application
on android emulator and prometheus database on the host
ADB port forwarding allows to map specific host's port to emulator's port
Syntax is as follows (for port 8080)
```
$ adb forward tcp:8080 tcp:8080
```
# Server

View File

@@ -62,6 +62,10 @@ dependencies {
implementation("io.ktor:ktor-client-core:2.3.0")
implementation("io.ktor:ktor-client-cio:2.3.0")
// ktor web server
implementation "io.ktor:ktor-server-cio:2.3.0"
implementation "io.ktor:ktor-server-core:2.3.0"
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'

View File

@@ -4,6 +4,7 @@ import android.os.Bundle
import android.text.BoringLayout.Metrics
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
@@ -22,6 +23,7 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.io.StringWriter
//https://www.geeksforgeeks.org/how-to-launch-an-application-automatically-on-system-boot-up-in-android/
class MainActivity : ComponentActivity() {
private val collectorRegistry: CollectorRegistry = CollectorRegistry()
@@ -83,12 +85,28 @@ class MainActivity : ComponentActivity() {
return writer.toString()
}
private fun startPromServer(){
//TODO impl
val promServer : PrometheusServer = PrometheusServer(
config = PrometheusServerConfig(
8080,
::reallyCollectMetrics
)
)
promServer.startBackground()
}
@Composable
fun PrometheusHomepage() {
Button(onClick = {
println(CollectMetrics())
}){
Text("Click this button")
Column {
Button(onClick = {
println(CollectMetrics())
}) {
Text("Click this button")
}
Button(onClick = ::startPromServer){
Text("Prometheus server")
}
}
}
}
@@ -96,6 +114,7 @@ class MainActivity : ComponentActivity() {
//TODO how to call coroutine / async from custom collector
//TODO how to extract any hw system metric from android API
//TODO how to get permission on first application start only
//TODO viewmodel, state management
//class GlobalViewModel : ViewModel() {
// val state = mutableStateOf<Int>(Resource.Success(i))

View File

@@ -0,0 +1,70 @@
package com.birdthedeveloper.prometheus.android.prometheus.android.exporter
import android.util.Log
import io.ktor.server.application.call
import io.ktor.server.engine.*
import io.ktor.server.cio.*
import io.ktor.server.response.respondText
import io.ktor.server.routing.get
import io.ktor.server.routing.routing
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
fun something(){
//TODO
}
// Configuration object for PrometheusServer class
data class PrometheusServerConfig(
val port : Int = 8080,
val performScrape : suspend () -> String,
)
// Expose metrics on given port using Ktor http server
class PrometheusServer(config: PrometheusServerConfig){
private val config : PrometheusServerConfig
private lateinit var server : ApplicationEngine
init {
this.config = config
}
private suspend fun getMetrics() : String{
val result : String = try{
config.performScrape()
}catch(e: Exception){
""
}
return result
}
private fun configureServer(){
server = embeddedServer(CIO, port = config.port) {
routing {
get("/") {
call.respondText("Prometheus Android Exporter")
}
get("/metrics") {
call.respondText(getMetrics())
}
}
}
}
fun startBackground(){
configureServer()
GlobalScope.launch {
launch{
server.start(wait = true)
}
}
log("startBackground", "done")
}
private fun log(title: String, text: String) {
Log.v("PROMETHEUS SERVER", "$title: $text")
}
}

12
local/docker-compose.yaml Normal file
View File

@@ -0,0 +1,12 @@
# Simple run of prometheus database with a configuration file on localhost
version: '3.9'
services:
prometheus:
container_name: prometheus
image: bitnami/prometheus:2.43.0
restart: on-failure
volumes:
- ./prometheus.yaml:/etc/prometheus/prometheus.yml
network_mode: host

15
local/prometheus.yaml Normal file
View File

@@ -0,0 +1,15 @@
# Prometheus global configuration file
global:
scrape_interval: 5s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
scrape_configs:
- job_name: "prometheus"
static_configs:
- targets: ["localhost:9090"] # scrape prometheus itself
- job_name: "android phones"
static_configs:
- targets: [
"localhost:8080"
]