Logger日志系统实现流程研究

综述:日志系统的实现流程

1、应用层应用程序:调用应用程序框架层的java接口,实际是java类的静态函数,android.util.Log(如Log.i());----------应用程序

2、应用框架层java接口:Log的静态方法如(v()、i()、e()),调用本层对应的JNI方法:如:println_native   ------------java类Log jar包:system/framework/framework.jar

3、应用框架层JNI方法:调用运行库层的C接口:如__android_log_buf_write  -C库:libandroid_runtime.so

4、运行库层C接口:通过设备文件类访问内核空间的Logger驱动程序:如write\read   C库:liblog.so

5、驱动程序层:实现日志的操作    -C库:打包进内核

一、应用层android程序写日志

1、导入应用框架层接口类:import android.util.Log

2、调用类的静态函数Log.i(Info_Tag,"This a info log");
二、应用框架层android.util.Log

1、源文件、输出文件及编译方法

源文件:frameworks/base/core/java/android/util/Log.java

输出jar包:system/framework/framework.jar

编译方法:mmm framework/base

2、Log.java日志接口类文件概要说明

public final class Log {
//final class: 当一个类声明为final,决定该类不能被继承,应用框架层接口类一般这样定义
//final data : 用于基本数据类型定义时,其值不可变,相当于定义常量 
//public static 函数:静态函数,属于类,通过类来调用,接口函数一般这样定义 
   
    //定义了2~7一共6个日志优先级别ID,不同的级别调用不同的函数
    public static final int VERBOSE = 2;
    public static final int DEBUG = 3;
    public static final int INFO = 4;
    public static final int WARN = 5;
    public static final int ERROR = 6;
    public static final int ASSERT = 7;
   
    //V优先级的接口函数
    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));
    }
   
   //d优先级的接口函数
    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));
    }
   
   //i优先级的接口函数
    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));
    }
 
   //w优先级的接口函数
    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));
    }

    //e优先级的接口函数
    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));
    }

    //日志类型ID,有四个日志类型,对应3个日志缓冲区设备文件,此处接口函数全用main日志缓冲区
    /** @hide */ public static final int LOG_ID_MAIN = 0;//对应设备文件 dev/log/main
    /** @hide */ public static final int LOG_ID_RADIO = 1;//对应设备文件 dev/log/radio
    /** @hide */ public static final int LOG_ID_EVENTS = 2;//对应设备文件 dev/log/enents
    /** @hide */ public static final int LOG_ID_SYSTEM = 3;//对应设备文件 dev/log/main
    
    //声明了println_native本地方法,接口函数通过该方法写入日志
    /** @hide */ public static native int println_native(int bufID,int priority, String tag, String msg);
}

三、应用框架层JNI方法

1、源文件、输出文件及编译方法

源文件:frameworks/base/core/jni/android_util_Log.cpp

输出C库:system/lib/libandroid_runtime.so

编译方法:mmm frameworks/base/core/jni

2、jni方法分析

   实现方法:

//android_util_Log对应android.util.Log类,有jni声明
  static jint android_util_Log_println_native(...) 
  {...
     __android_log_buf_write(...);//调用运行库的方法
    ....
  } 
  定义方法表:

  static JNINativeMethod gMethods[] = {  
    ....
    { "println_native",  "(IILjava/lang/String;Ljava/lang/String;)I", (void*) android_util_Log_println_native },  
};  
注册方法表:

int register_android_util_Log(JNIEnv* env)  
{  
   ....     
    return AndroidRuntime::registerNativeMethods(env, "android/util/Log", gMethods, NELEM(gMethods));  
}  
说明:在gMethods变量中,定义了println_native本地方法对应的函数调用是android_util_Log_println_native。在android_util_Log_println_native函数中,调用运行时库函数__android_log_buf_write来实现Log的写入操作

四、运行库层liblog.so

1、源文件、输出库及编译方法

源文件目录:system/core/liblog/,其中的logd_write.c这个文件实现_android_log_buf_write方法

输出库文件:system/lib/liblog.so

编译方法:mmm  system/core/liblog

2、说明:运行库层函数通过标准的文件操作函数open read write和设备文件描述符fd通过操作系统调用日志驱动程序,从而实现日志的写入

五、Logger驱动程序


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值