Skip to content

Commit d2a14dc

Browse files
committed
Merge branch 'feat/error-reporting-v2' into 'master'
Přidány logy a další kontext pro crash reporting See merge request fmasa/pv239-project!64
2 parents c9d1380 + b26d733 commit d2a14dc

20 files changed

+114
-40
lines changed

app/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,4 +137,6 @@ dependencies {
137137
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
138138

139139
implementation "io.arrow-kt:arrow-core:0.10.4"
140+
141+
implementation 'com.jakewharton.timber:timber:4.7.1'
140142
}

app/src/main/java/cz/muni/fi/rpg/Application.kt

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
package cz.muni.fi.rpg
22

3+
import com.google.firebase.crashlytics.FirebaseCrashlytics
4+
import cz.muni.fi.rpg.common.log.CrashlyticsTree
5+
import cz.muni.fi.rpg.common.log.KoinTimberLogger
36
import cz.muni.fi.rpg.di.appModule
47
import org.koin.android.ext.koin.androidContext
5-
import org.koin.android.ext.koin.androidLogger
68
import org.koin.androidx.fragment.koin.fragmentFactory
79
import org.koin.core.context.startKoin
10+
import timber.log.Timber
811
import android.app.Application as BaseApplication
912

1013
class Application : BaseApplication() {
@@ -16,9 +19,15 @@ class Application : BaseApplication() {
1619

1720
// declare used Android context
1821
androidContext(this@Application)
19-
androidLogger()
22+
logger(KoinTimberLogger())
2023
// declare modules
2124
modules(appModule)
2225
}
26+
27+
Timber.plant(
28+
if (BuildConfig.DEBUG)
29+
Timber.DebugTree()
30+
else CrashlyticsTree(FirebaseCrashlytics.getInstance())
31+
)
2332
}
2433
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package cz.muni.fi.rpg.common.log
2+
3+
import android.util.Log
4+
import com.google.firebase.crashlytics.FirebaseCrashlytics
5+
import timber.log.Timber
6+
7+
/**
8+
* Handles log entries as either log context or error reporting to Crashlytics
9+
*/
10+
class CrashlyticsTree(
11+
private val crashlytics: FirebaseCrashlytics
12+
) : Timber.Tree() {
13+
14+
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
15+
crashlytics.log(message)
16+
17+
if (priority == Log.WARN || priority == Log.ERROR) {
18+
crashlytics.recordException(t ?: Exception(message))
19+
}
20+
}
21+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package cz.muni.fi.rpg.common.log
2+
3+
import org.koin.core.logger.KOIN_TAG
4+
import org.koin.core.logger.Level
5+
import org.koin.core.logger.Logger
6+
import timber.log.Timber
7+
8+
class KoinTimberLogger(level: Level = Level.INFO) : Logger(level) {
9+
10+
private val tree = Timber.tag(KOIN_TAG)
11+
12+
override fun log(level: Level, msg: String) {
13+
when (level) {
14+
Level.DEBUG -> tree.d(msg)
15+
Level.INFO -> tree.i(msg)
16+
Level.ERROR -> tree.e(msg)
17+
else -> tree.e(msg)
18+
}
19+
}
20+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package cz.muni.fi.rpg.common.log
2+
3+
import com.google.firebase.crashlytics.FirebaseCrashlytics
4+
5+
class Reporter {
6+
companion object {
7+
private val crashlytics by lazy { FirebaseCrashlytics.getInstance() }
8+
9+
fun setUserId(id: String) {
10+
crashlytics.setUserId(id)
11+
}
12+
}
13+
}
14+
15+

app/src/main/java/cz/muni/fi/rpg/model/firestore/jackson/JacksonAggregateMapper.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
package cz.muni.fi.rpg.model.firestore.jackson
22

3-
import android.util.Log
43
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility
54
import com.fasterxml.jackson.annotation.PropertyAccessor
65
import com.fasterxml.jackson.core.type.TypeReference
76
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
87
import com.google.firebase.firestore.DocumentSnapshot
98
import cz.muni.fi.rpg.model.firestore.AggregateMapper
109
import cz.muni.fi.rpg.model.firestore.DocumentData
10+
import timber.log.Timber
1111
import kotlin.reflect.KClass
1212

1313
internal class JacksonAggregateMapper<T : Any>(
@@ -21,7 +21,7 @@ internal class JacksonAggregateMapper<T : Any>(
2121
.setVisibility(PropertyAccessor.IS_GETTER, Visibility.NONE)
2222

2323
override fun fromDocumentSnapshot(snapshot: DocumentSnapshot): T {
24-
Log.d("JacksonAggregateMapper", "Mapping document $snapshot to ${aggregateType.simpleName}")
24+
Timber.d("Mapping document $snapshot to ${aggregateType.simpleName}")
2525
return mapper.convertValue(snapshot.data, aggregateType.java)
2626
}
2727

app/src/main/java/cz/muni/fi/rpg/model/firestore/repositories/FirestoreCharacterRepository.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package cz.muni.fi.rpg.model.firestore.repositories
22

3-
import android.util.Log
43
import androidx.lifecycle.LiveData
54
import arrow.core.Either
65
import com.google.firebase.firestore.FirebaseFirestore
@@ -12,19 +11,19 @@ import cz.muni.fi.rpg.model.domain.character.CharacterNotFound
1211
import cz.muni.fi.rpg.model.domain.character.CharacterRepository
1312
import cz.muni.fi.rpg.model.firestore.*
1413
import kotlinx.coroutines.tasks.await
14+
import timber.log.Timber
1515
import java.util.*
1616

1717
internal class FirestoreCharacterRepository(
1818
firestore: FirebaseFirestore,
1919
private val mapper: AggregateMapper<Character>
2020
) : CharacterRepository {
21-
private val tag = this::class.simpleName
2221
private val parties = firestore.collection(COLLECTION_PARTIES)
2322

2423
override suspend fun save(partyId: UUID, character: Character) {
2524
val data = mapper.toDocumentData(character)
2625

27-
Log.d(tag,"Saving character $data in party $partyId to firestore")
26+
Timber.d("Saving character $data in party $partyId to firestore")
2827
characters(partyId).document(character.userId).set(data, SetOptions.merge()).await()
2928
}
3029

app/src/main/java/cz/muni/fi/rpg/model/firestore/repositories/FirestoreInventoryItemRepository.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package cz.muni.fi.rpg.model.firestore.repositories
22

3-
import android.util.Log
43
import com.google.firebase.firestore.CollectionReference
54
import com.google.firebase.firestore.FirebaseFirestore
65
import com.google.firebase.firestore.FirebaseFirestoreException
@@ -12,12 +11,12 @@ import cz.muni.fi.rpg.model.domain.inventory.InventoryItemNotFound
1211
import cz.muni.fi.rpg.model.domain.inventory.InventoryItemRepository
1312
import cz.muni.fi.rpg.model.firestore.*
1413
import kotlinx.coroutines.tasks.await
14+
import timber.log.Timber
1515

1616
internal class FirestoreInventoryItemRepository(
1717
firestore: FirebaseFirestore,
1818
private val mapper: AggregateMapper<InventoryItem>
1919
) : InventoryItemRepository {
20-
private val tag = this::class.simpleName
2120
private val parties = firestore.collection(COLLECTION_PARTIES)
2221

2322
override fun findAllForCharacter(characterId: CharacterId) =
@@ -28,7 +27,7 @@ internal class FirestoreInventoryItemRepository(
2827

2928
override suspend fun save(characterId: CharacterId, item: InventoryItem) {
3029
val data = mapper.toDocumentData(item)
31-
Log.d(tag,"Saving inventory item $data for character $characterId")
30+
Timber.d("Saving inventory item $data for character $characterId")
3231

3332
inventoryItems(characterId)
3433
.document(item.id.toString())

app/src/main/java/cz/muni/fi/rpg/model/firestore/repositories/FirestorePartyRepository.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package cz.muni.fi.rpg.model.firestore.repositories
22

3-
import android.util.Log
43
import androidx.lifecycle.LiveData
54
import arrow.core.Either
65
import com.google.firebase.firestore.FirebaseFirestore
@@ -14,19 +13,19 @@ import cz.muni.fi.rpg.model.firestore.AggregateMapper
1413
import cz.muni.fi.rpg.model.firestore.DocumentLiveData
1514
import cz.muni.fi.rpg.model.firestore.QueryLiveData
1615
import kotlinx.coroutines.tasks.await
16+
import timber.log.Timber
1717
import java.util.*
1818

1919
internal class FirestorePartyRepository(
2020
private val firestore: FirebaseFirestore,
2121
private val mapper: AggregateMapper<Party>
2222
) : PartyRepository {
23-
private val tag = this::class.simpleName
2423
private val parties = firestore.collection("parties")
2524

2625
override suspend fun save(party: Party) {
2726
val data = mapper.toDocumentData(party)
2827

29-
Log.d(tag,"Saving party $data to firestore")
28+
Timber.d("Saving party $data to firestore")
3029
try {
3130
firestore.runTransaction { transaction ->
3231
transaction.set(parties.document(party.id.toString()), data, SetOptions.merge())

app/src/main/java/cz/muni/fi/rpg/ui/StartupActivity.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import android.content.Intent
44
import android.widget.Toast
55
import androidx.appcompat.app.AppCompatActivity
66
import cz.muni.fi.rpg.R
7+
import cz.muni.fi.rpg.common.log.Reporter
78
import cz.muni.fi.rpg.viewModels.AuthenticationViewModel
89
import kotlinx.coroutines.CoroutineScope
910
import kotlinx.coroutines.Dispatchers
@@ -21,6 +22,7 @@ class StartupActivity : AppCompatActivity(R.layout.activity_startup),
2122

2223
launch {
2324
if (viewModel.isAuthenticated() || viewModel.authenticateAnonymously()) {
25+
Reporter.setUserId(viewModel.getUserId())
2426
showPartyList()
2527
} else {
2628
withContext(Dispatchers.Main) {

0 commit comments

Comments
 (0)