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

##一、为什么要使用日志管理工具
###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**
```
<?xml version="1.0" encoding="utf-8"?>
<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);
}

}
```

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

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

Android之日志管理(Log)的更多相关文章

  1. android log4j日志管理的使用

    以下为log4j1的日志管理,在android 6.0 一下能正常使用,时候更加高级的胃log4j2,持续跟新 android中的log4j日志文件使用需要两个包,我们不需要进行配置文件的配置,一切都 ...

  2. 使用Android的日志工具Log

    Android中的日志工具类是Log,这个类中提供了5个方法来供我们打印日志 1.Log.v()用于打印那些最为琐碎的,意义最小的日志信息.对应级别verbose,是Android日志里面级别最低的一 ...

  3. Android打印日志管理

    做项目的时候,免不了要打印许多日志,等项目上线了,想要去除日志是又找不到在哪里怎么办?我们可以建立一个日志打印的类来统一管理: public class LogUtil { public static ...

  4. Android的日志工具Log

    Android中的日志工具类是Log(android.util.Log),这个类提供了以下几个方法来供我们打印日志. ♦ Log.v():这个方法用于打印那些最为琐碎的,意义最小的日志信息.对应级别v ...

  5. Android之崩溃日志管理

    文章大纲 一.Android崩溃日志管理简介二.崩溃日志管理实战三.项目源码下载   一.Android崩溃日志管理简介 1. 什么是android崩溃日志管理   开发中有些地方未注意可能造成异常抛 ...

  6. Android中日志工具的使用

    添加LogCat到你的Eclipse日志在任何项目的开发过程中都会起到非常重要的作用,在Android项目中如果你想要查看日志则必须要使用LogCat工具.当你第一次在Eclipse中运行Androi ...

  7. LogCook 一个简单实用的Android日志管理工具

    众所周知,日志的管理是软件系统很重要的一部分,千万不可忽略其重要性.完整的日志将会在系统维护中起着异常重要的作用,就好像磨刀不误砍柴工一样,日志就像对系统进行分析的工具,工具便捷了,对系统分析起来就能 ...

  8. Android开发日志统一管理

    在开发中,我们通常要对日志的输出做统一管理,下面就为大家推荐一个日志输出类,在开发阶段只需将DEBUG常量设为true,生产环境将DEBUG设为false即可控制日志的输出.啥都不说了,需要的朋友直接 ...

  9. 转 -Filebeat + Redis 管理 LOG日志实践

    Filebeat + Redis 管理 LOG日志实践 小赵营 关注 2019.01.06 17:52* 字数 1648 阅读 24评论 0喜欢 2 引用 转载 请注明出处 某早上,领导怒吼声远远传来 ...

随机推荐

  1. nginx与Apache的对比以及优缺点

    本文来自其他文章.如有好的问题,希望各位大神多多分享, 谢谢了..... 今天准备较详细的对比一下apache httpd与nginx两个web服务器的异同点.优缺点.由于我并不是做web开发的,所以 ...

  2. Linux Vim配置

    用过很多vim配置的版本,怎么说,想轻量级就不要胡加乱七八糟的功能:如果不在乎反应是不是快速,侧重功能是否强大,可以参考vim大神的配置策略(spf13-vim)https://github.com/ ...

  3. Scrapy 和 scrapy-redis的区别

    Scrapy 和 scrapy-redis的区别 Scrapy 是一个通用的爬虫框架,但是不支持分布式,Scrapy-redis是为了更方便地实现Scrapy分布式爬取,而提供了一些以redis为基础 ...

  4. javaweb项目部署到tomcat服务器

    http://jingyan.baidu.com/album/a501d80c0c65baec630f5ef6.html?picindex=8

  5. RabbitMQ 集群与网络分区(理论知识)

    关于network partition网络设备故障导致的网络分裂.比如,存在A\B\C\D\E五个节点,A\B处于同一子网,B\C\D处于另外一子网,中间通过交换机相连.若两个子网间的交换机故障了即发 ...

  6. Java RESTful 框架的性能比较

    来源:鸟窝, colobu.com/2015/11/17/Jax-RS-Performance-Comparison/ 如有好文章投稿,请点击 → 这里了解详情 在微服务流行的今天,我们会从纵向和横向 ...

  7. Go的context的问题

    Go的context的问题 2017-05-29 最近被由context引发的一个bug坑得不轻,所以反思一下Go的context的问题. context是隐式的约束,没有检测 如果我们写一个函数,比 ...

  8. codeForces 472D 最小生成树

    题目大意:给出一个图中点的两两距离,问是否是一棵树,若是,求出平均边权最大的点 prim最小生成树,若原图是树,则最小生成树的距离就是原距离.否则不是. 搞出来树了,第二问随便dfs就好了. #inc ...

  9. nginx + tomcat 反向代理

    简单的配置:# my test java+nginx project server { listen ; server_name localhost; root /home/user/Desktop/ ...

  10. GIL(全局解释器锁)

    GIL(全局解释器锁)     每个线程在执行的过程都需要先获取GIL     作用:在单核的情况下实现多任务(多线程),保证同一时刻只有一个线程可以执行代码,因此造成了我们使用多线程的时候无法实现并 ...