欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android 实现自己的LOG信息

程序员文章站 2024-03-05 17:10:01
       在程序开发过程中,log是广泛使用的用来记录程序执行过程的机制,它既可以用于程序调试,也可以用于产...

       在程序开发过程中,log是广泛使用的用来记录程序执行过程的机制,它既可以用于程序调试,也可以用于产品运营中的事件记录。在android系统中,提供了简单、便利的log机制,开发人员可以方便地使用。在这一篇文章中,我们简单介绍在android内核空间和用户空间中log的使用和查看方法。

        一. 内核开发时log的使用。android内核是基于linux kerne 2.36的,因此,linux kernel的log机制同样适合于android内核,它就是有名的printk,与c语言的printf齐名。与printf类似,printk提供格式化输入功能,同时,它也具有所有log机制的特点--提供日志级别过虑功能。printk提供了8种日志级别(<linux/kernel.h>):

#define kern_emerg "<0>"  /* system is unusable   */ 
#define kern_alert "<1>"  /* action must be taken immediately */ 
#define kern_crit "<2>"  /* critical conditions   */ 
#deinfe kern_err "<3>"  /* error conditions   */ 
#deinfe kern_warning "<4>"  /* warning conditions   */ 
#deinfe kern_notice "<5>"  /* normal but significant condition */ 
#deinfe kern_info "<6>"  /* informational   */ 
#deinfe kern_debug "<7>"  /* debug-level messages   */ 

       printk的使用方法:

       printk(kern_alert"this is the log printed by printk in linux kernel space.");

       kern_alert表示日志级别,后面紧跟着要格式化字符串。

       在android系统中,printk输出的日志信息保存在/proc/kmsg中,要查看/proc/kmsg的内容,参照android内核源码 在ubuntu上下载,编译,安装一文,在后台中运行模拟器:

       user-name@machine-name:~/android$ emulator &

       启动adb shell工具:

       user-name@machine-name:~/android$ adb shell

       查看/proc/kmsg文件:

       root@android:/ # cat  /proc/kmsg

        二. 用户空间程序开发时log的使用。android系统在用户空间中提供了轻量级的logger日志系统,它是在内核中实现的一种设备驱动,与用户空间的logcat工具配合使用能够方便地跟踪调试程序。在android系统中,分别为c/c++ 和java语言提供两种不同的logger访问接口。c/c++日志接口一般是在编写硬件抽象层模块或者编写jni方法时使用,而java接口一般是在应用层编写app时使用。

       android系统中的c/c++日志接口是通过宏来使用的。在system/core/include/android/log.h定义了日志的级别:

/* 
 * android log priority values, in ascending priority order. 
 */ 
typedef enum android_logpriority { 
 android_log_unknown = 0, 
 android_log_default, /* only for setminpriority() */ 
 android_log_verbose, 
 android_log_debug, 
 android_log_info, 
 android_log_warn, 
 android_log_error, 
 android_log_fatal, 
 android_log_silent, /* only for setminpriority(); must be last */ 
} android_logpriority; 

在system/core/include/cutils/log.h中,定义了对应的宏,如对应于android_log_verbose的宏logv:

/* 
 * this is the local tag used for the following simplified 
 * logging macros. you can change this preprocessor definition 
 * before using the other macros to change the tag. 
 */ 
#ifndef log_tag 
#define log_tag null 
#endif 
 
/* 
 * simplified macro to send a verbose log message using the current log_tag. 
 */ 
#ifndef logv 
#if log_ndebug 
#define logv(...) ((void)0) 
#else 
#define logv(...) ((void)log(log_verbose, log_tag, __va_args__)) 
#endif 
#endif 
 
/* 
 * basic log message macro. 
 * 
 * example: 
 * log(log_warn, null, "failed with error %d", errno); 
 * 
 * the second argument may be null or "" to indicate the "global" tag. 
 */ 
#ifndef log 
#define log(priority, tag, ...) \ 
  log_pri(android_##priority, tag, __va_args__) 
#endif 
 
/* 
 * log macro that allows you to specify a number for priority. 
 */ 
#ifndef log_pri 
#define log_pri(priority, tag, ...) \ 
  android_printlog(priority, tag, __va_args__) 
#endif 
 
/* 
 * ================================================================ 
 * 
 * the stuff in the rest of this file should not be used directly. 
 */ 
#define android_printlog(prio, tag, fmt...) \ 
  __android_log_print(prio, tag, fmt) 

因此,如果要使用c/c++日志接口,只要定义自己的log_tag宏和包含头文件system/core/include/cutils/log.h就可以了:

         #define log_tag "my log tag"

         #include <cutils/log.h>

         就可以了,例如使用logv:

         logv("this is the log printed by logv in android user space.");

           再来看android系统中的java日志接口。android系统在frameworks层中定义了log接口:

        (frameworks/base/core/java/android/util/log.java):

................................................ 
 
public final class log { 
 
................................................ 
 
 /** 
  * priority constant for the println method; use log.v. 
   */ 
 public static final int verbose = 2; 
 
 /** 
  * priority constant for the println method; use log.d. 
   */ 
 public static final int debug = 3; 
 
 /** 
  * priority constant for the println method; use log.i. 
   */ 
 public static final int info = 4; 
 
 /** 
  * priority constant for the println method; use log.w. 
   */ 
 public static final int warn = 5; 
 
 /** 
  * priority constant for the println method; use log.e. 
   */ 
 public static final int error = 6; 
 
 /** 
  * priority constant for the println method. 
   */ 
 public static final int assert = 7; 
 
..................................................... 
 
 public static int v(string tag, string msg) { 
  return println_native(log_id_main, verbose, tag, msg); 
 } 
 
 public static int v(string tag, string msg, throwable tr) { 
  return println_native(log_id_main, verbose, tag, msg + '\n' + getstacktracestring(tr)); 
 } 
 
 public static int d(string tag, string msg) { 
  return println_native(log_id_main, debug, tag, msg); 
 } 
 
 public static int d(string tag, string msg, throwable tr) { 
  return println_native(log_id_main, debug, tag, msg + '\n' + getstacktracestring(tr)); 
 } 
 
 public static int i(string tag, string msg) { 
  return println_native(log_id_main, info, tag, msg); 
 } 
 
 public static int i(string tag, string msg, throwable tr) { 
  return println_native(log_id_main, info, tag, msg + '\n' + getstacktracestring(tr)); 
 } 
 
 public static int w(string tag, string msg) { 
  return println_native(log_id_main, warn, tag, msg); 
 } 
 
 public static int w(string tag, string msg, throwable tr) { 
  return println_native(log_id_main, warn, tag, msg + '\n' + getstacktracestring(tr)); 
 } 
 
 public static int w(string tag, throwable tr) { 
  return println_native(log_id_main, warn, tag, getstacktracestring(tr)); 
 } 
  
 public static int e(string tag, string msg) { 
  return println_native(log_id_main, error, tag, msg); 
 } 
 
 public static int e(string tag, string msg, throwable tr) { 
  return println_native(log_id_main, error, tag, msg + '\n' + getstacktracestring(tr)); 
 } 
 
.................................................................. 

       因此,如果要使用java日志接口,只要在类中定义的log_tag常量和引用android.util.log就可以了:

        private static final string log_tag = "my_log_tag";

        log.i(log_tag, "this is the log printed by log.i in android user space.");

        要查看这些log的输出,可以配合logcat工具。如果是在eclipse环境下运行模拟器,并且安装了android插件,那么,很简单,直接在eclipse就可以查看了:

 Android 实现自己的LOG信息

  如果是在自己编译的android源代码工程中使用,则在后台中运行模拟器:

       user-name@machine-name:~/android$ emulator &

       启动adb shell工具:

       user-name@machine-name:~/android$ adb shell

       使用logcat命令查看日志:

       root@android:/ # logcat

       这样就可以看到输出的日志了。

 以上就是android 自己的log信息实现方法,有需要的朋友看下。