Android应用中添加Log4j的示例

[2016-06-30]最新的log4j已经集成在DR_support_lib库中

具体请看: https://coding.net/u/wrcold520/p/DR_support_lib/git/tree/master

[2016-06-28] 1 增加log4j的支持
[2016-06-28] 2 增加全局异常处理(可自定义程序崩溃提示消息,自定义发送错误报告到服务器)
[2016-06-28] 3 增加两种应用退出方法:① appExit,结束掉所有Acitivity的生命周期,正常退出;② appKill,结束掉所有Acitivity的生命周期,杀掉程序进程后退出。
[2016-06-29] 4 增加透明状态栏和导航栏(默认开启,蓝色背景)

 

1、新建Android项目

Project: AndroidLog4j

Package:cn.darkranger.log

Activity:MainActivity

2、在libs中添加log4j-1.2.17.jar包

3、添加android-logging-log4j-1.0.3.jar

我看了一下,这里面只有两个类,我就用反编译工具反编译成了java文件,写入代码中了

LogCatAppender.java(主要作用是将log在控制台的输出转化为Android中的LogCat输出)

package cn.darkranger.log.log4j;

import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.Layout;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.spi.LoggingEvent;

import android.util.Log;

/**
 * 源自 android-logging-log4j-1.0.3.jar
 * 
 * @author Administrator
 */
public class LogCatAppender extends AppenderSkeleton {
    protected Layout tagLayout;

    public LogCatAppender(Layout messageLayout, Layout tagLayout) {
        this.tagLayout = tagLayout;
        setLayout(messageLayout);
    }

    public LogCatAppender(Layout messageLayout) {
        //这里定义的是Tag名称
        this(messageLayout, new PatternLayout("%c"));
    }

    public LogCatAppender() {
        this(new PatternLayout("%c"));
    }

    protected void append(LoggingEvent le) {
        switch (le.getLevel().toInt()) {
        case 5000:
            if (le.getThrowableInformation() != null) {
                Log.v(getTagLayout().format(le), getLayout().format(le), le.getThrowableInformation().getThrowable());
            } else {
                Log.v(getTagLayout().format(le), getLayout().format(le));
            }
            break;
        case 10000:
            if (le.getThrowableInformation() != null) {
                Log.d(getTagLayout().format(le), getLayout().format(le), le.getThrowableInformation().getThrowable());
            } else {
                Log.d(getTagLayout().format(le), getLayout().format(le));
            }
            break;
        case 20000:
            if (le.getThrowableInformation() != null) {
                Log.i(getTagLayout().format(le), getLayout().format(le), le.getThrowableInformation().getThrowable());
            } else {
                Log.i(getTagLayout().format(le), getLayout().format(le));
            }
            break;
        case 30000:
            if (le.getThrowableInformation() != null) {
                Log.w(getTagLayout().format(le), getLayout().format(le), le.getThrowableInformation().getThrowable());
            } else {
                Log.w(getTagLayout().format(le), getLayout().format(le));
            }
            break;
        case 40000:
            if (le.getThrowableInformation() != null) {
                Log.e(getTagLayout().format(le), getLayout().format(le), le.getThrowableInformation().getThrowable());
            } else {
                Log.e(getTagLayout().format(le), getLayout().format(le));
            }
            break;
        case 50000:
            if (le.getThrowableInformation() != null) {
                Log.wtf(getTagLayout().format(le), getLayout().format(le), le.getThrowableInformation().getThrowable());
            } else
                Log.wtf(getTagLayout().format(le), getLayout().format(le));
            break;
        }
    }

    public void close() {
    }

    public boolean requiresLayout() {
        return true;
    }

    public Layout getTagLayout() {
        return this.tagLayout;
    }

    public void setTagLayout(Layout tagLayout) {
        this.tagLayout = tagLayout;
    }
}

 

 LogConfig.java(主要作用是配置一些基本的信息)

package cn.darkranger.log.log4j;

import java.io.IOException;

import org.apache.log4j.Layout;
import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.RollingFileAppender;
import org.apache.log4j.helpers.LogLog;


/**
 * 源自 android-logging-log4j-1.0.3.jar
 * 
 * @author Administrator
 */
public class LogConfig {
    private Level rootLevel = Level.DEBUG;
    /**
     *    ### log文件的格式
     *  
     *    ### 输出格式解释:
     *    ### [%-d{yyyy-MM-dd HH:mm:ss}][Class: %c.%M(%F:%L)] %n[Level: %-5p] - Msg: %m%n
     *    
     *    ### %d{yyyy-MM-dd HH:mm:ss}: 时间,大括号内是时间格式
     *    ### %c: 全类名
     *    ### %M: 调用的方法名称
     *    ### %F:%L  类名:行号(在控制台可以追踪代码)
     *    ### %n: 换行
     *    ### %p: 日志级别,这里%-5p是指定的5个字符的日志名称,为的是格式整齐
     *    ### %m: 日志信息
        
     *    ### 输出的信息大概如下:
     *    ### [时间{时间格式}][信息所在的class.method(className:lineNumber)] 换行
     *    ### [Level: 5个字符的等级名称] - Msg: 输出信息 换行
     */
    private String filePattern = "[%-d{yyyy-MM-dd HH:mm:ss}][Class: %c.%M(%F:%L)] %n[Level: %-5p] - Msg: %m%n";
    
    /**
     *    ### LogCat控制台输出格式
     * 
     *    ### [Class: 信息所在的class.method(className:lineNumber)] 换行 
     *    ### [Level: 5个字符的等级名称] - Msg: 输出信息 换行
     */
    private String logCatPattern = "[Class: %c.%M(%F:%L)] %n[Level: %-5p] - Msg: %m%n";
    private String fileName = "android-log4j.log";
    private int maxBackupSize = 5;
    private long maxFileSize = 1024 * 1024 * 5L;
    private boolean immediateFlush = true;
    private boolean useLogCatAppender = true;
    private boolean useFileAppender = true;
    private boolean resetConfiguration = true;
    private boolean internalDebugging = false;

    public LogConfig() {
    }

    public LogConfig(String fileName) {
        setFileName(fileName);
    }

    public LogConfig(String fileName, Level rootLevel) {
        this(fileName);
        setRootLevel(rootLevel);
    }

    public LogConfig(String fileName, Level rootLevel, String filePattern) {
        this(fileName);
        setRootLevel(rootLevel);
        setFilePattern(filePattern);
    }

    public LogConfig(String fileName, int maxBackupSize, long maxFileSize, String filePattern, Level rootLevel) {
        this(fileName, rootLevel, filePattern);
        setMaxBackupSize(maxBackupSize);
        setMaxFileSize(maxFileSize);
    }

    public void configure() {
        Logger root = Logger.getRootLogger();

        if (isResetConfiguration()) {
            LogManager.getLoggerRepository().resetConfiguration();
        }

        LogLog.setInternalDebugging(isInternalDebugging());

        if (isUseFileAppender()) {
            configureFileAppender();
        }

        if (isUseLogCatAppender()) {
            configureLogCatAppender();
        }

        root.setLevel(getRootLevel());
    }

    public void setLevel(String loggerName, Level level) {
        Logger.getLogger(loggerName).setLevel(level);
    }

    private void configureFileAppender() {
        Logger root = Logger.getRootLogger();

        Layout fileLayout = new PatternLayout(getFilePattern());
        RollingFileAppender rollingFileAppender;
        try {
            rollingFileAppender = new RollingFileAppender(fileLayout, getFileName());
        } catch (IOException e) {
            throw new RuntimeException("Exception configuring log system", e);
        }

        rollingFileAppender.setMaxBackupIndex(getMaxBackupSize());
        rollingFileAppender.setMaximumFileSize(getMaxFileSize());
        rollingFileAppender.setImmediateFlush(isImmediateFlush());

        root.addAppender(rollingFileAppender);
    }

    private void configureLogCatAppender() {
        Logger root = Logger.getRootLogger();
        Layout logCatLayout = new PatternLayout(getLogCatPattern());
        LogCatAppender logCatAppender = new LogCatAppender(logCatLayout);

        root.addAppender(logCatAppender);
    }

    public Level getRootLevel() {
        return this.rootLevel;
    }

    public void setRootLevel(Level level) {
        this.rootLevel = level;
    }

    public String getFilePattern() {
        return this.filePattern;
    }

    public void setFilePattern(String filePattern) {
        this.filePattern = filePattern;
    }

    public String getLogCatPattern() {
        return this.logCatPattern;
    }

    public void setLogCatPattern(String logCatPattern) {
        this.logCatPattern = logCatPattern;
    }

    public String getFileName() {
        return this.fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public int getMaxBackupSize() {
        return this.maxBackupSize;
    }

    public void setMaxBackupSize(int maxBackupSize) {
        this.maxBackupSize = maxBackupSize;
    }

    public long getMaxFileSize() {
        return this.maxFileSize;
    }

    public void setMaxFileSize(long maxFileSize) {
        this.maxFileSize = maxFileSize;
    }

    public boolean isImmediateFlush() {
        return this.immediateFlush;
    }

    public void setImmediateFlush(boolean immediateFlush) {
        this.immediateFlush = immediateFlush;
    }

    public boolean isUseFileAppender() {
        return this.useFileAppender;
    }

    public void setUseFileAppender(boolean useFileAppender) {
        this.useFileAppender = useFileAppender;
    }

    public boolean isUseLogCatAppender() {
        return this.useLogCatAppender;
    }

    public void setUseLogCatAppender(boolean useLogCatAppender) {
        this.useLogCatAppender = useLogCatAppender;
    }

    public void setResetConfiguration(boolean resetConfiguration) {
        this.resetConfiguration = resetConfiguration;
    }

    public boolean isResetConfiguration() {
        return this.resetConfiguration;
    }

    public void setInternalDebugging(boolean internalDebugging) {
        this.internalDebugging = internalDebugging;
    }

    public boolean isInternalDebugging() {
        return this.internalDebugging;
    }
}

 

4、编写LogUtil.java工具类(主要作用是重新配置Log4j的一些参数,设置成为合适自己项目的log,在这里我们通过调用LogUtil.configLog()就可以了,简洁)

LogUtil.java

package cn.darkranger.log.log4j;

import java.io.File;
import java.util.Locale;

import org.apache.log4j.Level;

import android.os.Environment;

/**
 * LogUtil 工具类
 * 
 * @author Administrator
 *
 */
@SuppressWarnings("all")
public class LogUtil {
    
    /** 这里的AppName决定log的文件位置和名称 **/
    private static final String APP_NAME = "MyApp";

    /** 设置log文件全路径,这里是 MyApp/Log/myapp.log **/
    private static final String LOG_FILE_PATH = Environment.getExternalStorageDirectory() + File.separator + APP_NAME
            + File.separator + "Log" + File.separator + APP_NAME.toLowerCase(Locale.CHINA) + ".log";

    /**
     *    ### log文件的格式
     *  
     *    ### 输出格式解释:
     *    ### [%-d{yyyy-MM-dd HH:mm:ss}][Class: %c.%M(%F:%L)] %n[Level: %-5p] - Msg: %m%n
     *    
     *    ### %d{yyyy-MM-dd HH:mm:ss}: 时间,大括号内是时间格式
     *    ### %c: 全类名
     *    ### %M: 调用的方法名称
     *    ### %F:%L  类名:行号(在控制台可以追踪代码)
     *    ### %n: 换行
     *    ### %p: 日志级别,这里%-5p是指定的5个字符的日志名称,为的是格式整齐
     *    ### %m: 日志信息
        
     *    ### 输出的信息大概如下:
     *    ### [时间{时间格式}][信息所在的class.method(className:lineNumber)] 换行
     *    ### [Level: 5个字符的等级名称] - Msg: 输出信息 换行
     */
    private static final String LOG_FILE_PATTERN = "[%-d{yyyy-MM-dd HH:mm:ss}][Class: %c.%M(%F:%L)] %n[Level: %-5p] - Msg: %m%n";

    /** 生产环境下的log等级 **/
    private static final Level LOG_LEVEL_PRODUCE = Level.ALL;

    /** 发布以后的log等级 **/
    private static final Level LOG_LEVEL_RELEASE = Level.INFO;

    /**
     * 配置log4j参数
     */
    public static void configLog(){
        
        LogConfig logConfig = new LogConfig();

        /** 设置Log等级,生产环境下调用setLogToProduce(),发布后调用setLogToRelease() **/
        setLogToProduce(logConfig);
        
        logConfig.setFileName(LOG_FILE_PATH);

        logConfig.setLevel("org.apache", Level.ERROR);

        logConfig.setFilePattern(LOG_FILE_PATTERN);

        logConfig.setMaxFileSize(1024 * 1024 * 5);

        logConfig.setImmediateFlush(true);

        logConfig.configure();

    }

    /**
     * 将log设置为生产环境
     * 
     * @param logConfig
     */
    private static void setLogToProduce(LogConfig logConfig) {
        logConfig.setRootLevel(LOG_LEVEL_PRODUCE);
    }

    /**
     * 将log设置为发布以后的环境
     * 
     * @param logConfig
     */
    private static void setLogToRelease(LogConfig logConfig) {
        logConfig.setRootLevel(LOG_LEVEL_RELEASE);
    }
}

 

 5、编写MyApplication.java(继承Application,然后在onCreate()中调用LogUtil.configLog()方法来配置Log4j,这样程序一开始就相当于初始化了Log4j的配置)

package cn.darkranger.log.application;

import org.apache.log4j.Logger;

import android.app.Application;
import cn.darkranger.log.log4j.LogUtil;

public class MyApplication extends Application {
    
    @Override
    public void onCreate() {
        super.onCreate();
        
        //配置log4j基本参数
        LogUtil.configLog();

        //获取Application Log
        Logger log = Logger.getLogger(MyApplication.class);
        
        //输出MyApplication的信息
        log.info("Log4j Is Ready and My Application Was Created Successfully! ");
    }
    

}

6、修改AndroidManifest.xml(主要有两个地方,一是添加读取存储的权限,二是指定Application为我们刚刚写的MyApplication)

有下划线的地方就是我们添加的xml代码

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="cn.darkranger.log"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="11"
        android:targetSdkVersion="22" />

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <application
        android:name="cn.darkranger.log.application.MyApplication"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="cn.darkranger.log.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

 7、使用Log4j

  (1)创建Logger实例

    private static Logger log = Logger.getLogger(YourClassName.class);

  (2)在代码中用log记录信息

    log.info("onCreate()");
    log.fatal("this is fatal!");
    log.error("this is error!");
    log.warn("this is warn!");
    log.info("this is info!");
    log.debug("this is debug!");
    log.trace("this is trace!");

  (3)MainActivity.java中的示例(红色的部分就是log的记录)

package cn.darkranger.log;

import org.apache.log4j.Logger;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends AppCompatActivity {
    private static Logger log = Logger.getLogger(MainActivity.class);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        log.info("onCreate()");
        log.fatal("this is fatal!");
        log.error("this is error!");
        log.warn("this is warn!");
        log.info("this is info!");
        log.debug("this is debug!");
        log.trace("this is trace!");
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        log.info("onCreateOptionsMenu()");
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

 8、结果展示:


  控制台输出(自定义logcat输出格式:"[Class: %c.%M(%F:%L)] %n[Level: %-5p] - Msg: %m%n"):

 

  平板中的Log位置:计算机\Galaxy Tab A\Tablet\MyApp\Log\myapp.log(相对于计算机)

           设备存储\MyApp\Log\myapp.log(相对于平板)

[2016-06-16 17:14:54][Class: cn.darkranger.log.application.MyApplication.onCreate(MyApplication.java:21)] 
[Level: INFO ] - Msg: Log4j Is Ready and My Application Was Created Successfully! 
[2016-06-16 17:14:54][Class: cn.darkranger.log.MainActivity.onCreate(MainActivity.java:17)] 
[Level: INFO ] - Msg: onCreate()
[2016-06-16 17:14:54][Class: cn.darkranger.log.MainActivity.onCreate(MainActivity.java:18)] 
[Level: FATAL] - Msg: this is fatal!
[2016-06-16 17:14:54][Class: cn.darkranger.log.MainActivity.onCreate(MainActivity.java:19)] 
[Level: ERROR] - Msg: this is error!
[2016-06-16 17:14:54][Class: cn.darkranger.log.MainActivity.onCreate(MainActivity.java:20)] 
[Level: WARN ] - Msg: this is warn!
[2016-06-16 17:14:54][Class: cn.darkranger.log.MainActivity.onCreate(MainActivity.java:21)] 
[Level: INFO ] - Msg: this is info!
[2016-06-16 17:14:54][Class: cn.darkranger.log.MainActivity.onCreate(MainActivity.java:22)] 
[Level: DEBUG] - Msg: this is debug!
[2016-06-16 17:14:54][Class: cn.darkranger.log.MainActivity.onCreate(MainActivity.java:23)] 
[Level: TRACE] - Msg: this is trace!
[2016-06-16 17:14:54][Class: cn.darkranger.log.MainActivity.onCreateOptionsMenu(MainActivity.java:30)] 
[Level: INFO ] - Msg: onCreateOptionsMenu()

 

项目示例地址:

https://files.cnblogs.com/files/wrcold520/AndroidLog4j.zip

posted @ 2016-06-16 17:22  Ember24  阅读(4974)  评论(0编辑  收藏  举报