[Unity]收集报错日志上传ftp服务器

    游戏一到测试阶段,就想获取游戏测试的报错日志,因为玩家基数大,一个开发团队不可能测试到方方面面,所以收集客户端报错日志就是必须的,有用过腾讯的bugly,官方文档写的云里雾里的,有Unity插件导入,还有安卓工程导入,都没说是两边都需要导入还是怎样,要靠猜,太累。接好后发现只能获取java层的报错,没系统学过,表示压力巨大。

    只好自己写一个来收集报错日志,利用Unity自身的Application.logMessageReceived方法来实现,代码很简单,就是拼接自己想要的报错日志上传。也加了个接口,可以通过lua热更实现关闭上传。

    public static void SetIsOpenCollcetLog(bool bIsCollcetLog)
    {
        LogCollection.bIsCollcetLog = bIsCollcetLog;
    }

    /// <summary>
    /// 初始化
    /// </summary>
    /// <param name="postUrl">上传url</param>
    /// <param name="bIsPostServer">是否上传</param>
    public static void Initialize(bool bIsShowStackTrace = true)
    {
        LogCollection.bIsCollcetLog = true;
        LogCollection.bIsShowStackTrace = bIsShowStackTrace;
        Application.logMessageReceived += HandleMessage;
        LogCollection.logFilePath = Application.persistentDataPath + "/log.txt";
    }

    private static void HandleMessage(string logString, string logStackTrace, LogType logType)
    {
        if (!LogCollection.bIsCollcetLog) return;
        if (string.IsNullOrEmpty(logString) && string.IsNullOrEmpty(logStackTrace)) return;
        if (lastLogString.Equals(logString) && lastLogStackTrace.Equals(logStackTrace) && lastLogType == logType) return;
        lastLogString = logString;
        lastLogStackTrace = logStackTrace;
        lastLogType = logType;

        switch (logType)
        {
            case LogType.Assert:
                tempLog = string.Format("Assert: {0}\nstack trace: {1}", logString, LogCollection.bIsShowStackTrace ? logStackTrace : string.Empty);
                break;
            case LogType.Error:
                tempLog = string.Format("Error: {0}\nstack trace: {1}", logString, LogCollection.bIsShowStackTrace ? logStackTrace : string.Empty);
                break;
            case LogType.Exception:
                tempLog = string.Format("deviceName: {0}\ndeviceModel: {1}\noperatingSystem:{2}\ngraphicsDeviceName: {3}\n", SystemInfo.deviceName, SystemInfo.deviceModel, SystemInfo.operatingSystem, SystemInfo.graphicsDeviceName);
                tempLog = string.Format("device: {0}\nException: {1}\nstack trace: {2}", tempLog, logString, LogCollection.bIsShowStackTrace ? logStackTrace : string.Empty);
                break;
            default:
                tempLog = string.Format("default: {0}\nstack trace: {1}", logString, LogCollection.bIsShowStackTrace ? logStackTrace : string.Empty);
                break;
        }

        if (!string.IsNullOrEmpty(tempLog))
        {
            PostToFtp(tempLog);
        }
    }

    ftp上传代码是之前写的,不是最新的,大致思想都在:

private static void PostToFtp(string message)
    {
        if (string.IsNullOrEmpty(message)) return;

        try
        {
            FileStream fileStream = new FileStream(logFilePath, FileMode.Create, FileAccess.Write);
            StreamWriter sw = new StreamWriter(fileStream);
            sw.WriteLine(tempLog);
            sw.Flush();
            sw.Close();


            // 上传到Ftp
            FtpUploadFile(logFilePath);
        }
        catch(Exception e)
        {
            
        }
    }


    private static List<string> directoryList;
    private static bool bIsGetDirectoryList = false;
    private static int requetTimeOut = 5000;

    /// <summary>
    /// ftp上传文件
    /// </summary>
    /// <param name="file"></param>
    private static void FtpUploadFile(string file)
    {
        if (string.IsNullOrEmpty(file)) return;

        System.DateTime nowTime = System.DateTime.Now;
        string curDay = nowTime.ToString("yyyyMMdd");
        FtpCheckDirectoryExist(curDay);

        FtpWebRequest req = null;
        FileInfo fileInfo = null;
        FileStream fileStream = null;
        Stream stream = null;
        try
        {
            fileInfo = new FileInfo(file);

            string curTime = (nowTime.ToString("HH_mm_ss_fff"));
            string destPath = string.Format("{0}{1}/{2}.txt", ftpUrl, curDay, curTime);
            req = (FtpWebRequest)WebRequest.Create(new Uri(destPath));
            req.UseBinary = true;
            req.Credentials = new NetworkCredential(ftpUserName, ftpPassword);
            req.KeepAlive = false;
            req.Method = WebRequestMethods.Ftp.UploadFile;
            req.Timeout = requetTimeOut;
            req.ContentLength = fileInfo.Length;

            int buffLength = 2048;
            byte[] buff = new byte[buffLength];
            int contentLen;
            fileStream = fileInfo.OpenRead();
            stream = req.GetRequestStream();
            contentLen = fileStream.Read(buff, 0, buffLength);
            while (contentLen != 0)
            {
                stream.Write(buff, 0, contentLen);
                contentLen = fileStream.Read(buff, 0, buffLength);
            }
        }
        catch(Exception e)
        {
            
        }
        finally
        {
            if(stream != null)
                stream.Close();
            if (fileStream != null)
                fileStream.Close();
            if (fileInfo != null)
                fileInfo.Delete();
            if (req != null)
                req.Abort();
        }
    }

    /// <summary>
    /// 检测ftp文件夹是否存在,不存在则创建
    /// </summary>
    /// <param name="destFilePath"></param>
    private static void FtpCheckDirectoryExist(string destFilePath)
    {
        if (string.IsNullOrEmpty(destFilePath)) return;
        FtpInitDirectoryList();

        bool bIsExit = false;
        for(int i = 0; i < directoryList.Count; ++i)
        {
            if (destFilePath.Equals(directoryList[i]))
            {
                bIsExit = true;
                break;
            }
        }

        if (bIsExit) return;

        FtpCreateDirectory(destFilePath);
    }

    /// <summary>
    /// 获取ftp服务器上文件夹列表
    /// </summary>
    private static void FtpInitDirectoryList()
    {
        if (bIsGetDirectoryList) return;
        bIsGetDirectoryList = true;

        if (null == directoryList)
            directoryList = new List<string>();
        else
            directoryList.Clear();

        FtpWebRequest req = null;
        WebResponse response = null;
        StreamReader reader = null;

        req = (FtpWebRequest)WebRequest.Create(ftpUrl);
        req.UseBinary = true;
        req.Credentials = new NetworkCredential(ftpUserName, ftpPassword);
        req.KeepAlive = false;
        req.Method = WebRequestMethods.Ftp.ListDirectory;
        req.Timeout = requetTimeOut;
        try
        {
            response = req.GetResponse();
            reader = new StreamReader(response.GetResponseStream(), Encoding.Default);

            string line = reader.ReadLine();
            while(line != null)
            {
                directoryList.Add(line);
                line = reader.ReadLine();
            }

            reader.Close();
            response.Close();
        }
        catch(Exception e)
        {
            
        }
        finally
        {
            if (reader != null)
                reader.Close();
            if (response != null)
                response.Close();
            if(req != null)
                req.Abort();
        }
    }

    /// <summary>
    /// ftp服务器上创建文件夹
    /// </summary>
    private static void FtpCreateDirectory(string destFilePath)
    {
        if (string.IsNullOrEmpty(destFilePath)) return;

        FtpWebRequest req = null;
        WebResponse response = null;

        req = (FtpWebRequest)WebRequest.Create(ftpUrl + destFilePath);
        req.Credentials = new NetworkCredential(ftpUserName, ftpPassword);
        req.KeepAlive = false;
        req.Method = WebRequestMethods.Ftp.MakeDirectory;
        req.Timeout = requetTimeOut;
        try
        {
            response = req.GetResponse();
            response.Close();

            if (null == directoryList)
                directoryList = new List<string>();
            directoryList.Add(destFilePath);
        }
        catch(Exception e)
        {
            
        }
        finally
        {
            if (response != null)
                response.Close();
            if (req != null)
                req.Abort();
        }
    }

    注意在Application.logMessageReceived方法中就不能使用Debug.Log等方法,这是Unity防止死循环做的处理。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值