Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adds ability to export libxmtp logs from native to react native #466

Merged
merged 3 commits into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ import org.xmtp.proto.message.contents.Invitation.ConsentProofPayload
import org.xmtp.proto.message.contents.PrivateKeyOuterClass
import uniffi.xmtpv3.org.xmtp.android.library.libxmtp.GroupPermissionPreconfiguration
import uniffi.xmtpv3.org.xmtp.android.library.libxmtp.PermissionOption
import java.io.BufferedReader
import java.io.File
import java.io.InputStreamReader
import java.util.Date
import java.util.UUID
import kotlin.coroutines.Continuation
Expand Down Expand Up @@ -1564,12 +1566,29 @@ class XMTPModule : Module() {
val client = clients[inboxId] ?: throw XMTPException("No client")
client.contacts.isGroupAllowed(groupId)
}

AsyncFunction("isGroupDenied") { inboxId: String, groupId: String ->
logV("isGroupDenied")
val client = clients[inboxId] ?: throw XMTPException("No client")
client.contacts.isGroupDenied(groupId)
}

AsyncFunction("exportNativeLogs") Coroutine { ->
withContext(Dispatchers.IO) {
try {
val process = Runtime.getRuntime().exec("logcat -d")
val bufferedReader = BufferedReader(InputStreamReader(process.inputStream))

val log = StringBuilder()
var line: String?
while (bufferedReader.readLine().also { line = it } != null) {
log.append(line).append("\n")
}
log.toString()
} catch (e: Exception) {
e.message
}
}
}
}

//
Expand Down
9 changes: 2 additions & 7 deletions example/src/tests/groupTests.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import { Wallet } from 'ethers'
import RNFS from 'react-native-fs'
import { DecodedMessage } from 'xmtp-react-native-sdk/lib/DecodedMessage'

import {
Test,
assert,
createClients,
delayToPropogate,
} from './test-utils'
import { Test, assert, createClients, delayToPropogate } from './test-utils'
import {
Client,
Conversation,
Expand All @@ -17,7 +13,6 @@ import {
GroupUpdatedContent,
GroupUpdatedCodec,
} from '../../../src/index'
import { Wallet } from 'ethers'

export const groupTests: Test[] = []
let counter = 1
Expand Down
12 changes: 11 additions & 1 deletion example/src/tests/tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { PrivateKeyAccount } from 'viem'
import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts'
import { DecodedMessage } from 'xmtp-react-native-sdk/lib/DecodedMessage'

import { Test, assert, delayToPropogate } from './test-utils'
import { Test, assert, createClients, delayToPropogate } from './test-utils'
import {
Query,
JSContentCodec,
Expand Down Expand Up @@ -1526,3 +1526,13 @@ test('can start conversations without consent proofs', async () => {
await delayToPropogate()
return true
})

test('can export logs', async () => {
await createClients(2)

const logs = await Client.exportNativeLogs()
console.log(logs)
assert(logs.includes('libxmtp'), 'should be able to read libxmtp logs')

return true
})
16 changes: 16 additions & 0 deletions ios/XMTPModule.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import ExpoModulesCore
import XMTP
import LibXMTP
import OSLog

extension Conversation {
static func cacheKeyForTopic(inboxId: String, topic: String) -> String {
Expand Down Expand Up @@ -1459,6 +1460,21 @@ public class XMTPModule: Module {
}
return await client.contacts.isGroupDenied(groupId: groupId)
}

AsyncFunction("exportNativeLogs") { () -> String in
var logOutput = ""
let logStore = try OSLogStore(scope: .currentProcessIdentifier)
let position = logStore.position(timeIntervalSinceLatestBoot: -300) // Last 5 min of logs
let entries = try logStore.getEntries(at: position)

for entry in entries {
if let logEntry = entry as? OSLogEntryLog {
logOutput.append("\(logEntry.date): \(logEntry.composedMessage)\n")
}
}

return logOutput
}
}

//
Expand Down
4 changes: 4 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1149,6 +1149,10 @@ export async function processWelcomeMessage<
return new Group(client, JSON.parse(json))
}

export async function exportNativeLogs() {
return XMTPModule.exportNativeLogs()
}

export const emitter = new EventEmitter(XMTPModule ?? NativeModulesProxy.XMTP)

interface AuthParams {
Expand Down
4 changes: 4 additions & 0 deletions src/lib/Client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,10 @@ export class Client<
})
}

static async exportNativeLogs() {
return XMTPModule.exportNativeLogs()
}

private static removeAllSubscriptions(
createSubscription?: Subscription,
enableSubscription?: Subscription,
Expand Down
Loading