Annotation-triggered method call logging for your debug builds.

Related tags

Logger hugo
Overview

Hugo

Annotation-triggered method call logging for your debug builds.

As a programmer, you often add log statements to print method calls, their arguments, their return values, and the time it took to execute. This is not a question. Every one of you does this. Shouldn't it be easier?

Simply add @DebugLog to your methods and you will automatically get all of the things listed above logged for free.

@DebugLog
public String getName(String first, String last) {
  SystemClock.sleep(15); // Don't ever really do this!
  return first + " " + last;
}
V/Example: ⇢ getName(first="Jake", last="Wharton")
V/Example: ⇠ getName [16ms] = "Jake Wharton"

The logging will only happen in debug builds and the annotation itself is never present in the compiled class file for any build type. This means you can keep the annotation and check it into source control. It has zero effect on non-debug builds.

Add it to your project today!

buildscript {
  repositories {
    mavenCentral()
  }

  dependencies {
    classpath 'com.jakewharton.hugo:hugo-plugin:1.2.1'
  }
}

apply plugin: 'com.android.application'
apply plugin: 'com.jakewharton.hugo'

Disable logging temporarily by adding the following:

hugo {
  enabled false
}

If you want to toggle logging at runtime, use Hugo.setEnabled(true|false)

Local Development

Working on this project? Here's some helpful Gradle tasks:

  • install - Install plugin, runtime, and annotations into local repo.
  • cleanExample - Clean the example project build.
  • assembleExample - Build the example project. Must run install first.
  • installExample - Build and install the example project debug APK onto a device.

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
  • java.lang.VerifyError while using @DebugLog anywhere in my app

    java.lang.VerifyError while using @DebugLog anywhere in my app

            dalvikvm  W  VFY: invoke type does not match method type of Lcom/example/MyActivity;.someMethodToLog
                        W  VFY:  rejecting opcode 0x6f at 0x0000
                        W  VFY:  rejected Lcom/example/MyActivity;.access$1000 (Lcom/example/MyActivity;)V
                        W  Verifier rejected class Lcom/example/MyActivity;
                        W  Class init failed in newInstance call (Lcom/example/MyActivity;)
        AndroidRuntime  D  Shutting down VM
              dalvikvm  W  threadid=1: thread exiting with uncaught exception (group=0x417d3898)
        AndroidRuntime  E  FATAL EXCEPTION: main
                        E  java.lang.VerifyError: com/example/MyActivity
                        E      at java.lang.Class.newInstanceImpl(Native Method)
                        E      at java.lang.Class.newInstance(Class.java:1130)
                        E      at android.app.Instrumentation.newActivity(Instrumentation.java:1078)
                        E      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2220)
                        E      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2359)
                        E      at android.app.ActivityThread.access$700(ActivityThread.java:165)
                        E      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1326)
                        E      at android.os.Handler.dispatchMessage(Handler.java:99)
                        E      at android.os.Looper.loop(Looper.java:137)
                        E      at android.app.ActivityThread.main(ActivityThread.java:5455)
                        E      at java.lang.reflect.Method.invokeNative(Native Method)
                        E      at java.lang.reflect.Method.invoke(Method.java:525)
                        E      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1187)
                        E      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
                        E      at dalvik.system.NativeStart.main(Native Method)
    
    opened by MufriA 60
  • Hugo + Retrolambda - is it possible to use both?

    Hugo + Retrolambda - is it possible to use both?

    Hi,

    Thanks for great library. Is it possible to use Hugo with retrolambda? I was trying to use them both in one project without any success. Everything is compiling but I don't see any hugo's logs when I start app.

    I've changed hugo-example app where you can reproduce it ( https://github.com/radzio/hugo/blob/master/hugo-example/build.gradle )

    Any ideas / suggestions?

    Cheers, Radek

    opened by radzio 9
  • This commit will fix the VerifyError listed in https://github.com/JakeWh...

    This commit will fix the VerifyError listed in https://github.com/JakeWh...

    This commit will fix the VerifyError listed in https://github.com/JakeWharton/hugo/issues/9

    The issue seems to have been resolved by upgrading to the latest build tools.

    opened by yhartanto 8
  • Wrong logged time

    Wrong logged time

    Before using Hugo I used my own util class with such methods (same for methods, that return void):

    public static <T> T howLong(String methodName, Method<T> command) {
        try {
          final long startTime = System.currentTimeMillis();
          final T result = command.execute();
          Timber.d("%s executed in %dms, thread: %s", methodName, System.currentTimeMillis() - startTime, Thread.currentThread().getName());
          return result;
        } catch (Exception e) {
          throw new RuntimeException(e);
        }
      }
    

    Im trying to write gif encoder from scratch, and I log almost everything. I noticed, that all execution is pretty long, but one method (that should be the longest) is not long at all, I tried to log every other method, and finally I use my old util to log time and what I got:

    V/AmazingGifEncoder: ⇠ map [1065ms] = [0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36...
    D/TimeUtils: Mapping pixels executed in 6745ms, thread: RxComputationThreadPool-1
    

    At the same moment total execution time seems to be calculated correctly:

    V/AmazingGifEncoder: ⇠ addFrame [7213ms]
    D/TimeUtils: Adding frame executed in 7215ms, thread: RxComputationThreadPool-1
    
    opened by antonshkurenko 7
  • DebugLog does not work in library module

    DebugLog does not work in library module

    Project with multi-module setup (application + library) does not log methods annotated with @DebugLog from library module. In application module it works fine.

    here is example https://github.com/curilpe/hugo-test

    EDIT:

    problem is not in hugo but in android gradle plugin because all library modules are release builds regardless of build type of application.

    to change it to debug build just put in build file of library module

    android { defaultPublishConfig "debug" }

    opened by curilpe 7
  • Gradle DSL method not found: hugo()

    Gradle DSL method not found: hugo()

    Hi, I am trying to follow your instructions for disabling hugo in Gradle. I put this in my app's build.gradle file: hugo { enabled false }

    However, Android Studio is throwing a build error:

    Error:(32, 0) Gradle DSL method not found: 'hugo()'

    Please advise how I can correct this. Igor

    opened by IgorGanapolsky 6
  • plugin id is 'hugo', not 'com.jakewharton.hugo'

    plugin id is 'hugo', not 'com.jakewharton.hugo'

    Trying to use your (wonderfull, thank you so much for that) plugin in my app. Wrote this (as per your README.md):

    buildscript {
        repositories {
            mavenCentral()
        }
    
        dependencies {
            classpath 'com.android.tools.build:gradle:0.12.+'
            classpath 'org.robolectric:robolectric-gradle-plugin:0.11.+'
            // The following adds the ability to use @DebugLog on methods
            classpath 'com.jakewharton.hugo:hugo-plugin:1.1.0'
        }
    }
    
    allprojects {
        repositories {
            mavenCentral()
        }
    }
    
    apply plugin: 'com.android.application'
    apply plugin: 'com.jakewharton.hugo'
    

    Got:

    Plugin with id 'com.jakewharton.hugo' not found

    Changed to

    apply plugin: 'hugo'
    

    and it worked perfectly! So either I'm missing a point here (being a complete groovy/gradle beginner, that's quite possible) or you need to update your README

    opened by fpoyer 6
  • AspectJ exception

    AspectJ exception

    I have noticed that Hugo stopped outputting anything in the logcat. At the same time, I got a bunch of aspectJ error logs in my app root folder. I think it has to do with the inner class you usually create when you need parcelables.

    Here is basically what the logs say:

    org.aspectj.weaver.BCException: Whilst processing type 'Lcom/wannacorp/api/model/VirtualZone$1;' - cannot cast the outer type to a reference type.  Signature=Lcom/wannacorp/api/model/VirtualZone; toString()=com.wannacorp.api.model.VirtualZone
    when processing type mungers 
    when weaving 
    when batch building BuildConfig[null] #Files=0 AopXmls=#0
    
        at org.aspectj.weaver.AbstractReferenceTypeDelegate.getFormalTypeParametersFromOuterClass(AbstractReferenceTypeDelegate.java:110)
        at org.aspectj.weaver.bcel.BcelObjectType.ensureGenericSignatureUnpacked(BcelObjectType.java:767)
        at org.aspectj.weaver.bcel.BcelObjectType.getSuperclass(BcelObjectType.java:231)
        at org.aspectj.weaver.ReferenceType.getSuperclass(ReferenceType.java:897)
        at org.aspectj.weaver.bcel.BcelWeaver.weaveParentsFor(BcelWeaver.java:1302)
        at org.aspectj.weaver.bcel.BcelWeaver.weave(BcelWeaver.java:1121)
        at org.aspectj.ajdt.internal.compiler.AjPipeliningCompilerAdapter.weaveQueuedEntries(AjPipeliningCompilerAdapter.java:514)
        at org.aspectj.ajdt.internal.compiler.AjPipeliningCompilerAdapter.afterCompiling(AjPipeliningCompilerAdapter.java:375)
        at org.aspectj.ajdt.internal.compiler.CompilerAdapter.ajc$afterReturning$org_aspectj_ajdt_internal_compiler_CompilerAdapter$2$f9cc9ca0(CompilerAdapter.aj:73)
        at org.aspectj.org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:550)
        at org.aspectj.ajdt.internal.core.builder.AjBuildManager.performCompilation(AjBuildManager.java:1031)
        at org.aspectj.ajdt.internal.core.builder.AjBuildManager.performBuild(AjBuildManager.java:272)
        at org.aspectj.ajdt.internal.core.builder.AjBuildManager.batchBuild(AjBuildManager.java:185)
        at org.aspectj.ajdt.ajc.AjdtCommand.doCommand(AjdtCommand.java:112)
        at org.aspectj.ajdt.ajc.AjdtCommand.runCommand(AjdtCommand.java:60)
        at org.aspectj.tools.ajc.Main.run(Main.java:371)
        at org.aspectj.tools.ajc.Main$run.call(Unknown Source)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:120)
        at hugo.weaving.plugin.HugoPlugin$_apply_closure2_closure3.doCall(HugoPlugin.groovy:55)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
        (... 20 lines more of stack trace) 
    

    And the source code of the class in question:

    /**
     * A special zone that contains all spots of a country/zone that are not attached to any subzone within
     * that entity
     *
     * Created by Vincent Mimoun-Prat @ MarvinLabs, 04/07/2014.
     */
    public class VirtualZone implements Zone, android.os.Parcelable {
    
        private Zone parentZone;
        private int spotCount;
    
        public VirtualZone() {
        }
    
        public VirtualZone(Zone parentZone, int spotCount) {
            assert (parentZone != null);
    
            this.parentZone = parentZone;
            this.spotCount = spotCount;
        }
    
        // =============================================================================================
        // Zone implementation
        // ==
    
        @Override
        public long getId() {
            return parentZone.getId();
        }
    
        @Override
        public int getSpotCount() {
            return spotCount;
        }
    
        @Override
        public Location getSouthWest() {
            return parentZone.getSouthWest();
        }
    
        @Override
        public Location getNorthEast() {
            return parentZone.getNorthEast();
        }
    
        @Override
        public String getName() {
            return parentZone.getName();
        }
    
        @Override
        public String getGeoPath() {
            return parentZone.getGeoPath();
        }
    
        @Override
        public List<Zone> getSubZones() {
            return Lists.newArrayListWithExpectedSize(0);
        }
    
        // =============================================================================================
        // Parcelable
        // ==
    
        @Override
        public int describeContents() {
            return 0;
        }
    
        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeParcelable(this.parentZone, 0);
            dest.writeInt(this.spotCount);
        }
    
        private VirtualZone(Parcel in) {
            this.parentZone = in.readParcelable(Zone.class.getClassLoader());
            this.spotCount = in.readInt();
        }
    
        public static final Creator<VirtualZone> CREATOR = new Creator<VirtualZone>() {
            public VirtualZone createFromParcel(Parcel source) {
                return new VirtualZone(source);
            }
    
            public VirtualZone[] newArray(int size) {
                return new VirtualZone[size];
            }
        };
    
        // =============================================================================================
        // Accessors
        // ==
    
        public Zone getParentZone() {
            return parentZone;
        }
    
    
        // =============================================================================================
        // Other methods
        // ==
    
        @Override
        public boolean equals(Object o) {
            if (o == this) {
                return true;
            }
    
            if (o instanceof VirtualZone) {
                VirtualZone other = (VirtualZone) o;
    
                if (!Objects.equal(parentZone, other.parentZone)) {
                    return false;
                }
    
                if (spotCount != other.spotCount) {
                    return false;
                }
    
                return true;
            }
    
            return false;
        }
    
        @Override
        public String toString() {
            return Objects.toStringHelper(this)
                    .add("parentZone", parentZone)
                    .add("spotCount", spotCount)
                    .toString();
        }
    }
    
    opened by vpratfr 6
  • Add support for Trace.beginSection/endSection

    Add support for Trace.beginSection/endSection

    Not sure if this is in the scope of Hugo, but have an annotation for wrapping methods in Trace.beginSection/endSection would be very helpful.

    Maybe a parameter to @DebugLog? @DebugLog(trace=true) Maybe a separate annotation ( @DebugTrace ) ?

    output would function like:

    class Bar{
      void foo(int snarg){
         if( SDK_INT >= 18 ){
                Trace.beginSection("Bar.foo(snarg="+ snarg+")")); 
          }
          try {
                 <method_body>
          } finally {
             if( SDK_INT >= 18 ){
                 Trace.endSection();
             }
          }
      }
    
    }
    
    opened by yogurtearl 5
  • Add a 'verbose' parameter to @DebugLog which en-/disables the logging

    Add a 'verbose' parameter to @DebugLog which en-/disables the logging

    I would like to be able to give @DebugLog a parameter which en-/disables the logging. I don't wan't to see all logs everytime. So eg. if I'm interested in the api logs I would adjust my verbose constant to see them and if I'm interested in other parts I can disable them (to don't be distracted).

    opened by tschob 5
  • Libraries' @DebugLog doesn't work

    Libraries' @DebugLog doesn't work

    My project has a number of modules apart from the actual app. Today I've tried to use Hugo on one of the 'android-library' modules, and nothing is logged when the app module runs.

    Project modules: app (has compile project(':mylibrary')) mylibrary (has apply plugin: 'hugo')

    Already tried to also apply plugin: 'hugo' on the app module, with no luck.

    opened by jonasfa 5
  •  please solve this type of issue

    please solve this type of issue

    when Open camera and show unfortunately Stop how to solve it i using this library on our app it work perfect but different device on different times show its type msg how can solve this type of issue

    opened by studysqure 0
  • Improve GRADLE build Performance

    Improve GRADLE build Performance

    Parallel builds. This project contains multiple modules. Parallel builds can improve the build speed by executing tasks in parallel. We can enable this feature by setting org.gradle.parallel=true.

    Configuration on demand. Configuration on demand tells Gradle to configure modules that only are relevant to the requested tasks instead of configuring all of them. We can enable this feature by setting org.gradle.configureondemand=true.

    gradle caching. Shared caches can reduce the number of tasks you need to execute by reusing outputs already generated elsewhere. This can significantly decrease build times. We can enable this feature by setting org.gradle.caching=true.

    Gradle daemon. The Daemon is a long-lived process that help to avoid the cost of JVM startup for every build. Since Gradle 3.0, Gradle daemon is enabled by default. For an older version, you should enable it by setting org.gradle.daemon=true.

    ===================== If there are any inappropriate modifications in this PR, please give me a reply and I will change them.

    opened by xiayingfeng 0
  • Not working with multi-module Kotlin Android project

    Not working with multi-module Kotlin Android project

    I have a multi-module Android project in Kotlin. When I am trying to use Hugo in that I am getting an error message during build saying that the advice was not applied. Below is the exact message I am getting, can anyone tell me why?

    Task :ui:compileDebugJavaWithJavac advice defined in hugo.weaving.internal.Hugo has not been applied [Xlint:adviceDidNotMatch]

    I have created a sample project to demonstrate this behavior, you can check it here. https://github.com/suvro/test-android-aop

    opened by suvro 0
Owner
Jake Wharton
Jake Wharton
Kotlin multi-platform logging library with structured logging and coroutines support

Klogging Klogging is a pure-Kotlin logging library that aims to be flexible and easy to use. It uses Kotlin idioms for creating loggers and sending lo

Klogging 51 Dec 20, 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
📄The reliable, generic, fast and flexible logging framework for Android

logback-android v2.0.0 Overview logback-android brings the power of logback to Android. This library provides a highly configurable logging framework

Tony Trinh 1.1k Jan 5, 2023
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 in-display logging library for Android 📲

Vlog provides an easy and convenient way to access logs right on your phone.

girish budhwani 121 Dec 26, 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
A demonstration of Kotlin-logging with logback.

try-kotlin-logging A demonstration of Kotlin-logging with logback. Usage # output a log to STDOUT and file(myApp.log) $ ./gradlew run # => 2021-12-11

Hayato Tachikawa 1 Dec 13, 2021
simple Kotlin logging: colorized logs for Kotlin on the JVM

sklog - simple Kotlin logging Kotlin (JVM) logging library for printing colorized text to the console, with an easy upgrade path to the popular kotlin

null 1 Jul 26, 2022
Jambo is an open source remote logging library

Jambo Jambo is an open source remote logging library. For those who would like to see their logs remotely on their android device Jambo is the library

Tabasumu 6 Aug 26, 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
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
This is an Kotlin Library that enables Annotation-triggered method call logging for Kotlin Multiplatform.

This is an Kotlin Library that enables Annotation-triggered method call logging for Kotlin Multiplatform.

Jens Klingenberg 187 Dec 18, 2022
This project consists in the approach of a bakery business, in which the user can book one or more products (cakes), in addition to having the method of payment in cash (post-shipment) or the method of payment via mobile

This project consists in the approach of a bakery business, in which the user can book one or more products (cakes), in addition to having the method of payment in cash (post-shipment) or the method of payment via mobile

Paul Guillen Acuña 2 Dec 20, 2022
🍼Debug Bottle is an Android runtime debug / develop tools written using kotlin language.

???? 中文 / ???? 日本語 / ???? English ?? Debug Bottle An Android debug / develop tools written using Kotlin language. All the features in Debug bottle are

Yuriel Arlencloyn 846 Nov 14, 2022
🍼Debug Bottle is an Android runtime debug / develop tools written using kotlin language.

???? 中文 / ???? 日本語 / ???? English ?? Debug Bottle An Android debug / develop tools written using Kotlin language. All the features in Debug bottle are

Yuriel Arlencloyn 846 Nov 14, 2022
Kotlin multi-platform logging library with structured logging and coroutines support

Klogging Klogging is a pure-Kotlin logging library that aims to be flexible and easy to use. It uses Kotlin idioms for creating loggers and sending lo

Klogging 51 Dec 20, 2022
A gRPC Kotlin based server and client starter that builds with Gradle and runs on the JVM

gRPC Kotlin starter Overview This directory contains a simple bar service written as a Kotlin gRPC example. You can find detailed instructions for bui

Hypto 8 Sep 19, 2022
A template project that builds a SDL application programmed in Zig to Android from scratch

A template project that builds a SDL application programmed in Zig to Android from scratch

Matheus Lessa 11 Jul 19, 2022
Gradle plugin to manage tests which should only run nightly and not every time a CI/CD pipeline builds.

NightlyTestsPlugin Gradle Plugin to configure which (j)Unit tests should only be run nightly and not everytime a CI/CD pipeline is triggered. Usage To

VISUS Health IT GmbH 0 Dec 7, 2021