在unity开发中,有用的crash/log信息可以帮助我们更好的发现和解决游戏存在的bug。我们收集log的系统称之为日志上报系统。
目前做的比较好的工具是腾讯的Bugly
腾讯Bugly,为移动开发者提供专业的异常上报和运营统计,帮助开发者快速发现并解决异常,同时掌握产品运营动态,及时跟进用户反馈。
今天,我们用Unity原生的方法 Application.RegisterLogCallbackThreaded 来实现这样的系统
Application.RegisterLogCallbackThreaded
public static void RegisterLogCallbackThreaded(LogCallback handler);
游戏初始化时注册调用,LogCallback 是一个委托,用来处理日志信息
LogCallback
public delegate void LogCallback (string condition, string stackTrace, LogType type);
LogCallback 中有三个参数
- string condition
日志内容 - string stackTrace
日志堆栈 - LogType type
日志类型
我们只要把相关日志信息传给后台,在加上 玩家id,时间,服务器 等信息。就组成了简单的日志上报系统
Demo
function HandleLog (logString : String, stackTrace : String, type : LogType) {
#if UNITY_EDITOR
if (logString.Contains("Request error (error):") && stackTrace.Contains("UnityEditor.AsyncHTTPClient:Done") && type == LogType.Error)
{
return;
}
#endif
#if !UNITY_EDITOR && UNITY_ANDROID
var isException:boolean = true;
if(logString == "eglMakeCurrent(s_EGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT): EGL_BAD_DISPLAY: An EGLDisplay argument does not name a valid EGL display connection.")
{
//send to see if this is fixed by unity version upgrade.
isException = false;
}
else if(logString.Contains("[EGL]"))
{
//not send to reduce the amount of bugs,in case of ignorance of the real bugs.
isException = false;
return;
}
#else
var isException:boolean = true;
#endif
switch( type ){
case LogType.Error:
#if UNITY_EDITOR
if ( logString == "The profiler has run out of samples for this frame. This frame will be skipped." )
break;
#endif
if(logString.Contains("because it was not built with the right version or build target"))
{
isException = false;
}
UnityNet.reportErrorToServer( "CLIENT_ERROR", null, null, String.Format(LogFormatToSend, logString, stackTrace), isException);
break;
case LogType.Assert:
UnityNet.reportErrorToServer( "CLIENT_ASSERT", null, null, String.Format(LogFormatToSend, logString, stackTrace), isException);
break;
case LogType.Exception:
if( saveDataThread ){
saveDataThread.Join();
}
if( saveStrThread ){
saveStrThread.Join();
}
if(saveBuildingDataThread)
{
saveBuildingDataThread.Join();
}
if(saveTroopDataThread)
{
saveTroopDataThread.Join();
}
if(saveGearDataThread != null)
saveGearDataThread.Join();
if(saveGearSkillDataThread != null)
saveGearSkillDataThread.Join();
if(saveGearLevelUpDataThread != null)
saveGearLevelUpDataThread.Join();
if(saveGearSysUnlockDataThread != null)
saveGearSysUnlockDataThread.Join();
if(logString.StartsWith("IOException"))
{
stackTrace = stackTrace + NativeCaller.GetAllOpenFile();
}
UnityNet.reportErrorToServer( "CLIENT_EXCEPTION", null, null, String.Format(LogFormatToSend, logString, stackTrace), isException);
break;
}
}
ps:UnityNet.reportErrorToServer 是传给我们后台的上传方法,仅供参考,可自行实现
NOTE:
统计堆栈的时候移动端是统计不到行数的,只能统计到方法。而且不同平台统计到同一个log的log描述和log堆栈不一定一样
网友评论