Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Adding logging

You can override the default logger used by the Notification Plugin to use your own logging implementation or dependency. Lets look at an example of a file logger.

Swift
In iOS lets use the XCGLogger to handle logging to a separate log file in the app group's shared directory.
import BreezSDK
import XCGLogger

fileprivate let appGroup = "group.com.example.application"

class NotificationService: SDKNotificationService {
    // Override the `init` function 
    override init() {
        // Initialize XCGLogger
        let logsDir = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroup)!.appendingPathComponent("logs")
        let extensionLogFile = logsDir.appendingPathComponent("\(Date().timeIntervalSince1970).ios-extension.log")
        
        xcgLogger = {
            let log = XCGLogger.default
            log.setup(level: .info, showThreadName: true, showLevel: true, showFileNames: true, showLineNumbers: true, writeToFile: extensionLogFile.path)
            return log
            
        }()
        
        super.init()
        // Set notification plugin logger that utilizes the XCGLogger library
        let logger = CustomLogListener(logger: xcgLogger)
        setLogger(logger: logger)
        // Use the same logger to listen in on BreezSDK logs
        do {
            try setLogStream(logStream: logger)
        } catch let e {
            self.logger.log(tag: TAG, line:"Failed to set log stream: \(e)", level: "ERROR")
        }
    }
}
Kotlin
In Android lets use the tinylog to handle logging to a file. First create a utility class to configure tinylog.
package com.example.application

import android.content.Context
import java.io.File
import org.tinylog.kotlin.Logger

class LogHelper {
    companion object {
        private const val TAG = "LogHelper"
        private var isInit: Boolean? = null

        internal fun configureLogger(applicationContext: Context): Boolean? {
            synchronized(this) {
                // Get `/logs` folder from app data directory
                val loggingDir =
                    File(applicationContext.applicationInfo.dataDir, "/logs").apply {
                        mkdirs()
                    }

                System.setProperty("tinylog.directory", loggingDir.absolutePath)
                System.setProperty("tinylog.timestamp", System.currentTimeMillis().toString())

                if (isInit == false) {
                    Logger.tag(TAG).debug { "Starting ${BuildConfig.APPLICATION_ID}..." }
                    Logger.tag(TAG).debug { "Logs directory: '$loggingDir'" }
                    isInit = true
                }
                return isInit
            }
        }
    }
}

When a message is received by the messaging service, configure the logger.

package com.example.application

import breez_sdk_notification.MessagingService
import com.example.application.LogHelper.Companion.configureLogger
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage

class ExampleFcmService : MessagingService, FirebaseMessagingService() {
    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        super.onMessageReceived(remoteMessage)
        // Initialise the logger
        configureLogger(applicationContext)
        Logger.tag(TAG).debug { "FCM message received!" }

        // Go on to call `startServiceIfNeeded`
    }
}

When the foreground service is created, initialise the Breez SDK log stream and subscribe to log entries

package com.example.application

import breez_sdk.setLogStream
import breez_sdk_notification.ForegroundService
import breez_sdk_notification.NotificationHelper.Companion.registerNotificationChannels
import org.tinylog.kotlin.Logger

class ExampleForegroundService : ForegroundService() {
    // Override the `onCreate` function
    override fun onCreate() {
        super.onCreate()
        registerNotificationChannels(applicationContext, DEFAULT_CLICK_ACTION)
        // Set notification plugin logger that utilizes the tinylog library
        val logger = CustomLogListener()
        setLogger(logger)
        // Use the same logger to listen in on BreezSDK logs
        try {
            setLogStream(logger)
        } catch (e: Exception) {
            Logger.tag(TAG).error { "Failed to set log stream: ${e.message}" }
        }
    }
}

Implement a custom LogStream listener, this can be used to listen to log entries from both the Notification Plugin and Breez SDK.

Swift
import XCGLogger

class CustomLogListener : LogStream {
    private var logger: XCGLogger
    
    init(logger: XCGLogger) {
        self.logger = logger
    }
    
    func log(l: LogEntry) {
        switch(l.level) {
        case "ERROR":
            logger.error { l.line }
            break
        case "WARN":
            logger.warning { l.line }
            break
        case "INFO":
            logger.info { l.line }
            break
        case "DEBUG":
            logger.debug { l.line }
            break
        case "TRACE":
            logger.verbose { l.line }
            break
        default:
            return
        }
    }
}
Kotlin
package com.example.application

import breez_sdk.LogEntry
import breez_sdk.LogStream
import org.tinylog.kotlin.Logger

class CustomLogListener : LogStream {
    override fun log(l: LogEntry) {
        when (l.level) {
            "ERROR" -> Logger.tag(TAG).error { l.line }
            "WARN" -> Logger.tag(TAG).warn { l.line }
            "INFO" -> Logger.tag(TAG).info { l.line }
            "DEBUG" -> Logger.tag(TAG).debug { l.line }
            "TRACE" -> Logger.tag(TAG).trace { l.line }
        }
    }
}