mirror of
https://github.com/mii443/prometheus-android-exporter.git
synced 2025-12-03 19:18:26 +00:00
prometheus server and pushprox working
This commit is contained in:
22
README.md
22
README.md
@@ -1,11 +1,29 @@
|
|||||||
# prometheus-android-exporter
|
# 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
|
# Not public
|
||||||
143.42.59.63:9090 - prometheus
|
143.42.59.63:9090 - prometheus
|
||||||
|
|
||||||
# Client
|
# 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
|
# Server
|
||||||
|
|
||||||
|
|||||||
@@ -62,6 +62,10 @@ dependencies {
|
|||||||
implementation("io.ktor:ktor-client-core:2.3.0")
|
implementation("io.ktor:ktor-client-core:2.3.0")
|
||||||
implementation("io.ktor:ktor-client-cio: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.core:core-ktx:1.7.0'
|
||||||
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
|
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import android.os.Bundle
|
|||||||
import android.text.BoringLayout.Metrics
|
import android.text.BoringLayout.Metrics
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.material.Button
|
import androidx.compose.material.Button
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material.MaterialTheme
|
||||||
@@ -22,6 +23,7 @@ import kotlinx.coroutines.delay
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.io.StringWriter
|
import java.io.StringWriter
|
||||||
|
|
||||||
|
//https://www.geeksforgeeks.org/how-to-launch-an-application-automatically-on-system-boot-up-in-android/
|
||||||
class MainActivity : ComponentActivity() {
|
class MainActivity : ComponentActivity() {
|
||||||
|
|
||||||
private val collectorRegistry: CollectorRegistry = CollectorRegistry()
|
private val collectorRegistry: CollectorRegistry = CollectorRegistry()
|
||||||
@@ -83,19 +85,36 @@ class MainActivity : ComponentActivity() {
|
|||||||
return writer.toString()
|
return writer.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun startPromServer(){
|
||||||
|
//TODO impl
|
||||||
|
val promServer : PrometheusServer = PrometheusServer(
|
||||||
|
config = PrometheusServerConfig(
|
||||||
|
8080,
|
||||||
|
::reallyCollectMetrics
|
||||||
|
)
|
||||||
|
)
|
||||||
|
promServer.startBackground()
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun PrometheusHomepage() {
|
fun PrometheusHomepage() {
|
||||||
|
Column {
|
||||||
Button(onClick = {
|
Button(onClick = {
|
||||||
println(CollectMetrics())
|
println(CollectMetrics())
|
||||||
}){
|
}) {
|
||||||
Text("Click this button")
|
Text("Click this button")
|
||||||
}
|
}
|
||||||
|
Button(onClick = ::startPromServer){
|
||||||
|
Text("Prometheus server")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO how to call coroutine / async from custom collector
|
//TODO how to call coroutine / async from custom collector
|
||||||
//TODO how to extract any hw system metric from android API
|
//TODO how to extract any hw system metric from android API
|
||||||
//TODO how to get permission on first application start only
|
//TODO how to get permission on first application start only
|
||||||
|
//TODO viewmodel, state management
|
||||||
|
|
||||||
//class GlobalViewModel : ViewModel() {
|
//class GlobalViewModel : ViewModel() {
|
||||||
// val state = mutableStateOf<Int>(Resource.Success(i))
|
// val state = mutableStateOf<Int>(Resource.Success(i))
|
||||||
|
|||||||
@@ -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
12
local/docker-compose.yaml
Normal 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
15
local/prometheus.yaml
Normal 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"
|
||||||
|
]
|
||||||
Reference in New Issue
Block a user