/** * UploadFiles - uploads the two files using HTTP POST * * @param LogFilename - the local log file * @param IniFilename - the local ini file * @param uniqueID - the id of the crash report associated with these files. * @return bool - true if successful */ public bool UploadFiles(string ProcessName, bool bWasAnEnsure, Int32 InProcessID, string LogFilename, string IniFilename, string MiniDumpFilename, string CrashVideoFilename, int uniqueID, OutputLogFile logFile) { logFile.WriteLine("Uploading files..."); logFile.WriteLine("\t" + LogFilename); logFile.WriteLine("\t" + IniFilename); logFile.WriteLine("\t" + MiniDumpFilename); logFile.WriteLine("\t" + CrashVideoFilename); Boolean bWasSuccessful = false; Boolean bUploadedLog = true; Boolean bUploadedVideo = true; Boolean bUploadedMiniDump = true; Boolean bCanAccessLog; Boolean bCanAccessVideo; Boolean bCanAccessMiniDump; bCanAccessLog = CanAccessFile(ProcessName, bWasAnEnsure, InProcessID, LogFilename, logFile); bCanAccessVideo = CanAccessFile(ProcessName, bWasAnEnsure, InProcessID, CrashVideoFilename, logFile); bCanAccessMiniDump = CanAccessFile(ProcessName, bWasAnEnsure, InProcessID, MiniDumpFilename, logFile); WebClient client = new WebClient(); // Send the Crash Id up so that the uploader can name the files correctly. // This used to save crash files to their own unique folder, but that method has been replaced with appending _<crashId> to the filename. client.Headers.Add("NewFolderName", uniqueID.ToString()); if(bCanAccessLog) { try { bUploadedLog = UploadFile("LogName", StripPath(LogFilename), LogFilename, logFile, client); } catch (NullReferenceException nrE) { bUploadedLog = false; logFile.WriteLine("Uploading "+ LogFilename+ " caused Null Reference Exception: "+nrE.Message); } } else { bUploadedLog = false; logFile.WriteLine("Could not access File: " + LogFilename); } // Upload Crash Video if(bCanAccessVideo) { try { bUploadedVideo = UploadFile("SaveFileName", "CrashVideo.avi", CrashVideoFilename, logFile, client); } catch (NullReferenceException nrE) { logFile.WriteLine("Uploading "+ CrashVideoFilename+ " caused Null Reference Exception: "+nrE.Message); } if(!bUploadedVideo) { string NetworkPath = @"\\devweb-02\ReportVideos\"; try { // Try copying over the network // \\devweb-02\ReportVideos if(!String.IsNullOrEmpty(CrashVideoFilename) ) { logFile.WriteLine("Attempting to copy file " + CrashVideoFilename + " over the network to " +NetworkPath ); File.Copy(CrashVideoFilename, NetworkPath + uniqueID.ToString()+ "_"+StripPath(CrashVideoFilename)); bUploadedVideo = true; } else { logFile.WriteLine("Argument Null or Empty"); } } catch(Exception e) { logFile.WriteLine(e.ToString()); logFile.WriteLine("Couldn't copy crash video to network..."); try { File.Copy(CrashVideoFilename, CrashVideoFilename+"_" + uniqueID.ToString(), true); } catch (Exception copyFileException) { logFile.WriteLine(copyFileException.Message); logFile.WriteLine("Couldn't copy File " + CrashVideoFilename + ", continuing..."); } throw new Exception("Failed to upload Crash Video to " + NetworkPath + uniqueID.ToString() + "_" + StripPath(CrashVideoFilename) + "after a web and a network copy attempts"); } } } else { bUploadedVideo = false; var CheckFileInfo = new FileInfo(CrashVideoFilename); if (CheckFileInfo.Exists) { logFile.WriteLine("Could not access File: " + CrashVideoFilename); } else { logFile.WriteLine("File: " + CrashVideoFilename+" does not exist."); } } // Upload Minidump if (bCanAccessMiniDump) { try { bUploadedMiniDump = UploadFile("SaveFileName", "MiniDump.dmp", MiniDumpFilename, logFile, client); } catch (NullReferenceException nrE) { bUploadedMiniDump = false; logFile.WriteLine("Uploading "+ MiniDumpFilename+ " caused Null Reference Exception: "+nrE.Message); } } else { bUploadedMiniDump = false; logFile.WriteLine("Could not access File: " + LogFilename); } //Upload file successes try { ReportService.RegisterReport reportService = new ReportService.RegisterReport(); try { bWasSuccessful = reportService.AddCrashFiles(uniqueID, bUploadedLog, bUploadedMiniDump, bUploadedVideo); } catch (Exception e) { throw e; } } catch (WebException webEx) { logFile.WriteLine(webEx.Message); logFile.WriteLine(webEx.InnerException.Message); bWasSuccessful = false; } // Temporary - write out log file contents to autoreporter log logFile.WriteLine(""); logFile.WriteLine("----------"); logFile.WriteLine("Log file: " + LogFilename); logFile.WriteLine("----------"); Int32 FailCount = 0; bool bWroteLogFile = false; bool bFileExists = false; Int64 FileSize = 0; while ((FailCount < 10) && !bWroteLogFile) { FileInfo RealLogInfo = new FileInfo(LogFilename); bFileExists |= RealLogInfo.Exists; if(bFileExists) { try { FileSize = System.Math.Max(FileSize, RealLogInfo.Length); } catch (IOException) { logFile.WriteLine("Could not Access file: " + LogFilename + " to get it's size."); } } if (RealLogInfo.Exists && (FileSize > 0)) { using (StreamReader sr = RealLogInfo.OpenText()) { while (sr.Peek() > 0) { logFile.WriteLine(sr.ReadLine()); } } logFile.WriteLine("----------"); bWroteLogFile = true; } else { FailCount++; // Sleep for a second before trying again System.Threading.Thread.Sleep(1000); } } if (bWroteLogFile == false) { logFile.WriteLine("Attempted to write log file to autoreport log failed."); logFile.WriteLine("\tFile does " + (bFileExists ? "" : "NOT") + " Exist"); logFile.WriteLine("\tFile size = " + FileSize); } return bWasSuccessful; }
static void Main(string[] args) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); string logFileName; if (args.Length >= 2) { string logDirectory; int endOfLogPath = args [2].LastIndexOf('/'); logDirectory = args [2].Substring(0, endOfLogPath + 1); logFileName = logDirectory + "AutoReportLog.txt"; } else { logFileName = "AutoReportLog.txt"; } OutputLogFile LogFile = new OutputLogFile(logFileName); LogFile.WriteLine("Log opened: " + logFileName); LogFile.WriteLine(""); LogFile.WriteLine("Current Time = " + DateTime.Now.ToString()); LogFile.WriteLine(""); LogFile.WriteLine("Arguments:"); foreach (string arg in args) { LogFile.WriteLine(arg); } if (args.Length < 6) { LogFile.WriteLine("Expected 5 arguments: AutoReport Dump file name, Log file name, Ini dump file name, Mini dump file name, Crash video file name and ProcessID"); LogFile.Close(); return; } Int32 ProcessId = Convert.ToInt32(args [0]); Thread.Sleep(1000); // Check for additional options bool bForceUnattended = false; bool bShowBalloon = false; for (int ExtraArgIndex = 6; ExtraArgIndex < args.Length; ++ExtraArgIndex) { string CurArgString = args [ExtraArgIndex]; // -Unattended : forces unattended mode regardless of command line string if (CurArgString.Equals("-Unattended", StringComparison.OrdinalIgnoreCase)) { bForceUnattended = true; } // -Balloon : displays a system tray notify icon (balloon) and forces unattended mode else if (CurArgString.Equals("-Balloon", StringComparison.OrdinalIgnoreCase)) { // balloon not possible on Mac if (Environment.OSVersion.Platform != PlatformID.Unix) { bShowBalloon = true; } // Unattended mode is implied with -Balloon bForceUnattended = true; } else { LogFile.WriteLine(String.Format("Unrecognized parameter: {0}", CurArgString)); LogFile.Close(); return; } } ReportFile rFile = new ReportFile(); ReportFileData reportData = new ReportFileData(); LogFile.WriteLine("Parsing report file: " + args [1]); if (!rFile.ParseReportFile(args [1], reportData, LogFile)) { LogFile.WriteLine("Failed to parse report file: " + args [1]); LogFile.Close(); return; } string ProcessName = reportData.GameName; Int32 SpaceIndex = ProcessName.IndexOf(' '); if (SpaceIndex != -1) { // This is likely UE4 UDK... parse off the game name ProcessName = ProcessName.Substring(0, SpaceIndex); } bool bIsUnattended = reportData.CommandLine.Contains("unattended") || bForceUnattended || Environment.OSVersion.Platform == PlatformID.Unix; string CrashDescription; string Summary = CrashDescription = bShowBalloon ? "Handled error" : "Unattended mode"; if (bShowBalloon) { String MsgText = "An unexpected error has occurred but the application has recovered. A report will be submitted to the QA database."; // If the error occurred in the editor then we'll remind them to save their changes if (reportData.EngineMode.Contains("Editor")) { MsgText += " Remember to save your work often."; } // Notify the user of the error by launching the NotifyObject. NotifyObject = new EpicBalloon(); NotifyObject.Show(MsgText, BalloonTimeInMs); } if (!bIsUnattended) { LogFile.WriteLine("Attempting to create a new crash description form..."); Form1 crashDescForm = new Form1(); crashDescForm.summary = Summary; crashDescForm.crashDesc = CrashDescription; LogFile.WriteLine("Running attended..."); crashDescForm.SetCallStack(reportData.CallStack); LogFile.WriteLine("Running the application..."); Application.Run(crashDescForm); Summary = crashDescForm.summary; CrashDescription = crashDescForm.crashDesc; } LogFile.WriteLine("Crash Summary = " + Summary); LogFile.WriteLine("Crash Description = " + CrashDescription); LogFile.WriteLine("Registering report service..."); // Create an instance of AutoReportService handler to make a web request to the AutoReportService to create a Crash Report in the database. Once this is complete we'll upload the associated files. ReportService.RegisterReport reportService = new ReportService.RegisterReport(); Exception serviceException = new Exception(""); bool serviceError = false; LogFile.WriteLine("Attempting to create a new crash..."); int uniqueIndex = -1; // Make the web request try { uniqueIndex = reportService.CreateNewCrash(-1, reportData.ComputerName, reportData.UserName, reportData.GameName, reportData.PlatformName, reportData.LanguageExt, reportData.TimeOfCrash, reportData.BuildVer, reportData.ChangelistVer, reportData.CommandLine, reportData.BaseDir, reportData.CallStack, reportData.EngineMode); } catch (Exception e) { LogFile.WriteLine("AutoReporter had an exception in accessing the reportService! --> " + e.ToString()); serviceException = e; serviceError = true; LogFile.WriteLine(e.Message); } LogFile.WriteLine(""); LogFile.WriteLine("uniqueIndex = " + uniqueIndex.ToString()); LogFile.WriteLine(""); if (uniqueIndex == -1) { LogFile.WriteLine("The service failed to create a new Crash!"); serviceError = true; serviceException = new Exception("The service failed to create a new Crash!"); } LogFile.WriteLine("Attempting to create a new UpdateReportFiles instance..."); // Create handler to upload the files. UploadReportFiles reportUploader = new UploadReportFiles(); bool fileUploadSuccess = false; if (!serviceError) { LogFile.WriteLine("Attempting to upload files..."); try { fileUploadSuccess = reportUploader.UploadFiles(ProcessName, bShowBalloon, ProcessId, args [2], args [3], args [4], args [5], uniqueIndex, LogFile); } catch (NullReferenceException nre) { LogFile.WriteLine(nre.Source + " Caused Null Reference Exception"); // Try again: try { LogFile.WriteLine("Process Name: " + ProcessName); LogFile.WriteLine("bShowBalloon: " + bShowBalloon); LogFile.WriteLine("ProcessId: " + ProcessId); LogFile.WriteLine("args[2]: " + args [2]); LogFile.WriteLine("args[3]: " + args [3]); LogFile.WriteLine("args[4]: " + args [4]); LogFile.WriteLine("args[5] ; " + args [5]); LogFile.WriteLine("uniqueIndex " + uniqueIndex); LogFile.WriteLine("LogFile " + LogFile); fileUploadSuccess = reportUploader.UploadFiles(ProcessName, bShowBalloon, ProcessId, args [2], args [3], args [4], args [5], uniqueIndex, LogFile); } catch (NullReferenceException nre2) { LogFile.WriteLine(nre2.Source + " Caused Null Reference Exception Two Times"); serviceError = true; } } catch (Exception e) { LogFile.WriteLine("AutoReporter had an exception uploading files! --> " + e.ToString()); serviceException = e; serviceError = true; } if (fileUploadSuccess) { LogFile.WriteLine("Successfully uploaded files"); LogFile.WriteLine("Saved: " + args [5]); } else { LogFile.WriteLine("Failed to upload some files!"); } } //Update Crash with Summary and Description Info bool updateSuccess = false; string logDirectory2; int endOfLogPath2 = args [2].LastIndexOf('/'); logDirectory2 = args [2].Substring(0, endOfLogPath2 + 1); logFileName = logDirectory2 + "AutoReportLog.txt"; LogFile.WriteLine("Attempting to add the crash description..."); try { updateSuccess = reportService.AddCrashDescription(uniqueIndex, CrashDescription, Summary); } catch (Exception e) { LogFile.WriteLine("AutoReporter had an exception adding crash description! --> " + e.ToString()); serviceException = e; serviceError = true; updateSuccess = false; LogFile.WriteLine(e.Message); } if (uniqueIndex != -1) { LogFile.WriteLine("Attempting to write the crash report URL..."); #if DEBUG string strCrashURL = Properties.Settings.Default.CrashURL_Debug + uniqueIndex; #else string strCrashURL = Properties.Settings.Default.CrashURL + uniqueIndex; #endif LogFile.WriteLine("CrashReport url = " + strCrashURL); LogFile.WriteLine(""); if (NotifyObject != null) { // Set up text to inform the user of the report submission String MsgText = "Your crash report was submitted, and the URL was copied to your clipboard. Click this balloon to display the crash report."; // setup crash report URL ready for use by the notification Clipboard.SetText(strCrashURL); m_CrashReportUrl = strCrashURL; // launch a notification that when clicked will link // to the crash report url. NotifyObject.SetEvents(OnBalloonClicked); NotifyObject.Show(MsgText, BalloonTimeInMs); } string str = reportData.PlatformName.ToLower(); if (str == "pc" || str == "mac") { LogFile.WriteLine("Attempting to send the crash report Id to the game log file..."); // On PC, so try just writing to the log. string AppLogFileName = Path.Combine(reportData.BaseDir, "..", reportData.GameName + "Game", "Logs", reportData.GameName + ".log"); if (!File.Exists(AppLogFileName)) { // It's also possible the log name is Engine.log (default game name from BaseEngine.ini) AppLogFileName = Path.Combine(reportData.BaseDir, "..", reportData.GameName + "Game", "Logs", "Engine.log"); if (!File.Exists(AppLogFileName)) { // Default to hardcoded UE4.log AppLogFileName = Path.Combine(reportData.BaseDir, "..", reportData.GameName + "Game", "Logs", "UE4.log"); } } LogFile.WriteLine("\n"); LogFile.WriteLine("Attempting to open log file: " + AppLogFileName); try { using (StreamWriter AppLogWriter = new StreamWriter(AppLogFileName, true)) { AppLogWriter.WriteLine(""); AppLogWriter.WriteLine("CrashReport url = " + strCrashURL); AppLogWriter.WriteLine(""); AppLogWriter.Flush(); } } catch (System.Exception e) { LogFile.WriteLine("AutoReporter had an exception creating a stream writer! --> " + e.ToString()); } } } if (updateSuccess) { LogFile.WriteLine("Successfully added crash description"); } else { LogFile.WriteLine("Service failed to add crash description!"); LogFile.Close(); return; } LogFile.WriteLine("Closing the AutoReporter log file..."); LogFile.Close(); try { //everything was successful, so clean up dump and log files on client System.IO.File.Delete(args [1]); System.IO.File.Delete(args [3]); //todo: need to handle partial failure cases (some files didn't upload, etc) to know if we should delete the log //System.IO.File.Delete(logFileName); } catch (Exception e) { string ExcStr = "AutoReporter had an exception deleting the temp files!\n" + e.ToString(); MessageBox.Show(ExcStr, "AutoReporter Status", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } // Make a copy of the log file w/ the CrashReport # in it... // This is to help track down the issue where empty log files are being uploaded to the crash reporter. string CopyFileName = logFileName.Replace(".txt", "_" + uniqueIndex + ".txt"); System.IO.File.Copy(logFileName, CopyFileName); if (NotifyObject != null) { // spin until the NotifyObject has closed while (NotifyObject.IsOpen) { // sleep while the notify balloon is fading System.Threading.Thread.Sleep(1000); // force check the events. Application.DoEvents(); } } }
static void Main (string[] args) { Application.EnableVisualStyles (); Application.SetCompatibleTextRenderingDefault (false); string logFileName; if (args.Length >= 2) { string logDirectory; int endOfLogPath = args [2].LastIndexOf ('/'); logDirectory = args [2].Substring (0, endOfLogPath + 1); logFileName = logDirectory + "AutoReportLog.txt"; } else { logFileName = "AutoReportLog.txt"; } OutputLogFile LogFile = new OutputLogFile (logFileName); LogFile.WriteLine ("Log opened: " + logFileName); LogFile.WriteLine (""); LogFile.WriteLine ("Current Time = " + DateTime.Now.ToString ()); LogFile.WriteLine (""); LogFile.WriteLine ("Arguments:"); foreach (string arg in args) { LogFile.WriteLine (arg); } if (args.Length < 6) { LogFile.WriteLine ("Expected 5 arguments: AutoReport Dump file name, Log file name, Ini dump file name, Mini dump file name, Crash video file name and ProcessID"); LogFile.Close (); return; } Int32 ProcessId = Convert.ToInt32 (args [0]); Thread.Sleep (1000); // Check for additional options bool bForceUnattended = false; bool bShowBalloon = false; for (int ExtraArgIndex = 6; ExtraArgIndex < args.Length; ++ExtraArgIndex) { string CurArgString = args [ExtraArgIndex]; // -Unattended : forces unattended mode regardless of command line string if (CurArgString.Equals ("-Unattended", StringComparison.OrdinalIgnoreCase)) { bForceUnattended = true; } // -Balloon : displays a system tray notify icon (balloon) and forces unattended mode else if (CurArgString.Equals ("-Balloon", StringComparison.OrdinalIgnoreCase)) { // balloon not possible on Mac if(Environment.OSVersion.Platform != PlatformID.Unix) bShowBalloon = true; // Unattended mode is implied with -Balloon bForceUnattended = true; } else { LogFile.WriteLine (String.Format ("Unrecognized parameter: {0}", CurArgString)); LogFile.Close (); return; } } ReportFile rFile = new ReportFile (); ReportFileData reportData = new ReportFileData (); LogFile.WriteLine ("Parsing report file: " + args [1]); if (!rFile.ParseReportFile (args [1], reportData, LogFile)) { LogFile.WriteLine ("Failed to parse report file: " + args [1]); LogFile.Close (); return; } string ProcessName = reportData.GameName; Int32 SpaceIndex = ProcessName.IndexOf (' '); if (SpaceIndex != -1) { // This is likely UE4 UDK... parse off the game name ProcessName = ProcessName.Substring (0, SpaceIndex); } bool bIsUnattended = reportData.CommandLine.Contains ("unattended") || bForceUnattended || Environment.OSVersion.Platform == PlatformID.Unix; string CrashDescription; string Summary = CrashDescription = bShowBalloon ? "Handled error" : "Unattended mode"; if (bShowBalloon) { String MsgText = "An unexpected error has occurred but the application has recovered. A report will be submitted to the QA database."; // If the error occurred in the editor then we'll remind them to save their changes if (reportData.EngineMode.Contains("Editor")) { MsgText += " Remember to save your work often."; } // Notify the user of the error by launching the NotifyObject. NotifyObject = new EpicBalloon(); NotifyObject.Show(MsgText, BalloonTimeInMs); } if (!bIsUnattended) { LogFile.WriteLine ("Attempting to create a new crash description form..."); Form1 crashDescForm = new Form1 (); crashDescForm.summary = Summary; crashDescForm.crashDesc = CrashDescription; LogFile.WriteLine ("Running attended..."); crashDescForm.SetCallStack (reportData.CallStack); LogFile.WriteLine ("Running the application..."); Application.Run (crashDescForm); Summary = crashDescForm.summary; CrashDescription = crashDescForm.crashDesc; } LogFile.WriteLine ("Crash Summary = " + Summary); LogFile.WriteLine ("Crash Description = " + CrashDescription); LogFile.WriteLine ("Registering report service..."); // Create an instance of AutoReportService handler to make a web request to the AutoReportService to create a Crash Report in the database. Once this is complete we'll upload the associated files. ReportService.RegisterReport reportService = new ReportService.RegisterReport (); Exception serviceException = new Exception (""); bool serviceError = false; LogFile.WriteLine ("Attempting to create a new crash..."); int uniqueIndex = -1; // Make the web request try { uniqueIndex = reportService.CreateNewCrash (-1, reportData.ComputerName, reportData.UserName, reportData.GameName, reportData.PlatformName, reportData.LanguageExt, reportData.TimeOfCrash, reportData.BuildVer, reportData.ChangelistVer, reportData.CommandLine, reportData.BaseDir, reportData.CallStack, reportData.EngineMode); } catch (Exception e) { LogFile.WriteLine ("AutoReporter had an exception in accessing the reportService! --> " + e.ToString ()); serviceException = e; serviceError = true; LogFile.WriteLine (e.Message); } LogFile.WriteLine (""); LogFile.WriteLine ("uniqueIndex = " + uniqueIndex.ToString ()); LogFile.WriteLine (""); if (uniqueIndex == -1) { LogFile.WriteLine ("The service failed to create a new Crash!"); serviceError = true; serviceException = new Exception ("The service failed to create a new Crash!"); } LogFile.WriteLine ("Attempting to create a new UpdateReportFiles instance..."); // Create handler to upload the files. UploadReportFiles reportUploader = new UploadReportFiles (); bool fileUploadSuccess = false; if (!serviceError) { LogFile.WriteLine ("Attempting to upload files..."); try { fileUploadSuccess = reportUploader.UploadFiles (ProcessName, bShowBalloon, ProcessId, args [2], args [3], args [4], args [5], uniqueIndex, LogFile); } catch (NullReferenceException nre) { LogFile.WriteLine (nre.Source + " Caused Null Reference Exception"); // Try again: try { LogFile.WriteLine ("Process Name: " + ProcessName); LogFile.WriteLine ("bShowBalloon: " + bShowBalloon); LogFile.WriteLine ("ProcessId: " + ProcessId); LogFile.WriteLine ("args[2]: " + args [2]); LogFile.WriteLine ("args[3]: " + args [3]); LogFile.WriteLine ("args[4]: " + args [4]); LogFile.WriteLine ("args[5] ; " + args [5]); LogFile.WriteLine ("uniqueIndex " + uniqueIndex); LogFile.WriteLine ("LogFile " + LogFile); fileUploadSuccess = reportUploader.UploadFiles (ProcessName, bShowBalloon, ProcessId, args [2], args [3], args [4], args [5], uniqueIndex, LogFile); } catch (NullReferenceException nre2) { LogFile.WriteLine (nre2.Source + " Caused Null Reference Exception Two Times"); serviceError = true; } } catch (Exception e) { LogFile.WriteLine ("AutoReporter had an exception uploading files! --> " + e.ToString ()); serviceException = e; serviceError = true; } if (fileUploadSuccess) { LogFile.WriteLine ("Successfully uploaded files"); LogFile.WriteLine ("Saved: " + args [5]); } else { LogFile.WriteLine ("Failed to upload some files!"); } } //Update Crash with Summary and Description Info bool updateSuccess = false; string logDirectory2; int endOfLogPath2 = args [2].LastIndexOf ('/'); logDirectory2 = args [2].Substring (0, endOfLogPath2 + 1); logFileName = logDirectory2 + "AutoReportLog.txt"; LogFile.WriteLine ("Attempting to add the crash description..."); try { updateSuccess = reportService.AddCrashDescription (uniqueIndex, CrashDescription, Summary); } catch (Exception e) { LogFile.WriteLine ("AutoReporter had an exception adding crash description! --> " + e.ToString ()); serviceException = e; serviceError = true; updateSuccess = false; LogFile.WriteLine (e.Message); } if (uniqueIndex != -1) { LogFile.WriteLine ("Attempting to write the crash report URL..."); #if DEBUG string strCrashURL = Properties.Settings.Default.CrashURL_Debug + uniqueIndex; #else string strCrashURL = Properties.Settings.Default.CrashURL + uniqueIndex; #endif LogFile.WriteLine ("CrashReport url = " + strCrashURL); LogFile.WriteLine (""); if (NotifyObject != null) { // Set up text to inform the user of the report submission String MsgText = "Your crash report was submitted, and the URL was copied to your clipboard. Click this balloon to display the crash report."; // setup crash report URL ready for use by the notification Clipboard.SetText (strCrashURL); m_CrashReportUrl = strCrashURL; // launch a notification that when clicked will link // to the crash report url. NotifyObject.SetEvents(OnBalloonClicked); NotifyObject.Show(MsgText, BalloonTimeInMs); } string str = reportData.PlatformName.ToLower (); if (str == "pc" || str == "mac") { LogFile.WriteLine ("Attempting to send the crash report Id to the game log file..."); // On PC, so try just writing to the log. string AppLogFileName = Path.Combine (reportData.BaseDir, "..", reportData.GameName + "Game", "Logs", reportData.GameName + ".log"); if (!File.Exists (AppLogFileName)) { // It's also possible the log name is Engine.log (default game name from BaseEngine.ini) AppLogFileName = Path.Combine (reportData.BaseDir, "..", reportData.GameName + "Game", "Logs", "Engine.log"); if (!File.Exists (AppLogFileName)) // Default to hardcoded UE4.log AppLogFileName = Path.Combine (reportData.BaseDir, "..", reportData.GameName + "Game", "Logs", "UE4.log"); } LogFile.WriteLine ("\n"); LogFile.WriteLine ("Attempting to open log file: " + AppLogFileName); try { using (StreamWriter AppLogWriter = new StreamWriter(AppLogFileName, true)) { AppLogWriter.WriteLine (""); AppLogWriter.WriteLine ("CrashReport url = " + strCrashURL); AppLogWriter.WriteLine (""); AppLogWriter.Flush (); } } catch (System.Exception e) { LogFile.WriteLine ("AutoReporter had an exception creating a stream writer! --> " + e.ToString ()); } } } if (updateSuccess) { LogFile.WriteLine ("Successfully added crash description"); } else { LogFile.WriteLine ("Service failed to add crash description!"); LogFile.Close (); return; } LogFile.WriteLine ("Closing the AutoReporter log file..."); LogFile.Close (); try { //everything was successful, so clean up dump and log files on client System.IO.File.Delete (args [1]); System.IO.File.Delete (args [3]); //todo: need to handle partial failure cases (some files didn't upload, etc) to know if we should delete the log //System.IO.File.Delete(logFileName); } catch (Exception e) { string ExcStr = "AutoReporter had an exception deleting the temp files!\n" + e.ToString (); MessageBox.Show (ExcStr, "AutoReporter Status", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } // Make a copy of the log file w/ the CrashReport # in it... // This is to help track down the issue where empty log files are being uploaded to the crash reporter. string CopyFileName = logFileName.Replace (".txt", "_" + uniqueIndex + ".txt"); System.IO.File.Copy (logFileName, CopyFileName); if (NotifyObject != null) { // spin until the NotifyObject has closed while (NotifyObject.IsOpen) { // sleep while the notify balloon is fading System.Threading.Thread.Sleep (1000); // force check the events. Application.DoEvents (); } } }
/** * UploadFiles - uploads the two files using HTTP POST * * @param LogFilename - the local log file * @param IniFilename - the local ini file * @param uniqueID - the id of the crash report associated with these files. * @return bool - true if successful */ public bool UploadFiles(string ProcessName, bool bWasAnEnsure, Int32 InProcessID, string LogFilename, string IniFilename, string MiniDumpFilename, string CrashVideoFilename, int uniqueID, OutputLogFile logFile) { logFile.WriteLine("Uploading files..."); logFile.WriteLine("\t" + LogFilename); logFile.WriteLine("\t" + IniFilename); logFile.WriteLine("\t" + MiniDumpFilename); logFile.WriteLine("\t" + CrashVideoFilename); Boolean bWasSuccessful = false; Boolean bUploadedLog = true; Boolean bUploadedVideo = true; Boolean bUploadedMiniDump = true; Boolean bCanAccessLog; Boolean bCanAccessVideo; Boolean bCanAccessMiniDump; bCanAccessLog = CanAccessFile(ProcessName, bWasAnEnsure, InProcessID, LogFilename, logFile); bCanAccessVideo = CanAccessFile(ProcessName, bWasAnEnsure, InProcessID, CrashVideoFilename, logFile); bCanAccessMiniDump = CanAccessFile(ProcessName, bWasAnEnsure, InProcessID, MiniDumpFilename, logFile); WebClient client = new WebClient(); // Send the Crash Id up so that the uploader can name the files correctly. // This used to save crash files to their own unique folder, but that method has been replaced with appending _<crashId> to the filename. client.Headers.Add("NewFolderName", uniqueID.ToString()); if (bCanAccessLog) { try { bUploadedLog = UploadFile("LogName", StripPath(LogFilename), LogFilename, logFile, client); } catch (NullReferenceException nrE) { bUploadedLog = false; logFile.WriteLine("Uploading " + LogFilename + " caused Null Reference Exception: " + nrE.Message); } } else { bUploadedLog = false; logFile.WriteLine("Could not access File: " + LogFilename); } // Upload Crash Video if (bCanAccessVideo) { try { bUploadedVideo = UploadFile("SaveFileName", "CrashVideo.avi", CrashVideoFilename, logFile, client); } catch (NullReferenceException nrE) { logFile.WriteLine("Uploading " + CrashVideoFilename + " caused Null Reference Exception: " + nrE.Message); } if (!bUploadedVideo) { string NetworkPath = @"\\devweb-02\ReportVideos\"; try { // Try copying over the network // \\devweb-02\ReportVideos if (!String.IsNullOrEmpty(CrashVideoFilename)) { logFile.WriteLine("Attempting to copy file " + CrashVideoFilename + " over the network to " + NetworkPath); File.Copy(CrashVideoFilename, NetworkPath + uniqueID.ToString() + "_" + StripPath(CrashVideoFilename)); bUploadedVideo = true; } else { logFile.WriteLine("Argument Null or Empty"); } } catch (Exception e) { logFile.WriteLine(e.ToString()); logFile.WriteLine("Couldn't copy crash video to network..."); try { File.Copy(CrashVideoFilename, CrashVideoFilename + "_" + uniqueID.ToString(), true); } catch (Exception copyFileException) { logFile.WriteLine(copyFileException.Message); logFile.WriteLine("Couldn't copy File " + CrashVideoFilename + ", continuing..."); } throw new Exception("Failed to upload Crash Video to " + NetworkPath + uniqueID.ToString() + "_" + StripPath(CrashVideoFilename) + "after a web and a network copy attempts"); } } } else { bUploadedVideo = false; var CheckFileInfo = new FileInfo(CrashVideoFilename); if (CheckFileInfo.Exists) { logFile.WriteLine("Could not access File: " + CrashVideoFilename); } else { logFile.WriteLine("File: " + CrashVideoFilename + " does not exist."); } } // Upload Minidump if (bCanAccessMiniDump) { try { bUploadedMiniDump = UploadFile("SaveFileName", "MiniDump.dmp", MiniDumpFilename, logFile, client); } catch (NullReferenceException nrE) { bUploadedMiniDump = false; logFile.WriteLine("Uploading " + MiniDumpFilename + " caused Null Reference Exception: " + nrE.Message); } } else { bUploadedMiniDump = false; logFile.WriteLine("Could not access File: " + LogFilename); } //Upload file successes try { ReportService.RegisterReport reportService = new ReportService.RegisterReport(); try { bWasSuccessful = reportService.AddCrashFiles(uniqueID, bUploadedLog, bUploadedMiniDump, bUploadedVideo); } catch (Exception e) { throw e; } } catch (WebException webEx) { logFile.WriteLine(webEx.Message); logFile.WriteLine(webEx.InnerException.Message); bWasSuccessful = false; } // Temporary - write out log file contents to autoreporter log logFile.WriteLine(""); logFile.WriteLine("----------"); logFile.WriteLine("Log file: " + LogFilename); logFile.WriteLine("----------"); Int32 FailCount = 0; bool bWroteLogFile = false; bool bFileExists = false; Int64 FileSize = 0; while ((FailCount < 10) && !bWroteLogFile) { FileInfo RealLogInfo = new FileInfo(LogFilename); bFileExists |= RealLogInfo.Exists; if (bFileExists) { try { FileSize = System.Math.Max(FileSize, RealLogInfo.Length); } catch (IOException) { logFile.WriteLine("Could not Access file: " + LogFilename + " to get it's size."); } } if (RealLogInfo.Exists && (FileSize > 0)) { using (StreamReader sr = RealLogInfo.OpenText()) { while (sr.Peek() > 0) { logFile.WriteLine(sr.ReadLine()); } } logFile.WriteLine("----------"); bWroteLogFile = true; } else { FailCount++; // Sleep for a second before trying again System.Threading.Thread.Sleep(1000); } } if (bWroteLogFile == false) { logFile.WriteLine("Attempted to write log file to autoreport log failed."); logFile.WriteLine("\tFile does " + (bFileExists ? "" : "NOT") + " Exist"); logFile.WriteLine("\tFile size = " + FileSize); } return(bWasSuccessful); }