首先回顾下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 HashMap<String, String> mAllParams;
/**
* 上传所需要pid
*/
private int mPid;
/**
* 构造方法
*
* @param strUrl 上传所需要的url
* @param allParams 需要上传的额外的参数【除了日志以外】
* @param pid 日志所在的pid
*/
public LogUploader(String strUrl, HashMap<String, String> 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<String, String>
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);
}
}
这篇博客介绍了HarmonyOS的HiLog日志系统与Android的日志系统的等级定义,并展示了如何对HiLog进行封装,包括文件输出和上传功能。作者还探讨了HarmonyOS中日志路径的差异,并分享了自定义LogUtil类的代码实现,用于日志记录和管理。
1958

被折叠的 条评论
为什么被折叠?



