当前位置: 首页 > 工具软件 > Timber > 使用案例 >

python timber_如何使用Timber更有效地记录日志

高兴贤
2023-12-01

python timber

by Ayusch Jain

通过Ayusch Jain

如何使用Timber更有效地记录日志 (How to log more efficiently with Timber)

Logging is one of the most used utilities in the Android framework. It is really helpful in debugging your code when debugging by break-point just won't work.

日志记录是Android框架中最常用的实用程序之一。 当无法通过断点进行调试时,这对调试代码非常有帮助。

It is generally a good practice to place Log statements in your code. These statements help you keep a track of flow control in your application. Similarly, it is not recommended to have log statements in your release ready code, since those log statements can be read by anyone who connects their phone to a PC. So, when releasing your application to the play store, it is recommended to remove all the log statements from your code.

通常,将Log语句放置在您的代码中是一个好习惯。 这些语句可帮助您跟踪应用程序中的流控制。 同样,不建议在发布准备就绪的代码中包含日志语句,因为将电话连接到PC的任何人都可以读取这些日志语句。 因此,在将应用程序发布到Play商店时,建议从代码中删除所有日志语句。

But this can be a real pain. There are so many log statements all over your code. Now you have to find each one and remove it from your code for the release version.

但这可能是一个真正的痛苦。 您的代码中有太多的日志语句。 现在,您必须找到每个版本,并将其从发行版本的代码中删除。

Another problem with the default logging mechanism is that you need to pass the TAG every time you write a log statement.

默认日志记录机制的另一个问题是,每次编写日志语句时都需要传递TAG。

Wouldn’t it be wonderful if the log statements would automatically disable themselves when in production? Wouldn’t it be great if the Log statements automatically picked up the TAG/classname while logging and you could just focus on writing better code?

如果日志语句在生产中会自动禁用自身,那将不是很好吗? 如果Log语句在记录时自动选择TAG / classname并只专注于编写更好的代码,那不是很好吗?

Well, problems such as these and many more are solved by a better logging library in android, called Timber (by Jake Wharton).

好吧,诸如此类的问题以及更多的问题都可以通过Android中更好的日志记录库Timber (由Jake Wharton编写)解决。

It is a light-weight, easy to use library. It takes care of most of the maintenance you need to do while logging so that you can focus more on writing great code and less on the maintenance stuff.

它是一个轻巧,易于使用的库。 它可以处理您在记录日志时需要执行的大部分维护工作,因此您可以将更多精力放在编写出色的代码上,而将精力放在维护工作上。

Let’s go ahead and create a sample application to see how you can include Timber in your android application and make your logging life easier.

让我们继续创建一个示例应用程序,以了解如何将Timber包含在android应用程序中 ,并使记录工作变得更轻松。

入门 (Getting Started)

We will be creating a simple Android application with 4 buttons. Each button would print out different priority log statement on the console.

我们将创建一个带有4个按钮的简单Android应用程序。 每个按钮将在控制台上打印出不同的优先级日志语句。

Create a new project in Android and add a dependency for Timber in your app level build.gradle file. At the time of this writing, this is the latest dependency version for timber:

在Android中创建一个新项目,并在您的应用程序级别build.gradle文件中添加Timber的依赖项。 在撰写本文时,这是木材的最新依赖版本:

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

初始化木材 (Initializing Timber)

With the dependency downloaded, now it’s time to initialize the timber library. The best place to initialize timber is in the Application class which will be active during the entire lifetime of the application. So, let’s create a custom application class and initialize our Timber library in it:

下载依赖项后,现在该初始化木材库了。 初始化木材的最佳位置是在Application类中,它将在应用程序的整个生命周期内处于活动状态。 因此,让我们创建一个自定义应用程序类并在其中初始化我们的Timber库

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

创建MainActivity (Creating MainActivity)

Let’s now create our MainActivity by adding 4 buttons and setting on click listeners to each of them. Here is my activity_main.xml file. I’m using ConstraintLayout as my root layout and including 4 buttons each for different logging levels.

现在,我们通过添加4个按钮并在每个按钮上设置点击监听器来创建MainActivity。 这是我的activity_main.xml文件。 我使用ConstraintLayout作为我的根布局,并分别包含4个用于不同日志记录级别的按钮。

<?xml version="1.0" encoding="utf-8"?><android.support.constraint.ConstraintLayout        xmlns:android="http://schemas.android.com/apk/res/android"        xmlns:tools="http://schemas.android.com/tools"        xmlns:app="http://schemas.android.com/apk/res-auto"        android:layout_width="match_parent"        android:layout_height="match_parent"        tools:context=".MainActivity">
<Button            android:text="Error Log"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:id="@+id/btn_error" app:layout_constraintStart_toStartOf="parent" android:layout_marginStart="8dp"            app:layout_constraintEnd_toEndOf="parent" android:layout_marginEnd="8dp" android:layout_marginTop="108dp"            app:layout_constraintTop_toTopOf="parent" app:layout_constraintHorizontal_bias="0.498"/>    <Button            android:text="Info Log"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:id="@+id/btn_info" android:layout_marginTop="64dp"            app:layout_constraintTop_toBottomOf="@+id/btn_error" app:layout_constraintStart_toStartOf="parent"            android:layout_marginStart="8dp" app:layout_constraintEnd_toEndOf="parent" android:layout_marginEnd="8dp"            app:layout_constraintHorizontal_bias="0.498"/>    <Button            android:text="Debug Log"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:id="@+id/btn_debug" android:layout_marginTop="72dp"            app:layout_constraintTop_toBottomOf="@+id/btn_info" app:layout_constraintStart_toStartOf="parent"            android:layout_marginStart="8dp" app:layout_constraintEnd_toEndOf="parent" android:layout_marginEnd="8dp"    />    <Button            android:text="Verbose Log"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:id="@+id/btn_verbose" android:layout_marginTop="68dp"            app:layout_constraintTop_toBottomOf="@+id/btn_debug" app:layout_constraintStart_toStartOf="parent"            android:layout_marginStart="8dp" app:layout_constraintEnd_toEndOf="parent" android:layout_marginEnd="8dp"            android:layout_marginBottom="8dp"            app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintVertical_bias="0.061"/></android.support.constraint.ConstraintLayout>

Now it’s time to set click listeners to these buttons and print a log statement every time a button is clicked. I’m using kotlin’s synthetic bindings instead of regular findViewById calls or Butterknife. Here is my MainActivity.kt file:

现在是时候将单击侦听器设置为这些按钮,并在每次单击按钮时打印一条日志语句。 我使用的是kotlin的合成绑定,而不是常规的findViewById调用或Butterknife。 这是我的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.")    }
}

Notice how we didn’t need to initialize any TAG variable in our class, Timber does it automatically for you.

请注意,我们无需在类中初始化任何TAG变量,Timber会自动为您完成。

自定义木材以进行调试和发布 (Customizing Timber for Debug and Release)

Now, this is where Timber really shines. What we’ve done till now was nothing great, just printing the log statements on button clicks. But as you know, logging in production is not a good idea. We will write code to disable the logs for production while keeping them enabled during debug mode.

现在, 这是Timber真正发光的地方。 到目前为止,我们所做的一切都还不错,只是在单击按钮时打印日志语句。 但是,正如您所知,登录生产并不是一个好主意。 我们将编写代码以禁用生产日志,同时在调试模式下保持启用状态。

We’ll write an if block to check if our app is in debug mode and enable logging for that. If not, then we want to initialize Timber using a custom tree.

我们将编写一个if块来检查我们的应用程序是否处于调试模式,并为此启用日志记录。 如果不是,那么我们要使用自定义树来初始化Timber

Here’s the modified MainApplication.kt class:

这是修改后的MainApplication.kt类:

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())        }    }}

As you can see, we’ve initialized timber using a custom ReleaseTree when in release mode. Now let’s go ahead and create our own release tree.

如您所见,在发布模式下,我们使用自定义的ReleaseTree初始化了木材。 现在,让我们继续创建自己的发行树。

创建一个自定义树 (Creating a Custom Tree)

Creating a release tree is fairly simple. Create a new Kotlin class and extend it from Timber.Tree. Implement all the abstract functions and you’re good to go.

创建发行树非常简单。 创建一个新的Kotlin类,并从Timber.Tree扩展它。 实现所有抽象功能,您就很好了。

Here’s my ReleaseTree.kt:

这是我的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.        }    }
}

As you can see, whenever there is an error, we can send the log to an online service such as Firebase CrashAnalytics or Crashlytics and not logging out on production.

如您所见,每当发生错误时,我们都可以将日志发送到诸如Firebase CrashAnalytics或Crashlytics之类的在线服务,而不会注销生产。

结果 (Result)

使用Timber与Android Logging的好处 (Benefits of using Timber vs Android Logging)

Let’s look at some of the benefits of using Timber library instead of the default Log utility by android sdk.

让我们看一下使用Timber库代替android sdk的默认Log实用程序的一些好处。

  • 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.

    无需担心 TAG:Timber会自动为您生成TAG,因此您不必担心在每个课程中都包含全局TAG。

  • 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.

    无需手动删除Log语句 :如已显示,禁用发行版应用程序的日志记录确实很容易。 因此,您不再需要遍历整个代码并手动删除所有日志。

  • 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.

    生产中的自定义行为 :在生产版本中,尽管您确实想记录可能发生的崩溃,但您不想记录。 您可以使用自定义调试树(如上所示)实现此目的,该树不会将日志记录到logcat,而是将日志发送到您的crashlytics服务。

  • 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.

很长时间以来,我一直忽略使用日志语句并打印出更好的日志。 随着我的代码越来越大,问题也越来越复杂,我意识到我需要采用更好,更高效的调试例程。 因此,使用Timber是朝正确方向迈出的一步。

*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.

*重要* :我为移动开发人员创建了一个SLACK工作区,在这里我们可以分享我们对最新技术的了解,特别是在Android开发,RxJava,Kotlin,Flutter和总体上整体移动开发方面

Click on this link to join the slack workspace. It’s absolutely free!

单击此链接以加入松弛工作空间。 完全免费!

This article was originally posted at https://ayusch.com/timber-for-android

本文最初发布在https://ayusch.com/timber-for-android

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

喜欢你读的书吗? 不要忘记在FacebookWhatsappLinkedIn上分享此帖子。

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

您可以在LinkedInQuoraTwitterInstagram上关注我,在那里我回答移动开发(尤其是Android和Flutter)有关的问题

翻译自: https://www.freecodecamp.org/news/how-to-log-more-efficiently-with-timber-a3f41b193940/

python timber

 类似资料: