> For the complete documentation index, see [llms.txt](https://docs.payments.thalescloud.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.payments.thalescloud.io/nfc-wallet-sdk-android/additional-features/collect-logs-with-secure-logger.md).

# Collect logs with LogService

## Overview

The NFC Wallet SDK collects runtime logs and stores them in the application sandbox.

Your digital wallet application can retrieve log files and share them with Thales for troubleshooting.

Starting with NFC Wallet SDK 6.14.0, logging is enabled automatically with the default configuration.

## SDK integration

### Get the log service

{% hint style="warning" %}
Secure logger API is deprecated. You need to use LogService.

See [Migrate from secure logger api](#migrate-from-secure-logger-api) for more details.
{% endhint %}

Retrieve the `LogService` instance:

{% tabs %}
{% tab title="Java" %}

```java
LogService logService = SDKInitializer.getLogService(context);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val logService = SDKInitializer.getLogService(context)
```

{% endtab %}
{% endtabs %}

The SDK applies the default configuration automatically during SDK initialization.

###

{% tabs %}
{% tab title="Java" %}

```java
// Before 6.14.0
SecureLog secureLog = SDKInitializer.INSTANCE.configureSecureLog(
        new SecureLogConfig.Builder(context)
                .build()
);

secureLog.setLevel(SecureLogLevel.INFO);
List<File> files = secureLog.getFiles();
secureLog.deleteFiles();

// Since 6.14.0
LogService logService = SDKInitializer.getLogService(context);

logService.setLevel(LogService.Level.INFO);
List<File> files = logService.getFiles();
logService.deleteFiles();
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
// Before 6.14.0
val secureLog = SDKInitializer.INSTANCE.configureSecureLog(
    SecureLogConfig.Builder(context).build()
)

secureLog.setLevel(SecureLogLevel.INFO)
val files = secureLog.files
secureLog.deleteFiles()

// Since 6.14.0
val logService = SDKInitializer.getLogService(context)

logService.setLevel(LogService.Level.INFO)
val files = logService.files
logService.deleteFiles()
```

{% endtab %}
{% endtabs %}

### Change log level

Use `setLevel(...)` to change the log level. The default log level is `Level.WARN`.

{% tabs %}
{% tab title="Java" %}

```java
LogService logService = SDKInitializer.getLogService(context);
logService.setLevel(LogService.Level.INFO);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val logService = SDKInitializer.getLogService(context)
logService.setLevel(LogService.Level.INFO)
```

{% endtab %}
{% endtabs %}

Set the level to `OFF` to stop writing new log entries.

### Log levels

Use the lowest level that supports your use case.

| Level   | Numeric value | Use                                                              |
| ------- | ------------- | ---------------------------------------------------------------- |
| `ALL`   | 7             | Capture all log entries. Equivalent to `DEBUG`.                  |
| `DEBUG` | 7             | Capture detailed logs for troubleshooting. Use temporarily only. |
| `INFO`  | 6             | Capture routine operational logs.                                |
| `ERROR` | 3             | Capture runtime errors that require investigation.               |
| `WARN`  | 4             | Capture warnings. This is the default level.                     |
| `FATAL` | 2             | Capture unrecoverable runtime errors only.                       |
| `OFF`   | 0             | Disable logging.                                                 |

{% hint style="info" %}
Use `DEBUG` only for short troubleshooting sessions.

For normal operation, keep the default level `WARN`.
{% endhint %}

### Disable logging

Starting with NFC Wallet SDK 6.14.0, logging is enabled by default.

Set the level to `OFF` to disable it:

{% tabs %}
{% tab title="Java" %}

```java
LogService logService = SDKInitializer.getLogService(context);
logService.setLevel(LogService.Level.OFF);
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val logService = SDKInitializer.getLogService(context)
logService.setLevel(LogService.Level.OFF)
```

{% endtab %}
{% endtabs %}

### Retrieve log files

After you retrieve the `LogService` instance, call `getFiles()`:

{% tabs %}
{% tab title="Java" %}

```java
LogService logService = SDKInitializer.getLogService(context);

// Return the list of files
List<File> files = logService.getFiles();
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val logService = SDKInitializer.getLogService(context)

// Return the list of files
val files = logService.files
```

{% endtab %}
{% endtabs %}

Call `deleteFiles()` to delete the log files:

{% tabs %}
{% tab title="Java" %}

```java
LogService logService = SDKInitializer.getLogService(context);
logService.deleteFiles();
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
val logService = SDKInitializer.getLogService(context)
logService.deleteFiles()
```

{% endtab %}
{% endtabs %}

### Full example

This example retrieves the log service instance, zips all log files, and shares them using an Android share sheet.

{% tabs %}
{% tab title="Java" %}
{% code title="LogServiceHelper.java" expandable="true" %}

```java
public class LogServiceHelper {

    private static LogService getLogService(Context context) {
        return SDKInitializer.getLogService(context);
    }

    public static void setDebugLogLevel(Context context) {
        LogService logService = getLogService(context);
        logService.setLevel(LogService.Level.DEBUG);
    }

    public static void shareLogs(Activity activity) {
        LogService logService = getLogService(activity.getApplicationContext());
        List<File> files = logService.getFiles();
        if (files == null || files.isEmpty()) {
            // No log to share
            return;
        }

        File directory = files.get(0).getParentFile();
        String outputZipPath = activity.getCacheDir().getAbsolutePath() + "/temp.zip";

        Thread zipTask = new Thread(new Runnable() {
            @Override
            public void run() {
                File file = new File(outputZipPath);
                if (file.exists()) {
                    file.delete();
                }

                zipFolder(directory.getAbsolutePath(), outputZipPath);

                if (!file.exists() || !file.canRead()) {
                    return;
                }

                // If you use a FileProvider, declare it in the application manifest.
                Uri uri = FileProvider.getUriForFile(activity, "your.fileprovider.authority", file);

                Intent shareIntent = new Intent(Intent.ACTION_SEND);
                shareIntent.setType("application/zip");
                shareIntent.putExtra(Intent.EXTRA_SUBJECT, "Log files");
                shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
                shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

                activity.startActivity(Intent.createChooser(shareIntent, "Share logs"));
            }
        });

        zipTask.start();
    }

    private static void zipFolder(String inputFolderPath, String outZipPath) {
        try {
            FileOutputStream fos = new FileOutputStream(outZipPath);
            ZipOutputStream zos = new ZipOutputStream(fos);
            File srcFile = new File(inputFolderPath);
            File[] files = srcFile.listFiles();

            for (int i = 0; i < files.length; i++) {
                byte[] buffer = new byte[1024];
                FileInputStream fis = new FileInputStream(files[i]);
                zos.putNextEntry(new ZipEntry(files[i].getName()));
                int length;
                while ((length = fis.read(buffer)) > 0) {
                    zos.write(buffer, 0, length);
                }
                zos.closeEntry();
                fis.close();
            }
            zos.close();
        } catch (IOException ioe) {
            Log.e("", ioe.getMessage());
        }
    }
}
```

{% endcode %}
{% endtab %}

{% tab title="Kotlin" %}
{% code title="LogServiceHelper.kt" expandable="true" %}

```kotlin
object LogServiceHelper {

    private fun getLogService(context: Context): LogService {
        return SDKInitializer.getLogService(context)
    }

    fun setDebugLogLevel(context: Context) {
        val logService = getLogService(context)
        logService.setLevel(LogService.Level.DEBUG)
    }

    fun shareLogs(activity: Activity) {
        val logService = getLogService(activity.applicationContext)
        val files = logService.files
        if (files.isNullOrEmpty()) {
            // No log to share
            return
        }

        val directory = files[0].parentFile
        val outputZipPath = activity.cacheDir.absolutePath + "/temp.zip"

        val zipTask = Thread {
            val file = File(outputZipPath)
            if (file.exists()) {
                file.delete()
            }

            zipFolder(directory.absolutePath, outputZipPath)

            if (!file.exists() || !file.canRead()) {
                return@Thread
            }

            // If you use a FileProvider, declare it in the application manifest.
            val uri = FileProvider.getUriForFile(activity, "your.fileprovider.authority", file)

            val shareIntent = Intent(Intent.ACTION_SEND).apply {
                type = "application/zip"
                putExtra(Intent.EXTRA_SUBJECT, "Log files")
                putExtra(Intent.EXTRA_STREAM, uri)
                addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
            }

            activity.startActivity(Intent.createChooser(shareIntent, "Share logs"))
        }

        zipTask.start()
    }

    private fun zipFolder(inputFolderPath: String, outZipPath: String) {
        try {
            val fos = FileOutputStream(outZipPath)
            val zos = ZipOutputStream(fos)
            val srcFile = File(inputFolderPath)
            val files = srcFile.listFiles() ?: return

            for (currentFile in files) {
                val buffer = ByteArray(1024)
                val fis = FileInputStream(currentFile)
                zos.putNextEntry(ZipEntry(currentFile.name))
                var length: Int
                while (fis.read(buffer).also { length = it } > 0) {
                    zos.write(buffer, 0, length)
                }
                zos.closeEntry()
                fis.close()
            }
            zos.close()
        } catch (ioe: IOException) {
            Log.e("", ioe.message ?: "")
        }
    }
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Migrate from secure logger API

Remove the deprecated configuration code.

Then retrieve the `LogService` instance when you need it.

| Deprecated API                                                | Replacement                                             |
| ------------------------------------------------------------- | ------------------------------------------------------- |
| `SDKInitializer.INSTANCE.configureSecureLog(SecureLogConfig)` | `SDKInitializer.getLogService(Context)`                 |
| `SecureLogConfig.Builder(...)`                                | No replacement. The SDK uses the default configuration. |
| `secureLog.setLevel(SecureLogLevel.X)`                        | `logService.setLevel(LogService.Level.X)`               |
| `secureLog.getFiles()`                                        | `logService.getFiles()`                                 |
| `secureLog.deleteFiles()`                                     | `logService.deleteFiles()`                              |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.payments.thalescloud.io/nfc-wallet-sdk-android/additional-features/collect-logs-with-secure-logger.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
