public static void HbCrashEvent(object sender, CrashedEventArgs e) { if (e.ShutdownImminent.Equals(true)) { /* if (ConfigKey.HbSaverKey.Enabled()) { if (ConfigKey.HbSaverKey.Enabled()) { if (!File.Exists("heartbeatsaver.exe")) { Logger.Log(LogType.Warning, "heartbeatsaver.exe does not exist and failed to launch"); return; } //start the heartbeat saver Process HeartbeatSaver = new Process(); HeartbeatSaver.StartInfo.FileName = "heartbeatsaver.exe"; HeartbeatSaver.Start(); } }*/ } }
static void RaiseCrashedEvent( CrashedEventArgs e ) { var h = Crashed; if( h != null ) h( null, e ); }
const int MinCrashReportInterval = 61; // minimum interval between submitting crash reports, in seconds public static void LogAndReportCrash( [CanBeNull] string message, [CanBeNull] string assembly, [CanBeNull] Exception exception, bool shutdownImminent ) { if( message == null ) message = "(null)"; if( assembly == null ) assembly = "(null)"; if( exception == null ) exception = new Exception( "(null)" ); Log( LogType.SeriousError, "{0}: {1}", message, exception ); bool submitCrashReport = ConfigKey.SubmitCrashReports.Enabled(); bool isCommon = CheckForCommonErrors( exception ); try { var eventArgs = new CrashedEventArgs( message, assembly, exception, submitCrashReport && !isCommon, isCommon, shutdownImminent ); RaiseCrashedEvent( eventArgs ); isCommon = eventArgs.IsCommonProblem; } catch { } if( !submitCrashReport || isCommon ) { return; } lock( CrashReportLock ) { if( DateTime.UtcNow.Subtract( lastCrashReport ).TotalSeconds < MinCrashReportInterval ) { Log( LogType.Warning, "Logger.SubmitCrashReport: Could not submit crash report, reports too frequent." ); return; } lastCrashReport = DateTime.UtcNow; try { StringBuilder sb = new StringBuilder(); sb.Append( "version=" ).Append( Uri.EscapeDataString( Updater.CurrentRelease.VersionString ) ); sb.Append( "&message=" ).Append( Uri.EscapeDataString( message ) ); sb.Append( "&assembly=" ).Append( Uri.EscapeDataString( assembly ) ); sb.Append( "&runtime=" ); if( MonoCompat.IsMono ) { sb.Append( Uri.EscapeDataString( "Mono " + MonoCompat.MonoVersionString ) ); } else { sb.Append( Uri.EscapeDataString( "CLR " + Environment.Version ) ); } sb.Append( "&os=" ).Append( Environment.OSVersion.Platform + " / " + Environment.OSVersion.VersionString ); if( exception is TargetInvocationException ) { exception = (exception).InnerException; } else if( exception is TypeInitializationException ) { exception = (exception).InnerException; } sb.Append( "&exceptiontype=" ).Append( Uri.EscapeDataString( exception.GetType().ToString() ) ); sb.Append( "&exceptionmessage=" ).Append( Uri.EscapeDataString( exception.Message ) ); sb.Append( "&exceptionstacktrace=" ).Append( Uri.EscapeDataString( exception.StackTrace ) ); if( File.Exists( Paths.ConfigFileName ) ) { sb.Append( "&config=" ).Append( Uri.EscapeDataString( File.ReadAllText( Paths.ConfigFileName ) ) ); } else { sb.Append( "&config=" ); } string[] lastFewLines; lock( LogLock ) { lastFewLines = RecentMessages.ToArray(); } sb.Append( "&log=" ).Append( Uri.EscapeDataString( String.Join( Environment.NewLine, lastFewLines ) ) ); byte[] formData = Encoding.UTF8.GetBytes( sb.ToString() ); HttpWebRequest request = (HttpWebRequest)WebRequest.Create( CrashReportUri ); request.Method = "POST"; request.Timeout = 15000; // 15s timeout request.ContentType = "application/x-www-form-urlencoded"; request.CachePolicy = new RequestCachePolicy( RequestCacheLevel.NoCacheNoStore ); request.ContentLength = formData.Length; request.UserAgent = Updater.UserAgent; using( Stream requestStream = request.GetRequestStream() ) { requestStream.Write( formData, 0, formData.Length ); requestStream.Flush(); } string responseString; using( HttpWebResponse response = (HttpWebResponse)request.GetResponse() ) { using( Stream responseStream = response.GetResponseStream() ) { using( StreamReader reader = new StreamReader( responseStream ) ) { responseString = reader.ReadLine(); } } } request.Abort(); if( responseString != null && responseString.StartsWith( "ERROR" ) ) { Log( LogType.Error, "Crash report could not be processed by fCraft.net." ); } else { int referenceNumber; if( responseString != null && Int32.TryParse( responseString, out referenceNumber ) ) { Log( LogType.SystemActivity, "Crash report submitted (Reference #{0})", referenceNumber ); } else { Log( LogType.SystemActivity, "Crash report submitted." ); } } } catch( Exception ex ) { Log( LogType.Warning, "Logger.SubmitCrashReport: {0}", ex.Message ); } } }
/// <summary> Logs and reports a crash or an unhandled exception. /// Details are logged, and a crash report may be submitted to fCraft.net. /// Note that this method may take several seconds to finish, /// since it gathers system information and possibly communicates to fCraft.net. </summary> /// <param name="message"> Description/context of the crash. May be null if unknown. </param> /// <param name="assembly"> Assembly or component where the crash/exception was caught. May be null if unknown. </param> /// <param name="exception"> Exception. May be null. </param> /// <param name="shutdownImminent"> Whether this crash will likely report in a server shutdown. /// Used for Logger.Crashed event. </param> public static void LogAndReportCrash( [CanBeNull] string message, [CanBeNull] string assembly, [CanBeNull] Exception exception, bool shutdownImminent ) { if( message == null ) message = "(none)"; if( assembly == null ) assembly = "(none)"; if( exception == null ) exception = new Exception( "(none)" ); Log( LogType.SeriousError, "{0}: {1}", message, exception ); // see if crash report should be submitted or skipped, based on CheckForCommonErrors and Crashed event try { bool submitCrashReport = ConfigKey.SubmitCrashReports.Enabled(); bool isCommon = CheckForCommonErrors( exception ); try { var eventArgs = new CrashedEventArgs( message, assembly, exception, submitCrashReport && !isCommon, isCommon, shutdownImminent ); RaiseCrashedEvent( eventArgs ); isCommon = eventArgs.IsCommonProblem; } catch( Exception ex ) { Log( LogType.Error, "Crash reporter callback failure: {0}", ex ); } if( !submitCrashReport || isCommon ) { return; } } catch( Exception ex ) { Log( LogType.Error, "Crash reporter failure: {0}", ex ); } lock( CrashReportLock ) { // For compatibility with lighttpd server (that received crash reports) ServicePointManager.Expect100Continue = false; // Make sure tight errors-in-loops don't spam the reporter if( DateTime.UtcNow.Subtract( lastCrashReport ) < MinCrashReportInterval ) { Log( LogType.Warning, "Logger.SubmitCrashReport: Could not submit crash report, reports too frequent." ); return; } lastCrashReport = DateTime.UtcNow; LogAndReportCrashInner( message, assembly, exception ); } }
const int MinCrashReportInterval = 61; // minimum interval between submitting crash reports, in seconds /// <summary> Logs and reports a crash or an unhandled exception. /// Details are logged, and a crash report may be submitted to fCraft.net. /// Note that this method may take several seconds to finish, /// since it gathers system information and possibly communicates to fCraft.net. </summary> /// <param name="message"> Description/context of the crash. May be null if unknown. </param> /// <param name="assembly"> Assembly or component where the crash/exception was caught. May be null if unknown. </param> /// <param name="exception"> Exception. May be null. </param> /// <param name="shutdownImminent"> Whether this crash will likely report in a server shutdown. /// Used for Logger.Crashed event. </param> public static void LogAndReportCrash( [CanBeNull] string message, [CanBeNull] string assembly, [CanBeNull] Exception exception, bool shutdownImminent ) { if( message == null ) message = "(none)"; if( assembly == null ) assembly = "(none)"; if( exception == null ) exception = new Exception( "(none)" ); Log( LogType.SeriousError, "{0}: {1}", message, exception ); bool submitCrashReport = ConfigKey.SubmitCrashReports.Enabled(); bool isCommon = CheckForCommonErrors( exception ); try { var eventArgs = new CrashedEventArgs( message, assembly, exception, submitCrashReport && !isCommon, isCommon, shutdownImminent ); RaiseCrashedEvent( eventArgs ); isCommon = eventArgs.IsCommonProblem; } catch { } if( !submitCrashReport || isCommon ) { return; } lock( CrashReportLock ) { // For compatibility with lighttpd server (that received crash reports) ServicePointManager.Expect100Continue = false; if( DateTime.UtcNow.Subtract( lastCrashReport ).TotalSeconds < MinCrashReportInterval ) { Log( LogType.Warning, "Logger.SubmitCrashReport: Could not submit crash report, reports too frequent." ); return; } lastCrashReport = DateTime.UtcNow; LogAndReportCrashInner( message, assembly, exception ); } }
static void RaiseCrashedEvent( CrashedEventArgs e ) { var handler = Crashed; if( handler != null ) handler( null, e ); }
/// <summary> Logs and reports a crash or an unhandled exception. /// Details are logged, and a crash report may be submitted to fCraft.net. /// Note that this method may take several seconds to finish, /// since it gathers system information and possibly communicates to fCraft.net. </summary> /// <param name="message"> Description/context of the crash. May be null if unknown. </param> /// <param name="assembly"> Assembly or component where the crash/exception was caught. May be null if unknown. </param> /// <param name="exception"> Exception. May be null. </param> /// <param name="shutdownImminent"> Whether this crash will likely report in a server shutdown. /// Used for Logger.Crashed event. </param> public static void LogAndReportCrash( [CanBeNull] string message, [CanBeNull] string assembly, [CanBeNull] Exception exception, bool shutdownImminent ) { if( message == null ) message = "(none)"; if( assembly == null ) assembly = "(none)"; if( exception == null ) exception = new Exception( "(none)" ); Log( LogType.SeriousError, "{0}: {1}", message, exception ); bool isCommon = CheckForCommonErrors( exception ); try { var eventArgs = new CrashedEventArgs( message, assembly, exception, !isCommon, isCommon, shutdownImminent ); RaiseCrashedEvent( eventArgs ); isCommon = eventArgs.IsCommonProblem; } catch { } if( isCommon ) { return; } }