How to enable ORMLite internal log on Android

When using ORM system sometimes we want to what SQLs are executed at background to understand how it works. The ORMLite support several different log system, like SLF4J,COMMONS_LOGGING, LOG4J and ANDROID native log android.util.Log. It will use Android log for internal log by default. In code com.j256.ormlite.android.AndroidLog method isLevelEnabledInternal, it will determinate if log is enabled by Log.isLoggable

private final static String ALL_LOGS_NAME = "ORMLite";
...
return Log.isLoggable(className, androidLevel) || Log.isLoggable(ALL_LOGS_NAME, androidLevel);

That means there are two ways to enable ORMLite internal log.

  1. You can change the default level by setting a system property: 'setprop log.tag. ' Where level is either VERBOSE, DEBUG, INFO, WARN, ERROR, ASSERT, or SUPPRESS. SUPPRESS will turn off all logging for your tag.
  2. You can also create a local.prop file that with the following in it: 'log.tag.=' and place that in /data/local.prop.

The YOUR_LOG_TAG could be any ORMLite short class name or "ORMLite" for all of them. So that you can enable ORMLite internal log like this:

$ adb shell
# setprop log.tag.ORMLite DEBUG

Notice that setprop is temporary until you reboot your device, even on rooted phones. You can persist properties through reboots if you write them into local.prop which is only possible on rooted phones.

How to debug with Android Logging

AP Logger Architecture

AP Logger Architecture

The above image shows the architecture of Android logging system.It provides a java class for logging named android.util.Log. It also provides log macros for native C applications in liblog.

There are four log devices in the kernel. Three for user space log: /dev/log/main, /dev/log/radio, /dev/log/events. One for kernel space log: /dev/log/kernel.

For user space applications, those binary log messages will be written to /dev/log/events. Those log messages with the tag "HTC_RIL" "RILJ" "RILC" "RILD" "RIL" "AT" "GSM" "STK" will be written to /dev/log/radio. Other log messages will be written to /dev/log/main.

The log devices named /dev/log/kernel is for kernel log message collection. A console is registered in /dev/log/kernel and collect all the printk output to the device. It will output kernel log messages with the same log format as other log devices.

Logcat is a tool provided by Android. It could read log messages from log devices and output to the console or to a file. You can find the detail usage later.

An aplog daemon is added for offline log. A filter is added to do some security checking.

Logging interface For Java applications

Logging class Introduction

Class Name: android.util.Log General method:

 Log.v() 
 Log.d() 
 Log.i() 
 Log.w()

The order in terms of verbosity, from least to most is ERROR, WARN, INFO, DEBUG, VERBOSE. VERBOSE should never be compiled into an application except during development. DEBUG logs are compiled in but stripped at runtime. ERROR, WARN and INFO logs are always kept.

TIP: A good convention is to declare a TAG constant in your class: private static final String TAG = "TAG_MyActivity"; and use that in subsequent calls to the log methods. Log.v(TAG, "index=" + i);

When you're building the string to pass into Log.d, Java uses a StringBuilder and at least three allocations occur: the StringBuilder itself, the buffer, and the String object. Realistically, there is also another buffer allocation and copy, and even more pressure on the GC. That means that if your log message is filtered out, you might be doing significant work and incurring significant overhead.

For more details, please visit Android log reference

Program Example

package com.android.hello;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import android.util.Log; /*import log class*/

private static final String TAG = "MyActivity"; /* define log tag*/

public class !HelloAndroid extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreaipte(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        TextView tv = new TextView(this);
        tv.setText("Hello, Android");
        setContentView(tv);

        Log.i(TAG, "this is a log.i message");
        Log.v(TAG, "test is a log.v message");
        Log.d(TAG, "test is a log.d message");
        Log.w(TAG, "test is a log.w message");
        Log.e(TAG, "test is a log.e message");
    }
}

Logging interface For Native applications

Header File include <cutils/log.h>

Logging Macros

Common Logging Macros

LOGV LOGD LOGI LOGW LOGE

Condition Logging Macros

LOGV_IF LOGD_IF LOGI_IF LOGW_IF LOGE_IF

The definition is as below:

#define CONDITION(cond) (__builtin_expect((cond)!=0,0))
#define LOGV_IF(cond, ...)   ( (CONDITION(cond)) ?((void)LOG(LOG_VERBOSE, LOG_TAG, VA_ARGS)) : (void)0 )

Logging Macros overview

API for sending log output.

NOTE:

  1. You should define LOG_TAG in your C source code firstly.
  2. To build out C/C++ applications outside android, you should add LOCAL_SHARED_LIBRARIES := liblog libcutils in your Android.mk file

Program Example

#include <stdio.h> 
#include <cutils/log.h> /* log header file*/
#include <cutils/properties.h>

/* define log tag */
#ifdef LOG_TAG
#undef LOG_TAG
#define LOG_TAG "app"
#endif
int main()
{
    LOGV("Verbose: _app");
    LOGD("Debug: _app");
    LOGI("Info: _app");
    LOGW("Warn: _app");
    LOGE("Error: _app");
    printf("Hello Android.\n");
    return 0;
}

Log command on Android

Command location

/system/bin/log

Command usage

log [-p priorityChar] [-t tag] message

priorityChar should be one of : v, d, i, w, e

Log format on Android

The format of a log messages is

tv_sec   tv_nsec     priority     pid    tid     tag     messageLen       Message
  • tag: log tag
  • tv_sec & tv_nsec: the timestamp of the log messages
  • pid: the process id of where log messages come from
  • tid: the thread id
  • Priority value is one of the following character values, ordered from lowest to highest priority:

    • V — Verbose (lowest priority)*
    • D — Debug*
    • I — Info*
    • W — Warning*
    • E — Error*
    • F — Fatal*
    • S — Silent (highest priority, on which nothing is ever printed)*