package roboguice.util.temp;
import java.text.SimpleDateFormat;
import android.app.Application;
import android.content.pm.ApplicationInfo;
import android.util.Log;
/**
* A more natural android logging facility. WARNING: CHECK OUT COMMON PITFALLS
* BELOW Unlike {@link android.util.Log}, Log provides sensible defaults. Debug
* and Verbose logging is enabled for applications that have
* "android:debuggable=true" in their AndroidManifest.xml. For apps built using
* SDK Tools r8 or later, this means any debug build. Release builds built with
* r8 or later will have verbose and debug log messages turned off. The default
* tag is automatically set to your app's packagename, and the current context
* (eg. activity, service, application, etc) is appended as well. You can add an
* additional parameter to the tag using {@link #Log(String)}. Log-levels can be
* programatically overridden for specific instances using
* {@link #Log(String, boolean, boolean)}. Log messages may optionally use
* {@link String#format(String, Object...)} formatting, which will not be
* evaluated unless the log statement is output. Additional parameters to the
* logging statement are treated as varrgs parameters to
* {@link String#format(String, Object...)} Also, the current file and line is
* automatically appended to the tag (this is only done if debug is enabled for
* performance reasons). COMMON PITFALLS: * Make sure you put the exception
* FIRST in the call. A common mistake is to place it last as is the
* android.util.Log convention, but then it will get treated as varargs
* parameter. * vararg parameters are not appended to the log message! You must
* insert them into the log message using %s or another similar format parameter
* Usage Examples: Ln.v("hello there"); Ln.d("%s %s", "hello", "there"); Ln.e(
* exception, "Error during some operation"); Ln.w( exception,
* "Error during %s operation", "some other");
*/
public final class Ln {
/**
* config is initially set to BaseConfig() with sensible defaults, then
* replaced by BaseConfig(ContextSingleton) during guice static injection
* pass.
*/
private static final BaseConfig CONFIG = new BaseConfig();
/**
* print is initially set to Print(), then replaced by guice during static
* injection pass. This allows overriding where the log message is delivered
* to.
*/
private static Print print = new Print();
private Ln() {
}
public static int v(Throwable t) {
return CONFIG.minimumLogLevel <= Log.VERBOSE ? print.println(Log.VERBOSE, Log.getStackTraceString(t)) : 0;
}
public static int v(Object s1, Object... args) {
if (CONFIG.minimumLogLevel > Log.VERBOSE) {
return 0;
}
final String s = Strings.toString(s1);
final String message = args.length > 0 ? String.format(s, args) : s;
return print.println(Log.VERBOSE, message);
}
public static int v(Throwable throwable, Object s1, Object... args) {
if (CONFIG.minimumLogLevel > Log.VERBOSE) {
return 0;
}
final String s = Strings.toString(s1);
final String message = (args.length > 0 ? String.format(s, args) : s) + '\n' + Log.getStackTraceString(throwable);
return print.println(Log.VERBOSE, message);
}
public static int d(Throwable t) {
return CONFIG.minimumLogLevel <= Log.DEBUG ? print.println(Log.DEBUG, Log.getStackTraceString(t)) : 0;
}
public static int d(Object s1, Object... args) {
if (CONFIG.minimumLogLevel > Log.DEBUG) {
return 0;
}
final String s = Strings.toString(s1);
final String message = args.length > 0 ? String.format(s, args) : s;
return print.println(Log.DEBUG, message);
}
public static int d(Throwable throwable, Object s1, Object... args) {
if (CONFIG.minimumLogLevel > Log.DEBUG) {
return 0;
}
final String s = Strings.toString(s1);
final String message = (args.length > 0 ? String.format(s, args) : s) + '\n' + Log.getStackTraceString(throwable);
return print.println(Log.DEBUG, message);
}
public static int i(Throwable t) {
return CONFIG.minimumLogLevel <= Log.INFO ? print.println(Log.INFO, Log.getStackTraceString(t)) : 0;
}
public static int i(Object s1, Object... args) {
if (CONFIG.minimumLogLevel > Log.INFO) {
return 0;
}
final String s = Strings.toString(s1);
final String message = args.length > 0 ? String.format(s, args) : s;
return print.println(Log.INFO, message);
}
public static int i(Throwable throwable, Object s1, Object... args) {
if (CONFIG.minimumLogLevel > Log.INFO) {
return 0;
}
final String s = Strings.toString(s1);
final String message = (args.length > 0 ? String.format(s, args) : s) + '\n' + Log.getStackTraceString(throwable);
return print.println(Log.INFO, message);
}
public static int w(Throwable t) {
return CONFIG.minimumLogLevel <= Log.WARN ? print.println(Log.WARN, Log.getStackTraceString(t)) : 0;
}
public static int w(Object s1, Object... args) {
if (CONFIG.minimumLogLevel > Log.WARN) {
return 0;
}
final String s = Strings.toString(s1);
final String message = args.length > 0 ? String.format(s, args) : s;
return print.println(Log.WARN, message);
}
public static int w(Throwable throwable, Object s1, Object... args) {
if (CONFIG.minimumLogLevel > Log.WARN) {
return 0;
}
final String s = Strings.toString(s1);
final String message = (args.length > 0 ? String.format(s, args) : s) + '\n' + Log.getStackTraceString(throwable);
return print.println(Log.WARN, message);
}
public static int e(Throwable t) {
return CONFIG.minimumLogLevel <= Log.ERROR ? print.println(Log.ERROR, Log.getStackTraceString(t)) : 0;
}
public static int e(Object s1, Object... args) {
if (CONFIG.minimumLogLevel > Log.ERROR) {
return 0;
}
final String s = Strings.toString(s1);
final String message = args.length > 0 ? String.format(s, args) : s;
return print.println(Log.ERROR, message);
}
public static int e(Throwable throwable, Object s1, Object... args) {
if (CONFIG.minimumLogLevel > Log.ERROR) {
return 0;
}
final String s = Strings.toString(s1);
final String message = (args.length > 0 ? String.format(s, args) : s) + '\n' + Log.getStackTraceString(throwable);
return print.println(Log.ERROR, message);
}
public static boolean isDebugEnabled() {
return CONFIG.minimumLogLevel <= Log.DEBUG;
}
public static boolean isVerboseEnabled() {
return CONFIG.minimumLogLevel <= Log.VERBOSE;
}
public static Config getConfig() {
return CONFIG;
}
public interface Config {
int getLoggingLevel();
void setLoggingLevel(int level);
}
public static class BaseConfig implements Config {
protected int minimumLogLevel = Log.VERBOSE;
protected String packageName = "";
protected String scope = "";
protected BaseConfig() {
}
public BaseConfig(Application context) {
try {
packageName = context.getPackageName();
final int flags = context.getPackageManager().getApplicationInfo(packageName, 0).flags;
minimumLogLevel = (flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0 ? Log.VERBOSE : Log.INFO;
scope = packageName.toUpperCase();
Ln.d("Configuring Logging, minimum log level is %s", logLevelToString(minimumLogLevel));
} catch (Exception e) {
Log.e(packageName, "Error configuring logger", e);
}
}
@Override
public int getLoggingLevel() {
return minimumLogLevel;
}
@Override
public void setLoggingLevel(int level) {
minimumLogLevel = level;
}
}
public static String logLevelToString(int loglevel) {
switch (loglevel) {
case Log.VERBOSE:
return "VERBOSE";
case Log.DEBUG:
return "DEBUG";
case Log.INFO:
return "INFO";
case Log.WARN:
return "WARN";
case Log.ERROR:
return "ERROR";
case Log.ASSERT:
return "ASSERT";
default:
return "UNKNOWN";
}
}
public static void setPrint(Print print) {
Ln.print = print;
}
/** Default implementation logs to android.util.Log */
public static class Print {
private static final int DEFAULT_STACK_TRACE_LINE_COUNT = 5;
public int println(int priority, String msg) {
return Log.println(priority, getScope(), processMessage(msg));
}
protected String processMessage(String msg) {
if (CONFIG.minimumLogLevel <= Log.DEBUG) {
msg = String.format("%s %s %s", new SimpleDateFormat("HH:mm:ss.SSS").format(System.currentTimeMillis()), Thread.currentThread().getName(), msg);
}
return msg;
}
protected static String getScope() {
if (CONFIG.minimumLogLevel <= Log.DEBUG) {
final StackTraceElement trace = Thread.currentThread().getStackTrace()[DEFAULT_STACK_TRACE_LINE_COUNT];
return CONFIG.scope + "/" + trace.getFileName() + ":" + trace.getLineNumber();
}
return CONFIG.scope;
}
}
}