首先回顾下android
android.util 种Log包:v i e w println getStackTraceString以及定义等级方式: public static final int ASSERT = 7; public static final int DEBUG = 3; public static final int ERROR = 6; public static final int INFO = 4; public static final int VERBOSE = 2; public static final int WARN = 5;
再封装时候需要处理整个app 输出log的等级判定,包括shell日志输出,上传功能
HiLog 是harmonyos 的主要log 输出类,定义等级如下: public static final int DEBUG = 3; public static final int ERROR = 6; public static final int FATAL = 7; public static final int INFO = 4; public static final int LOG_APP = 0; public static final int WARN = 5;
LOG_APP是目前sdk api实现唯一一个接口,后续会进行扩展。
另外,本人再devEco studio ide种寻找Hilog的file expore 文件管理器,目前未找到,不知道为何要去除该内容,本人思考可能由于harmonyos最终的文件形式module形式安装hab或者apk格式,存在多个文件日志流问题,涉及安全。
所以本人尝试了,Hilog一些类似android 封装,发现基本都可以用,代码类放着末尾,只是简单进行封装。
对比下2个端文件路径差别,有些路径是本人加入,可以看前段实践:
- LogUtil.d(TAG, "getCacheDir=" + context.getCacheDir().getPath());
- LogUtil.d(TAG, "getCodeCacheDir=" + context.getCodeCacheDir().getPath());
- LogUtil.d(TAG, "getDatabaseDir=" + context.getDatabaseDir().getPath());
- LogUtil.d(TAG, "getDataDir=" + context.getDataDir().getPath());
- LogUtil.d(TAG, "getExternalCacheDir=" + context.getExternalCacheDir().getPath());
- LogUtil.d(TAG, "getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)=" +
- context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).getPath());
- LogUtil.d(TAG, "getDistributedDir=" + getDistributedDir().getPath());
- LogUtil.d(TAG, "getFilesDir=" + getFilesDir().getPath());
- LogUtil.d(TAG, "getNoBackupFilesDir=" + getNoBackupFilesDir().getPath());
- LogUtil.d(TAG, "getPreferencesDir=" + getPreferencesDir().getPath());
- 07-20 16:17:29.676 27894-27894/? I System.out: ThreadAbilitySlice getCacheDir=/data/user/0/com.xmf.harmonydemo/cache
- 07-20 16:17:29.676 27894-27894/? I System.out: ThreadAbilitySlice getCodeCacheDir=/data/user/0/com.xmf.harmonydemo/code_cache
- 07-20 16:17:29.677 27894-27894/? I System.out: ThreadAbilitySlice getDatabaseDir=/data/data/com.xmf.harmonydemo/ThreadAbility/databases
- 07-20 16:17:29.677 27894-27894/? I System.out: ThreadAbilitySlice getDataDir=/data/user/0/com.xmf.harmonydemo
- 07-20 16:17:29.683 27894-27894/? I System.out: ThreadAbilitySlice getExternalCacheDir=/storage/emulated/0/Android/data/com.xmf.harmonydemo/cache
- 07-20 16:17:29.685 27894-27894/? I System.out: ThreadAbilitySlice getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)=/storage/emulated/0/Android/data/com.xmf.harmonydemo/files/Download
- 07-20 16:17:29.690 27894-27894/? I System.out: ThreadAbilitySlice getDistributedDir=/mnt/mdfs/699956351188076798/merge_view/data/com.xmf.harmonydemo/ThreadAbility
- 07-20 16:17:29.690 27894-27894/? I System.out: ThreadAbilitySlice getFilesDir=/data/user/0/com.xmf.harmonydemo/files
- 07-20 16:17:29.690 27894-27894/? I System.out: ThreadAbilitySlice getNoBackupFilesDir=/data/user/0/com.xmf.harmonydemo/no_backup
- 07-20 16:17:29.690 27894-27894/? I System.out: ThreadAbilitySlice getPreferencesDir=/data/data/com.xmf.harmonydemo/ThreadAbility/preferences
整体生成代码如下:
package com.example.harmonyfragment.tools; import com.example.harmonyfragment.BuildConfig; import ohos.hiviewdfx.HiLog; import ohos.hiviewdfx.HiLogLabel; import java.io.*; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Locale; /** * 用于harmonyos 日志的处理,支持:写入文件,上传记录文件 */ public class LogUtil { /** * 文件路径 */ private String mFilePath; /** * 线程运行标志 */ private boolean isRunning = true; /** * 调用这个类的线程 */ private int mPid; //可以通过TAG 或 DOMAIN 筛选 private static final int DOMAIN = 0x00001; public static final String TAG = "RUIJIE_TAG"; private static final HiLogLabel LABEL = new HiLogLabel(getLogLeve(), DOMAIN, TAG); //判断是否为线上包 public static int logLeve = HiLog.LOG_APP; /** * 写日志对象 */ private LogWriter logWriter; /** * 写入本地日志线程,只包含 */ private class LogWriter extends Thread { /** * 文件路径 */ private String mFilePath; /** * 调用这个类的线程 */ private int mPid; /** * 线程运行标志 */ private boolean isRunning = true; public String saveFlag ; /** * @param filePath 文件路径 * @param pid */ public LogWriter(String filePath, int pid, String packageName) { this.mPid = pid; this.saveFlag = packageName; this.mFilePath = filePath; } @Override public void run() { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.CHINA);//日期格式化对象 Process process = null;//进程 BufferedReader reader = null; FileWriter writer = null; try { //执行命令行 String cmd = "logcat *:e *:w | grep"; process = Runtime.getRuntime().exec(cmd); //得到输入流 reader = new BufferedReader(new InputStreamReader(process.getInputStream()), 1024); //创建文件 File file = new File(mFilePath); if (!file.exists()) { file.getParentFile().mkdirs(); file.createNewFile(); } writer = new FileWriter(file, true); //循环写入文件 String line = null; while (isRunning) { line = reader.readLine(); if (line != null && line.length() > 0 ) { writer.append(String.format("PID:%s %s%s%s%s",this.mPid,"\t",sdf.format(new Date(System.currentTimeMillis())),"\t",line)); writer.flush(); } else { break; } } } catch (Exception e) { e.printStackTrace(); } finally { if (process != null) { process.destroy(); } if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } if (writer != null) { try { writer.flush(); writer.close(); } catch (IOException e) { e.printStackTrace(); } } process = null; reader = null; writer = null; } } public void end() { isRunning = false; } } /** * 整个应用只需要调用一次即可:开始本地记录 * * @param filePath 要写入的目的文件路径 * @param iswrite 是否需要写入sdk */ public void startWriteLogToSdcard(String filePath,boolean iswrite,String packageName) { if (iswrite) { if (logWriter == null) { try { /** LogUtil这个类的pid,必须在类外面得到 */ logWriter = new LogWriter(filePath, ohos.os.ProcessManager.getPid(),packageName); } catch (Exception e) { e.printStackTrace(); } } logWriter.run(); } } /** * 日志上传线程 */ private class LogUploader extends Thread { /** * 当前线程是否正在运行 */ private boolean isRunning = true; /** * 上传所需要的url */ private String mStrUrl; /** * 上传所需要的其他参数 */ private HashMapmAllParams; /** * 上传所需要pid */ private int mPid; /** * 构造方法 * * @param strUrl 上传所需要的url * @param allParams 需要上传的额外的参数【除了日志以外】 * @param pid 日志所在的pid */ public LogUploader(String strUrl, HashMap allParams, int pid) { this.mStrUrl = strUrl; this.mAllParams = allParams; this.mPid = pid; } @Override public void run() { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.CHINA);//日期格式化对象 Process process = null;//进程 BufferedReader reader = null; try { //执行命令行,得到输入流 String cmd = "logcat *:e *:w | grep"; process = Runtime.getRuntime().exec(cmd); reader = new BufferedReader(new InputStreamReader(process.getInputStream()), 1024); String line = null; while (isRunning) { line = reader.readLine(); if (line != null && line.length() > 0) { String log = String.format("PID:%s %s%s%s%s",this.mPid,"\t",sdf.format(new Date(System.currentTimeMillis())),"\t",line); mAllParams.put("log", log); } else { break; } } } catch (Exception e) { e.printStackTrace(); } finally { if (process != null) { process.destroy(); } if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } process = null; reader = null; } } public void end() { isRunning = false; } } /* ========================下面的是需要上传的数据========================== */ private LogUploader logUploader; /** * 整个应用调用一次即可:上传日志数据 * * @param strUrl 上传所需要的url * @param allParams 需要上传的额外的参数【除了日志以外】 * @param isUploadLog 是否需要上传 */ public void startUploadLog(String strUrl, HashMap allParams,boolean isUploadLog) { if (isUploadLog) { if (logUploader == null) { logUploader = new LogUploader(strUrl, allParams, ohos.os.ProcessManager.getPid()); } logUploader.start(); } } /** * 整个应用调用一次即可:结束上传日志数据 */ public void endUploadLog() { if (logUploader != null) { logUploader.end(); } } /** * 整个应用只需要调用一次即可:结束本地记录 */ public void endWriteLogToSdcard() { if (logWriter != null) { logWriter.end(); } } public static void setLogLeve(int logLeve) { LogUtil.logLeve = logLeve; } public static int getLogLeve() { if(BuildConfig.DEBUG){ return HiLog.LOG_APP; } return logLeve; } public static void error(String msg) { HiLog.error(LABEL, String.format("%s",msg)); } public static void debug(String msg) { HiLog.debug(LABEL, String.format("%s",msg)); } public static void warn(String msg) { HiLog.warn(LABEL, String.format("%s",msg)); } public static void info(String msg) { HiLog.info(LABEL, String.format("%s",msg)); } public static void fatal(String msg) { HiLog.fatal(LABEL, String.format("%s",msg)); } public static void info(String tag,String format,Object... objects){ HiLogLabel logLabel = new HiLogLabel(getLogLeve(),DOMAIN,tag); HiLog.info(logLabel,format,objects); } public static void debug(String tag,String format,Object... objects){ HiLogLabel logLabel = new HiLogLabel(getLogLeve(),DOMAIN,tag); HiLog.debug(logLabel,format,objects); } public static void error(String tag, String format, Object... objects){ HiLogLabel logLabel = new HiLogLabel(getLogLeve(),DOMAIN,tag); HiLog.error(logLabel,format,objects); } public static void warn(String tag,String format,Object... objects){ HiLogLabel logLabel = new HiLogLabel(getLogLeve(),DOMAIN,tag); HiLog.warn(logLabel,format,objects); } public static void fatal(String tag,String format,Object... objects){ HiLogLabel logLabel = new HiLogLabel(getLogLeve(),DOMAIN,tag); HiLog.fatal(logLabel,format,objects); } }