public static LogEntryStrackTrace FromStackTrace(StackTrace stackTrace) { if (stackTrace == null) { return(Empty); } if (stackTrace.FrameCount == 0) { return(Empty); } try { LogEntryStrackTrace result = new LogEntryStrackTrace(); StackFrame[] frames = stackTrace.GetFrames(); // Skip all frames within the logging framework itself int skipFrames = 0; for (int i = 0; i < frames.Length; i++) { MethodBase method = frames[i].GetMethod(); Type type = method.DeclaringType; bool isLoggingType = !string.IsNullOrEmpty(type.Namespace) && type.Namespace.StartsWith(typeof(Log).Namespace); // Select the first stack frame that is not part of the // logging code, which is defined as everything in the // same namespace as the Log class if (isLoggingType) { skipFrames++; } else { break; } } if (skipFrames < frames.Length) { result._frames = new LogEntryStrackFrame[frames.Length - skipFrames]; for (int i = skipFrames; i < frames.Length; i++) { result._frames[i - skipFrames] = LogEntryStrackFrame.FromStackFrame(frames[i]); } } return(result); } catch (Exception) { return(Error); } }
public static LogEntryStrackTrace FromUnityStackTrace(string stackTrace, string message) { try { // Do we have an actual stack trace from Unity? Parse it. if (!string.IsNullOrEmpty(stackTrace)) { string[] lines = stackTrace.Split(new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries); // Skip stack frames within Unity's own Debug class int skipLines = 0; while (skipLines < lines.Length && lines[skipLines].StartsWith("UnityEngine.Debug:", StringComparison.InvariantCultureIgnoreCase)) { skipLines++; } LogEntryStrackTrace result = new LogEntryStrackTrace(); if (skipLines < lines.Length) { result._frames = new LogEntryStrackFrame[lines.Length - skipLines]; for (int i = skipLines; i < lines.Length; i++) { result._frames[i - skipLines] = LogEntryStrackFrame.FromUnityStackFrame(lines[i]); } } return(result); } // Otherwise, try to parse the message in order to obtain a stack frame. // This will trigger for Unity reporting build errors. else if (!string.IsNullOrEmpty(message)) { LogEntryStrackTrace result = new LogEntryStrackTrace(); result._frames = new LogEntryStrackFrame[1]; result._frames[0] = LogEntryStrackFrame.FromUnityBuildMessage(message); return(result); } else { return(Empty); } } catch (Exception) { return(Error); } }
public void Write(Log source, LogEntry entry, object context) { lock (_lock) { EnsureKnownChannels(); EnsureTypeCount(); if (!_knownChannels.Contains(source.Name)) { _knownChannels.Add(source.Name); } // If this log entry was actually written using Unity Debug.Log API // and merely forwarded to us for integration purposes, the context // will be a UnityLogContext structure. We can use this to extact // the callstack that was provided. UnityLogContext unityContext = (context is UnityLogContext) ? (UnityLogContext)context : default(UnityLogContext); // Store the log inside a wrapper struct, which contains all information // that can be used for diagnostic purposes, not just the actual log that // is written. EditorWindowLogEntry logEntry = new EditorWindowLogEntry { Log = entry, SingleLineMessage = entry.Message.Split('\n')[0], Indent = _indent, SourceName = source.Name, Context = new LogEntryContext(context), CallStack = (unityContext.StackTrace != null) ? LogEntryStrackTrace.FromUnityStackTrace(unityContext.StackTrace, entry.Message) : LogEntryStrackTrace.FromStackTrace(new StackTrace(2, true)) }; _logEntries.Add(logEntry); _typeCount[entry.Type]++; _logsReceivedSinceLastPoll = true; } }