Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to export android Unity error and debug logs to file?

I am attempting to develop an app for the Samsung Gear VR (with the Samsung Galaxy S8) and as it requires me to pull out the USB cable in order to plug the phone onto the Gear VR device, this does not allow me to do USB debugging.

How do I go about exporting error and debug messages into a file I can read in order to figure out what's going wrong?

So far, research has shown that android Unity player does not save to a log file while the other platforms do, and adb is the way to go for USB debugging... Only I can't do that for Gear.

like image 775
Alternate Video Production Avatar asked Dec 23 '22 14:12

Alternate Video Production


1 Answers

How to export android Unity error and debug logs to file?

That doesn't exist yet. You have to make one yourself.

1.Subscribe to Unity Log event:

Application.logMessageReceived += LogCallback;

2.Store them in a List. When application is about to exit, serialize to json and save it with File.WriteAllBytes.

The path to save it to is Application.persistentDataPath. See this post that shows where the path can be found on any build in Unity.

Below is an example script that reads logs and saves it when app is about to exit. Also, it has the ability to email you the log data. This requires the DataSaver class from this post. Note that the email is sent next time the app is re-opened not when it exit.

using System.Collections.Generic;
using UnityEngine;

using System.IO;
using System.Net;
using System.Net.Mail;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System;
using System.Text;

public class LogSaverAndSender : MonoBehaviour
{
    public bool enableSave = true;
    public bool enableMailing = true;

    public string yourEmail = "[email protected]";
    public string yourEmailPassword = "password";
    public string toEmail = "[email protected]";


    [Serializable]
    public struct Logs
    {
        public string condition;
        public string stackTrace;
        public LogType type;

        public string dateTime;

        public Logs(string condition, string stackTrace, LogType type, string dateTime)
        {
            this.condition = condition;
            this.stackTrace = stackTrace;
            this.type = type;
            this.dateTime = dateTime;
        }
    }

    [Serializable]
    public class LogInfo
    {
        public List<Logs> logInfoList = new List<Logs>();
    }

    LogInfo logs = new LogInfo();

    void OnEnable()
    {
        //Email last saved log
        if (enableMailing)
        {
            mailLog();
        }

        //Subscribe to Log Event
        Application.logMessageReceived += LogCallback;
    }

    //Called when there is an exception
    void LogCallback(string condition, string stackTrace, LogType type)
    {
        //Create new Log
        Logs logInfo = new Logs(condition, stackTrace, type, DateTime.Now.ToString("yyyy-MM-ddTHH:mm:sszzz"));

        //Add it to the List
        logs.logInfoList.Add(logInfo);
    }

    void mailLog()
    {
        //Read old/last saved log
        LogInfo loadedData = DataSaver.loadData<LogInfo>("savelog");
        string date = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:sszzz");

        //Send only if there is something to actually send
        if (loadedData != null && loadedData.logInfoList != null

            && loadedData.logInfoList.Count > 0)
        {

            Debug.Log("Found log to send!");

            //Convert to json
            string messageToSend = JsonUtility.ToJson(loadedData, true);

            string attachmentPath = Path.Combine(Application.persistentDataPath, "data");
            attachmentPath = Path.Combine(attachmentPath, "savelog.txt");

            //Finally send email
            sendMail(yourEmail, yourEmailPassword, toEmail, "Log: " + date, messageToSend, attachmentPath);

            //Clear old log
            DataSaver.deleteData("savelog");
        }
    }

    void sendMail(string fromEmail, string emaiPassword, string toEmail, string eMailSubject, string eMailBody, string attachmentPath = null)
    {
        try
        {
            MailMessage mail = new MailMessage();

            mail.From = new MailAddress(fromEmail);
            mail.To.Add(toEmail);
            mail.Subject = eMailSubject;
            mail.Body = eMailBody;

            if (attachmentPath != null)
            {
                System.Net.Mail.Attachment attachment = new System.Net.Mail.Attachment(attachmentPath);
                mail.Attachments.Add(attachment);
            }

            SmtpClient smtpClient = new SmtpClient();
            smtpClient.Host = "smtp.gmail.com";
            smtpClient.Port = 587;
            smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
            smtpClient.Credentials = new System.Net.NetworkCredential(fromEmail, emaiPassword) as ICredentialsByHost;
            smtpClient.EnableSsl = true;
            ServicePointManager.ServerCertificateValidationCallback =
                delegate (object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
                { return true; };
            smtpClient.Send(mail);
        }
        catch (Exception e) { }
    }

    void OnDisable()
    {
        //Un-Subscribe from Log Event
        Application.logMessageReceived -= LogCallback;
    }

    //Save log  when focous is lost
    void OnApplicationFocus(bool hasFocus)
    {
        if (!hasFocus)
        {
            //Save
            if (enableSave)
                DataSaver.saveData(logs, "savelog");
        }
    }

    //Save log on exit
    void OnApplicationPause(bool pauseStatus)
    {
        if (pauseStatus)
        {
            //Save
            if (enableSave)
                DataSaver.saveData(logs, "savelog");
        }
    }
}
like image 139
Programmer Avatar answered Dec 27 '22 03:12

Programmer