最近做项目的时候发现,需要有一个完整的log机制。这样不仅方便调试而且方便观察。

一、需求

  目前我认为一个完善的log机制应该是这样的。

  一、双击定位

  二、生命周期是全局的

  三、输出包括consloe 和 log 日志,并且这些log的打印是可配置的。

  四、未完待续,如果你有更好的想法,请留言。

二、代码实现

  不废话,直接上代码

  

using UnityEngine;
using System;
using System.Text;
using System.IO;
using System.Collections; namespace LogUtil { public class LogManager : MonoBehaviour
{
//public
static string LogPath = Application.persistentDataPath + "/"; //public
static string LogFilePath = string.Format("{0}{1}", LogPath, "info");
//public
static int infoCount = 0; //public
static string LogWaringFilePath = string.Format("{0}{1}", LogPath, "waring");
//public
static int waringCount = 0; //public
static string LogErrorFilePath = string.Format("{0}{1}", LogPath, "error");
//public
static int errorCount = 0; //public
static string LogExceptionFilePath = string.Format("{0}{1}", LogPath, "exception");
//public
static int exceptionCount = 0; static LogManager _instance = null; //创建第一个实例或引用任何静态成员之前,将自动调用静态构造函数
static LogManager()
{
GameObject tmp = new GameObject("LogManager");
DontDestroyOnLoad(tmp);
_instance = tmp.AddComponent<LogManager>();
//Debug.Log("LogManager");
} //配置是否生成Log日志
public static bool IsRegister = true;
//配置是否控制台打印
public static bool IsLog = true;
void Awake()
{
//register callback
if (IsRegister) Application.RegisterLogCallbackThreaded(OutPutLog);
} public static void Log(object message)
{
if (IsLog) Debug.Log(message);
} public static void LogError(object message)
{
if (IsLog) Debug.LogError(message);
} public static void LogWarning(object message)
{
if (IsLog) Debug.LogWarning(message);
} public static void LogException(Exception message)
{
if (IsLog) Debug.LogException(message);
} public static void LogException(string message)
{
if (IsLog) Debug.LogException(new Exception(message));
} FileStream logStream = new FileStream(string.Format("{0}.log", LogFilePath), FileMode.Create);
FileStream warningStream = new FileStream(string.Format("{0}.log", LogWaringFilePath), FileMode.Create);
FileStream errorStream = new FileStream(string.Format("{0}.log", LogErrorFilePath), FileMode.Create);
FileStream exceptionStream = new FileStream(string.Format("{0}.log", LogExceptionFilePath), FileMode.Create); public void OutPutLog(string condition, string stackTrace, LogType type)
{ string curTime = DateTime.Now.ToString();
string hint = string.Format("{0} [{1}] {2}\n{3}\n", curTime, type.ToString(), condition, stackTrace);
byte[] buffer = Encoding.UTF8.GetBytes(hint); switch (type)
{
case LogType.Error: if (errorStream != null)
{
errorStream.Write(buffer, 0, buffer.Length); if (errorStream.Length > 1024 * 1024)
{
errorStream.Close(); File.Move(string.Format("{0}.log", LogErrorFilePath), string.Format("{0}_{1}.log", LogErrorFilePath, waringCount++)); errorStream = new FileStream(string.Format("{0}.log", LogErrorFilePath), FileMode.Create);
}
} break;
case LogType.Exception: if (exceptionStream != null)
{
exceptionStream.Write(buffer, 0, buffer.Length); if (exceptionStream.Length > 1024 * 1024)
{
exceptionStream.Close(); File.Move(string.Format("{0}.log", LogExceptionFilePath), string.Format("{0}_{1}.log", LogExceptionFilePath, waringCount++)); exceptionStream = new FileStream(string.Format("{0}.log", LogExceptionFilePath), FileMode.Create);
}
} break;
case LogType.Log: if (logStream != null)
{
logStream.Write(buffer, 0, buffer.Length); if (logStream.Length > 1024 * 1024)
{
logStream.Close(); File.Move(string.Format("{0}.log", LogFilePath), string.Format("{0}_{1}.log", LogFilePath, infoCount++)); logStream = new FileStream(string.Format("{0}.log", LogFilePath), FileMode.Create);
}
}
break;
case LogType.Warning: if (warningStream != null)
{
warningStream.Write(buffer, 0, buffer.Length); if (warningStream.Length > 1024 * 1024)
{
warningStream.Close(); File.Move(string.Format("{0}.log", LogWaringFilePath), string.Format("{0}_{1}.log", LogWaringFilePath, waringCount++)); warningStream = new FileStream(string.Format("{0}.log", LogWaringFilePath), FileMode.Create);
}
} break;
default:
break;
}
} } }

三、完善

  上述的代码基本实现了2,3的需求功能,但是1的双击定位问题却带来了。

  我们可以封装成一个dll,然后就解决了这个问题。

  参考链接如下 注意引用UnityEngine这个链接即可

   http://www.cnblogs.com/errorx/archive/2011/03/29/1999170.html

http://game.ceeger.com/Manual/UsingDLL.html
     file:///C:/Unity3D/Editor/Data/Documentation/html/en/Manual/UsingDLL.html

  

  我把那个类库建在自己的工程目录下,按F6 生成dll

  

放入自己的工程就可以了。原来的cs文件记得删除哟!

 

四、资料

  我把dll与源码共享出来,如果有更好的修改方式,你也可以完善。

  http://yunpan.cn/Q7dukcFjA3tAv  访问密码 ed22

2014-9-7 日 更新

  如果你在导入和使用dll编译的时候发现了错误

  

  

  估计是因为你.net框架过高,把你的类库的level 降到3.5即可

  

Unity3D Log 收集机制的更多相关文章

  1. 探索 OpenStack 之(17):计量模块 Ceilometer 中的数据收集机制

    本文将阐述 Ceilometer 中的数据收集机制.Ceilometer 使用三种机制来收集数据: Notifications:Ceilometer 接收 OpenStack 其它服务发出的 noti ...

  2. LOG收集系统(一):原日志至收集

    Date: 20140207Auth: Jin 设置一个LOG收集系统1. 收集原生(不解析,不压缩)的业务日志和WEB日志(NGINX,PHP)2. 提供给开发,测试直接阅读和下载 需求分析原生日志 ...

  3. RTP 记录 log 该机制

    我们 RCV 在这里,经常跑concurrent request RTP: Receiving Transaction Processor, 它主要是用来处理 RCV_TRANSACTIONS_INT ...

  4. android log写入机制

    这几天和华为的leader面试了下.感觉不错.关键是小女.不容易.是技术面啊.我说的不容易不是面试不容易,是说在华为写代码的小女不容易.哥走南闯北这么多年,女人代码写的好真不多. 其实在任何时候,只要 ...

  5. Cocos2d-x之Log输出机制

    |   版权声明:本文为博主原创文章,未经博主允许不得转载. 在cocos2d-x中,我们使用log这个函数进行输出,log可以输出很多参数,它的使用方式就和使用c语言中的printf的使用方式差不多 ...

  6. JAVA分代收集机制详解

    Java堆中是JVM管理的最大一块内存空间.主要存放对象实例. 在JAVA中堆被分为两块区域:新生代(young).老年代(old). 堆大小=新生代+老年代:(新生代占堆空间的1/3.老年代占堆空间 ...

  7. Kafka内核理解:消息的收集/消费机制

    原文:https://www.cnblogs.com/daochong/p/6425762.html 一.Kafka数据收集机制 Kafka集群中由producer负责数据的产生,并发送到对应的Top ...

  8. [Kafka] - Kafka内核理解:消息的收集/消费机制

    一.Kafka数据收集机制 Kafka集群中由producer负责数据的产生,并发送到对应的Topic:Producer通过push的方式将数据发送到对应Topic的分区 Producer发送到Top ...

  9. kubernets轻量 contain log 日志收集技巧

    首先这里要收集的日志是容器的日志,而不是集群状态的日志 要完成的三个点,收集,监控,报警,收集是基础,监控和报警可以基于收集的日志来作,这篇主要实现收集 不想看字的可以直接看代码,一共没几行,尽量用调 ...

随机推荐

  1. 去掉影响效率的where 1=1

    最近看了篇文章,觉得挺有道理.实际项目中,我们进行sql条件过滤,我们不能确定是不是有条件.也不能确定条件的个数.大多数人会先把sql语句组装为: 这样,如果有其他过滤条件直接加上“and 其他条件” ...

  2. C++ 11 之初始化

    1.4中不同初始化的形式     a.string s("zhl").int i(3);    //括号初始化     b.string s="zhl".int ...

  3. java.util.TreeMap源码分析

    TreeMap的实现基于红黑树,排列的顺序根据key的大小,或者在创建时提供的比较器,取决于使用哪个构造器. 对于,containsKey,get,put,remove操作,保证时间复杂度为log(n ...

  4. 不用Unity库,利用.NET动态代理自己实现AOP

    AOP意为面向切面的程序设计,主要表现为对不同的代码逻辑进行隔离,从而降低不同业务逻辑之间的耦合性,AOP又理解为“横切”,可以在不改变原有实现的情况下,对代码进行拦截和扩展,如果原有设计像一个瓶子, ...

  5. 观察者模式(Observer)

    观察者模式是经常使用到的一种设计模式,在我们的生活中也经常遇到,小到学校上学让同学帮忙看着老师有没有过来,在教室里做一些与学习无关的事情,大到股市里面我们遇到的,到股票涨到或者跌到一定程度的时候通知我 ...

  6. xml_editor

    概要 该工程是用来操作xml, 目的是为了在程序中操作xml中各类节点更加简单, 下面按照 工程简介, 库内部实现, 库接口使用, xml工具使用, xpath简介 几个部分来介绍该c++库. 工程简 ...

  7. 在 linux x86-32 模式下分析内存映射流程

    前言 虚拟内存机制已经成为了现代操作系统所不可缺少的一部分, 不仅可以为每个程序提供独立的地址空间保证安全性,更可以通过和磁盘的内存交换来提高内存的使用效率.虚拟内存管理作为linux 上的重要组成部 ...

  8. Spring MVC的启动过程

    一.概述 下面一个基本的运用springMVC的的web.xml的配置,这里要注意两个地方,一个是ContextLoadListener,一个是DispatcherServlet.web容器正是通过这 ...

  9. PHP学习之数组的定义和填充

    数组就是把一组数据按顺序放在一起.PHP的数组和其它的语言数组有一点点不同:第一,保存的数据是可以是任何类型的:第二,数组的索引可以是数字,也可以是字符串. PHP的数组,说白了,就是关联数据每一条数 ...

  10. Delphi 两个应用程序(进程)之间的通信

    两个应用程序之间的通信实际上是两个进程之间的通信.由于本人知识有限,决定应用消息来实现.需要用到的知识: 1.RegisterWindowMessage(); //参数类型:pchar:返回值:Lon ...