Save ADB Log
namespace System.Diagnostics { [DefaultEvent("Exited")] [DefaultProperty("StartInfo")] [Designer("System.Diagnostics.Design.ProcessDesigner, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] [MonitoringDescription("Represents a system process")] public class Process : Component { public Process(); ~Process(); [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("Base process priority.")] [MonoTODOAttribute] public int BasePriority { get; } [Browsable(false)] [DefaultValue(false)] [MonitoringDescription("Check for exiting of the process to raise the apropriate event.")] public bool EnableRaisingEvents { get; set; } [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The exit code of the process.")] public int ExitCode { get; } [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The exit time of the process.")] public DateTime ExitTime { get; } [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("Handle for this process.")] public IntPtr Handle { get; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("Handles for this process.")] [MonoTODOAttribute] public int HandleCount { get; } [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("Determines if the process is still running.")] public bool HasExited { get; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("Process identifier.")] public int Id { get; } [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The name of the computer running the process.")] [MonoTODOAttribute] public string MachineName { get; } [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The main module of the process.")] public ProcessModule MainModule { get; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The handle of the main window of the process.")] [MonoTODOAttribute] public IntPtr MainWindowHandle { get; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The title of the main window of the process.")] [MonoTODOAttribute] public string MainWindowTitle { get; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The maximum working set for this process.")] public IntPtr MaxWorkingSet { get; set; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The minimum working set for this process.")] public IntPtr MinWorkingSet { get; set; } [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The modules that are loaded as part of this process.")] public ProcessModuleCollection Modules { get; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The number of bytes that are not pageable.")] [MonoTODOAttribute] [Obsolete("Use NonpagedSystemMemorySize64")] public int NonpagedSystemMemorySize { get; } [ComVisible(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The number of bytes that are not pageable.")] [MonoTODOAttribute] public long NonpagedSystemMemorySize64 { get; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The number of bytes that are paged.")] [MonoTODOAttribute] [Obsolete("Use PagedMemorySize64")] public int PagedMemorySize { get; } [ComVisible(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The number of bytes that are paged.")] [MonoTODOAttribute] public long PagedMemorySize64 { get; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The amount of paged system memory in bytes.")] [MonoTODOAttribute] [Obsolete("Use PagedSystemMemorySize64")] public int PagedSystemMemorySize { get; } [ComVisible(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The amount of paged system memory in bytes.")] [MonoTODOAttribute] public long PagedSystemMemorySize64 { get; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The maximum amount of paged memory used by this process.")] [MonoTODOAttribute] [Obsolete("Use PeakPagedMemorySize64")] public int PeakPagedMemorySize { get; } [ComVisible(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The maximum amount of paged memory used by this process.")] [MonoTODOAttribute] public long PeakPagedMemorySize64 { get; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The maximum amount of virtual memory used by this process.")] [Obsolete("Use PeakVirtualMemorySize64")] public int PeakVirtualMemorySize { get; } [ComVisible(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The maximum amount of virtual memory used by this process.")] public long PeakVirtualMemorySize64 { get; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The maximum amount of system memory used by this process.")] [Obsolete("Use PeakWorkingSet64")] public int PeakWorkingSet { get; } [ComVisible(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The maximum amount of system memory used by this process.")] public long PeakWorkingSet64 { get; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("Process will be of higher priority while it is actively used.")] [MonoTODOAttribute] public bool PriorityBoostEnabled { get; set; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The relative process priority.")] [MonoLimitationAttribute("Under Unix, only root is allowed to raise the priority.")] public ProcessPriorityClass PriorityClass { get; set; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The amount of memory exclusively used by this process.")] [Obsolete("Use PrivateMemorySize64")] public int PrivateMemorySize { get; } [ComVisible(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The amount of memory exclusively used by this process.")] public long PrivateMemorySize64 { get; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The amount of processing time spent in the OS core for this process.")] public TimeSpan PrivilegedProcessorTime { get; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The name of this process.")] public string ProcessName { get; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("Allowed processor that can be used by this process.")] [MonoTODOAttribute] public IntPtr ProcessorAffinity { get; set; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("Is this process responsive.")] [MonoTODOAttribute] public bool Responding { get; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The session ID for this process.")] [MonoNotSupportedAttribute("")] public int SessionId { get; } [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The standard error stream of this process.")] public StreamReader StandardError { get; } [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The standard input stream of this process.")] public StreamWriter StandardInput { get; } [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The standard output stream of this process.")] public StreamReader StandardOutput { get; } [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] [MonitoringDescription("Information for the start of this process.")] public ProcessStartInfo StartInfo { get; set; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The time this process started.")] public DateTime StartTime { get; } [Browsable(false)] [DefaultValue(null)] [MonitoringDescription("The object that is used to synchronize event handler calls for this process.")] public ISynchronizeInvoke SynchronizingObject { get; set; } [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The number of threads of this process.")] [MonoTODOAttribute] public ProcessThreadCollection Threads { get; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The total CPU time spent for this process.")] public TimeSpan TotalProcessorTime { get; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The CPU time spent for this process in user mode.")] public TimeSpan UserProcessorTime { get; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The amount of virtual memory currently used for this process.")] [Obsolete("Use VirtualMemorySize64")] public int VirtualMemorySize { get; } [ComVisible(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The amount of virtual memory currently used for this process.")] public long VirtualMemorySize64 { get; } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The amount of physical memory currently used for this process.")] [Obsolete("Use WorkingSet64")] public int WorkingSet { get; } [ComVisible(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [MonitoringDescription("The amount of physical memory currently used for this process.")] public long WorkingSet64 { get; } [Browsable(true)] [MonitoringDescription("Raised when it receives error data")] public event DataReceivedEventHandler ErrorDataReceived; [Category("Behavior")] [MonitoringDescription("Raised when this process exits.")] public event EventHandler Exited; [Browsable(true)] [MonitoringDescription("Raised when it receives output data")] public event DataReceivedEventHandler OutputDataReceived; [MonoTODOAttribute] public static void EnterDebugMode(); public static Process GetCurrentProcess(); public static Process GetProcessById(int processId); [MonoTODOAttribute("There is no support for retrieving process information from a remote machine")] public static Process GetProcessById(int processId, string machineName); public static Process[] GetProcesses(); [MonoTODOAttribute("There is no support for retrieving process information from a remote machine")] public static Process[] GetProcesses(string machineName); public static Process[] GetProcessesByName(string processName); [MonoTODOAttribute] public static Process[] GetProcessesByName(string processName, string machineName); [MonoTODOAttribute] public static void LeaveDebugMode(); public static Process Start(ProcessStartInfo startInfo); public static Process Start(string fileName); public static Process Start(string fileName, string arguments); public static Process Start(string fileName, string username, SecureString password, string domain); public static Process Start(string fileName, string arguments, string username, SecureString password, string domain); [ComVisible(false)] public void BeginErrorReadLine(); [ComVisible(false)] public void BeginOutputReadLine(); [ComVisible(false)] public void CancelErrorRead(); [ComVisible(false)] public void CancelOutputRead(); public void Close(); public bool CloseMainWindow(); public void Kill(); public void Refresh(); public bool Start(); public override string ToString(); public void WaitForExit(); public bool WaitForExit(int milliseconds); [MonoTODOAttribute] public bool WaitForInputIdle(); [MonoTODOAttribute] public bool WaitForInputIdle(int milliseconds); protected override void Dispose(bool disposing); protected void OnExited(); } }
using UnityEngine; using System.Collections; using UnityEditor; using System.Diagnostics; using System.Collections.Generic; using System.Linq; using System; public class LogCatWindow : EditorWindow { // How many log entries to store in memory. Keep it low for better performance. private const int memoryLimit = 2000; // How many log entries to show in unity3D editor. Keep it low for better performance. private const int showLimit = 200; // Filters private bool prefilterOnlyUnity = true; private bool filterOnlyError = false; private bool filterOnlyWarning = false; private bool filterOnlyDebug = false; private bool filterOnlyInfo = false; private bool filterOnlyVerbose = false; private string filterByString = String.Empty; // Android adb logcat process private Process logCatProcess; // Log entries private List<LogCatLog> logsList = new List<LogCatLog>(); private List<LogCatLog> filteredList = new List<LogCatLog>(memoryLimit); // Filtered GUI list scroll position private Vector2 scrollPosition = new Vector2(0, 0); // Add menu item named "LogCat" to the Window menu [MenuItem("Window/LogCat - Android Logger")] public static void ShowWindow() { // Show existing window instance. If one doesn't exist, make one. EditorWindow.GetWindow(typeof(LogCatWindow), false, "Logcat"); } void Update() { if (logsList.Count == 0) return; lock (logsList) { // Filter filteredList = logsList.Where(log => (filterByString.Length <= 2 || log.Message.ToLower().Contains(filterByString.ToLower())) && ((!filterOnlyError && !filterOnlyWarning && !filterOnlyDebug && !filterOnlyInfo && !filterOnlyVerbose) || filterOnlyError && log.Type == 'E' || filterOnlyWarning && log.Type == 'W' || filterOnlyDebug && log.Type == 'D' || filterOnlyInfo && log.Type == 'I' || filterOnlyVerbose && log.Type == 'V')).ToList(); } } void OnGUI() { GUILayout.BeginHorizontal(); // Enable pre-filter if process is not started GUI.enabled = logCatProcess == null; prefilterOnlyUnity = GUILayout.Toggle(prefilterOnlyUnity, "Only Unity", "Button", GUILayout.Width(80)); // Enable button if process is not started GUI.enabled = logCatProcess == null; if (GUILayout.Button("Start", GUILayout.Width(60))) { // Start `adb logcat -c` to clear the log buffer ProcessStartInfo clearProcessInfo = new ProcessStartInfo(); clearProcessInfo.WindowStyle = ProcessWindowStyle.Hidden; clearProcessInfo.CreateNoWindow = true; clearProcessInfo.UseShellExecute = false; clearProcessInfo.FileName = EditorPrefs.GetString("AndroidSdkRoot") + "/platform-tools/adb"; clearProcessInfo.Arguments = @"logcat -c"; Process.Start(clearProcessInfo); // Start `adb logcat` (with additional optional arguments) process for filtering ProcessStartInfo logProcessInfo = new ProcessStartInfo(); logProcessInfo.CreateNoWindow = true; logProcessInfo.UseShellExecute = false; logProcessInfo.RedirectStandardOutput = true; logProcessInfo.RedirectStandardError = true; logProcessInfo.FileName = EditorPrefs.GetString("AndroidSdkRoot") + "/platform-tools/adb"; logProcessInfo.WindowStyle = ProcessWindowStyle.Hidden; // Add additional -s argument for filtering by Unity tag. logProcessInfo.Arguments = "logcat"+(prefilterOnlyUnity ? " -s \"Unity\"": ""); logCatProcess = Process.Start(logProcessInfo); logCatProcess.ErrorDataReceived += (sender, errorLine) => { if (errorLine.Data != null && errorLine.Data.Length > 2) AddLog(new LogCatLog(errorLine.Data)); }; logCatProcess.OutputDataReceived += (sender, outputLine) => { if (outputLine.Data != null && outputLine.Data.Length > 2) AddLog(new LogCatLog(outputLine.Data)); }; logCatProcess.BeginErrorReadLine(); logCatProcess.BeginOutputReadLine(); } // Disable button if process is already started GUI.enabled = logCatProcess != null; if (GUILayout.Button("Stop", GUILayout.Width(60))) { try { logCatProcess.Kill(); } catch(InvalidOperationException ex) { // Just ignore it. } finally { logCatProcess = null; } } GUI.enabled = true; if (GUILayout.Button("Clear", GUILayout.Width(60))) { lock (logsList) { logsList.Clear(); filteredList.Clear(); } } GUILayout.Label(filteredList.Count + " matching logs", GUILayout.Height(20)); // Create filters filterByString = GUILayout.TextField(filterByString, GUILayout.Height(20)); GUI.color = new Color(0.75f, 0.5f, 0.5f, 1f); filterOnlyError = GUILayout.Toggle(filterOnlyError, "Error", "Button", GUILayout.Width(80)); GUI.color = new Color(0.95f, 0.95f, 0.3f, 1f); filterOnlyWarning = GUILayout.Toggle(filterOnlyWarning, "Warning", "Button", GUILayout.Width(80)); GUI.color = new Color(0.5f, 0.5f, 0.75f, 1f); filterOnlyDebug = GUILayout.Toggle(filterOnlyDebug, "Debug", "Button", GUILayout.Width(80)); GUI.color = new Color(0.5f, 0.75f, 0.5f, 1f); filterOnlyInfo = GUILayout.Toggle(filterOnlyInfo, "Info", "Button", GUILayout.Width(80)); GUI.color = Color.white; filterOnlyVerbose = GUILayout.Toggle(filterOnlyVerbose, "Verbose", "Button", GUILayout.Width(80)); GUILayout.EndHorizontal(); GUIStyle lineStyle = new GUIStyle(); lineStyle.normal.background = MakeTexture(600, 1, new Color(1.0f, 1.0f, 1.0f, 0.1f)); scrollPosition = GUILayout.BeginScrollView(scrollPosition, GUILayout.Height(Screen.height - 45)); // Show only top `showingLimit` log entries int fromIndex = filteredList.Count - showLimit; if (fromIndex < 0) fromIndex = 0; for (int i = fromIndex; i < filteredList.Count; i++) { LogCatLog log = filteredList[i]; GUI.backgroundColor = log.GetBgColor(); GUILayout.BeginHorizontal(lineStyle); GUILayout.Label(log.CreationDate + " | " + log.Message); GUILayout.EndHorizontal(); } GUILayout.EndScrollView(); } private Texture2D MakeTexture(int width, int height, Color col) { Color[] pix = new Color[width * height]; for (int i = 0; i < pix.Length; i++) pix [i] = col; Texture2D result = new Texture2D(width, height); result.SetPixels(pix); result.Apply(); return result; } private void AddLog(LogCatLog log) { lock (logsList) { if (logsList.Count > memoryLimit + 1) logsList.RemoveRange(0, logsList.Count - memoryLimit + 1); logsList.Add(log); } } private class LogCatLog { public LogCatLog(string data) { // First char indicates error type: // W - warning // E - error // D - debug // I - info // V - verbose Type = data[0]; Message = data.Substring(2); CreationDate = DateTime.Now.ToString("H:mm:ss"); } public string CreationDate { get; set; } public char Type { get; set; } public string Message { get; set; } public Color GetBgColor() { switch (Type) { case 'W': return Color.yellow; case 'I': return Color.green; case 'E': return Color.red; case 'D': return Color.blue; case 'V': default: return Color.grey; } } } }
1.4142
https://developer.oculus.com/blog/squeezing-performance-out-of-your-unity-gear-vr-game-continued/