Giter Club home page Giter Club logo

timber's Introduction

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

repositories {
  mavenCentral()
}

dependencies {
  implementation 'com.jakewharton.timber:timber:5.0.1'
}

Documentation is available at jakewharton.github.io/timber/docs/5.x/.

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

repositories {
  mavenCentral()
  maven {
    url 'https://oss.sonatype.org/content/repositories/snapshots/'
  }
}

dependencies {
  implementation 'com.jakewharton.timber:timber:5.1.0-SNAPSHOT'
}

Snapshot documentation is available at jakewharton.github.io/timber/docs/latest/.

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.

timber's People

Contributors

alexbeggs avatar benoitdion avatar clonetwin26 avatar dependabot[bot] avatar edenman avatar eygraber avatar f2prateek avatar imminent avatar jakewharton avatar johnjohndoe avatar jrodbx avatar kevinslashslash avatar kymjs avatar lakshaylalwani avatar macxtor avatar maxsiomindev avatar michaelevans avatar mikehardy avatar nikreiman avatar peterattardo avatar piotr-j avatar robertschmid-ast avatar runningcode avatar shaishavgandhi avatar shiraji avatar slvn avatar tasomaniac avatar turbo87 avatar vanniktech avatar vlazzle avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

timber's Issues

Planted trees

I would like to know if it's possible to check the status of the planted trees in the FOREST object. In my opinion it would be useful to have the following information:

  • the number of trees planted into the forest
  • the kind of trees planted into the forest

The reason is that I'm building a library that makes use of Timber, and I would like to avoid to add further Trees to the forest, or at least understand if a Tree is available or not.

Thank you!

DebugTree does not include crash case

In real case, when DebugTree is selected and crash happens, it does not report crash issue.

I know DebugTree and CrashReportingTree are different cases in the following codes. However, DebugTree should include crash case, does it make much sense?

if (BuildConfig.DEBUG) {
Timber.plant(new Timber.DebugTree());
} else {
Timber.plant(new CrashReportingTree());
}

« Unexpected failure during lint analysis » messages

I see these messages when using lint on my project:

Unexpected failure during lint analysis of Log.java (this is a bug in lint or one of the libraries it depends on)
WrongTimberUsageDetector.visitMethod(WrongTimberUsageDetector.java:108)->JavaVisitor$DelegatingJavaVisitor.visitMethodInvocation(JavaVisitor.java:1360)->MethodInvocation.accept(MethodInvocation.java:114)->ExpressionStatement.accept(ExpressionStatement.java:63)

FYI Log.java is the class in which I call Timber.

Not sure if this is enough for you to investigate the problem, please don't hesitate to ask if I can provide you with more logs or info.

Go Gradle

Maven annoys me more and more every day.

Remove android.Log dependency from Timber

Hi Jake!

My team is working on some core libraries to share on our Android apps and we are thinking about using Timber for logging. The thing is that some of those libraries are pure Java and we don't want to force them to take a dependency on Android. So we are wondering, what is your opinion about removing the android.Log dependency from Timber?

Thanks in advance!

Timber truncates log after two consecutive \n

Timber.d("{\n\n}");
Timber.d("{\n}");

This outputs the following:

11-23 17:14:28.348 12339-12339/? D/SplashActivity: {
11-23 17:14:28.348 12339-12339/? D/SplashActivity: {
                                                   }

For some reason anything after the double \n is truncated.
I tried debugging but I couln't go further than Log.println().

BinaryOperationInTimber highlights too much

Should only highlight the argument which does the concatenation.

Example.java:35: Warning: Replace String concatenation with Timber's string formatting [BinaryOperationInTimber]
    Timber.d("Hello " + firstName + " " + lastName + "!");
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Gracefully ignore argument errors in log output

I just switched to use Timber in my app - thanks a lot for the library!
One problem I encountered very quickly: if you do the slightest mistake in a String format and not supply the correct amount of arguments, your app crashes like this:

FATAL EXCEPTION: IntentService[XYZService]
                     E  Process: de.zordid.xyz, PID: 10874
                     E  java.util.MissingFormatArgumentException: Format specifier: tT
                     E      at java.util.Formatter.getArgument(Formatter.java:1111)
                     E      at java.util.Formatter.doFormat(Formatter.java:1076)
                     E      at java.util.Formatter.format(Formatter.java:1042)
                     E      at java.util.Formatter.format(Formatter.java:1011)
                     E      at java.lang.String.format(String.java:1803)
                     E      at java.lang.String.format(String.java:1777)
                     E      at timber.log.Timber$Tree.prepareLog(Timber.java:312)
                     E      at timber.log.Timber$Tree.v(Timber.java:235)
                     E      at timber.log.Timber$1.v(Timber.java:120)
                     E      at timber.log.Timber.v(Timber.java:13)

(in this special case I tried to log timestamps and used "%tF %tT%z" but forgot to double my time argument...

Wouldn't it be better if such internal problems when trying to log would be handled by Timber, preventing the app to crash?
Thanks!

Depend on slf4j-api instead of Android Log

You could depend on slf4j-api instead of android Log, then timber could be used in Java only sub modules/projects.

Or maybe depend on whichever one is present at runtime, so slf4j-api and android are both optional dependencies.

Just a thought... ( might be beyond your vision for this lib )

Timber.j(Object o) for JSON formatted log output

I don't think I saw anything like it in the current source. Wouldn't it be nice if we could get an entire object represented as a Json Formatted String in the log ? It would save time from actually having to debug with break points.

Add workaround for logcat max length

Maybe you can add some checks in Timber for log message length? If it more than MAX_LENGHT divide it into two messages?
Logcat has no possibility to turn on word wrap and some of the messages just truncated.

Build: 1.2 Preview 1, AI-140.1773923, 20150306,
1.8.0_11-b12x64 Oracle Corporation, Windows 7(amd64) v6.1 Service Pack 1 (1920x1080, 1440x900)

TimberArgTypes mixes 0-based and 1-based indexing.

String format is 0-based while the argument itself is 1-based.

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);
                             ~~~~~~~~

Logging generic type as String causes unexpected lint failure

Running lint on the following code causes an "unexpected failure."

public class Foo<T> {

    public void logBar(T bar) {
        Timber.d("bar: %s", bar);
    }
}

The error message is:

Unexpected failure during lint analysis of Foo.java (this is a bug in lint or one of the libraries it depends on)
EcjParser.equalsCompound(EcjParser.java:2351)->EcjParser$EcjResolvedClass.isSubclassOf(EcjParser.java:1381)->WrongTimberUsageDetector.isSubclassOf(WrongTimberUsageDetector.java:329)->WrongTimberUsageDetector.checkThrowablePosition(WrongTimberUsageDetector.java:448)

The failure message goes away if we replace Timber.d("bar: %s", bar); with Timber.d("bar: %s", bar.toString());. It seems like lint isn't able to recognize the implicit toString() method call.

Furthermore, I'm seeing this issue for the Gradle plugin version 1.5.0. Using the plugin version 1.3.1 also makes the failure message disappear.

Here's an example app with this issue.

Tag Timber as @NonNls or String parameters

It would be helpful if Timber's log statements where Strings are parameters were tagged as @NonNls for that parameter. That would allow AndroidStudio to skip over Timber statements when running the "Hard Coded String" inspection.

There are a method to change the TAG?

Hello

There are a method to change the tag and not use the class name?

I have try to implement a new Tree and override the tag method but doesn't work.

Thank you for your work and this awesome library

java.lang.NoClassDefFoundError in API 18

When trying to upload the debug variant of an app I am developing using Timber. When trying in one of my old devices running API 18, I get the following error

E/AndroidRuntime: FATAL EXCEPTION: main
                                                                             java.lang.NoClassDefFoundError: timber.log.Timber$1
                                                                                 at timber.log.Timber.<clinit>(Timber.java:150)
                                                                                 at com.aitorvs.android.nlcommute.MyApplication.onCreate(MyApplication.java:36)
                                                                                 at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1007)
                                                                                 at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4444)
                                                                                 at android.app.ActivityThread.access$1300(ActivityThread.java:141)
                                                                                 at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1316)
                                                                                 at android.os.Handler.dispatchMessage(Handler.java:99)
                                                                                 at android.os.Looper.loop(Looper.java:137)
                                                                                 at android.app.ActivityThread.main(ActivityThread.java:5103)
                                                                                 at java.lang.reflect.Method.invokeNative(Native Method)
                                                                                 at java.lang.reflect.Method.invoke(Method.java:525)
                                                                                 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
                                                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
                                                                                 at dalvik.system.NativeStart.main(Native Method)

and MyApplication.java:36 is the Timber.plant(...) inside the true IF branch like bellow:

        if (BuildConfig.DEBUG) {
            Timber.plant(new Timber.DebugTree() {
                             @Override
                             protected String createStackElementTag(StackTraceElement element) {
                                 return super.createStackElementTag(element) + ":" + element.getLineNumber();
                             }
                         }
            );
        } else {
            Timber.plant(new TimberReleaseTree());
        }

I have tested the app in other devices running L and M and runs OK for both release and debug versions so I assume is something related to TImber internals.

I am using version Timber 4.1.0.

Persistent usage of timber (including low-level classes) is not clear

I like idea of timber, but usage of it in real Android apps is not clear for me.

With current Dagger approach (provided in sample) we can inject timber only to Android Application related classes (Activities, Fragments, Services, etc). But we need logging in other classes too, part of them is too low-level to be injected with Dagger.

I have only one bad idea how to do it — pass timber object again and again through whole hierarchy.

Are you using timber+Dagger in production apps? How it works for you for logging in low-level classes?

Timber + POJO test

Hi,

for my Android projects, I've been using slf4j-android, like this:

public class MyClass {
private static final Logger logger = LoggerFactory.getLogger(MyClass.class);
void function() {
logger.debug("debug message");
}
}

I have a couple of POJO unit tests (business logic), and some robolectric tests (UI). But if a POJO test is using MyClass, it won't run because the android logging classes are missing. So for those tests, I include logback-access / classic / core.

My plan now is to use Timber instead, but when I run a test, it complains about SparseBooleanArray not being found. So I was wondering if we could make Timber not Android specific (if that makes any sense)?

thanks

Get Tag from Tree

How can I get the actual tag inside the planted class that extends from Timber.HollowTree?

LogNotTimber does not highlight enough

Should ideally get all of "Log.d" underlined.

Example.java:35: Warning: Using 'Log' instead of 'Timber' [LogNotTimber]
    Log.d("Greeting", "Hello " + firstName + " " + lastName + "!");
        ~

New lint check for wrong parameter types

When migrating from Android Log system to Timber log system, the Throwable parameter has to be the first parameter when using Timber.

Therefore a Lint check would be nice which would detect that the following statement is wrong.

Timber.w(e.getMessage(), e);

Since it should be

Timber.w(e, e.getMessage());

Issues cleaning lint.jar

Since updating to Timber 4.0.1 I seem to be getting this issue a lot when trying to clean for a rebuild;
Works fine when I close Android Studio, but trying to clean from AS seems to keep failing, cleaning from terminal and keeping AS running works sometimes.

$ ./gradlew clean
:XYZ:clean FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':XYZ:clean'.
> Unable to delete file: D:\dev\XYZ\build\intermediates\exploded-aar\com.jakewharton.timber\timber\4.0.1\jars\lint.jar

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 5.935 secs

I'm running Windows 10, AS 1.4, gradle 2.7.

Any ideas?

Missing Timber.v?

Curious if there is an intentional reason for the lack of Timber.v.

Throwable is not logged

When I do this:

public void failure(RetrofitError error) {
    Timber.e(error, "Error while retrieving books");
}

The message appears in the logcat console, but the exception is not logged:

08-14 13:30:06.724    1929-1929/com.github.geekarist.hpo E/BookListActivity﹕ Error while retrieving books

I did plant a DebugTree in my Application.onCreate:

if (BuildConfig.DEBUG) {
    Timber.plant(new Timber.DebugTree());
}

I'm using Timber version 3.1.0, and while investigating this I ended up in Timber.java:378, in the log(priority, tag, message, throwable) method, which doesn't use the throwable.

Is this an intended behaviour?

Proguard configuration?

I'm upgrading from 3.1.0 to 4.0.1. I see a new warning now, related to proguard:

Warning: timber.log.Timber: can't find referenced class org.jetbrains.annotations.NonNls

I added this proguard rule and the warning went away:

-dontwarn org.jetbrains.annotations.NonNls

Is this the correct resolution?
Thanks!

Tag creation fails for short stack traces

An ArrayOutOfBounds exception occurs when a new throwable generates a stack trace that is less than 5 elements long

In Timber.java:

private static String createTag() {
      String tag = NEXT_TAG.get();
      if (tag != null) {
        NEXT_TAG.remove();
        return tag;
      }

      tag = new Throwable().getStackTrace()[5].getClassName(); // exception occurs here
      Matcher m = ANONYMOUS_CLASS.matcher(tag);
      if (m.find()) {
        tag = m.replaceAll("");
      }
      return tag.substring(tag.lastIndexOf('.') + 1);
    }

TimberTagLength should only highlight argument

Currently it includes the "Timber" class and "tag" method.

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);
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

HollowTree missing in 3.0.0 and 3.0.1 releases

While updating my dependencies, I pointed to the latest release of Timber:

compile 'com.jakewharton.timber:timber:3.0.1'


hollowtree

The HollowTree symbol cannot resolve (clean, rebuild). If I extend Timber.DebugTree in the snippet below it will build just fine.

inittimber


release 3.0.0 must have introduced this issue as extending Timber.HollowTree in release 2.7.1 works properly.

Better if check log level before preparing log

public static abstract class Tree {

    ...

    private void prepareLog(int priority, Throwable t, String message, Object... args) {
        if(!isLoggable(priority)) {
            return;
        }
        ...
    }

    protected abstract boolean isLoggable(int priority);
}

Allow DebugTree to be subclassed

I might be missing something, but I can't find a way to implement a CrashReportingTree like in the example that implements TaggedTree instead of Tree.

As a consequence of this, logs sent to Crashlytics don't have the context of the tag associated to them, which make them pretty useless.

It would be great if the tagging functionality implemented in DebugTree was abstracted out so that other subclasses could reuse it, or if the implementation of the Tree methods weren't marked as final so that they could be overridden to forward logs to Crashlytics instead (or anything else).

unplant/unplantAll methods

It would allow enabling/disabling logging when app is running instead of having to close and relaunch. My use case: I need to analyze logs from users who are having problems with my app. I can plant trees whenever needed (say when users enable logging via app settings), but there is no way to "unplant".

is Android minSdkVersion = 15 required?

Hey there,

i just wanted to update from 3.1.0 to 4.0.1 but as i'm supporting minSdkVersion = 14 i get errors that my minSdk may not be lower that your minSdk set in your AndroidManifest.

does Timber require SDK 15+? It is possible to override the version with <uses-sdk tools:overrideLibrary="timber.log" /> in AndroidManifest.xml but i'd prefer to not need that.

Thanks.

:app:clean is unable to delete lint.jar

Since updating to Timber 4.1.0, anytime I try to do a Build -> Clean Project (or Rebuild Project) in Android Studio (v 1.5 stable), it is unable to delete the lint.jar file.

Error:Execution failed for task ':app:clean'.

Unable to delete file: C:\src\android_app\AndroidApp_2015.4.1-lib-updates\AndroidApp\app\build\intermediates\exploded-aar\com.jakewharton.timber\timber\4.1.0\jars\lint.jar

Windows 7
JDK 1.8.0_51

Expose StackTraceElement in DebugTree

It would be nice to make trees like this:

class LineNumberTree extends Timber.DebugTree {
    @Override
    protected String createTag() {
        return super.createTag() + ":" + stackTraceElement.getLineNumber();
    }
}

Currently I have to implement createTag() by myself or call Throwable.getStackTrace() two times, I'm not sure it's efficient:

class LineNumberTree extends Timber.DebugTree {
    @Override
    protected String createTag() {
        StackTraceElement[] stackTrace = new Throwable().getStackTrace();
        String lineNumber = ":" + stackTrace[5].getLineNumber();
        return super.createTag() + lineNumber;
    }
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.