Logger.kt 4.55 KB
Newer Older
Ricki Hirner's avatar
Ricki Hirner committed
1 2 3 4 5 6 7 8
/*
 * Copyright © Ricki Hirner (bitfire web engineering).
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v3.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/gpl.html
 */

9
package at.bitfire.davdroid.log
Ricki Hirner's avatar
Ricki Hirner committed
10

11
import android.app.PendingIntent
Ricki Hirner's avatar
Ricki Hirner committed
12
import android.content.Context
13
import android.content.Intent
14
import android.content.SharedPreferences
Ricki Hirner's avatar
Ricki Hirner committed
15
import android.os.Process
16
import android.preference.PreferenceManager
Ricki Hirner's avatar
Ricki Hirner committed
17
import android.support.v4.app.NotificationCompat
18
import android.support.v4.app.NotificationManagerCompat
Ricki Hirner's avatar
Ricki Hirner committed
19
import android.util.Log
20
import at.bitfire.davdroid.R
21
import at.bitfire.davdroid.ui.AppSettingsActivity
22
import at.bitfire.davdroid.ui.NotificationUtils
Ricki Hirner's avatar
Ricki Hirner committed
23 24 25 26 27 28 29 30
import org.apache.commons.lang3.time.DateFormatUtils
import java.io.File
import java.io.IOException
import java.util.logging.FileHandler
import java.util.logging.Level

object Logger {

31
    const val LOG_TO_EXTERNAL_STORAGE = "log_to_external_storage"
32 33 34 35

    val log = java.util.logging.Logger.getLogger("davdroid")!!


36
    private lateinit var preferences: SharedPreferences
37 38 39 40 41

    fun initialize(context: Context) {
        preferences = PreferenceManager.getDefaultSharedPreferences(context)
        preferences.registerOnSharedPreferenceChangeListener { _, s ->
            if (s == LOG_TO_EXTERNAL_STORAGE)
Ricki Hirner's avatar
Ricki Hirner committed
42
                reinitialize(context.applicationContext)
Ricki Hirner's avatar
Ricki Hirner committed
43
        }
44

Ricki Hirner's avatar
Ricki Hirner committed
45
        reinitialize(context.applicationContext)
46 47
    }

Ricki Hirner's avatar
Ricki Hirner committed
48
    private fun reinitialize(context: Context) {
49 50 51 52 53 54 55 56 57 58 59 60 61 62
        val logToFile = preferences.getBoolean(LOG_TO_EXTERNAL_STORAGE, false)
        val logVerbose = logToFile || Log.isLoggable(log.name, Log.DEBUG)

        log.info("Verbose logging: $logVerbose; to file: $logToFile")

        // set logging level according to preferences
        val rootLogger = java.util.logging.Logger.getLogger("")
        rootLogger.level = if (logVerbose) Level.ALL else Level.INFO

        // remove all handlers and add our own logcat handler
        rootLogger.useParentHandlers = false
        rootLogger.handlers.forEach { rootLogger.removeHandler(it) }
        rootLogger.addHandler(LogcatHandler)

63
        val nm = NotificationManagerCompat.from(context)
64 65
        // log to external file according to preferences
        if (logToFile) {
66
            val builder = NotificationUtils.newBuilder(context, NotificationUtils.CHANNEL_DEBUG)
67
            builder .setSmallIcon(R.drawable.ic_sd_storage_notification)
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
                    .setContentTitle(context.getString(R.string.logging_davdroid_file_logging))
                    .setLocalOnly(true)

            val dir = context.getExternalFilesDir(null)
            if (dir != null)
                try {
                    val fileName = File(dir, "davdroid-${Process.myPid()}-${DateFormatUtils.format(System.currentTimeMillis(), "yyyyMMdd-HHmmss")}.txt").toString()
                    log.info("Logging to $fileName")

                    val fileHandler = FileHandler(fileName)
                    fileHandler.formatter = PlainTextFormatter.DEFAULT
                    rootLogger.addHandler(fileHandler)

                    val prefIntent = Intent(context, AppSettingsActivity::class.java)
                    prefIntent.putExtra(AppSettingsActivity.EXTRA_SCROLL_TO, LOG_TO_EXTERNAL_STORAGE)

                    builder .setContentText(dir.path)
                            .setCategory(NotificationCompat.CATEGORY_STATUS)
                            .setPriority(NotificationCompat.PRIORITY_HIGH)
                            .setContentIntent(PendingIntent.getActivity(context, 0, prefIntent, PendingIntent.FLAG_UPDATE_CURRENT))
88
                            .setStyle(NotificationCompat.BigTextStyle().bigText(context.getString(R.string.logging_to_external_storage, dir.path)))
89 90 91 92
                            .setOngoing(true)

                } catch(e: IOException) {
                    log.log(Level.SEVERE, "Couldn't create external log file", e)
93 94 95
                    val message = context.getString(R.string.logging_couldnt_create_file, e.localizedMessage)
                    builder .setContentText(message)
                            .setStyle(NotificationCompat.BigTextStyle().bigText(message))
96 97 98 99 100
                            .setCategory(NotificationCompat.CATEGORY_ERROR)
                }
            else
                builder.setContentText(context.getString(R.string.logging_no_external_storage))

101
            nm.notify(NotificationUtils.NOTIFY_EXTERNAL_FILE_LOGGING, builder.build())
102
        } else
103
            nm.cancel(NotificationUtils.NOTIFY_EXTERNAL_FILE_LOGGING)
Ricki Hirner's avatar
Ricki Hirner committed
104 105 106
    }

}