Android之日志管理(Log)(原创)

Stella981
• 阅读 612

##文章大纲
一、为什么要使用日志管理工具
二、日志管理工具实战
三、项目源码下载

Android之日志管理(Log)(原创)

##一、为什么要使用日志管理工具
###1. 对IT安全至关重要
  当您使用强大的日志管理软件自动触发以保护您的系统时,您已经赢得了一半的战斗,以确保您的IT基础设施安全。某些日志管理工具具有阻止可疑IP地址,删除帐户,甚至完全关闭显示受感染迹象的计算机的内置功能。
  此外,有效的日志管理工具可以实现并简化您的入侵检测系统。因此,当您的入侵检测系统发出恶意活动信号时,您可以快速检查由日志管理工具生成和维护的日志文件。日志文件可以进一步提供重要线索,便于故障排除以帮助您。

###2. 帮助企业更有效地运营
  使用日志管理工具的直接好处之一是它可以最大限度地减少生产中的停机时间。日志管理工具是解决方案带中的主要力量,可以使您智能地掌握与生产相关的可能问题。它允许您知道什么时候重要的事情已经改变或改变。反过来,这会对您的技术平稳运行以及整个业务流程产生重大影响。
  此外,有效的日志管理对于满足合规性也很重要。某些合规性要求您监控和记录每个应用程序以及IT基础架构中的系统的事件。

###3. 找到问题的根源
  使用复杂的日志管理工具维护日志文件允许进行根本原因分析,稍后便于调试。你可以避免艰苦的手工努力,试图弄清楚什么是轨道,以及究竟是什么导致了一个可能的问题。这进一步使您在处理所有类型的问题时越来越有效。
  您可以浏览日志文件,甚至可以使用该工具发现任何违规行为。这有助于使系统恢复正常工作。日志管理工具可帮助您更深入地识别现代组织遇到的威胁。

##二、日志管理工具实战
  在此次项目实战过程中,我们重点关注于两个点,第一个是团队开发过程中的问题定位,比如日志打印包含类名、接口编写人、错误信息等内容,方便问题快速定位,第二个是项目上线后的优化,我们可以将手机机型、版本号、项目版本、错误信息等以文件存在手机中,定期将数据传送到服务器。
###1. 获取手机相关信息
  该模块信息在团队协作开发中无需体现出来,在项目上线后,错误日志的上传才需要用到,用于问题快速定位,相关源码如下所示:
```
package com.example.administrator.mylogger;

import android.content.Context;
import android.os.Build;

/**
* 手机相关信息获取
*/
public class PhoneMessage {

//获取设备的屏幕宽度
public static int getDeviceWidth(Context context) {
return context.getResources().getDisplayMetrics().widthPixels;
}

//获取设备的屏幕高度
public static int getDeviceHeight(Context context) {
return context.getResources().getDisplayMetrics().heightPixels;
}

//获取厂商名
public static String getDeviceManufacturer() {

return Build.MANUFACTURER;
}

//获取手机品牌
public static String getDeviceBrand() {

return Build.BRAND;
}

//获取手机型号
public static String getDeviceModel() {
return android.os.Build.MODEL;
}

//获取手机Android系统SDK
public static int getDeviceSDK() {
return android.os.Build.VERSION.SDK_INT;
}

//获取手机Android版本
public static String getDeviceAndroidVersion() {
return android.os.Build.VERSION.RELEASE;
}

public static String getPhoneMessage(Context context)
{

String phoneMessage = "屏幕宽度:" + getDeviceWidth(context) + "\n" + "屏幕高度:" + getDeviceHeight(context) + "\n" + "手机厂商名:" + getDeviceManufacturer()

+ "\n" + "手机品牌:" + getDeviceBrand() + "\n" + "手机型号:" + getDeviceModel() + "\n" + "Android系统SDK:" + getDeviceSDK()

+ "\n" + "手机Android版本:" + getDeviceAndroidVersion() ;

return phoneMessage;

}
}

```

###2. 获取app相关信息
  该模块获取的信息包括app名称、版本号、包名、类名、开发人等信息,在团队开发过程中,只需要体现包名、类型和开发人信息即可,而在错误日志上传到服务器时,则需全部上传,具体获取app信息代码如下:
```
package com.example.administrator.mylogger;

import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;

/**
* 获取app相关信息
*/
public class AppUtils {

/**
* 获取应用程序名称
*/
private static synchronized String getAppName(Context context) {
try {
PackageManager packageManager = context.getPackageManager();
PackageInfo packageInfo = packageManager.getPackageInfo(
context.getPackageName(), 0);
int labelRes = packageInfo.applicationInfo.labelRes;
return context.getResources().getString(labelRes);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}

/**
* [获取应用程序版本名称信息]
* @param context
* @return 当前应用的版本名称
*/
private static synchronized String getVersionName(Context context) {
try {
PackageManager packageManager = context.getPackageManager();
PackageInfo packageInfo = packageManager.getPackageInfo(
context.getPackageName(), 0);
return packageInfo.versionName;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}

/**
* [获取应用程序版本号]
* @param context
* @return 当前应用的版本号
*/
private static synchronized int getVersionCode(Context context) {
try {
PackageManager packageManager = context.getPackageManager();
PackageInfo packageInfo = packageManager.getPackageInfo(
context.getPackageName(), 0);
return packageInfo.versionCode;
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}

//获取当前的activity的完整路径
public static String getRunningActivityName(Context context){
ActivityManager activityManager=(ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
String runningActivity=activityManager.getRunningTasks(1).get(0).topActivity.getClassName();
return runningActivity;
}

//用于错误日志存进手机中使用
public static String getAppMessage(Context context)
{
String message = "\n App名称:"+getAppName(context) + "\n 版本名称:"+getVersionName(context) + "\n 版本号:" + getVersionCode(context) + "\n 类名:" + getRunningActivityName(context);

return message;
}
}

```

###3. 开发人员信息管理封装类
```
package com.example.administrator.mylogger;

/**
* 管理开发人员的姓名,用于日志打印 方便问题定位
*/
public class NameManager {

public static String wxc = "吴晓畅";
}

```

###4. 日志输出封装类
```
package com.example.administrator.mylogger;

import android.app.ActivityManager;
import android.content.Context;
import android.util.Log;
import java.util.Date;
import java.text.SimpleDateFormat;

/**
* 关于操作中的日志信息输出
*
* @author 吴晓畅
*
*/
public final class Logger {

private static final boolean isinput = true;// 用于判断是否输出日志 可以控制整个应用的输出 调试模式 true 上线模式 false

//Android的Log等级通常有五类,按照日志级别由低到高分别是Verbose、Debug、Info、Warning、Error 等级逐步增大
private final static int logLevel = Log.VERBOSE; //日志级别,大于或者等于logLevel才会被打印

/**
* 输出故障的日志信息
*
* @param context
* 系统名称模块名称接口名称
* @param msg
* 详细描述
*
* @param userName
* 接口编写人
*/
public static void d(Context context, String msg, String userName) {

if (isinput) {

if(logLevel <= Log.DEBUG)
{

Log.d(AppUtils.getRunningActivityName(context), "\n 接口编写人:" + userName + "\n 日志信息:" + msg);
}

}

}

/**
* 输出错误的日志信息
*
* @param context
* 系统名称模块名称接口名称
* @param msg
* 详细描述
* @param userName
* 接口编写人
*/
public static void e(Context context, String msg, String userName) {

if (isinput) {

if(logLevel <= Log.ERROR)
{

Log.e(AppUtils.getRunningActivityName(context), "\n 接口编写人:" + userName + "\n 日志信息:" + msg);

}

}
}

/**
* 输出程序的日志信息
*
* @param context
* 系统名称模块名称接口名称
* @param msg
* 详细描述
* @param userName
* 接口编写人
*/
public static void i(Context context, String msg, String userName) {

if (isinput) {

if(logLevel <= Log.INFO)
{

Log.i(AppUtils.getRunningActivityName(context), "\n 接口编写人:" + userName + "\n 日志信息:" + msg);

}

}

}

/**
* 输出冗余的日志信息
*
* @param context
* 系统名称模块名称接口名称
* @param msg
* 详细描述
* @param userName
* 接口编写人
*/
public static void v(Context context, String msg, String userName) {
if (isinput) {

if(logLevel <= Log.VERBOSE)
{

Log.v(AppUtils.getRunningActivityName(context), "\n 接口编写人:" + userName + "\n 日志信息:" + msg);

}
}
}

/**
* 输出警告的日志信息
*
* @param context
* 系统名称模块名称接口名称
* @param msg
* 详细描述
* @param userName
* 接口编写人
*/
public static void w(Context context, String msg, String userName) {

//获取手机相关信息
String phoneMessage = PhoneMessage.getPhoneMessage(context);

SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式

//获取错误日志信息
String errorMessage = "\n 接口信息:" + AppUtils.getAppMessage(context) + "\n" + "接口编写人:" + userName + "\n" + "错误信息为:" + msg + "\n" +
"错误时间:" + df.format(new Date());

//将手机信息、错误信息缓存进手机

//

if (isinput) {

if(logLevel <= Log.WARN)
{

Log.w(AppUtils.getRunningActivityName(context), "\n 接口编写人:" + userName + "\n 日志信息:" + msg);
}

}
}

}
```
温馨提示:
(1) isinput变量用于判断是否输出日志 可以控制整个应用的输出 调试模式 true 上线模式 false
(2)Android的Log等级通常有五类,按照日志级别由低到高分别是Verbose、Debug、Info、Warning、Error, 等级逐步增大,在该项目中,我们用logLevel变量控制日志输出,当日志级别大于或者等于logLevel才会被打印

###5. 测试工具使用
**新建activity_main.xml**
```

<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>
```

**MainActivity代码**
```
package com.example.administrator.mylogger;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

import java.text.SimpleDateFormat;
import java.util.Date;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

TextView textView = findViewById(R.id.textView);

SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式

textView.setText(PhoneMessage.getPhoneMessage(MainActivity.this) + "\n 接口信息:" + AppUtils.getAppMessage(MainActivity.this) + "\n" + "接口编写人:" + NameManager.wxc + "\n" + "错误信息为:" + "测试错误" + "\n" +
"错误时间:" + df.format(new Date()));

Logger.e(MainActivity.this, "测试错误", NameManager.wxc);
}

}
```

**运行结果如下所示**

Android之日志管理(Log)(原创)

Android之日志管理(Log)(原创)

##三、项目源码下载
链接:https://pan.baidu.com/s/1OMwtwbjMV9BI-tfCceTErQ
提取码:ybhu

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这