Skip to content

Commit

Permalink
Merge pull request #126 from amosproj/vis_metrics_updated
Browse files Browse the repository at this point in the history
Vis metrics updated
  • Loading branch information
fhilgers authored Nov 27, 2024
2 parents 0e6dc2b + 5a7a9b2 commit 5709aa4
Show file tree
Hide file tree
Showing 23 changed files with 1,010 additions and 146 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ import android.app.Application
import android.content.Context
import android.content.pm.PackageManager
import de.amosproj3.ziofa.api.ConfigurationAccess
import de.amosproj3.ziofa.api.DataStreamProvider
import de.amosproj3.ziofa.api.ProcessListAccess
import de.amosproj3.ziofa.bl.ConfigurationManager
import de.amosproj3.ziofa.bl.DataStreamManager
import de.amosproj3.ziofa.bl.PackageInformationProvider
import de.amosproj3.ziofa.client.ClientFactory
import de.amosproj3.ziofa.client.RustClientFactory
Expand All @@ -30,13 +32,16 @@ class ZiofaApplication : Application() {
single<PackageManager> { get<Context>().packageManager }
single<PackageInformationProvider> { PackageInformationProvider(get()) }
single<ClientFactory> { RustClientFactory("http://[::1]:50051") }
single<DataStreamProvider> { DataStreamManager(get()) }
single { ConfigurationManager(clientFactory = get()) } binds
arrayOf(ConfigurationAccess::class, ProcessListAccess::class)
viewModel { ConfigurationViewModel(configurationAccess = get()) }
viewModel {
ProcessesViewModel(processListAccess = get(), packageInformationProvider = get())
}
viewModel { VisualizationViewModel(clientFactory = get()) }
viewModel {
VisualizationViewModel(configurationManager = get(), dataStreamProvider = get())
}
}

override fun onCreate() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-FileCopyrightText: 2024 Luca Bretting <[email protected]>
//
// SPDX-License-Identifier: MIT

package de.amosproj3.ziofa.api

import kotlinx.coroutines.flow.Flow

interface DataStreamProvider {
suspend fun counter(ebpfProgramName: String): Flow<UInt>

suspend fun vfsWriteEvents(pids: List<UInt>): Flow<WriteEvent.VfsWriteEvent>

suspend fun sendMessageEvents(pids: List<UInt>): Flow<WriteEvent.SendMessageEvent>
}
28 changes: 28 additions & 0 deletions frontend/app/src/main/java/de/amosproj3/ziofa/api/WriteEvent.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// SPDX-FileCopyrightText: 2024 Luca Bretting <[email protected]>
//
// SPDX-License-Identifier: MIT

package de.amosproj3.ziofa.api

sealed class WriteEvent(
val fileDescriptor: ULong,
val processId: UInt,
val startTimestamp: ULong,
val durationOrSize: ULong,
) {

data class VfsWriteEvent(
val fd: ULong,
val pid: UInt,
val size: ULong,
val timestampMillis: ULong, // unix time
) : WriteEvent(fd, pid, timestampMillis, size)

data class SendMessageEvent(
val fd: ULong,
val pid: UInt,
val tid: UInt,
val beginTimestamp: ULong,
val durationMicros: ULong,
) : WriteEvent(fd, pid, beginTimestamp, durationMicros)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// SPDX-FileCopyrightText: 2024 Luca Bretting <[email protected]>
//
// SPDX-License-Identifier: MIT

package de.amosproj3.ziofa.bl

import de.amosproj3.ziofa.api.DataStreamProvider
import de.amosproj3.ziofa.api.WriteEvent
import de.amosproj3.ziofa.client.ClientFactory
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.map
import timber.log.Timber
import uniffi.shared.EventData

class DataStreamManager(private val clientFactory: ClientFactory) : DataStreamProvider {

override suspend fun counter(ebpfProgramName: String): Flow<UInt> {
return clientFactory
.connect()
.also {
try {
it.load()
// default wifi interface on android, now configurable
it.attach("wlan0")
it.startCollecting()
} catch (e: Exception) {
Timber.e(e.stackTraceToString())
}
}
.serverCount()
}

override suspend fun vfsWriteEvents(pids: List<UInt>): Flow<WriteEvent.VfsWriteEvent> =
clientFactory
.connect()
.initStream()
.map { it.eventData }
.filter { it is EventData.VfsWrite }
.map {
if (it is EventData.VfsWrite) {
WriteEvent.VfsWriteEvent(
it.v1.fp,
it.v1.pid,
it.v1.bytesWritten,
it.v1.beginTimeStamp,
)
} else throw Exception("only for the compiler")
}

override suspend fun sendMessageEvents(pids: List<UInt>): Flow<WriteEvent.SendMessageEvent> =
clientFactory
.connect()
.initStream()
.map { it.eventData }
.filter { it is EventData.SysSendmsg }
.map {
if (it is EventData.SysSendmsg) {
WriteEvent.SendMessageEvent(
it.v1.fd.toULong(),
it.v1.pid,
it.v1.tid,
it.v1.beginTimeStamp,
it.v1.durationMicroSec,
)
} else throw Exception("only for the compiler")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ fun ConfigurationScreen(
EbpfOptions(
options = state.options,
onVfsWriteChanged = { newValue -> viewModel.vfsWriteChanged(pids, newValue) },
onSendMessageChanged = { newValue ->
viewModel.sendMessageChanged(pids, newValue)
},
)

// Show the submit button if the user changed settings
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import de.amosproj3.ziofa.api.ConfigurationAccess
import de.amosproj3.ziofa.api.ConfigurationUpdate
import de.amosproj3.ziofa.ui.configuration.data.ConfigurationScreenState
import de.amosproj3.ziofa.ui.configuration.data.EbpfProgramOptions
import de.amosproj3.ziofa.ui.configuration.data.VfsWriteOption
import de.amosproj3.ziofa.ui.configuration.data.WriteOption
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
Expand All @@ -21,6 +21,7 @@ import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import timber.log.Timber
import uniffi.shared.Configuration
import uniffi.shared.SysSendmsgConfig
import uniffi.shared.VfsWriteConfig

class ConfigurationViewModel(val configurationAccess: ConfigurationAccess) : ViewModel() {
Expand All @@ -30,7 +31,10 @@ class ConfigurationViewModel(val configurationAccess: ConfigurationAccess) : Vie

private val checkedOptions =
MutableStateFlow(
EbpfProgramOptions(vfsWriteOption = VfsWriteOption(enabled = false, pids = listOf()))
EbpfProgramOptions(
vfsWriteOption = WriteOption.VfsWriteOption(enabled = false, pids = listOf()),
sendMessageOption = WriteOption.SendMessageOption(enabled = false, pids = listOf()),
)
)

private val _configurationScreenState =
Expand All @@ -54,7 +58,21 @@ class ConfigurationViewModel(val configurationAccess: ConfigurationAccess) : Vie
checkedOptions.update {
it.copy(
vfsWriteOption =
VfsWriteOption(
WriteOption.VfsWriteOption(
enabled = newState,
pids = pids?.let { it.map { it.toUInt() } } ?: listOf(),
)
)
}
_configurationScreenState.update { ConfigurationScreenState.Valid(checkedOptions.value) }
_changed.update { true }
}

fun sendMessageChanged(pids: IntArray?, newState: Boolean) {
checkedOptions.update {
it.copy(
sendMessageOption =
WriteOption.SendMessageOption(
enabled = newState,
pids = pids?.let { it.map { it.toUInt() } } ?: listOf(),
)
Expand Down Expand Up @@ -92,19 +110,32 @@ class ConfigurationViewModel(val configurationAccess: ConfigurationAccess) : Vie

private fun ConfigurationUpdate.Valid.toUIOptions(): EbpfProgramOptions {
val vfsOption =
this.configuration.vfsWrite?.let { VfsWriteOption(enabled = true, pids = it.pids) }
?: VfsWriteOption(enabled = false, pids = listOf())
this.configuration.vfsWrite?.let {
WriteOption.VfsWriteOption(enabled = true, pids = it.pids)
} ?: WriteOption.VfsWriteOption(enabled = false, pids = listOf())

return EbpfProgramOptions(vfsWriteOption = vfsOption)
val sendMsgOption =
this.configuration.sysSendmsg?.let {
WriteOption.SendMessageOption(enabled = true, pids = it.pids)
} ?: WriteOption.SendMessageOption(enabled = false, pids = listOf())

return EbpfProgramOptions(vfsWriteOption = vfsOption, sendMessageOption = sendMsgOption)
}

private fun EbpfProgramOptions.toConfiguration(): Configuration {
val vfsConfig =
if (this.vfsWriteOption.enabled) {
VfsWriteConfig(this.vfsWriteOption.pids)
} else null
val sendMessageConfig =
if (this.sendMessageOption.enabled) {
SysSendmsgConfig(this.sendMessageOption.pids)
} else null

// TODO: sysSendmsg
return Configuration(vfsWrite = vfsConfig, sysSendmsg = null, uprobes = listOf())
return Configuration(
vfsWrite = vfsConfig,
sysSendmsg = sendMessageConfig,
uprobes = listOf(),
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ import androidx.compose.ui.unit.dp
import de.amosproj3.ziofa.ui.configuration.data.EbpfProgramOptions

@Composable
fun EbpfOptions(options: EbpfProgramOptions, onVfsWriteChanged: (Boolean) -> Unit) {
fun EbpfOptions(
options: EbpfProgramOptions,
onVfsWriteChanged: (Boolean) -> Unit,
onSendMessageChanged: (Boolean) -> Unit,
) {
LazyColumn(modifier = Modifier.padding(horizontal = 20.dp).fillMaxSize()) {
item { Spacer(Modifier.height(15.dp)) }

Expand All @@ -39,5 +43,19 @@ fun EbpfOptions(options: EbpfProgramOptions, onVfsWriteChanged: (Boolean) -> Uni
)
}
}

item {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
) {
Text("Send Message Analysis")
Checkbox(
checked = options.sendMessageOption.enabled,
onCheckedChange = onSendMessageChanged,
)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@

package de.amosproj3.ziofa.ui.configuration.data

data class EbpfProgramOptions(val vfsWriteOption: VfsWriteOption)
data class EbpfProgramOptions(
val vfsWriteOption: WriteOption.VfsWriteOption,
val sendMessageOption: WriteOption.SendMessageOption,
)

data class VfsWriteOption(val enabled: Boolean, val pids: List<UInt>)
sealed class WriteOption() {
data class VfsWriteOption(val enabled: Boolean, val pids: List<UInt>)

data class SendMessageOption(val enabled: Boolean, val pids: List<UInt>)
}
Loading

0 comments on commit 5709aa4

Please sign in to comment.