A logger with a small, extensible API which provides utility on top of Android's normal Log class.

Related tags

Utility timber
Overview

Timber

This is a logger with a small, extensible API which provides utility on top of Android's normal Log class.

I copy this class into all the little apps I make. I'm tired of doing it. Now it's a library.

Behavior is added through Tree instances. You can install an instance by calling Timber.plant. Installation of Trees should be done as early as possible. The onCreate of your application is the most logical choice.

The DebugTree implementation will automatically figure out from which class it's being called and use that class name as its tag. Since the tags vary, it works really well when coupled with a log reader like Pidcat.

There are no Tree implementations installed by default because every time you log in production, a puppy dies.

Usage

Two easy steps:

  1. Install any Tree instances you want in the onCreate of your application class.
  2. Call Timber's static methods everywhere throughout your app.

Check out the sample app in timber-sample/ to see it in action.

Lint

Timber ships with embedded lint rules to detect problems in your app.

  • TimberArgCount (Error) - Detects an incorrect number of arguments passed to a Timber call for the specified format string.

    Example.java:35: Error: Wrong argument count, format string Hello %s %s! requires 2 but format call supplies 1 [TimberArgCount]
        Timber.d("Hello %s %s!", firstName);
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
  • TimberArgTypes (Error) - Detects arguments which are of the wrong type for the specified format string.

    Example.java:35: Error: Wrong argument type for formatting argument '#0' in success = %b: conversion is 'b', received String (argument #2 in method call) [TimberArgTypes]
        Timber.d("success = %b", taskName);
                                 ~~~~~~~~
    
  • TimberTagLength (Error) - Detects the use of tags which are longer than Android's maximum length of 23.

    Example.java:35: Error: The logging tag can be at most 23 characters, was 35 (TagNameThatIsReallyReallyReallyLong) [TimberTagLength]
        Timber.tag("TagNameThatIsReallyReallyReallyLong").d("Hello %s %s!", firstName, lastName);
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
  • LogNotTimber (Warning) - Detects usages of Android's Log that should be using Timber.

    Example.java:35: Warning: Using 'Log' instead of 'Timber' [LogNotTimber]
        Log.d("Greeting", "Hello " + firstName + " " + lastName + "!");
            ~
    
  • StringFormatInTimber (Warning) - Detects String.format used inside of a Timber call. Timber handles string formatting automatically.

    Example.java:35: Warning: Using 'String#format' inside of 'Timber' [StringFormatInTimber]
        Timber.d(String.format("Hello, %s %s", firstName, lastName));
                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
  • BinaryOperationInTimber (Warning) - Detects string concatenation inside of a Timber call. Timber handles string formatting automatically and should be preferred over manual concatenation.

    Example.java:35: Warning: Replace String concatenation with Timber's string formatting [BinaryOperationInTimber]
        Timber.d("Hello " + firstName + " " + lastName + "!");
                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
  • TimberExceptionLogging (Warning) - Detects the use of null or empty messages, or using the exception message when logging an exception.

    Example.java:35: Warning: Explicitly logging exception message is redundant [TimberExceptionLogging]
         Timber.d(e, e.getMessage());
                     ~~~~~~~~~~~~~~
    

Download

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

Snapshots of the development version are available in Sonatype's snapshots repository.

License

Copyright 2013 Jake Wharton

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Comments
  • AGP 7.0.0-alpha13: lint task fails

    AGP 7.0.0-alpha13: lint task fails

    When running the lint task with AGP 7.0.0-alpha13 it will fail with the following error:

    The lint detector
    timber.lint.WrongTimberUsageDetector
    called context.getMainProject() during module analysis.
    
    This does not work correctly when running in cli.
    
    In particular, there may be false positives or false negatives because
    the lint check may be using the minSdkVersion or manifest information
    from the library instead of any consuming app module.
    
    Contact the vendor of the lint issue to get it fixed/updated (if
    known, listed below), and in the meantime you can try to work around
    this by disabling the following issues:
    
    "LogNotTimber","StringFormatInTimber","ThrowableNotAtBeginning","BinaryOperationInTimber","TimberArgCount","TimberArgTypes","TimberTagLength","TimberExceptionLogging"
    
    Issue Vendors:
    Identifier: timber-4.7.1
    
    Call stack: Context.getMainProject(Context.kt:117)
    ←WrongTimberUsageDetector.visitMethod(WrongTimberUsageDetector.java:80)
    ←Detector.visitMethodCall(Detector.kt:551)
    ←UElementVisitor$DelegatingPsiVisitor.visitMethodCallExpression(UElementVisitor.kt:1095)
    ←UElementVisitor$DelegatingPsiVisitor.visitCallExpression(UElementVisitor.kt:1075)
    ←KotlinUFunctionCallExpression.accept(KotlinUFunctionCallExpression.kt:186)
    ←UQualifiedReferenceExpression$DefaultImpls.accept(UQualifiedReferenceExpression.kt:34)
    ←KotlinUQualifiedReferenceExpression.accept(KotlinUQualifiedReferenceExpression.kt:29)
    ←UQualifiedReferenceExpression$DefaultImpls.accept(UQualifiedReferenceExpression.kt:33)
    ←KotlinUQualifiedReferenceExpression.accept(KotlinUQualifiedReferenceExpression.kt:29)
    ←ImplementationUtilsKt.acceptList(implementationUtils.kt:23)
    ←UBlockExpression$DefaultImpls.accept(UBlockExpression.kt:21)
    ←KotlinUBlockExpression.accept(KotlinUBlockExpression.kt:24)
    ←ULambdaExpression$DefaultImpls.accept(ULambdaExpression.kt:33)
    ←KotlinULambdaExpression.accept(KotlinULambdaExpression.kt:29)
    ←ImplementationUtilsKt.acceptList(implementationUtils.kt:23)
    ←KotlinUFunctionCallExpression.accept(KotlinUFunctionCallExpression.kt:190)
    ←UQualifiedReferenceExpression$DefaultImpls.accept(UQualifiedReferenceExpression.kt:33)
    ←KotlinUQualifiedReferenceExpression.accept(KotlinUQualifiedReferenceExpression.kt:29)
    ←ImplementationUtilsKt.acceptList(implementationUtils.kt:23)
    

    Everything works fine when using AGP 7.0.0-alpha12. Disabling the issues obviously works as a temporary workaround.

    opened by ubuntudroid 20
  • Decouple Timber from Android.Log

    Decouple Timber from Android.Log

    Hi Jake!

    Few days ago I opened issue #62 asking about the possibility of removing android.Log from Timber class so it can be a pure Java logger. You closed it as a dupe of #29, which asks for making Timber dependent of slf4j-api. I'm not sure these two are asking for the same.

    In order to make my issue more clear I have created this PR as an "illustrative" solution. I know it may not be the best, mainly because it breaks the chain of compatibility for older versions because in favor of a new namespace for DebugTree (timber.log.android.DebugTree). But, at least, I hope that you can get a better picture of the goal that I want to achieve.

    Look forward to your feedback.

    Thanks!

    opened by saguinav 17
  • Support Log.wtf

    Support Log.wtf

    What About Supporting .wtf (Documentation: http://developer.android.com/reference/android/util/Log.html#wtf(java.lang.String, java.lang.Throwable) ) Log Levels.

    opened by CaptnBlubber 13
  • Allow override for tag depth

    Allow override for tag depth

    Pull DebugTree.CALL_STACK_INDEX into a protected getLoggingDepth() method. This is useful for apps that wrap Timber and don't want every tag to be "TimberWrapper" or whatever. Does not affect default behavior for users who don't want/need this.

    opened by drewhamilton 11
  • 4.6.0 update Lint fails with lombok/ast/Node

    4.6.0 update Lint fails with lombok/ast/Node

    After updating to 4.6.0 Lint fails with:

    :app:lintPlayReleaseUnexpected failure during lint analysis of null (this is a bug in lint or one of the libraries it depends on)
    
    `NoClassDefFoundError:PermissionRequirement.getAnnotationStringValue(PermissionRequirement.java:244)←PermissionRequirement.create(PermissionRequirement.java:111)←SupportAnnotationDetector.checkAnnotations(SupportAnnotationDetector.java:502)←SupportAnnotationDetector.access$100(SupportAnnotationDetector.java:178)←SupportAnnotationDetector$CallVisitor.checkCall(SupportAnnotationDetector.java:2772)←SupportAnnotationDetector$CallVisitor.visitCallExpression(SupportAnnotationDetector.java:2671)←UElementVisitor$DispatchPsiVisitor.visitCallExpression(UElementVisitor.java:520)←UElementVisitor$DelegatingPsiVisitor.visitCallExpression(UElementVisitor.java:1041)`
    
    You can set environment variable `LINT_PRINT_STACKTRACE=true` to dump a full stacktrace to stdout.
    java.lang.NoClassDefFoundError: lombok/ast/Node
    

    I am using: Gradle: 4.2.1 'com.android.tools.build:gradle:3.0.0' buildToolsVersion "27.0.0"

    opened by niqo01 11
  • API 14 Android 4.0 Support

    API 14 Android 4.0 Support

    Hi,

    I cannot use Timber on API 14. Is there a specific reason that minSdkVersion=15 is required?

    https://github.com/JakeWharton/timber/blob/master/build.gradle#L17

    Thank you,

    Jan

    opened by weitzj 11
  • Cannot resolve method 'plant(timber.log.Timber.DebugTree)'

    Cannot resolve method 'plant(timber.log.Timber.DebugTree)'

    • Android Studio version: Android Studio Bumblebee | 2021.1.1 Patch 1 (Build #AI-211.7628.21.2111.8139111)
    • Timber version: com.jakewharton.timber:timber:5.0.1

    Reproduction steps:

    1. Simply add the above dependency to an Android project (ensuring to use Android Studio Bumblebee+)
    2. Observe the Cannot resolve method 'plant(timber.log.Timber.DebugTree)' Lint error message:

    image

    Additional notes:

    • Didn't seem to occur on prior version of Android Studio (Arctic Fox and prior).
    • Does seem to affect Android Studio Bumblebee (Stable), Chipmunk (Beta) and Dolphin (Canary).
    • Doesn't appear to occur with pre-5.0.0 versions of Timber.
    • Loosely related to this issue.
    • Could be an Android Studio bug rather than a bug with Timber, though I figured best to report it here as it doesn't seem to affect pre-5.0.0 versions of Timber as mentioned previously.
    • In case the issue is in fact with Android Studio, @gmk57 has reported it on Android Studio bug tracker.
    opened by findyourexit 10
  • "Lint fails with 'Obsolete custom lint check' " resurfacing

    Is it possible that latest AGP is triggering #284 again? On com.android.tools.build:gradle:3.3.0-alpha04:

    timber-4.7.1.aar/.../lint.jar: Lint found an issue registry (timber.lint.TimberIssueRegistry) which is older than the current API level; these checks may not work correctly.

    opened by tir38 10
  • It's now possible to adjust the tag generation if the Timber is wrapped into another logger framework

    It's now possible to adjust the tag generation if the Timber is wrapped into another logger framework

    Let's image that we don't want to use Timber directly in our applications, but we have a custom interface for logging that use a Timber delegate as its implementation. Let's call that interface "Logger". So in the debug log we want to print the line when Logger.d() was called, not Timber.d() (we already know this line, it's always inside our "Logger"). The aim of this change is to make possible to customize which line from the calling stack trace should be printed by the DebugTree.

    opened by jakubkrolewski 10
  • tag is null

    tag is null

    When I extend Timber.Tree and override the log method I get passed a null tag:

    @Override
    protected void log(int priority, String tag, String message, Throwable t) {
       if (priority == Log.VERBOSE || priority == Log.DEBUG || priority == Log.INFO) {
          return;
       }
       // tag is null
       Log.println(priority, tag, message);
    }
    
    opened by brescia123 9
  • Do *not* truncate tags over 23 characters

    Do *not* truncate tags over 23 characters

    Quoting my comment https://github.com/JakeWharton/timber/issues/196#issuecomment-464646466

    Log doesn't care at all how long the tags are.

    The only thing where is an issue is that Log.isLoggable checks a system property. And system property keys were until API 24 limited in length to 31 characters. And "log.tag.".size + 23 equals 31.

    Source:

    • https://android.googlesource.com/platform/frameworks/base/+/kitkat-release/core/jni/android_util_Log.cpp
    • https://android.googlesource.com/platform/frameworks/base/+/oreo-release/core/jni/android_util_Log.cpp

    Going forward LogcatTree could

    • drop this limitation entirely or
    • enforce it for one or both of checking and printing just when withCompliantLogging() is used.
    opened by consp1racy 8
  • Make Tree:tag protected instead of internal

    Make Tree:tag protected instead of internal

    In a custom tree it may make sense to adjust tags with tree specific data. In timber v4 this was easily possible, not in v5 it isn't anymore.

    Is this project still active? If so, please make Tree::tag at least protected so that sub classes can access, it does not make much sense to hide it from a derived class imho.. and this limits functionality of sub tree currently...

    https://github.com/JakeWharton/timber/blob/9954d94abbaea9d003243be5b69f8ae0ffc0c99d/timber/src/main/java/timber/log/Timber.kt#L25

    opened by MFlisar 0
  • Could not load custom lint check jar

    Could not load custom lint check jar

    Hi , when im trying to build release im getting this error.

    Could not load custom lint check jar file C:\Users\me.gradle\caches\transforms-3\282411d3028f415e7f15eb7525ee01bd\transformed\jetified-timber-5.0.1\jars\lint.jar java.lang.NoClassDefFoundError: com/android/tools/lint/client/api/Vendor at timber.lint.TimberIssueRegistry.(TimberIssueRegistry.kt:25)

    Using com.android.tools.build:gradle:4.2.2 , i think thats the problem.

    More info here:

    https://github.com/doublesymmetry/react-native-track-player/issues/1776

    opened by izyspania 0
  • Getting a parse error when using file logging

    Getting a parse error when using file logging

    I am using file logging library getting parse error for date and log tag in console.

    expected: Date [ClassName:LineNumber method]: Log What I am getting is: %PARSER_ERROR[d] [p92:1 z]: log

    opened by RahulMSASEENDRAN 0
  • Escape percent symbol?

    Escape percent symbol?

    Hello, I just wanted to print a simple line like "10% space", no parameters. Just an example.

    If I use Log like this there are no problems: Log.e("test", "10% space")

    But if I use Timber it says I'm missing a parameter: Timber.e("10% space")

    I tried escaping the symbol in several ways but with no luck:

    "10\\% space" -> prints "10\% space"
    "10%% space" -> prints "10%% space"
    

    Am i missing something? Thanks

    opened by LucaBL 0
  • Update README.md

    Update README.md

    I added more details on the existing documentation file , focusing on the set up process of Timber once the dependencies have been downloaded.

    In the documentation of Timber it was not clear on the implementation process in the application in Kotlin, like described in this Fixes #466 https://github.com/JakeWharton/timber/issues/466#issue-1206198186.

    To fix that, I added the procedure to implement it programmatically in the users code base. It being a documentation update, the necessity of a test was not in mind.

    I added the following under the Set Up section.I updated documentation but i can roll back if needed

    Step 1 : Create an Application class that inherits from Application class .

    open class MyProjectApplication : Application() {
    }
    

    Step 2 : import the application package

    import android.app.Application
    

    Step 3 : override the onCreate() method and initialize the Timber class

    override the onCreate() method in your Application class

    open class MyProjectApplication : Application() {
        if (BuildConfig.DEBUG) {
          Timber.plant(new DebugTree());
        } else {
          Timber.plant(new CrashReportingTree());
        }
      ##}
    

    Step 4 : Define it in your Android Manifest , Application tag

    In your application tag, add it as a name attribute :

    <application  
           ....
           android:name=".MyProjectApplication"
           android:theme="@style/AppTheme"
          .... >
    
    opened by JosephRidge 0
Releases(5.0.1)
  • 5.0.1(Aug 13, 2021)

  • 5.0.0(Aug 10, 2021)

    The library has been rewritten in Kotlin, but it remains binary-compatible with 4.x. The intent is to support Kotlin multiplatform in the future. This is otherwise a relatively minor, bug-fix release.

    Changed

    • Minimum supported API level is now 14.
    • Minimum supported AGP (for embedded lint checks) is now 7.0.

    Fixed

    • DebugTree now finds first non-library class name which prevents exceptions in optimized builds where expected stackframes may have been inlined.
    • Enforce 23-character truncated tag length until API 26 per AOSP sources.
    • Support Long type for date/time format arguments when validating format strings in lint checks.
    • Do not report string literal concatenation in lint checks on log message.
    Source code(tar.gz)
    Source code(zip)
A small utility to record Android device screen to a GIF

RoboGif A small utility to record Android device screen to an optimized GIF so you can paste it to GitHub or a similar service. Requirements Python 2.

Jernej Virag 526 Dec 9, 2022
A collection of small utility functions to make it easier to deal with some otherwise nullable APIs on Android.

requireKTX is a collection of small utility functions to make it easier to deal with some otherwise nullable APIs on Android, using the same idea as requireContext, requireArguments, and other similar Android SDK methods.

Márton Braun 82 Oct 1, 2022
Small utility to create/restore encrypted backups

Quick Backup Choose some files and quickly create a complete encrypted and compressed file. Usage Clone the repository Run gradlew installShadowDist T

Leonardo Colman 5 Sep 18, 2021
Small utility used to add Homewizard Energy Socket tiles to Android Quick Settings

TileWizard [Alpha! Unstable!] Settings Result Functionality: Add up to 5 Wi-Fi Energy Sockets to Android Quick Settings. What do you need: Android dev

Niels Masdorp 2 Oct 19, 2021
Small command-line utility to safely merge multiple WhatsApp backups (msgstore.db) into one.

whatsapp-database-merger A small command-line utility that can be used to merge multiple WhatsApp databases (msgstore.db) into one. A few notes: input

Mattia Iavarone 31 Dec 27, 2022
A log collector for Android

Puree Description Puree is a log collector which provides the following features: Filtering: Enable to interrupt process before sending log. You can a

Cookpad 479 Dec 19, 2022
Kotlin matrix class which supports determinant, inverse matrix, matmul, etc.

Kotrix is a set of classes that helps people dealing with linear algebra in Kotlin.

Kanguk Lee 5 Dec 8, 2022
A small library which will save you from writing the same intent creation code again and again for the most simple tasks

Android Intents A small library which will save you from writing the same intent creation code again and again for the most simple tasks. I found myse

MarvinLabs 420 Nov 20, 2022
[] Define and render UI specs on top of your Android UI

dspec A simple way to define and render UI specs on top of your Android UI. Usage Enclose the target UI with a DesignSpecFrameLayout, usually the root

Lucas Rocha 561 Dec 16, 2022
Utility for detecting and notifying when your Android app goes background / becomes foreground

Foredroid Utility for detecting and notifying when your Android app goes background / becomes foreground. API-level 14+. Usage: Initialise Foreground

Steve Liles 151 Nov 29, 2022
Utility tool to make you a computer ninja.

Cmd Window Never spend 6 minutes doing something by hand when you can spend 6 hours failing to automate it - Zhuowej Zhang What is this about? This to

Marcin Radoszewski 3 Feb 1, 2022
FractalUtils - A collection of utility functions and classes, with an emphasis on game related utilities

A collection of utility functions and classes written in Kotlin. There is some emphasis on utilities useful for games (Geometry, Random, Time, Updating, etc).

null 2 Nov 11, 2022
A command line utility to help you investigate the sensitive data associated with Macie findings.

Macie Finding Data Reveal This project contains a command line utility to help you investigate the sensitive data associated with Macie findings.

AWS Samples 8 Nov 16, 2022
Utility library that utilizes KSP to generate Room type converter classes.

Roomie Roomie is an annotation processing library that utilizes KSP to geaRoomie is an annotation processing library that utilizes KSP to generate TypeConverter classes for Room. TypeConverter classes most often involve same boiler-plate code and Roomie makes it really easy to quickly create them with a single annotation.nerate TypeConverter classes for Room. TypeConverter classes most often invol

Chukwuka Eze 12 Aug 26, 2022
CHAOS - Like a utility knife for discord

CHAOS - Like a utility knife for discord. Currently under development. If you feel inclined, please support me by contributing to this project. Or alt

caffeine.moe 20 Nov 13, 2022
Obsi-bot: the next generation discord utility bot 🔥

obsi-bot obsi-bot is the next generation discord utility bot. It is developed in Kotlin using kordex and kord Help me translating Feel free to help me

mooziii 2 Nov 7, 2022
Wrapper around the android Camera class that simplifies its usage

EasyCamera Wrapper around the android Camera class that simplifies its usage (read more about the process) Usage: // the surface where the preview wil

Bozhidar Bozhanov 641 Dec 29, 2022
BinGait is a tool to disassemble and view java class files, developed by BinClub.

BinGait Tool to diassemble java class files created by x4e. Usage To run BinGait, run java -jar target/bingait-shadow.jar and BinGait will launch. If

null 18 Jul 7, 2022
Dagger Hilt, MVP Moxy, Retrofit, Kotlin coroutine, Sealed class

Dagger Hilt, MVP Moxy, Retrofit, Kotlin coroutine, Sealed class

Dostonjon 1 Nov 2, 2021