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

Related tags

Logger 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)
An easy way to customize your log in Android,including output to console, writing log to file in high performance way and so on

EasyLog An easy way to customize your log in Android,including output to console, writing log to file in high performance way and so on. 1. Initializa

Taylor 40 Dec 8, 2022
Utility logger library for storing logs into database and push them to remote server for debugging

HyperLog Android Overview Log format Download Initialize Usage Get Logs in a File Push Logs Files to Remote Server Sample Testing Endpoint using Reque

HyperTrack 675 Nov 14, 2022
Kermit is a Kotlin Multiplatform logging utility with composable log outputs

Kermit is a Kotlin Multiplatform logging utility with composable log outputs. The library provides prebuilt loggers for outputting to platform logging tools such as Logcat and NSLog.

Touchlab 395 Jan 4, 2023
An OkHttp interceptor which has pretty logger for request and response. +Mock support

LoggingInterceptor - Interceptor for OkHttp3 with pretty logger Usage val client = OkHttpClient.Builder() client.addInterceptor(LoggingInterceptor

ihsan BAL 1.3k Dec 26, 2022
✔️ Simple, pretty and powerful logger for android

Logger Simple, pretty and powerful logger for android Setup Download implementation 'com.orhanobut:logger:2.2.0' Initialize Logger.addLogAdapter(new A

Orhan Obut 13.5k Dec 30, 2022
Logger

StreamingAndroidLogger Introduction Convenient logger that adds support to having multiple different loggers and different log levels for each one of

Jan Rabe 46 Nov 29, 2022
Timber + Logger Integration. Make Logcat Prettier, show thread information and more.

Pretty Timber Android Logcat Timber + Logger Integration Video Instructions: https://youtu.be/zoS_i8VshCk Code App.kt class App : Application() {

Awesome Dev Notes | Android Dev Notes YouTube 29 Jun 6, 2022
Napier is a logger library for Kotlin Multiplatform.

Napier is a logger library for Kotlin Multiplatform. It supports for the android, ios, jvm, js. Logs written in common module are displayed on logger

Akira Aratani 457 Jan 7, 2023
Kotlin Multi Platform Logger, for android an ios : Logcat & print

Multiplatform Preferences Use a single object : Logger in your kotlin shared projects to display logs Note you can also use it in your real code on An

Florent CHAMPIGNY 49 Aug 22, 2022
Yakl - Yet Another Kotlin Logger

YAKL Yet Another Kotlin Logger. Motivation Current jvm loggers have some disadva

Mark Kosichkin 4 Jan 19, 2022
Pluto Logger is a Pluto plugin to manage and share your Debug logs

Pluto Logger Plugin Pluto Logger is a Pluto plugin to manage and share your Debug logs. It also comes with Timber support. ?? Integrate plugin in your

Pluto 1 Feb 8, 2022
Simple application to log your mood through the day and explain feature flags.

Mood Logger App (Android version) This Repo This repository contains code for building a very basic application to log your mood through the days. The

MongoDB Developer Relations 3 Oct 24, 2021
Library that makes debugging, log collection, filtering and analysis easier.

AndroidLogger Android Library that makes debugging, log collection, filtering and analysis easier. Contains 2 modules: Logger: 'com.github.ShiftHackZ.

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

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

Jake Wharton 9.8k Dec 30, 2022
A tiny Kotlin API for cheap logging on top of Android's normal Log class.

A tiny Kotlin API for cheap logging on top of Android's normal Log class.

Square 849 Dec 23, 2022
Annotation Processing Library. Generates proxy class on top of interface/abstract class, that allows to intercept calls. Also known as a design pattern: proxy, delegate, interceptor.

1. AutoProxy Annotation Processing Library. Generates proxy class on top of interface/abstract class, that allows to intercept calls. Also known as a

Oleksandr 19 Nov 24, 2022
An easy way to customize your log in Android,including output to console, writing log to file in high performance way and so on

EasyLog An easy way to customize your log in Android,including output to console, writing log to file in high performance way and so on. 1. Initializa

Taylor 40 Dec 8, 2022
Utility logger library for storing logs into database and push them to remote server for debugging

HyperLog Android Overview Log format Download Initialize Usage Get Logs in a File Push Logs Files to Remote Server Sample Testing Endpoint using Reque

HyperTrack 675 Nov 14, 2022
Kotlin extension function provides a facility to "add" methods to class without inheriting a class or using any type of design pattern

What is Kotlin Extension Function ? Kotlin extension function provides a facility to "add" methods to class without inheriting a class or using any ty

mohsen 21 Dec 3, 2022
A tiny window overlay to log app internal on top of your android app

DebugOverlay A logcat alike overlay to display log messages in your app as independent overlay. Typically in android you would log some app internals

Hannes Dorfmann 150 Nov 29, 2022