Skip to content

Adding SDKLogger Override in Example App #32

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

Merged
merged 4 commits into from
Oct 16, 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
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* [GlobalConfig](#globalconfig)
* [GlobalConfig.init](#globalconfiginit)
* [Updating configuration](#updating-configuration)
* [SDKLogger](#sdklogger)
* [ChatSession APIs](#chatsession-apis)
* [ChatSession Events](#chatsession-events)
* [Classes and Structs](#classes-and-structs)
Expand Down Expand Up @@ -121,6 +122,31 @@ val globalConfig = GlobalConfig(region = chatConfiguration.region)
chatSession.configure(globalConfig)
```

### SDKLogger
The `SDKLogger` class is responsible for logging relevant runtime information to the console which is useful for debugging purposes. The `SDKLogger` will log key events such as establishing a connection or failures such as failing to send a message.

#### `SDKLogger.configure`
This API will allow you to override the SDK's built-in logger with your own [ChatSDKLogger](#chatsdklogger) implementation. This is especially useful in cases where you would want to store logs for debugging purposes. Attaching these logs to issues filed in this project will greatly expedite the resolution process.

```
fun configureLogger(logger: ChatSDKLogger) {
this.logger = logger
}
```

#### ChatSDKLogger
The ChatSDKLogger is an interface used for the `SDKLogger`. Users can override the `SDKLogger` with any class that implements the ChatSDKLogger interface.

```
interface ChatSDKLogger {
fun logVerbose(message: () -> String)
fun logInfo(message: () -> String)
fun logDebug(message: () -> String)
fun logWarn(message: () -> String)
fun logError(message: () -> String)
}
```

--------------------

### ChatSession APIs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.ViewModelProvider
import com.amazon.connect.chat.androidchatexample.ui.theme.androidconnectchatandroidTheme
import com.amazon.connect.chat.androidchatexample.utils.CustomLogger
import com.amazon.connect.chat.androidchatexample.utils.FileUtils.getOriginalFileName
import com.amazon.connect.chat.androidchatexample.utils.FileUtils.previewFileFromCacheOrDownload
import com.amazon.connect.chat.androidchatexample.viewmodel.ChatViewModel
Expand All @@ -74,6 +75,7 @@ import com.amazon.connect.chat.sdk.model.Message
import com.amazon.connect.chat.sdk.model.MessageDirection
import com.amazon.connect.chat.sdk.model.TranscriptItem
import com.amazon.connect.chat.sdk.utils.CommonUtils.Companion.keyboardAsState
import com.amazon.connect.chat.sdk.utils.logger.SDKLogger
import dagger.hilt.android.AndroidEntryPoint
import java.net.URL

Expand All @@ -91,6 +93,14 @@ class MainActivity : ComponentActivity() {
)

chatViewModel = ViewModelProvider(this)[ChatViewModel::class.java]
val externalFileDir = applicationContext.getExternalFilesDir(null)

if (externalFileDir !== null) {
val logger = CustomLogger()
logger.setLogOutputDir(externalFileDir)
SDKLogger.configureLogger(logger)
}

setContent {
androidconnectchatandroidTheme {
// A surface container using the 'background' color from the theme
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.amazon.connect.chat.sdk.model.MessageDirection
import com.amazon.connect.chat.sdk.model.MessageStatus
import com.amazon.connect.chat.sdk.model.TranscriptItem
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import java.util.TimeZone

Expand All @@ -28,6 +29,20 @@ object CommonUtils {
}
}

fun formatDate(currentTimeMillis: Long, forLogs: Boolean = false): String {
val date = Date(currentTimeMillis)
var utcFormatter: SimpleDateFormat? = null
if (forLogs) {
utcFormatter = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US).apply {
timeZone = TimeZone.getTimeZone("UTC")
}
} else {
utcFormatter = SimpleDateFormat("yyyy-MM-dd_HH-mm", Locale.US).apply {
timeZone = TimeZone.getTimeZone("UTC")
}
}
return utcFormatter.format(date)
}

fun getMessageDirection(transcriptItem: TranscriptItem) {
when (transcriptItem) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,97 @@
package com.amazon.connect.chat.androidchatexample.utils

import com.amazon.connect.chat.sdk.utils.logger.ChatSDKLogger
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File
import java.io.FileNotFoundException
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import java.util.TimeZone
import kotlin.io.path.Path
import kotlin.io.path.appendText
import kotlin.io.path.createFile
import kotlin.io.path.exists

class CustomLogger : ChatSDKLogger {
private var outputFileDir: File? = null
private val job = SupervisorJob()
private val coroutineScope = CoroutineScope(job + Dispatchers.IO)

private val currentTimeMillis = System.currentTimeMillis()
private val loggerCreationDateAndTime = CommonUtils.formatDate(currentTimeMillis, false)

override fun logVerbose(message: () -> String) {
// Custom logging logic
println("VERBOSE: ${message()}")
val logMessage = "VERBOSE: ${message()}"
println(logMessage)
coroutineScope.launch {
writeToAppTempFile(logMessage)
}
}

override fun logInfo(message: () -> String) {
// Custom logging logic
println("INFO: ${message()}")
val logMessage = "INFO: ${message()}"
println(logMessage)
coroutineScope.launch {
writeToAppTempFile(logMessage)
}
}

override fun logDebug(message: () -> String) {
// Custom logging logic
println("DEBUG: ${message()}")
val logMessage = "DEBUG: ${message()}"
println(logMessage)
coroutineScope.launch {
writeToAppTempFile(logMessage)
}

}

override fun logWarn(message: () -> String) {
// Custom logging logic
println("WARN: ${message()}")
val logMessage = "WARN: ${message()}"
println(logMessage)
coroutineScope.launch {
writeToAppTempFile(logMessage)
}
}

override fun logError(message: () -> String) {
// Custom logging logic
println("ERROR: ${message()}")
val logMessage = "ERROR: ${message()}"
println(logMessage)
coroutineScope.launch {
writeToAppTempFile(logMessage)
}
}

fun setLogOutputDir(tempFile: File) {
outputFileDir = tempFile
}

private suspend fun writeToAppTempFile(content: String): Result<Boolean> {
return withContext(Dispatchers.IO) {
runCatching {
val currentTimeMillis = System.currentTimeMillis()
val formattedDateTimeForLogs = CommonUtils.formatDate(currentTimeMillis, true)
if (outputFileDir == null || !outputFileDir!!.exists() || !outputFileDir!!.isDirectory()) {
return@runCatching false
}
val filePath = Path(outputFileDir!!.absolutePath, "$loggerCreationDateAndTime-amazon-connect-logs.txt")

if (!filePath.exists()) {
filePath.createFile()
}

filePath.appendText("[$formattedDateTimeForLogs] $content \n")
true
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
package com.amazon.connect.chat.sdk

import android.net.Uri
import android.util.Log
import com.amazon.connect.chat.sdk.model.ChatDetails
import com.amazon.connect.chat.sdk.model.ChatEvent
import com.amazon.connect.chat.sdk.model.ContentType
import com.amazon.connect.chat.sdk.model.GlobalConfig
import com.amazon.connect.chat.sdk.model.Message
import com.amazon.connect.chat.sdk.model.MessageDirection
import com.amazon.connect.chat.sdk.model.MessageReceiptType
import com.amazon.connect.chat.sdk.model.MessageStatus
import com.amazon.connect.chat.sdk.model.TranscriptItem
import com.amazon.connect.chat.sdk.model.TranscriptResponse
import com.amazon.connect.chat.sdk.repository.ChatService
import com.amazon.connect.chat.sdk.utils.logger.SDKLogger
import com.amazonaws.services.connectparticipant.model.ScanDirection
import com.amazonaws.services.connectparticipant.model.SortKey
import com.amazonaws.services.connectparticipant.model.StartPosition
Expand Down
Loading