Files
mobile-android/app/src/main/java/com/rosetta/messenger/utils/MessageLogger.kt

392 lines
12 KiB
Kotlin
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.rosetta.messenger.utils
import android.util.Log
import com.rosetta.messenger.network.ProtocolManager
/**
* Утилита для логирования сообщений
* Безопасна для release сборки - логи не выводятся в production
*
* Логи отображаются:
* 1. В Logcat (всегда в debug)
* 2. В Debug Logs внутри чата (через ProtocolManager.debugLogs)
*/
object MessageLogger {
private const val TAG = "RosettaMsg"
// Всегда включён — вывод идёт только в ProtocolManager.addLog() (in-memory UI),
// не в logcat, безопасно для release
private val isEnabled: Boolean = true
/**
* Добавить лог в UI (Debug Logs в чате)
*/
private fun addToUI(message: String) {
ProtocolManager.addLog(message)
}
/**
* Логирование отправки сообщения
*/
fun logSendStart(
messageId: String,
toPublicKey: String,
textLength: Int,
attachmentsCount: Int,
isSavedMessages: Boolean,
replyToMessageId: String?
) {
if (!isEnabled) return
val shortId = messageId.take(8)
val shortKey = toPublicKey.take(12)
val replyStr = replyToMessageId?.take(8) ?: "-"
val msg = "📤 SEND | id:$shortId to:$shortKey len:$textLength att:$attachmentsCount saved:$isSavedMessages reply:$replyStr"
Log.d(TAG, msg)
addToUI(msg)
}
/**
* Логирование успешного шифрования
*/
fun logEncryptionSuccess(
messageId: String,
encryptedContentLength: Int,
encryptedKeyLength: Int
) {
if (!isEnabled) return
val shortId = messageId.take(8)
val msg = "🔐 ENCRYPT | id:$shortId content:${encryptedContentLength}b key:${encryptedKeyLength}b"
Log.d(TAG, msg)
addToUI(msg)
}
/**
* Логирование сохранения в БД
*/
fun logDbSave(
messageId: String,
dialogKey: String,
isNew: Boolean
) {
if (!isEnabled) return
val shortId = messageId.take(8)
val shortDialog = dialogKey.take(12)
val msg = "💾 DB | id:$shortId dialog:$shortDialog new:$isNew"
Log.d(TAG, msg)
addToUI(msg)
}
/**
* Логирование отправки пакета на сервер
*/
fun logPacketSend(
messageId: String,
toPublicKey: String,
timestamp: Long
) {
if (!isEnabled) return
val shortId = messageId.take(8)
val shortKey = toPublicKey.take(12)
val msg = "📡 PACKET→ | id:$shortId to:$shortKey ts:$timestamp"
Log.d(TAG, msg)
addToUI(msg)
}
/**
* Логирование успешной отправки
*/
fun logSendSuccess(messageId: String, duration: Long) {
if (!isEnabled) return
val shortId = messageId.take(8)
val msg = "✅ SENT | id:$shortId time:${duration}ms"
Log.d(TAG, msg)
addToUI(msg)
}
/**
* Логирование ошибки отправки
*/
fun logSendError(messageId: String, error: Throwable) {
if (!isEnabled) return
val shortId = messageId.take(8)
val errMsg = error.message?.take(50) ?: "unknown"
val msg = "❌ SEND ERR | id:$shortId err:$errMsg"
Log.e(TAG, msg, error)
addToUI(msg)
}
/**
* Логирование входящего сообщения
*/
fun logReceiveStart(
messageId: String,
fromPublicKey: String,
toPublicKey: String,
contentLength: Int,
attachmentsCount: Int,
timestamp: Long
) {
if (!isEnabled) return
val shortId = messageId.take(8)
val shortFrom = fromPublicKey.take(12)
val shortTo = toPublicKey.take(12)
val msg = "📥 RECV | id:$shortId from:$shortFrom to:$shortTo len:${contentLength}b att:$attachmentsCount ts:$timestamp"
Log.d(TAG, msg)
addToUI(msg)
}
/**
* Логирование проверки на дубликат
*/
fun logDuplicateCheck(messageId: String, isDuplicate: Boolean) {
if (!isEnabled) return
val shortId = messageId.take(8)
val status = if (isDuplicate) "DUP" else "✓NEW"
val msg = "🔍 CHECK | id:$shortId $status"
Log.d(TAG, msg)
addToUI(msg)
}
/**
* Логирование блокировки отправителя
*/
fun logBlockedSender(fromPublicKey: String) {
if (!isEnabled) return
val shortKey = fromPublicKey.take(12)
val msg = "🚫 BLOCKED | from:$shortKey"
Log.d(TAG, msg)
addToUI(msg)
}
/**
* Логирование успешной расшифровки
*/
fun logDecryptionSuccess(
messageId: String,
plainTextLength: Int,
attachmentsCount: Int
) {
if (!isEnabled) return
val shortId = messageId.take(8)
val msg = "🔓 DECRYPT | id:$shortId text:${plainTextLength}c att:$attachmentsCount"
Log.d(TAG, msg)
addToUI(msg)
}
/**
* Логирование ошибки расшифровки
*/
fun logDecryptionError(messageId: String, error: Throwable) {
if (!isEnabled) return
val shortId = messageId.take(8)
val errMsg = error.message?.take(50) ?: "unknown"
val msg = "❌ DECRYPT ERR | id:$shortId err:$errMsg"
Log.e(TAG, msg, error)
addToUI(msg)
}
/**
* Логирование успешного получения
*/
fun logReceiveSuccess(messageId: String, duration: Long) {
if (!isEnabled) return
val shortId = messageId.take(8)
val msg = "✅ RECEIVED | id:$shortId time:${duration}ms"
Log.d(TAG, msg)
addToUI(msg)
}
/**
* Логирование обновления статуса доставки
*/
fun logDeliveryStatus(
messageId: String,
toPublicKey: String,
status: String
) {
if (!isEnabled) return
val shortId = messageId.take(8)
val shortKey = toPublicKey.take(12)
val msg = "📬 DELIVERY | id:$shortId to:$shortKey status:$status"
Log.d(TAG, msg)
addToUI(msg)
}
/**
* Логирование прочтения сообщений
*/
fun logReadStatus(
fromPublicKey: String,
messagesCount: Int
) {
if (!isEnabled) return
val shortKey = fromPublicKey.take(12)
val msg = "👁 READ | from:$shortKey count:$messagesCount"
Log.d(TAG, msg)
addToUI(msg)
}
/**
* Логирование обновления диалога
*/
fun logDialogUpdate(
dialogKey: String,
lastMessage: String?,
unreadCount: Int
) {
if (!isEnabled) return
val shortDialog = dialogKey.take(12)
val shortMsg = lastMessage?.take(20) ?: "-"
val msg = "📋 DIALOG | key:$shortDialog last:\"$shortMsg\" unread:$unreadCount"
Log.d(TAG, msg)
addToUI(msg)
}
/**
* Логирование обновления кэша
*/
fun logCacheUpdate(dialogKey: String, totalMessages: Int) {
if (!isEnabled) return
val shortDialog = dialogKey.take(12)
val msg = "🗃 CACHE | dialog:$shortDialog total:$totalMessages"
Log.d(TAG, msg)
addToUI(msg)
}
/**
* Логирование расшифровки фото (inline blob)
*/
fun logPhotoDecryptStart(
messageId: String,
attachmentId: String,
blobSize: Int
) {
if (!isEnabled) return
val shortMsgId = messageId.take(8)
val shortAttId = attachmentId.take(8)
val msg = "🖼️ PHOTO DECRYPT | msg:$shortMsgId att:$shortAttId blob:${blobSize}b"
Log.d(TAG, msg)
addToUI(msg)
}
/**
* Логирование успешной расшифровки фото
*/
fun logPhotoDecryptSuccess(
messageId: String,
attachmentId: String,
saved: Boolean
) {
if (!isEnabled) return
val shortMsgId = messageId.take(8)
val shortAttId = attachmentId.take(8)
val msg = "✅ PHOTO OK | msg:$shortMsgId att:$shortAttId saved:$saved"
Log.d(TAG, msg)
addToUI(msg)
}
/**
* Логирование ошибки расшифровки фото (blob null)
*/
fun logPhotoDecryptFailed(
messageId: String,
attachmentId: String
) {
if (!isEnabled) return
val shortMsgId = messageId.take(8)
val shortAttId = attachmentId.take(8)
val msg = "❌ PHOTO DECRYPT FAIL | msg:$shortMsgId att:$shortAttId (decryptedBlob=null)"
Log.e(TAG, msg)
addToUI(msg)
}
/**
* Логирование ошибки сохранения фото
*/
fun logPhotoSaveFailed(
messageId: String,
attachmentId: String
) {
if (!isEnabled) return
val shortMsgId = messageId.take(8)
val shortAttId = attachmentId.take(8)
val msg = "⚠️ PHOTO SAVE FAIL | msg:$shortMsgId att:$shortAttId"
Log.e(TAG, msg)
addToUI(msg)
}
/**
* Логирование исключения при расшифровке фото
*/
fun logPhotoDecryptError(
messageId: String,
attachmentId: String,
error: Throwable
) {
if (!isEnabled) return
val shortMsgId = messageId.take(8)
val shortAttId = attachmentId.take(8)
val errMsg = error.message?.take(80) ?: "unknown"
val msg = "❌ PHOTO ERR | msg:$shortMsgId att:$shortAttId err:$errMsg"
Log.e(TAG, msg, error)
addToUI(msg)
}
/**
* Логирование CDN загрузки фото
*/
fun logPhotoCdnDownload(message: String) {
if (!isEnabled) return
val msg = "🖼️ $message"
Log.d(TAG, msg)
addToUI(msg)
}
/**
* Логирование успешной отправки read receipt
*/
fun logReadReceiptSent(opponentKey: String, retry: Boolean = false) {
if (!isEnabled) return
val shortKey = opponentKey.take(12)
val retryStr = if (retry) " (retry)" else ""
val msg = "👁 READ RECEIPT SENT$retryStr | to:$shortKey"
Log.d(TAG, msg)
addToUI(msg)
}
/**
* Логирование ошибки отправки read receipt
*/
fun logReadReceiptFailed(opponentKey: String, error: Throwable, retry: Boolean = false) {
if (!isEnabled) return
val shortKey = opponentKey.take(12)
val errMsg = error.message?.take(50) ?: "unknown"
val retryStr = if (retry) " (retry)" else ""
val msg = "❌ READ RECEIPT FAIL$retryStr | to:$shortKey err:$errMsg"
Log.e(TAG, msg, error)
addToUI(msg)
}
/**
* Общий debug лог
*/
fun debug(message: String) {
if (!isEnabled) return
Log.d(TAG, message)
addToUI(message)
}
/**
* Общий error лог
*/
fun error(message: String, error: Throwable? = null) {
if (!isEnabled) return
if (error != null) {
Log.e(TAG, message, error)
} else {
Log.e(TAG, message)
}
addToUI("$message")
}
}