diff --git a/app/build.gradle b/app/build.gradle
index decdc202..b3253cdd 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -75,13 +75,15 @@ dependencies {
implementation 'androidx.preference:preference-ktx:1.2.0'
implementation 'com.github.cyb3rko:QuickPermissions-Kotlin:1.1.2'
- implementation 'com.hypertrack:hyperlog:0.0.10'
implementation 'com.squareup.picasso:picasso:2.71828'
implementation 'io.noties.markwon:core:4.6.2'
implementation 'io.noties.markwon:image-picasso:4.6.2'
implementation 'io.noties.markwon:image:4.6.2'
implementation 'io.noties.markwon:ext-tables:4.6.2'
implementation 'io.noties.markwon:ext-strikethrough:4.6.2'
+
+ implementation 'org.tinylog:tinylog-api-kotlin:2.6.2'
+ implementation 'org.tinylog:tinylog-impl:2.6.2'
}
configurations {
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 6cbd775e..ff4af56d 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -12,6 +12,7 @@
= Build.VERSION_CODES.O) {
+ NotificationSupport.createForegroundChannel(
+ this,
+ this.getSystemService(NotificationManager::class.java)
+ )
+ }
+
+ super.onCreate()
+ }
+}
diff --git a/app/src/main/kotlin/com/github/gotify/MissedMessageUtil.kt b/app/src/main/kotlin/com/github/gotify/MissedMessageUtil.kt
index 3a697593..52e1a0f6 100644
--- a/app/src/main/kotlin/com/github/gotify/MissedMessageUtil.kt
+++ b/app/src/main/kotlin/com/github/gotify/MissedMessageUtil.kt
@@ -5,7 +5,7 @@ import com.github.gotify.api.ApiException
import com.github.gotify.api.Callback
import com.github.gotify.client.api.MessageApi
import com.github.gotify.client.model.Message
-import com.github.gotify.log.Log
+import org.tinylog.kotlin.Logger
internal class MissedMessageUtil(private val api: MessageApi) {
fun lastReceivedMessage(acceptID: (Long) -> Unit) {
@@ -41,7 +41,7 @@ internal class MissedMessageUtil(private val api: MessageApi) {
since = pagedMessages.paging.since
}
} catch (e: ApiException) {
- Log.e("cannot retrieve missing messages", e)
+ Logger.error(e, "cannot retrieve missing messages")
}
return result.reversed()
}
diff --git a/app/src/main/kotlin/com/github/gotify/NotificationSupport.kt b/app/src/main/kotlin/com/github/gotify/NotificationSupport.kt
index dd27c224..c9f5800c 100644
--- a/app/src/main/kotlin/com/github/gotify/NotificationSupport.kt
+++ b/app/src/main/kotlin/com/github/gotify/NotificationSupport.kt
@@ -10,7 +10,7 @@ import android.os.Build
import androidx.annotation.RequiresApi
import androidx.preference.PreferenceManager
import com.github.gotify.client.model.Application
-import com.github.gotify.log.Log
+import org.tinylog.kotlin.Logger
internal object NotificationSupport {
@RequiresApi(Build.VERSION_CODES.O)
@@ -93,7 +93,7 @@ internal object NotificationSupport {
notificationManager.createNotificationChannel(messagesImportanceDefault)
notificationManager.createNotificationChannel(messagesImportanceHigh)
} catch (e: Exception) {
- Log.e("Could not create channel", e)
+ Logger.error(e, "Could not create channel")
}
}
@@ -168,7 +168,7 @@ internal object NotificationSupport {
notificationManager.createNotificationChannel(messagesImportanceDefault)
notificationManager.createNotificationChannel(messagesImportanceHigh)
} catch (e: Exception) {
- Log.e("Could not create channel", e)
+ Logger.error(e, "Could not create channel")
}
}
diff --git a/app/src/main/kotlin/com/github/gotify/Utils.kt b/app/src/main/kotlin/com/github/gotify/Utils.kt
index 772d562a..196d0481 100644
--- a/app/src/main/kotlin/com/github/gotify/Utils.kt
+++ b/app/src/main/kotlin/com/github/gotify/Utils.kt
@@ -12,7 +12,6 @@ import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import com.github.gotify.client.JSON
-import com.github.gotify.log.Log
import com.google.android.material.snackbar.Snackbar
import com.google.gson.Gson
import com.squareup.picasso.Picasso.LoadedFrom
@@ -31,6 +30,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import okio.Buffer
import org.threeten.bp.OffsetDateTime
+import org.tinylog.kotlin.Logger
internal object Utils {
val JSON: Gson = JSON().gson
@@ -63,10 +63,10 @@ internal object Utils {
URL(URL(baseURL), target).toString()
}
} catch (e: MalformedURLException) {
- Log.e("Could not resolve absolute url", e)
+ Logger.error(e, "Could not resolve absolute url")
target
} catch (e: URISyntaxException) {
- Log.e("Could not resolve absolute url", e)
+ Logger.error(e, "Could not resolve absolute url")
target
}
}
@@ -79,7 +79,7 @@ internal object Utils {
}
override fun onBitmapFailed(e: Exception, errorDrawable: Drawable) {
- Log.e("Bitmap failed", e)
+ Logger.error(e, "Bitmap failed")
}
override fun onPrepareLoad(placeHolderDrawable: Drawable) {}
diff --git a/app/src/main/kotlin/com/github/gotify/api/Callback.kt b/app/src/main/kotlin/com/github/gotify/api/Callback.kt
index 0ef273cd..5b0d0f1e 100644
--- a/app/src/main/kotlin/com/github/gotify/api/Callback.kt
+++ b/app/src/main/kotlin/com/github/gotify/api/Callback.kt
@@ -1,7 +1,9 @@
package com.github.gotify.api
import android.app.Activity
-import com.github.gotify.log.Log
+import com.github.gotify.api.Callback.ErrorCallback
+import com.github.gotify.api.Callback.SuccessCallback
+import org.tinylog.kotlin.Logger
import retrofit2.Call
import retrofit2.Response
@@ -65,7 +67,7 @@ internal class Callback private constructor(
private fun errorCallback(): Callback {
return Callback(
onSuccess = {},
- onError = { exception -> Log.e("Error while api call", exception) }
+ onError = { exception -> Logger.error(exception, "Error while api call") }
)
}
diff --git a/app/src/main/kotlin/com/github/gotify/api/CertUtils.kt b/app/src/main/kotlin/com/github/gotify/api/CertUtils.kt
index 60a295bf..ce0cb26c 100644
--- a/app/src/main/kotlin/com/github/gotify/api/CertUtils.kt
+++ b/app/src/main/kotlin/com/github/gotify/api/CertUtils.kt
@@ -3,7 +3,6 @@ package com.github.gotify.api
import android.annotation.SuppressLint
import com.github.gotify.SSLSettings
import com.github.gotify.Utils
-import com.github.gotify.log.Log
import java.io.IOException
import java.security.GeneralSecurityException
import java.security.KeyStore
@@ -16,15 +15,18 @@ import javax.net.ssl.TrustManager
import javax.net.ssl.TrustManagerFactory
import javax.net.ssl.X509TrustManager
import okhttp3.OkHttpClient
+import org.tinylog.kotlin.Logger
internal object CertUtils {
@SuppressLint("CustomX509TrustManager")
private val trustAll = object : X509TrustManager {
@SuppressLint("TrustAllX509TrustManager")
- override fun checkClientTrusted(chain: Array, authType: String) {}
+ override fun checkClientTrusted(chain: Array, authType: String) {
+ }
@SuppressLint("TrustAllX509TrustManager")
- override fun checkServerTrusted(chain: Array, authType: String) {}
+ override fun checkServerTrusted(chain: Array, authType: String) {
+ }
override fun getAcceptedIssuers() = arrayOf()
}
@@ -62,7 +64,7 @@ internal object CertUtils {
}
} catch (e: Exception) {
// We shouldn't have issues since the cert is verified on login.
- Log.e("Failed to apply SSL settings", e)
+ Logger.error(e, "Failed to apply SSL settings")
}
}
diff --git a/app/src/main/kotlin/com/github/gotify/init/InitializationActivity.kt b/app/src/main/kotlin/com/github/gotify/init/InitializationActivity.kt
index fc9e7433..474c3af9 100644
--- a/app/src/main/kotlin/com/github/gotify/init/InitializationActivity.kt
+++ b/app/src/main/kotlin/com/github/gotify/init/InitializationActivity.kt
@@ -2,8 +2,6 @@ package com.github.gotify.init
import android.Manifest
import android.app.AlarmManager
-import android.app.NotificationManager
-import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
@@ -13,8 +11,6 @@ import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
-import androidx.preference.PreferenceManager
-import com.github.gotify.NotificationSupport
import com.github.gotify.R
import com.github.gotify.Settings
import com.github.gotify.api.ApiException
@@ -23,16 +19,14 @@ import com.github.gotify.api.Callback.SuccessCallback
import com.github.gotify.api.ClientFactory
import com.github.gotify.client.model.User
import com.github.gotify.client.model.VersionInfo
-import com.github.gotify.log.Log
-import com.github.gotify.log.UncaughtExceptionHandler
import com.github.gotify.login.LoginActivity
import com.github.gotify.messages.MessagesActivity
import com.github.gotify.service.WebSocketService
-import com.github.gotify.settings.ThemeHelper
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.livinglifetechway.quickpermissionskotlin.runWithPermissions
import com.livinglifetechway.quickpermissionskotlin.util.QuickPermissionsOptions
import com.livinglifetechway.quickpermissionskotlin.util.QuickPermissionsRequest
+import org.tinylog.kotlin.Logger
internal class InitializationActivity : AppCompatActivity() {
@@ -47,20 +41,8 @@ internal class InitializationActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- Log.init(this)
- val theme = PreferenceManager.getDefaultSharedPreferences(this)
- .getString(getString(R.string.setting_key_theme), getString(R.string.theme_default))!!
- ThemeHelper.setTheme(this, theme)
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- NotificationSupport.createForegroundChannel(
- this,
- (this.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager)
- )
- }
- UncaughtExceptionHandler.registerCurrentThread()
settings = Settings(this)
- Log.i("Entering ${javaClass.simpleName}")
+ Logger.info("Entering ${javaClass.simpleName}")
installSplashScreen().setKeepOnScreenCondition { splashScreenActive }
@@ -115,6 +97,7 @@ internal class InitializationActivity : AppCompatActivity() {
dialog(getString(R.string.not_available, settings.url))
return
}
+
401 -> {
dialog(getString(R.string.auth_failed))
return
@@ -153,7 +136,7 @@ internal class InitializationActivity : AppCompatActivity() {
}
private fun authenticated(user: User) {
- Log.i("Authenticated as ${user.name}")
+ Logger.info("Authenticated as ${user.name}")
settings.setUser(user.name, user.isAdmin)
requestVersion {
@@ -172,7 +155,7 @@ internal class InitializationActivity : AppCompatActivity() {
private fun requestVersion(runnable: Runnable) {
requestVersion(
callback = Callback.SuccessBody { version: VersionInfo ->
- Log.i("Server version: ${version.version}@${version.buildDate}")
+ Logger.info("Server version: ${version.version}@${version.buildDate}")
settings.serverVersion = version.version
runnable.run()
},
diff --git a/app/src/main/kotlin/com/github/gotify/log/Format.kt b/app/src/main/kotlin/com/github/gotify/log/Format.kt
deleted file mode 100644
index 578d2319..00000000
--- a/app/src/main/kotlin/com/github/gotify/log/Format.kt
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.github.gotify.log
-
-import android.content.Context
-import com.hypertrack.hyperlog.LogFormat
-
-internal class Format(context: Context) : LogFormat(context) {
- override fun getFormattedLogMessage(
- logLevelName: String,
- tag: String,
- message: String,
- timeStamp: String,
- senderName: String,
- osVersion: String,
- deviceUuid: String
- ) = "$timeStamp $logLevelName: $message"
-}
diff --git a/app/src/main/kotlin/com/github/gotify/log/Log.kt b/app/src/main/kotlin/com/github/gotify/log/Log.kt
deleted file mode 100644
index a4f3b912..00000000
--- a/app/src/main/kotlin/com/github/gotify/log/Log.kt
+++ /dev/null
@@ -1,47 +0,0 @@
-package com.github.gotify.log
-
-import android.content.Context
-import android.util.Log
-import com.hypertrack.hyperlog.HyperLog
-
-internal object Log {
- private const val TAG = "gotify"
-
- fun init(content: Context) {
- HyperLog.initialize(content, Format(content))
- HyperLog.setLogLevel(Log.INFO) // TODO configurable
- }
-
- fun get(): String {
- val logs = HyperLog.getDeviceLogsAsStringList(false)
- return logs.takeLast(200).reversed().joinToString("\n")
- }
-
- fun e(message: String) {
- HyperLog.e(TAG, message)
- }
-
- fun e(message: String, e: Throwable) {
- HyperLog.e(TAG, "$message\n${Log.getStackTraceString(e)}")
- }
-
- fun i(message: String) {
- HyperLog.i(TAG, message)
- }
-
- fun i(message: String, e: Throwable) {
- HyperLog.i(TAG, "$message\n${Log.getStackTraceString(e)}")
- }
-
- fun w(message: String) {
- HyperLog.w(TAG, message)
- }
-
- fun w(message: String, e: Throwable) {
- HyperLog.w(TAG, "$message\n${Log.getStackTraceString(e)}")
- }
-
- fun clear() {
- HyperLog.deleteLogs()
- }
-}
diff --git a/app/src/main/kotlin/com/github/gotify/log/LoggerHelper.kt b/app/src/main/kotlin/com/github/gotify/log/LoggerHelper.kt
new file mode 100644
index 00000000..cee7cca1
--- /dev/null
+++ b/app/src/main/kotlin/com/github/gotify/log/LoggerHelper.kt
@@ -0,0 +1,43 @@
+package com.github.gotify.log
+
+import android.content.Context
+import java.io.File
+import org.tinylog.kotlin.Logger
+
+class LoggerHelper {
+ companion object {
+ fun read(ctx: Context): String = folder(ctx)
+ .listFiles()
+ .orEmpty()
+ .flatMap { it.readLines() }
+ .fold(mutableListOf()) { newLines, line -> groupExceptions(newLines, line) }
+ .takeLast(200)
+ .reversed()
+ .joinToString(separator = "\n")
+
+ private fun groupExceptions(
+ newLines: MutableList,
+ line: String
+ ): MutableList {
+ if (newLines.isNotEmpty() && (line.startsWith('\t') || line.startsWith("Caused"))) {
+ newLines[newLines.lastIndex] += '\n' + line
+ } else {
+ newLines.add(line)
+ }
+ return newLines
+ }
+
+ fun clear(ctx: Context) {
+ folder(ctx).listFiles()?.forEach { it.writeText("") }
+ Logger.info("Logs cleared")
+ }
+
+ fun init(ctx: Context) {
+ val file = folder(ctx)
+ file.mkdirs()
+ System.setProperty("tinylog.directory", file.absolutePath)
+ }
+
+ private fun folder(ctx: Context): File = File(ctx.filesDir, "log")
+ }
+}
diff --git a/app/src/main/kotlin/com/github/gotify/log/LogsActivity.kt b/app/src/main/kotlin/com/github/gotify/log/LogsActivity.kt
index d78dbc41..4fc06102 100644
--- a/app/src/main/kotlin/com/github/gotify/log/LogsActivity.kt
+++ b/app/src/main/kotlin/com/github/gotify/log/LogsActivity.kt
@@ -15,6 +15,7 @@ import com.github.gotify.Utils.launchCoroutine
import com.github.gotify.databinding.ActivityLogsBinding
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
+import org.tinylog.kotlin.Logger
internal class LogsActivity : AppCompatActivity() {
@@ -25,7 +26,7 @@ internal class LogsActivity : AppCompatActivity() {
super.onCreate(savedInstanceState)
binding = ActivityLogsBinding.inflate(layoutInflater)
setContentView(binding.root)
- Log.i("Entering ${javaClass.simpleName}")
+ Logger.info("Entering ${javaClass.simpleName}")
updateLogs()
setSupportActionBar(binding.appBarDrawer.toolbar)
val actionBar = supportActionBar
@@ -37,7 +38,7 @@ internal class LogsActivity : AppCompatActivity() {
private fun updateLogs() {
launchCoroutine {
- val log = Log.get()
+ val log = LoggerHelper.read(this)
withContext(Dispatchers.Main) {
val content = binding.logContent
if (content.selectionStart == content.selectionEnd) {
@@ -62,11 +63,13 @@ internal class LogsActivity : AppCompatActivity() {
finish()
true
}
+
R.id.action_delete_logs -> {
- Log.clear()
+ LoggerHelper.clear(this)
binding.logContent.text = null
true
}
+
R.id.action_copy_logs -> {
val content = binding.logContent
val clipboardManager =
@@ -76,6 +79,7 @@ internal class LogsActivity : AppCompatActivity() {
Utils.showSnackBar(this, getString(R.string.logs_copied))
true
}
+
else -> false
}
}
diff --git a/app/src/main/kotlin/com/github/gotify/log/UncaughtExceptionHandler.kt b/app/src/main/kotlin/com/github/gotify/log/UncaughtExceptionHandler.kt
index 024af8ab..92aebcad 100644
--- a/app/src/main/kotlin/com/github/gotify/log/UncaughtExceptionHandler.kt
+++ b/app/src/main/kotlin/com/github/gotify/log/UncaughtExceptionHandler.kt
@@ -1,11 +1,11 @@
package com.github.gotify.log
-import com.github.gotify.log.Log.e
+import org.tinylog.kotlin.Logger
internal object UncaughtExceptionHandler {
fun registerCurrentThread() {
- Thread.setDefaultUncaughtExceptionHandler { _, e: Throwable? ->
- e("uncaught exception", e!!)
+ Thread.setDefaultUncaughtExceptionHandler { _, e: Throwable ->
+ Logger.error(e, "uncaught exception")
}
}
}
diff --git a/app/src/main/kotlin/com/github/gotify/login/LoginActivity.kt b/app/src/main/kotlin/com/github/gotify/login/LoginActivity.kt
index 77305c73..1f2d31ef 100644
--- a/app/src/main/kotlin/com/github/gotify/login/LoginActivity.kt
+++ b/app/src/main/kotlin/com/github/gotify/login/LoginActivity.kt
@@ -27,13 +27,13 @@ import com.github.gotify.client.model.VersionInfo
import com.github.gotify.databinding.ActivityLoginBinding
import com.github.gotify.databinding.ClientNameDialogBinding
import com.github.gotify.init.InitializationActivity
-import com.github.gotify.log.Log
import com.github.gotify.log.LogsActivity
import com.github.gotify.log.UncaughtExceptionHandler
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.textfield.TextInputEditText
import java.security.cert.X509Certificate
import okhttp3.HttpUrl
+import org.tinylog.kotlin.Logger
internal class LoginActivity : AppCompatActivity() {
private lateinit var binding: ActivityLoginBinding
@@ -69,7 +69,7 @@ internal class LoginActivity : AppCompatActivity() {
UncaughtExceptionHandler.registerCurrentThread()
binding = ActivityLoginBinding.inflate(layoutInflater)
setContentView(binding.root)
- Log.i("Entering ${javaClass.simpleName}")
+ Logger.info("Entering ${javaClass.simpleName}")
settings = Settings(this)
}
diff --git a/app/src/main/kotlin/com/github/gotify/messages/MessagesActivity.kt b/app/src/main/kotlin/com/github/gotify/messages/MessagesActivity.kt
index ac49dd66..929fa708 100644
--- a/app/src/main/kotlin/com/github/gotify/messages/MessagesActivity.kt
+++ b/app/src/main/kotlin/com/github/gotify/messages/MessagesActivity.kt
@@ -45,7 +45,6 @@ import com.github.gotify.client.model.Client
import com.github.gotify.client.model.Message
import com.github.gotify.databinding.ActivityMessagesBinding
import com.github.gotify.init.InitializationActivity
-import com.github.gotify.log.Log
import com.github.gotify.log.LogsActivity
import com.github.gotify.login.LoginActivity
import com.github.gotify.messages.provider.MessageState
@@ -60,6 +59,7 @@ import com.google.android.material.snackbar.Snackbar
import java.io.IOException
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
+import org.tinylog.kotlin.Logger
internal class MessagesActivity :
AppCompatActivity(),
@@ -89,7 +89,7 @@ internal class MessagesActivity :
binding = ActivityMessagesBinding.inflate(layoutInflater)
setContentView(binding.root)
viewModel = ViewModelProvider(this, MessagesModelFactory(this))[MessagesModel::class.java]
- Log.i("Entering " + javaClass.simpleName)
+ Logger.info("Entering " + javaClass.simpleName)
initDrawer()
val layoutManager = LinearLayoutManager(this)
@@ -132,6 +132,7 @@ internal class MessagesActivity :
override fun onDrawerOpened(drawerView: View) {
onBackPressedCallback.isEnabled = true
}
+
override fun onDrawerClosed(drawerView: View) {
updateAppOnDrawerClose?.let { selectApp ->
updateAppOnDrawerClose = null
@@ -175,7 +176,7 @@ internal class MessagesActivity :
try {
viewModel.picassoHandler.evict()
} catch (e: IOException) {
- Log.e("Problem evicting Picasso cache", e)
+ Logger.error(e, "Problem evicting Picasso cache")
}
startActivity(Intent(this, InitializationActivity::class.java))
finish()
@@ -625,13 +626,13 @@ internal class MessagesActivity :
}
}
if (currentClient != null) {
- Log.i("Delete client with id " + currentClient.id)
+ Logger.info("Delete client with id " + currentClient.id)
Api.execute(api.deleteClient(currentClient.id))
} else {
- Log.e("Could not delete client, client does not exist.")
+ Logger.error("Could not delete client, client does not exist.")
}
} catch (e: ApiException) {
- Log.e("Could not delete client", e)
+ Logger.error(e, "Could not delete client")
}
viewModel.settings.clear()
diff --git a/app/src/main/kotlin/com/github/gotify/messages/provider/MessageRequester.kt b/app/src/main/kotlin/com/github/gotify/messages/provider/MessageRequester.kt
index 973ea1fc..d2eb3f28 100644
--- a/app/src/main/kotlin/com/github/gotify/messages/provider/MessageRequester.kt
+++ b/app/src/main/kotlin/com/github/gotify/messages/provider/MessageRequester.kt
@@ -6,31 +6,31 @@ import com.github.gotify.api.Callback
import com.github.gotify.client.api.MessageApi
import com.github.gotify.client.model.Message
import com.github.gotify.client.model.PagedMessages
-import com.github.gotify.log.Log
+import org.tinylog.kotlin.Logger
internal class MessageRequester(private val messageApi: MessageApi) {
fun loadMore(state: MessageState): PagedMessages? {
return try {
- Log.i("Loading more messages for ${state.appId}")
+ Logger.info("Loading more messages for ${state.appId}")
if (MessageState.ALL_MESSAGES == state.appId) {
Api.execute(messageApi.getMessages(LIMIT, state.nextSince))
} else {
Api.execute(messageApi.getAppMessages(state.appId, LIMIT, state.nextSince))
}
} catch (apiException: ApiException) {
- Log.e("failed requesting messages", apiException)
+ Logger.error(apiException, "failed requesting messages")
null
}
}
fun asyncRemoveMessage(message: Message) {
- Log.i("Removing message with id ${message.id}")
+ Logger.info("Removing message with id ${message.id}")
messageApi.deleteMessage(message.id).enqueue(Callback.call())
}
fun deleteAll(appId: Long): Boolean {
return try {
- Log.i("Deleting all messages for $appId")
+ Logger.info("Deleting all messages for $appId")
if (MessageState.ALL_MESSAGES == appId) {
Api.execute(messageApi.deleteMessages())
} else {
@@ -38,7 +38,7 @@ internal class MessageRequester(private val messageApi: MessageApi) {
}
true
} catch (e: ApiException) {
- Log.e("Could not delete messages", e)
+ Logger.error(e, "Could not delete messages")
false
}
}
diff --git a/app/src/main/kotlin/com/github/gotify/picasso/PicassoDataRequestHandler.kt b/app/src/main/kotlin/com/github/gotify/picasso/PicassoDataRequestHandler.kt
index 14f00528..091fb6f8 100644
--- a/app/src/main/kotlin/com/github/gotify/picasso/PicassoDataRequestHandler.kt
+++ b/app/src/main/kotlin/com/github/gotify/picasso/PicassoDataRequestHandler.kt
@@ -2,10 +2,10 @@ package com.github.gotify.picasso
import android.graphics.BitmapFactory
import android.util.Base64
-import com.github.gotify.log.Log
import com.squareup.picasso.Picasso
import com.squareup.picasso.Request
import com.squareup.picasso.RequestHandler
+import org.tinylog.kotlin.Logger
/**
* Adapted from https://github.com/square/picasso/issues/1395#issuecomment-220929377 By
@@ -30,7 +30,7 @@ internal class PicassoDataRequestHandler : RequestHandler() {
if (bitmap == null) {
val show = if (uri.length > 50) uri.take(50) + "..." else uri
val malformed = RuntimeException("Malformed data uri: $show")
- Log.e("Could not load image", malformed)
+ Logger.error(malformed, "Could not load image")
throw malformed
}
diff --git a/app/src/main/kotlin/com/github/gotify/picasso/PicassoHandler.kt b/app/src/main/kotlin/com/github/gotify/picasso/PicassoHandler.kt
index 1a80bdb4..0189d6aa 100644
--- a/app/src/main/kotlin/com/github/gotify/picasso/PicassoHandler.kt
+++ b/app/src/main/kotlin/com/github/gotify/picasso/PicassoHandler.kt
@@ -8,13 +8,13 @@ import com.github.gotify.Settings
import com.github.gotify.Utils
import com.github.gotify.api.CertUtils
import com.github.gotify.client.model.Application
-import com.github.gotify.log.Log
import com.squareup.picasso.OkHttp3Downloader
import com.squareup.picasso.Picasso
import java.io.File
import java.io.IOException
import okhttp3.Cache
import okhttp3.OkHttpClient
+import org.tinylog.kotlin.Logger
internal class PicassoHandler(private val context: Context, private val settings: Settings) {
companion object {
@@ -52,7 +52,7 @@ internal class PicassoHandler(private val context: Context, private val settings
Utils.resolveAbsoluteUrl("${settings.url}/", app.image)
)
} catch (e: IOException) {
- Log.e("Could not load image for notification", e)
+ Logger.error(e, "Could not load image for notification")
}
return BitmapFactory.decodeResource(context.resources, R.drawable.gotify)
}
diff --git a/app/src/main/kotlin/com/github/gotify/service/WebSocketConnection.kt b/app/src/main/kotlin/com/github/gotify/service/WebSocketConnection.kt
index a92922bf..6b149840 100644
--- a/app/src/main/kotlin/com/github/gotify/service/WebSocketConnection.kt
+++ b/app/src/main/kotlin/com/github/gotify/service/WebSocketConnection.kt
@@ -8,7 +8,6 @@ import com.github.gotify.SSLSettings
import com.github.gotify.Utils
import com.github.gotify.api.CertUtils
import com.github.gotify.client.model.Message
-import com.github.gotify.log.Log
import java.util.Calendar
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicLong
@@ -18,6 +17,7 @@ import okhttp3.Request
import okhttp3.Response
import okhttp3.WebSocket
import okhttp3.WebSocketListener
+import org.tinylog.kotlin.Logger
internal class WebSocketConnection(
private val baseUrl: String,
@@ -105,7 +105,7 @@ internal class WebSocketConnection(
close()
state = State.Connecting
val nextId = ID.incrementAndGet()
- Log.i("WebSocket($nextId): starting...")
+ Logger.info("WebSocket($nextId): starting...")
webSocket = client.newWebSocket(request(), Listener(nextId))
return this
@@ -116,7 +116,7 @@ internal class WebSocketConnection(
if (webSocket != null) {
webSocket?.close(1000, "")
closed()
- Log.i("WebSocket(${ID.get()}): closing existing connection.")
+ Logger.info("WebSocket(${ID.get()}): closing existing connection.")
}
}
@@ -134,7 +134,7 @@ internal class WebSocketConnection(
state = State.Scheduled
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- Log.i("WebSocket: scheduling a restart in $seconds second(s) (via alarm manager)")
+ Logger.info("WebSocket: scheduling a restart in $seconds second(s) (via alarm manager)")
val future = Calendar.getInstance()
future.add(Calendar.SECOND, seconds.toInt())
alarmManager.setExact(
@@ -145,7 +145,7 @@ internal class WebSocketConnection(
null
)
} else {
- Log.i("WebSocket: scheduling a restart in $seconds second(s)")
+ Logger.info("WebSocket: scheduling a restart in $seconds second(s)")
reconnectHandler.removeCallbacks(reconnectCallback)
reconnectHandler.postDelayed(reconnectCallback, TimeUnit.SECONDS.toMillis(seconds))
}
@@ -155,7 +155,7 @@ internal class WebSocketConnection(
override fun onOpen(webSocket: WebSocket, response: Response) {
syncExec(id) {
state = State.Connected
- Log.i("WebSocket($id): opened")
+ Logger.info("WebSocket($id): opened")
onOpen.run()
if (errorCount > 0) {
@@ -168,7 +168,7 @@ internal class WebSocketConnection(
override fun onMessage(webSocket: WebSocket, text: String) {
syncExec(id) {
- Log.i("WebSocket($id): received message $text")
+ Logger.info("WebSocket($id): received message $text")
val message = Utils.JSON.fromJson(text, Message::class.java)
onMessageCallback(message)
}
@@ -178,7 +178,7 @@ internal class WebSocketConnection(
override fun onClosed(webSocket: WebSocket, code: Int, reason: String) {
syncExec(id) {
if (state == State.Connected) {
- Log.w("WebSocket($id): closed")
+ Logger.warn("WebSocket($id): closed")
onClose.run()
}
closed()
@@ -189,7 +189,7 @@ internal class WebSocketConnection(
override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
val code = if (response != null) "StatusCode: ${response.code()}" else ""
val message = if (response != null) response.message() else ""
- Log.e("WebSocket($id): failure $code Message: $message", t)
+ Logger.error(t) { "WebSocket($id): failure $code Message: $message" }
syncExec(id) {
closed()
if (response != null && response.code() >= 400 && response.code() <= 499) {
diff --git a/app/src/main/kotlin/com/github/gotify/service/WebSocketService.kt b/app/src/main/kotlin/com/github/gotify/service/WebSocketService.kt
index 9b6d9813..8c0a5dbf 100644
--- a/app/src/main/kotlin/com/github/gotify/service/WebSocketService.kt
+++ b/app/src/main/kotlin/com/github/gotify/service/WebSocketService.kt
@@ -28,7 +28,7 @@ import com.github.gotify.client.api.ApplicationApi
import com.github.gotify.client.api.MessageApi
import com.github.gotify.client.model.Application
import com.github.gotify.client.model.Message
-import com.github.gotify.log.Log
+import com.github.gotify.log.LoggerHelper
import com.github.gotify.log.UncaughtExceptionHandler
import com.github.gotify.messages.Extras
import com.github.gotify.messages.IntentUrlDialogActivity
@@ -37,6 +37,7 @@ import com.github.gotify.picasso.PicassoHandler
import io.noties.markwon.Markwon
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.atomic.AtomicLong
+import org.tinylog.kotlin.Logger
internal class WebSocketService : Service() {
companion object {
@@ -50,7 +51,7 @@ internal class WebSocketService : Service() {
object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
super.onAvailable(network)
- Log.i("WebSocket: Network available, reconnect if needed.")
+ Logger.info("WebSocket: Network available, reconnect if needed.")
connection?.start()
}
}
@@ -71,7 +72,7 @@ internal class WebSocketService : Service() {
settings.token
)
missingMessageUtil = MissedMessageUtil(client.createService(MessageApi::class.java))
- Log.i("Create ${javaClass.simpleName}")
+ Logger.info("Create ${javaClass.simpleName}")
picassoHandler = PicassoHandler(this, settings)
markwon = MarkwonFactory.createForNotification(this, picassoHandler.get())
}
@@ -84,15 +85,15 @@ internal class WebSocketService : Service() {
.unregisterNetworkCallback(networkCallback)
}
- Log.w("Destroy ${javaClass.simpleName}")
+ Logger.warn("Destroy ${javaClass.simpleName}")
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
- Log.init(this)
- if (connection != null) {
- connection!!.close()
- }
- Log.i("Starting ${javaClass.simpleName}")
+ LoggerHelper.init(this)
+ UncaughtExceptionHandler.registerCurrentThread()
+
+ connection?.close()
+ Logger.info("Starting ${javaClass.simpleName}")
super.onStartCommand(intent, flags, startId)
Thread { startPushService() }.start()
@@ -168,7 +169,7 @@ internal class WebSocketService : Service() {
getString(R.string.websocket_closed_logout)
)
} else {
- Log.i(
+ Logger.info(
"WebSocket closed but the user still authenticated, " +
"trying to reconnect"
)
@@ -406,7 +407,7 @@ internal class WebSocketService : Service() {
.bigPicture(picassoHandler.getImageFromUrl(notificationImageUrl))
)
} catch (e: Exception) {
- Log.e("Error loading bigImageUrl", e)
+ Logger.error(e, "Error loading bigImageUrl")
}
}
val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
diff --git a/app/src/main/kotlin/com/github/gotify/sharing/ShareActivity.kt b/app/src/main/kotlin/com/github/gotify/sharing/ShareActivity.kt
index 167509e9..6cd769de 100644
--- a/app/src/main/kotlin/com/github/gotify/sharing/ShareActivity.kt
+++ b/app/src/main/kotlin/com/github/gotify/sharing/ShareActivity.kt
@@ -18,10 +18,10 @@ import com.github.gotify.client.api.MessageApi
import com.github.gotify.client.model.Application
import com.github.gotify.client.model.Message
import com.github.gotify.databinding.ActivityShareBinding
-import com.github.gotify.log.Log
import com.github.gotify.messages.provider.ApplicationHolder
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
+import org.tinylog.kotlin.Logger
internal class ShareActivity : AppCompatActivity() {
private lateinit var binding: ActivityShareBinding
@@ -33,7 +33,7 @@ internal class ShareActivity : AppCompatActivity() {
binding = ActivityShareBinding.inflate(layoutInflater)
setContentView(binding.root)
- Log.i("Entering ${javaClass.simpleName}")
+ Logger.info("Entering ${javaClass.simpleName}")
setSupportActionBar(binding.appBarDrawer.toolbar)
val actionBar = supportActionBar
if (actionBar != null) {
@@ -146,7 +146,7 @@ internal class ShareActivity : AppCompatActivity() {
Api.execute(messageApi.createMessage(message))
true
} catch (apiException: ApiException) {
- Log.e("Failed sending message", apiException)
+ Logger.error(apiException, "Failed sending message")
false
}
}
diff --git a/app/src/main/resources/tinylog.properties b/app/src/main/resources/tinylog.properties
new file mode 100644
index 00000000..51eddf78
--- /dev/null
+++ b/app/src/main/resources/tinylog.properties
@@ -0,0 +1,11 @@
+writer1 = logcat
+writer1.level = trace
+writer1.format = {message}
+
+writer2 = rolling file
+writer2.level = info
+writer2.file = #{tinylog.directory}/log_{count}.txt
+writer2.backups = 2
+writer2.format = {date: yyyy-MM-dd HH:mm:ss.SSS} {level}: {message}
+writer2.policies = size: 1MB
+writer2.charset = UTF-8