Cómo iniciar sesión de manera más eficiente con Timber

El registro es una de las utilidades más utilizadas en el marco de Android . Es realmente útil para depurar su código cuando la depuración por punto de interrupción simplemente no funciona.

Por lo general, es una buena práctica colocar declaraciones de registro en su código. Estas declaraciones le ayudan a realizar un seguimiento del control de flujo en su aplicación. De manera similar, no se recomienda tener declaraciones de registro en su código de lanzamiento listo, ya que cualquiera que conecte su teléfono a una PC puede leer esas declaraciones de registro. Por lo tanto, al lanzar su aplicación a Play Store, se recomienda eliminar todas las declaraciones de registro de su código.

Pero esto puede ser un verdadero dolor de cabeza. Hay tantas declaraciones de registro en todo su código. Ahora debe encontrar cada uno y eliminarlo de su código para la versión de lanzamiento.

Otro problema con el mecanismo de registro predeterminado es que debe pasar el TAG cada vez que escribe una declaración de registro.

¿No sería maravilloso si las declaraciones de registro se deshabilitaran automáticamente cuando estén en producción? ¿No sería genial si las declaraciones de registro recogieran automáticamente el TAG / nombre de clase mientras se registra y usted pudiera concentrarse en escribir mejor código?

Bueno, problemas como estos y muchos más se resuelven con una mejor biblioteca de registro en Android, llamada Timber (por Jake Wharton).

Es una biblioteca liviana y fácil de usar. Se encarga de la mayor parte del mantenimiento que necesita hacer durante el registro para que pueda concentrarse más en escribir código excelente y menos en las cosas de mantenimiento.

Sigamos adelante y creemos una aplicación de muestra para ver cómo puede incluir Timber en su aplicación de Android y hacer su vida de registro más fácil.

Empezando

Crearemos una aplicación simple para Android con 4 botones. Cada botón imprimiría una declaración de registro de prioridad diferente en la consola.

Cree un nuevo proyecto en Android y agregue una dependencia para Timber en su archivo build.gradle de nivel de aplicación. En el momento de escribir este artículo, esta es la última versión de dependencia para madera:

implementation 'com.jakewharton.timber:timber:4.7.1'

Inicializando Timber

Con la dependencia descargada, ahora es el momento de inicializar la biblioteca de madera. El mejor lugar para inicializar la madera es la clase Aplicación, que estará activa durante toda la vida útil de la aplicación. Entonces, creemos una clase de aplicación personalizada e inicialicemos nuestra biblioteca Timber en ella:

class MainApplication : Application() { override fun onCreate() { super.onCreate() if(BuildConfig.DEBUG){ Timber.plant(Timber.DebugTree()) } }}

Creando MainActivity

Creemos ahora nuestra MainActivity agregando 4 botones y configurando los oyentes de clic en cada uno de ellos. Aquí está mi archivo activity_main.xml. Estoy usando ConstraintLayout como mi diseño raíz e incluyo 4 botones cada uno para diferentes niveles de registro.

Ahora es el momento de configurar los oyentes de clics para estos botones e imprimir una declaración de registro cada vez que se hace clic en un botón. Estoy usando enlaces sintéticos de kotlin en lugar de llamadas regulares findViewById o Butterknife. Aquí está mi archivo MainActivity.kt :

class MainActivity : AppCompatActivity() {
 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main)
 btn_error.setOnClickListener { onClickedError() }
 btn_info.setOnClickListener { onInfoClicked() }
 btn_debug.setOnClickListener { onDebugClicked() }
 btn_verbose.setOnClickListener { onVerboseClicked() } }
 private fun onVerboseClicked() { Timber.v("On Verbose Clicked") }
 private fun onDebugClicked() { Timber.d("On Debug Clicked.") }
 private fun onInfoClicked() { Timber.i("On Info clicked.") }
 private fun onClickedError() { Timber.e("On Error Clicked.") }
}

Observe que no necesitamos inicializar ninguna variable TAG en nuestra clase, Timber lo hace automáticamente por usted.

Personalización de Timber para depuración y publicación

Ahora, aquí es donde Timber realmente brilla . Lo que hemos hecho hasta ahora no ha sido nada bueno, solo imprimimos las declaraciones de registro al hacer clic en los botones. Pero como sabe, iniciar sesión en producción no es una buena idea. Escribiremos código para deshabilitar los registros para producción mientras los mantenemos habilitados durante el modo de depuración.

Escribiremos un bloque if para verificar si nuestra aplicación está en modo de depuración y habilitar el registro para eso. Si no, entonces queremos inicializar Timber usando un árbol personalizado.

Aquí está la clase MainApplication.kt modificada :

class MainApplication : Application() { override fun onCreate() { super.onCreate() if (BuildConfig.DEBUG) { Timber.plant(object : Timber.DebugTree() { override fun createStackElementTag(element: StackTraceElement): String? { return String.format( "Class:%s: Line: %s, Method: %s", super.createStackElementTag(element), element.lineNumber, element.methodName ) } }) } else { Timber.plant(ReleaseTree()) } }}

Como puede ver, hemos inicializado la madera usando un ReleaseTree personalizado cuando estamos en modo de lanzamiento. Ahora sigamos adelante y creemos nuestro propio árbol de versiones.

Crear un árbol personalizado

Crear un árbol de versiones es bastante sencillo. Cree una nueva clase de Kotlin y extiéndala desde Timber.Tree. Implemente todas las funciones abstractas y estará listo.

Aquí está mi ReleaseTree.kt :

class ReleaseTree : @NotNull Timber.Tree() { override fun log(priority: Int, tag: String?, message: String, t: Throwable?) { if (priority == Log.ERROR || priority == Log.WARN){ //SEND ERROR REPORTS TO YOUR Crashlytics. } }
}

Como puede ver, siempre que haya un error, podemos enviar el registro a un servicio en línea como Firebase CrashAnalytics o Crashlytics y no cerrar la sesión en producción.

Resultado

Beneficios de usar Timber vs Android Logging

Veamos algunos de los beneficios de usar la biblioteca Timber en lugar de la utilidad de registro predeterminada de Android SDK.

  • No need to worry about TAGS: Timber generates the TAGs automatically for you so you don’t have to worry about including a global TAG in every class.
  • No need to manually remove Log statements: As already shown, it’s really easy to disable Logging for release apps. Hence, you no longer have to go through your entire code and manually remove all the logs.
  • Customized behavior on production: In production versions, you don’t want to log, although you definitely want to log any crashes that might occur. You can implement this by using a custom debug tree (as shown above) which instead of logging to the logcat, sends the logs to your crashlytics service.
  • Customized Meta-Data: You can include customized metadata with your log statements. For example, I’ve added class name, line number and method name from which the log statement is getting printed in the implementation above. Having this data at your disposal can make debugging easier.
  • Lightweight: Does not increase your app size/method count by much. Really lightweight library as it is just a wrapper over the already existing log utility.

Conclusion

For a long time I had ignored the use of log statements and printing out better logs. As my code got bigger and problems got more complex, I realized I needed to adopt better and more efficient debugging routines. Hence, using Timber is one step in the right direction.

*Important*: I’ve created a SLACK workspace for mobile developers where we can share our learnings about everything latest in Tech, especially in Android Development, RxJava, Kotlin, Flutter, and overall mobile development in general.Click on this link to join the slack workspace. It’s absolutely free!This article was originally posted at //ayusch.com/timber-for-android

Like what you read? Don’t forget to share this post on Facebook, Whatsapp, and LinkedIn.

You can follow me on LinkedIn, Quora, Twitter, and Instagram where I answer questions related to Mobile Development, especially Android and Flutter.