Android logging system provides a method for collecting logs from various applications into a series of circular buffers. The logcat
command is
used to view the logs. Log message is the simplest method of debugging a program, yet one of the most powerful ones. This recipe focuses on message logging in NDK.
The following steps create our sample Android project:
NDKLoggingDemo
. Set the package name as cookbook.chapter3
. Create an activity named NDKLoggingDemoActivity
. Please refer to the Loading native libraries and registering native methods recipe of Chapter 2, Java Native Interface, if you want more detailed instructions.NDKLoggingDemo
, select Android Tools | Add Native Support. A window appears, click on Finish to dismiss it.mylog.h
under the jni
folder, and add the following content to it:#ifndef COOKBOOK_LOG_H #define COOKBOOK_LOG_H #include <android/log.h> #define LOG_LEVEL 9 #define LOG_TAG "NDKLoggingDemo" #define LOGU(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_UNKNOWN, LOG_TAG, __VA_ARGS__);} #define LOGD(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_DEFAULT, LOG_TAG, __VA_ARGS__);} #define LOGV(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__);} #define LOGDE(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__);} #define LOGI(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__);} #define LOGW(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__);} #define LOGE(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__);} #define LOGF(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_FATAL, LOG_TAG, __VA_ARGS__);} #define LOGS(level, ...) if (level <= LOG_LEVEL) {__android_log_print(ANDROID_LOG_SILENT, LOG_TAG, __VA_ARGS__);} #endif
NDKLoggingDemo.cpp
:#include <jni.h> #include "mylog.h" void outputLogs() { LOGU(9, "unknown log message"); LOGD(8, "default log message"); LOGV(7, "verbose log message"); LOGDE(6, "debug log message"); LOGI(5, "information log message"); LOGW(4, "warning log message"); LOGE(3, "error log message"); LOGF(2, "fatal error log message"); LOGS(1, "silent log message"); } extern "C" { JNIEXPORT void JNICALL Java_cookbook_chapter3_NDKLoggingDemoActivity_LoggingDemo(JNIEnv* env, jobject o){ outputLogs(); } }
NDKLoggingDemoActivity.java
to the following:package cookbook.chapter3; import android.os.Bundle; import android.app.Activity; public class NDKLoggingDemoActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LoggingDemo(); } public native void LoggingDemo(); static { System.loadLibrary("NDKLoggingDemo"); } }
Android.mk
file to include the Android log library as follows:LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := NDKLoggingDemo LOCAL_SRC_FILES := NDKLoggingDemo.cpp LOCAL_LDLIBS := -llog include $(BUILD_SHARED_LIBRARY)
NDKLoggingDemo
project, and select Build Project.$ adb logcat -c $ adb logcat NDKLoggingDemo:I *:S -v time
The following is a screenshot of the logcat output:
$ adb logcat NDKLoggingDemo:V *:S -v time
This will result into the following output:
mylog.h
from #define LOG_LEVEL 9
to #define LOG_LEVEL 4
. Rebuild the application, then restart the application.This recipe shows how to use Android log messages. Each log message in Android consists of the following three parts:
#define LOG_LEVEL 4
Alternatively, we can selectively display the log output using logcat
.
Sending log messages on Android consumes CPU resources and frequent log messages can affect the application performance. In addition, the logs are stored in a circular buffer. Too many logs will overwrite some earlier logs, which may not be desirable. Due to these facts, it is recommended we only log errors and exceptions at the release build.
logcat
is the command-line tool to view Android logs. It allows one to filter logs according to the log tag and priority. It is also capable of
dispalying logs in different formats.
For example, we used the following logcat
command in step 8 of the preceding How to do it... section.
adb logcat NDKLoggingDemo:I *:S -v time
The command filters out logs except those with the
NDKLoggingDemo
tag and priority I
(information) or higher. The filter is given in a tag:priority
format. NDKLoggingDemo:I
indicates logs with a NDKLoggingDemo
tag and priority information or higher will be displayed. *:S
sets the priority level for all other tags as "silent".
More details about logcat filtering and format can be found at http://developer.android.com/tools/help/logcat.html and http://developer.android.com/tools/debugging/debugging-log.html#outputFormat.