private void WriteLogToFile(bool WaitForLock) { if (string.IsNullOrEmpty(MyCurLog)) { return; } // ReSharper disable once EmptyEmbeddedStatement if (WaitForLock) { while (TheCommonUtils.cdeIsLocked(writeLock)) { ; // CODE REVIEW: This can go into a tight loop - should yield the thread or sleep for 1 few milliseconds before checking again } } if (!TheCommonUtils.cdeIsLocked(writeLock)) { lock (writeLock) { var bLogFileExists = System.IO.File.Exists(MyCurLog); if (MaxLogFileSize > 0 && bLogFileExists) { try { System.IO.FileInfo f2 = new System.IO.FileInfo(MyCurLog); if (f2.Length > MaxLogFileSize * (1024 * 1024)) { LogFilePath = mLogFilePath; System.IO.File.Move(MyCurLog, MySystemFileLogName); CheckFileRollover(); } } catch { //ignored } bLogFileExists = System.IO.File.Exists(MyCurLog); } try { using (System.IO.StreamWriter fs = new System.IO.StreamWriter(MyCurLog, bLogFileExists)) { foreach (TheEventLogEntry tLogs in MyMessageLog.MyMirrorCache.MyRecords.Values.Where(s => s.WasWritten == false).OrderBy(s => s.Serial).ToList()) //serial is more precise than CTIM { fs.WriteLine($"{tLogs.Source} : {tLogs.EventID} : {tLogs.Serial} : {tLogs.Message}"); //Serial is required to see the exact order of messages put in the log if the ms in the timestamp is the same tLogs.WasWritten = true; } } } catch { //ignored } } } }
/// <summary> /// Shutsdown the C-DEngine and all plugins /// Applications can override this function to add custom shutdown code /// </summary> /// <param name="ForceExit">If True and the C-DEngine will Stop or restart the hosting application. If it is hosted in IIS, the Application Pool hosting the app will be Stopped or Restarted depending on the next parameter</param> /// <param name="waitIfPending">Waits in case The shutdown is already initiated</param> public virtual void Shutdown(bool ForceExit, bool waitIfPending = false) { if (!waitIfPending) { if (!TheBaseAssets.MasterSwitch || TheCommonUtils.cdeIsLocked(ShutdownLock)) { return; //Make sure we dont do this twice } } lock (ShutdownLock) { if (TheBaseAssets.MasterSwitch) { if (TheBaseAssets.IsStarting) { TheBaseAssets.MySYSLOG?.WriteToLog(3, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM(TheBaseAssets.MyServiceHostInfo.ApplicationName, "Shutdown was requested, but startup has not finished. Waiting for startup to finish.", eMsgLevel.l3_ImportantMessage)); // Ensure we wait for user manager so CUOFS first-run-only settings are applied var sw = System.Diagnostics.Stopwatch.StartNew(); while (TheBaseAssets.IsStarting && sw.ElapsedMilliseconds < 60000) { Thread.Sleep(100); } if (TheBaseAssets.IsStarting) { TheBaseAssets.MySYSLOG?.WriteToLog(3, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(TheBaseAssets.MyServiceHostInfo.ApplicationName, "Shutdown was requested, but startup has not finished after wait time (60 seconds). Shutting down regardless. Some first-run-only settings may not have been applied.", eMsgLevel.l1_Error)); } } if (TheBaseAssets.MyServiceHostInfo.PreShutDownDelay > 0) { var tcsPreHandlers = new TaskCompletionSource <bool>(); TheCommonUtils.cdeRunAsync("PreShutdownHandlers", true, (o) => { TheCDEngines.MyContentEngine?.FireEvent(eEngineEvents.PreShutdown, null, TheBaseAssets.MyServiceHostInfo.PreShutDownDelay, false); tcsPreHandlers.TrySetResult(true); }); tcsPreHandlers.Task.Wait(TheBaseAssets.MyServiceHostInfo.PreShutDownDelay); } while (Interlocked.Read(ref TheBaseAssets.DelayShutDownCount) > 0) { TheCommonUtils.SleepOneEye(100, 100); } TheBaseAssets.MySYSLOG?.WriteToLog(3, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(TheBaseAssets.MyServiceHostInfo.ApplicationName, TheBaseAssets.MyServiceHostInfo.ApplicationTitle + " Initiating shutdown at : " + TheCommonUtils.GetDateTimeString(DateTimeOffset.Now), eMsgLevel.l6_Debug)); TheBaseAssets.MasterSwitch = false; TheBaseAssets.ForceShutdown = ForceExit; TheCDEngines.StopAllEngines(); TheBaseAssets.MySYSLOG?.WriteToLog(3, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(TheBaseAssets.MyServiceHostInfo.ApplicationName, TheBaseAssets.MyServiceHostInfo.ApplicationTitle + " Shutdown: Engines stopped at: " + TheCommonUtils.GetDateTimeString(DateTimeOffset.Now), eMsgLevel.l6_Debug)); TheCommCore.StopCommunication(); TheBaseAssets.MySYSLOG?.WriteToLog(3, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(TheBaseAssets.MyServiceHostInfo.ApplicationName, TheBaseAssets.MyServiceHostInfo.ApplicationTitle + " Shutdown: Communications stopped at: " + TheCommonUtils.GetDateTimeString(DateTimeOffset.Now), eMsgLevel.l6_Debug)); if (MyCommonDisco != null) { MyCommonDisco.ShutdownDiscoService(); TheBaseAssets.MySYSLOG?.WriteToLog(3, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(TheBaseAssets.MyServiceHostInfo.ApplicationName, TheBaseAssets.MyServiceHostInfo.ApplicationTitle + " Shutdown: Discovery Service stopped at: " + TheCommonUtils.GetDateTimeString(DateTimeOffset.Now), eMsgLevel.l6_Debug)); } if (TheBaseAssets.MySYSLOG != null) { string iis = ""; switch (TheBaseAssets.MyServiceHostInfo.cdeHostingType) { case cdeHostType.IIS: iis = " (Hosted in IIS)"; break; case cdeHostType.ASPCore: iis = " (Hosted in ASP.NET Core)"; break; } TheBaseAssets.MySYSLOG.WriteToLog(3, new TSM(TheBaseAssets.MyServiceHostInfo.ApplicationName, TheBaseAssets.MyServiceHostInfo.ApplicationTitle + iis + " Stopped at : " + TheCommonUtils.GetDateTimeString(DateTimeOffset.Now), eMsgLevel.l4_Message)); //Log Entry that service has been started TheBaseAssets.MySYSLOG.Shutdown(); } } } }