mirror of
https://github.com/mii443/prometheus-android-exporter.git
synced 2025-08-22 15:15:35 +00:00
first portion of metrics
This commit is contained in:
@ -74,4 +74,9 @@ $ ansible-playbook ansible_playbook.yaml --tags config
|
|||||||
|
|
||||||
## List of exported metrics:
|
## List of exported metrics:
|
||||||
|
|
||||||
TODO: add grafana dashboard json here
|
`android_battery_charge_ratio` - Current battery charge
|
||||||
|
`android_system_info{manufacturer, model, os_release, cpu_core_count}` - Information about Android system
|
||||||
|
`android_uptime_seconds` - Phone uptime in seconds
|
||||||
|
`android_cpu_active_seconds{core}` - Active CPU time in seconds since last time system booted
|
||||||
|
`android_cpu_total_seconds{core}` - Total CPU time in seconds since last time system booted
|
||||||
|
`android_system_temperature_celsius{where}` - Temperature on the device
|
||||||
|
1
client/.idea/gradle.xml
generated
1
client/.idea/gradle.xml
generated
@ -7,6 +7,7 @@
|
|||||||
<option name="testRunner" value="GRADLE" />
|
<option name="testRunner" value="GRADLE" />
|
||||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
|
<option name="gradleJvm" value="jbr-17" />
|
||||||
<option name="modules">
|
<option name="modules">
|
||||||
<set>
|
<set>
|
||||||
<option value="$PROJECT_DIR$" />
|
<option value="$PROJECT_DIR$" />
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
||||||
<uses-feature android:name="android.hardware.sensor.accelerometer" android:required="true" />
|
<uses-feature android:name="android.hardware.sensor.accelerometer" android:required="true" />
|
||||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||||
|
<uses-permission android:name="android.permission.DEVICE_POWER"/>
|
||||||
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
|
@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
package com.birdthedeveloper.prometheus.android.exporter.worker
|
package com.birdthedeveloper.prometheus.android.exporter.worker
|
||||||
|
|
||||||
|
import android.os.CpuUsageInfo
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import io.prometheus.client.Collector
|
import io.prometheus.client.Collector
|
||||||
|
import io.prometheus.client.Gauge
|
||||||
import io.prometheus.client.GaugeMetricFamily
|
import io.prometheus.client.GaugeMetricFamily
|
||||||
|
|
||||||
private const val TAG = "ANDROID_EXPORTER"
|
private const val TAG = "ANDROID_EXPORTER"
|
||||||
@ -15,32 +17,23 @@ class AndroidCustomExporter(private val metricEngine: MetricsEngine) : Collector
|
|||||||
val mfs: MutableList<MetricFamilySamples> = ArrayList()
|
val mfs: MutableList<MetricFamilySamples> = ArrayList()
|
||||||
|
|
||||||
//TODO scrape_duration gauge
|
//TODO scrape_duration gauge
|
||||||
|
val startTime = System.currentTimeMillis()
|
||||||
|
|
||||||
// metrics definitions
|
// metrics definitions
|
||||||
// collectBatteryStatus(mfs)
|
collectBatteryChargeRatio(mfs)
|
||||||
// collectGps(mfs)
|
collectUptimeInSeconds(mfs)
|
||||||
collectSteps(mfs)
|
// collectCpuUsage(mfs)
|
||||||
|
collectHasWiFiConnection(mfs)
|
||||||
|
collectHasCellularConnection(mfs)
|
||||||
|
// collectDeviceTemperatures(mfs)
|
||||||
|
collectAndroidInfo(mfs)
|
||||||
|
|
||||||
|
collectScrapeDuration(mfs, startTime)
|
||||||
|
|
||||||
Log.d(TAG, "Metrics collected")
|
Log.d(TAG, "Metrics collected")
|
||||||
return mfs
|
return mfs
|
||||||
}
|
}
|
||||||
|
|
||||||
// private fun collectBatteryStatus(mfs: MutableList<MetricFamilySamples>) {
|
|
||||||
// //TODO
|
|
||||||
// val batteryPercentageGauge = GaugeMetricFamily(
|
|
||||||
// "battery_percentage", //TODO convert to ratio
|
|
||||||
// "Current battery percentage", listOf(),
|
|
||||||
// )
|
|
||||||
//
|
|
||||||
// val batteryPercentage: Double = metricsEngineRef.batteryChargeRatio().toDouble()
|
|
||||||
// batteryPercentageGauge.addMetric(listOf(), batteryPercentage)
|
|
||||||
// mfs.add(batteryPercentageGauge)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// private fun collectGps(mfs: MutableList<MetricFamilySamples>){
|
|
||||||
// //TODO
|
|
||||||
// }
|
|
||||||
|
|
||||||
private fun collectSteps(mfs: MutableList<MetricFamilySamples>){
|
private fun collectSteps(mfs: MutableList<MetricFamilySamples>){
|
||||||
val gauge = GaugeMetricFamily(
|
val gauge = GaugeMetricFamily(
|
||||||
"steps",
|
"steps",
|
||||||
@ -50,4 +43,110 @@ class AndroidCustomExporter(private val metricEngine: MetricsEngine) : Collector
|
|||||||
gauge.addMetric(listOf(), 1.0)
|
gauge.addMetric(listOf(), 1.0)
|
||||||
mfs.add(gauge)
|
mfs.add(gauge)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun collectBatteryChargeRatio(mfs : MutableList<MetricFamilySamples>){
|
||||||
|
val gauge = GaugeMetricFamily(
|
||||||
|
"android_battery_charge_ratio",
|
||||||
|
"Current battery charge",
|
||||||
|
listOf(),
|
||||||
|
)
|
||||||
|
gauge.addMetric(listOf(), metricEngine.getBatteryChargeRatio())
|
||||||
|
mfs.add(gauge)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun collectUptimeInSeconds(mfs : MutableList<MetricFamilySamples>){
|
||||||
|
val gauge = GaugeMetricFamily(
|
||||||
|
"android_uptime_seconds",
|
||||||
|
"Android uptime in seconds",
|
||||||
|
listOf(),
|
||||||
|
)
|
||||||
|
gauge.addMetric(listOf(), metricEngine.getUptimeInSeconds())
|
||||||
|
mfs.add(gauge)
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO this does not work
|
||||||
|
private fun collectCpuUsage(mfs : MutableList<MetricFamilySamples>){
|
||||||
|
var coreIndex= 0
|
||||||
|
val cpuUsage : Array<CpuUsageInfo> = metricEngine.getCpuUsage()
|
||||||
|
val gaugeActive = GaugeMetricFamily(
|
||||||
|
"android_cpu_active_seconds",
|
||||||
|
"Active CPU time in seconds since last system booted",
|
||||||
|
listOf("core"),
|
||||||
|
)
|
||||||
|
val gaugeTotal = GaugeMetricFamily(
|
||||||
|
"android_cpu_total_seconds",
|
||||||
|
"Total CPU time in seconds since last system booted",
|
||||||
|
listOf("core")
|
||||||
|
)
|
||||||
|
|
||||||
|
cpuUsage.forEach {
|
||||||
|
gaugeActive.addMetric(listOf((coreIndex++).toString()), it.active / 1000.0)
|
||||||
|
gaugeActive.addMetric(listOf((coreIndex++).toString()), it.total / 1000.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
mfs.addAll(listOf(gaugeTotal, gaugeActive))
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO does not work
|
||||||
|
private fun collectDeviceTemperatures(mfs : MutableList<MetricFamilySamples>){
|
||||||
|
val deviceTemperatures = metricEngine.getDeviceTemperatures()
|
||||||
|
val gauge = GaugeMetricFamily(
|
||||||
|
"android_system_temperature_celsius{where}` - ",
|
||||||
|
"Temperature on the device",
|
||||||
|
listOf("where")
|
||||||
|
)
|
||||||
|
deviceTemperatures.entries.forEach{
|
||||||
|
gauge.addMetric(listOf(it.key), it.value)
|
||||||
|
}
|
||||||
|
mfs.add(gauge)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun collectHasWiFiConnection(mfs : MutableList<MetricFamilySamples>){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun collectHasCellularConnection(mfs : MutableList<MetricFamilySamples>){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun collectAndroidInfo(mfs : MutableList<MetricFamilySamples>){
|
||||||
|
val gauge = GaugeMetricFamily(
|
||||||
|
"android_system_info",
|
||||||
|
"Static information about the android phone",
|
||||||
|
listOf("manufacturer", "model", "os_release","cpu_core_count")
|
||||||
|
)
|
||||||
|
gauge.addMetric(listOf(
|
||||||
|
metricEngine.getAndroidManufacturer(),
|
||||||
|
metricEngine.getAndroidModel(),
|
||||||
|
metricEngine.getAndroidOsVersion(),
|
||||||
|
metricEngine.getNumberOfCpuCores().toString(),
|
||||||
|
), 1.0)
|
||||||
|
mfs.add(gauge)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun collectNumberOfCpuCores(mfs : MutableList<MetricFamilySamples>){
|
||||||
|
val gauge = GaugeMetricFamily(
|
||||||
|
"android_system_info",
|
||||||
|
"Static information about the android phone",
|
||||||
|
listOf("manufacturer", "model", "os_release",)
|
||||||
|
)
|
||||||
|
gauge.addMetric(listOf(
|
||||||
|
metricEngine.getAndroidManufacturer(),
|
||||||
|
metricEngine.getAndroidModel(),
|
||||||
|
metricEngine.getAndroidOsVersion(),
|
||||||
|
), 1.0)
|
||||||
|
mfs.add(gauge)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun collectScrapeDuration(mfs : MutableList<MetricFamilySamples>, startTime : Long){
|
||||||
|
val gauge = GaugeMetricFamily(
|
||||||
|
"android_scrape_duration_seconds",
|
||||||
|
"Duration of the metric scrape",
|
||||||
|
listOf()
|
||||||
|
)
|
||||||
|
|
||||||
|
val differenceMilis = System.currentTimeMillis() - startTime
|
||||||
|
gauge.addMetric(listOf(), differenceMilis / 1000.0)
|
||||||
|
mfs.add(gauge)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,10 +27,6 @@ data class AxisSpecificGauge(
|
|||||||
)
|
)
|
||||||
|
|
||||||
class HwSensorsCache(
|
class HwSensorsCache(
|
||||||
var batteryChargeRatio : Double? = null,
|
|
||||||
var numberOfSteps : Int? = null,
|
|
||||||
|
|
||||||
|
|
||||||
var headingDegrees : Double? = null,
|
var headingDegrees : Double? = null,
|
||||||
var headingAccuracyDegrees : Double? = null,
|
var headingAccuracyDegrees : Double? = null,
|
||||||
var hingeAngleDegrees : Double? = null,
|
var hingeAngleDegrees : Double? = null,
|
||||||
@ -83,11 +79,10 @@ val temperatureTypes : Map<Int, String> = mapOf(
|
|||||||
class MetricsEngine(private val context: Context) : SensorEventListener {
|
class MetricsEngine(private val context: Context) : SensorEventListener {
|
||||||
private val sensorManager = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager
|
private val sensorManager = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager
|
||||||
private val hwSensorsCache = HwSensorsCache()
|
private val hwSensorsCache = HwSensorsCache()
|
||||||
val hwPropertiesManager = context.getSystemService(Context.HARDWARE_PROPERTIES_SERVICE) as HardwarePropertiesManager
|
private val hwPropertiesManager = context.getSystemService(Context.HARDWARE_PROPERTIES_SERVICE) as HardwarePropertiesManager
|
||||||
|
|
||||||
init {
|
init {
|
||||||
//TODO
|
registerAllHwEventHandlers()
|
||||||
//registerAllHwEventHandlers()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hwSensorsValues(): HwSensorsCache {
|
fun hwSensorsValues(): HwSensorsCache {
|
||||||
@ -108,7 +103,7 @@ class MetricsEngine(private val context: Context) : SensorEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun dispose() {
|
fun dispose() {
|
||||||
//sensorManager.unregisterListener(this)
|
sensorManager.unregisterListener(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSensorChanged(event: SensorEvent?) {
|
override fun onSensorChanged(event: SensorEvent?) {
|
||||||
@ -193,15 +188,7 @@ class MetricsEngine(private val context: Context) : SensorEventListener {
|
|||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getBatteryChargeRatio(): Double {
|
||||||
// - network availability
|
|
||||||
// - 4G, 5G
|
|
||||||
// - ram
|
|
||||||
// - scrape duration
|
|
||||||
// - bluetooth - mac bluetooth
|
|
||||||
// - storage information
|
|
||||||
|
|
||||||
fun batteryChargeRatio(): Float {
|
|
||||||
val batteryStatus: Intent? = IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { intFilter ->
|
val batteryStatus: Intent? = IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { intFilter ->
|
||||||
context.registerReceiver(null, intFilter)
|
context.registerReceiver(null, intFilter)
|
||||||
}
|
}
|
||||||
@ -213,8 +200,8 @@ class MetricsEngine(private val context: Context) : SensorEventListener {
|
|||||||
level / scale.toFloat()
|
level / scale.toFloat()
|
||||||
}
|
}
|
||||||
|
|
||||||
batteryRatio ?: return -1.0f
|
batteryRatio ?: return -1.0
|
||||||
return batteryRatio
|
return batteryRatio.toDouble()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getNumberOfCpuCores(): Int {
|
fun getNumberOfCpuCores(): Int {
|
||||||
@ -225,7 +212,7 @@ class MetricsEngine(private val context: Context) : SensorEventListener {
|
|||||||
return SystemClock.elapsedRealtime() / 1000.0
|
return SystemClock.elapsedRealtime() / 1000.0
|
||||||
}
|
}
|
||||||
|
|
||||||
fun cpuUsage() : Array<CpuUsageInfo> {
|
fun getCpuUsage() : Array<CpuUsageInfo> {
|
||||||
return hwPropertiesManager.cpuUsages
|
return hwPropertiesManager.cpuUsages
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,7 +242,11 @@ class MetricsEngine(private val context: Context) : SensorEventListener {
|
|||||||
return Build.MANUFACTURER
|
return Build.MANUFACTURER
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO has_celular
|
fun getHasCellularConnected() : Boolean {
|
||||||
//TODO has_wifi
|
TODO()
|
||||||
//TODO prefix metrics with exporter name - android_ ...
|
}
|
||||||
|
|
||||||
|
fun getHasWiFiConnected() : Boolean {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
# Prometheus global configuration file
|
# Prometheus global configuration file
|
||||||
global:
|
global:
|
||||||
scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
|
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.
|
evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
|
||||||
scrape_configs:
|
scrape_configs:
|
||||||
- job_name: "prometheus"
|
- job_name: "prometheus"
|
||||||
|
Reference in New Issue
Block a user