mirror of https://github.com/winsw/winsw
				
				
				
			Reduce event log entries
							parent
							
								
									d90151b02f
								
							
						
					
					
						commit
						274deddfef
					
				| 
						 | 
				
			
			@ -9,9 +9,9 @@ namespace WinSW
 | 
			
		|||
{
 | 
			
		||||
    public interface IEventLogger
 | 
			
		||||
    {
 | 
			
		||||
        void LogEvent(string message);
 | 
			
		||||
        void WriteEntry(string message);
 | 
			
		||||
 | 
			
		||||
        void LogEvent(string message, EventLogEntryType type);
 | 
			
		||||
        void WriteEntry(string message, EventLogEntryType type);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
| 
						 | 
				
			
			@ -54,7 +54,7 @@ namespace WinSW
 | 
			
		|||
            }
 | 
			
		||||
            catch (IOException e)
 | 
			
		||||
            {
 | 
			
		||||
                this.EventLogger.LogEvent("Failed to move :" + sourceFileName + " to " + destFileName + " because " + e.Message);
 | 
			
		||||
                this.EventLogger.WriteEntry("Failed to move :" + sourceFileName + " to " + destFileName + " because " + e.Message);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -118,7 +118,7 @@ namespace WinSW
 | 
			
		|||
            }
 | 
			
		||||
            catch (Exception e)
 | 
			
		||||
            {
 | 
			
		||||
                this.EventLogger.LogEvent("Unhandled exception in task. " + e, EventLogEntryType.Error);
 | 
			
		||||
                this.EventLogger.WriteEntry("Unhandled exception in task. " + e, EventLogEntryType.Error);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -130,7 +130,7 @@ namespace WinSW
 | 
			
		|||
            }
 | 
			
		||||
            catch (Exception e)
 | 
			
		||||
            {
 | 
			
		||||
                this.EventLogger.LogEvent("Unhandled exception in task. " + e, EventLogEntryType.Error);
 | 
			
		||||
                this.EventLogger.WriteEntry("Unhandled exception in task. " + e, EventLogEntryType.Error);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -309,7 +309,7 @@ namespace WinSW
 | 
			
		|||
                    }
 | 
			
		||||
                    catch (IOException e)
 | 
			
		||||
                    {
 | 
			
		||||
                        this.EventLogger.LogEvent("Failed to roll log: " + e.Message);
 | 
			
		||||
                        this.EventLogger.WriteEntry("Failed to roll log: " + e.Message);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // even if the log rotation fails, create a new one, or else
 | 
			
		||||
| 
						 | 
				
			
			@ -439,7 +439,7 @@ namespace WinSW
 | 
			
		|||
                    }
 | 
			
		||||
                    catch (Exception ex)
 | 
			
		||||
                    {
 | 
			
		||||
                        this.EventLogger.LogEvent($"Failed to to trigger auto roll at time event due to: {ex.Message}");
 | 
			
		||||
                        this.EventLogger.WriteEntry($"Failed to to trigger auto roll at time event due to: {ex.Message}");
 | 
			
		||||
                    }
 | 
			
		||||
                    finally
 | 
			
		||||
                    {
 | 
			
		||||
| 
						 | 
				
			
			@ -476,7 +476,7 @@ namespace WinSW
 | 
			
		|||
                        }
 | 
			
		||||
                        catch (Exception e)
 | 
			
		||||
                        {
 | 
			
		||||
                            this.EventLogger.LogEvent($"Failed to roll size time log: {e.Message}");
 | 
			
		||||
                            this.EventLogger.WriteEntry($"Failed to roll size time log: {e.Message}");
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -516,7 +516,7 @@ namespace WinSW
 | 
			
		|||
            }
 | 
			
		||||
            catch (Exception e)
 | 
			
		||||
            {
 | 
			
		||||
                this.EventLogger.LogEvent($"Failed to Zip files. Error {e.Message}");
 | 
			
		||||
                this.EventLogger.WriteEntry($"Failed to Zip files. Error {e.Message}");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -534,7 +534,7 @@ namespace WinSW
 | 
			
		|||
            }
 | 
			
		||||
            catch (Exception e)
 | 
			
		||||
            {
 | 
			
		||||
                this.EventLogger.LogEvent($"Failed to Zip the File {sourceFilePath}. Error {e.Message}");
 | 
			
		||||
                this.EventLogger.WriteEntry($"Failed to Zip the File {sourceFilePath}. Error {e.Message}");
 | 
			
		||||
            }
 | 
			
		||||
            finally
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,7 +13,7 @@ namespace WinSW.Util
 | 
			
		|||
 | 
			
		||||
        public static void StopTree(this Process process, TimeSpan stopTimeout)
 | 
			
		||||
        {
 | 
			
		||||
            Stop(process, stopTimeout);
 | 
			
		||||
            StopPrivate(process, stopTimeout);
 | 
			
		||||
 | 
			
		||||
            foreach (Process child in GetChildren(process))
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			@ -81,7 +81,37 @@ namespace WinSW.Util
 | 
			
		|||
            return children;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static void Stop(Process process, TimeSpan stopTimeout)
 | 
			
		||||
        // true  => canceled
 | 
			
		||||
        // false => terminated
 | 
			
		||||
        // null  => finished
 | 
			
		||||
        internal static bool? Stop(this Process process, TimeSpan stopTimeout)
 | 
			
		||||
        {
 | 
			
		||||
            if (process.HasExited)
 | 
			
		||||
            {
 | 
			
		||||
                return null;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // (bool sent, bool exited)
 | 
			
		||||
            KeyValuePair<bool, bool> result = SignalHelper.SendCtrlCToProcess(process, stopTimeout);
 | 
			
		||||
            bool exited = result.Value;
 | 
			
		||||
            if (exited)
 | 
			
		||||
            {
 | 
			
		||||
                bool sent = result.Key;
 | 
			
		||||
                return sent ? true : (bool?)null;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                process.Kill();
 | 
			
		||||
            }
 | 
			
		||||
            catch when (process.HasExited)
 | 
			
		||||
            {
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static void StopPrivate(Process process, TimeSpan stopTimeout)
 | 
			
		||||
        {
 | 
			
		||||
            Logger.Info("Stopping process " + process.Id);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,7 +18,7 @@ namespace WinSW.Util
 | 
			
		|||
            if (!ConsoleApis.AttachConsole(process.Id))
 | 
			
		||||
            {
 | 
			
		||||
                int error = Marshal.GetLastWin32Error();
 | 
			
		||||
                Logger.Warn("Failed to attach to console. " + error switch
 | 
			
		||||
                Logger.Info("Failed to attach to console. " + error switch
 | 
			
		||||
                {
 | 
			
		||||
                    Errors.ERROR_ACCESS_DENIED => "WinSW is already attached to a console.", // TODO: test mode
 | 
			
		||||
                    Errors.ERROR_INVALID_HANDLE => "The process does not have a console.",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,11 +34,6 @@ namespace WinSW
 | 
			
		|||
 | 
			
		||||
        internal WinSWExtensionManager ExtensionManager { get; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Indicates to the watch dog thread that we are going to terminate the process,
 | 
			
		||||
        /// so don't try to kill us when the child exits.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        private volatile bool orderlyShutdown;
 | 
			
		||||
        private bool shuttingdown;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
| 
						 | 
				
			
			@ -51,14 +46,12 @@ namespace WinSW
 | 
			
		|||
 | 
			
		||||
        public WrapperService(XmlServiceConfig config)
 | 
			
		||||
        {
 | 
			
		||||
            this.config = config;
 | 
			
		||||
            this.ServiceName = config.Id;
 | 
			
		||||
            this.ExtensionManager = new WinSWExtensionManager(config);
 | 
			
		||||
            this.CanShutdown = true;
 | 
			
		||||
            this.CanStop = true;
 | 
			
		||||
            this.CanPauseAndContinue = false;
 | 
			
		||||
            this.AutoLog = true;
 | 
			
		||||
            this.shuttingdown = false;
 | 
			
		||||
            this.AutoLog = false;
 | 
			
		||||
 | 
			
		||||
            this.config = config;
 | 
			
		||||
            this.ExtensionManager = new WinSWExtensionManager(config);
 | 
			
		||||
 | 
			
		||||
            // Register the event log provider
 | 
			
		||||
            eventLogProvider.Service = this;
 | 
			
		||||
| 
						 | 
				
			
			@ -89,7 +82,7 @@ namespace WinSW
 | 
			
		|||
                string? line;
 | 
			
		||||
                while ((line = tr.ReadLine()) != null)
 | 
			
		||||
                {
 | 
			
		||||
                    this.LogInfo("Handling copy: " + line);
 | 
			
		||||
                    Log.Info("Handling copy: " + line);
 | 
			
		||||
                    string[] tokens = line.Split('>');
 | 
			
		||||
                    if (tokens.Length > 2)
 | 
			
		||||
                    {
 | 
			
		||||
| 
						 | 
				
			
			@ -139,7 +132,7 @@ namespace WinSW
 | 
			
		|||
            return logAppender;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void LogEvent(string message)
 | 
			
		||||
        public void WriteEntry(string message)
 | 
			
		||||
        {
 | 
			
		||||
            if (this.shuttingdown)
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			@ -157,7 +150,7 @@ namespace WinSW
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void LogEvent(string message, EventLogEntryType type)
 | 
			
		||||
        public void WriteEntry(string message, EventLogEntryType type)
 | 
			
		||||
        {
 | 
			
		||||
            if (this.shuttingdown)
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			@ -186,9 +179,21 @@ namespace WinSW
 | 
			
		|||
            this.EventLog.WriteEntry(message, type);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void LogInfo(string message)
 | 
			
		||||
        private void LogExited(string message, int exitCode)
 | 
			
		||||
        {
 | 
			
		||||
            this.LogEvent(message);
 | 
			
		||||
            if (exitCode == 0)
 | 
			
		||||
            {
 | 
			
		||||
                Log.Info(message);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                Log.Warn(message);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void LogMinimal(string message)
 | 
			
		||||
        {
 | 
			
		||||
            this.WriteEntry(message);
 | 
			
		||||
            Log.Info(message);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -201,6 +206,7 @@ namespace WinSW
 | 
			
		|||
            try
 | 
			
		||||
            {
 | 
			
		||||
                this.DoStart();
 | 
			
		||||
                this.LogMinimal("Service started successfully.");
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception e)
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			@ -214,6 +220,7 @@ namespace WinSW
 | 
			
		|||
            try
 | 
			
		||||
            {
 | 
			
		||||
                this.DoStop();
 | 
			
		||||
                this.LogMinimal("Service stopped successfully.");
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception e)
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			@ -228,6 +235,7 @@ namespace WinSW
 | 
			
		|||
            {
 | 
			
		||||
                this.shuttingdown = true;
 | 
			
		||||
                this.DoStop();
 | 
			
		||||
                this.LogMinimal("Service was shut down successfully.");
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception e)
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			@ -256,7 +264,7 @@ namespace WinSW
 | 
			
		|||
            {
 | 
			
		||||
                Download download = downloads[i];
 | 
			
		||||
                string downloadMessage = $"Downloading: {download.From} to {download.To}. failOnError={download.FailOnError.ToString()}";
 | 
			
		||||
                this.LogInfo(downloadMessage);
 | 
			
		||||
                Log.Info(downloadMessage);
 | 
			
		||||
                tasks[i] = download.PerformAsync();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -294,7 +302,7 @@ namespace WinSW
 | 
			
		|||
                {
 | 
			
		||||
                    using Process process = this.StartProcess(prestartExecutable, this.config.PrestartArguments);
 | 
			
		||||
                    this.WaitForProcessToExit(process);
 | 
			
		||||
                    this.LogInfo($"Pre-start process '{process.Format()}' exited with code {process.ExitCode}.");
 | 
			
		||||
                    this.LogExited($"Pre-start process '{process.Format()}' exited with code {process.ExitCode}.", process.ExitCode);
 | 
			
		||||
                    process.StopDescendants(additionalStopTimeout);
 | 
			
		||||
                }
 | 
			
		||||
                catch (Exception e)
 | 
			
		||||
| 
						 | 
				
			
			@ -305,7 +313,7 @@ namespace WinSW
 | 
			
		|||
 | 
			
		||||
            string startArguments = this.config.StartArguments ?? this.config.Arguments;
 | 
			
		||||
 | 
			
		||||
            this.LogInfo("Starting " + this.config.Executable);
 | 
			
		||||
            Log.Info("Starting " + this.config.Executable);
 | 
			
		||||
 | 
			
		||||
            // Load and start extensions
 | 
			
		||||
            this.ExtensionManager.LoadExtensions();
 | 
			
		||||
| 
						 | 
				
			
			@ -322,7 +330,7 @@ namespace WinSW
 | 
			
		|||
                {
 | 
			
		||||
                    using Process process = StartProcessLocked();
 | 
			
		||||
                    this.WaitForProcessToExit(process);
 | 
			
		||||
                    this.LogInfo($"Post-start process '{process.Format()}' exited with code {process.ExitCode}.");
 | 
			
		||||
                    this.LogExited($"Post-start process '{process.Format()}' exited with code {process.ExitCode}.", process.ExitCode);
 | 
			
		||||
                    process.StopDescendants(additionalStopTimeout);
 | 
			
		||||
                    this.startingProcess = null;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -353,7 +361,7 @@ namespace WinSW
 | 
			
		|||
                {
 | 
			
		||||
                    using Process process = StartProcessLocked(prestopExecutable, this.config.PrestopArguments);
 | 
			
		||||
                    this.WaitForProcessToExit(process);
 | 
			
		||||
                    this.LogInfo($"Pre-stop process '{process.Format()}' exited with code {process.ExitCode}.");
 | 
			
		||||
                    this.LogExited($"Pre-stop process '{process.Format()}' exited with code {process.ExitCode}.", process.ExitCode);
 | 
			
		||||
                    process.StopDescendants(additionalStopTimeout);
 | 
			
		||||
                    this.stoppingProcess = null;
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -363,16 +371,24 @@ namespace WinSW
 | 
			
		|||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this.LogInfo("Stopping " + this.config.Id);
 | 
			
		||||
            this.orderlyShutdown = true;
 | 
			
		||||
            Log.Info("Stopping " + this.config.Id);
 | 
			
		||||
            this.process.EnableRaisingEvents = false;
 | 
			
		||||
 | 
			
		||||
            string? stopExecutable = this.config.StopExecutable;
 | 
			
		||||
            string? stopArguments = this.config.StopArguments;
 | 
			
		||||
            if (stopExecutable is null && stopArguments is null)
 | 
			
		||||
            {
 | 
			
		||||
                Log.Debug("ProcessKill " + this.process.Id);
 | 
			
		||||
                this.process.StopTree(this.config.StopTimeout);
 | 
			
		||||
                this.ExtensionManager.FireOnProcessTerminated(this.process);
 | 
			
		||||
                Process process = this.process;
 | 
			
		||||
                Log.Debug("ProcessKill " + process.Id);
 | 
			
		||||
                bool? result = process.Stop(this.config.StopTimeout);
 | 
			
		||||
                this.LogMinimal($"Child process '{process.Format()}' " + result switch
 | 
			
		||||
                {
 | 
			
		||||
                    true => $"canceled with code {process.ExitCode}.",
 | 
			
		||||
                    false => "terminated.",
 | 
			
		||||
                    null => $"finished with code '{process.ExitCode}'."
 | 
			
		||||
                });
 | 
			
		||||
                this.process.StopDescendants(this.config.StopTimeout);
 | 
			
		||||
                this.ExtensionManager.FireOnProcessTerminated(process);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			@ -407,7 +423,7 @@ namespace WinSW
 | 
			
		|||
                {
 | 
			
		||||
                    using Process process = StartProcessLocked(poststopExecutable, this.config.PoststopArguments);
 | 
			
		||||
                    this.WaitForProcessToExit(process);
 | 
			
		||||
                    this.LogInfo($"Post-stop process '{process.Format()}' exited with code {process.ExitCode}.");
 | 
			
		||||
                    this.LogExited($"Post-Stop process '{process.Format()}' exited with code {process.ExitCode}.", process.ExitCode);
 | 
			
		||||
                    process.StopDescendants(additionalStopTimeout);
 | 
			
		||||
                    this.stoppingProcess = null;
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -483,40 +499,29 @@ namespace WinSW
 | 
			
		|||
 | 
			
		||||
        private void OnMainProcessExited(Process process)
 | 
			
		||||
        {
 | 
			
		||||
            string display = process.Format();
 | 
			
		||||
 | 
			
		||||
            if (this.orderlyShutdown)
 | 
			
		||||
            lock (this)
 | 
			
		||||
            {
 | 
			
		||||
                this.LogInfo($"Child process '{display}' terminated.");
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                Log.Warn($"Child process '{display}' finished with code {process.ExitCode}.");
 | 
			
		||||
 | 
			
		||||
                process.StopDescendants(this.config.StopTimeout);
 | 
			
		||||
 | 
			
		||||
                lock (this)
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    Log.Warn($"Child process '{process.Format()}' finished with code {process.ExitCode}.");
 | 
			
		||||
 | 
			
		||||
                    process.StopDescendants(this.config.StopTimeout);
 | 
			
		||||
 | 
			
		||||
                    this.startingProcess?.StopTree(additionalStopTimeout);
 | 
			
		||||
                    this.stoppingProcess?.StopTree(additionalStopTimeout);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // if we finished orderly, report that to SCM.
 | 
			
		||||
                // by not reporting unclean shutdown, we let Windows SCM to decide if it wants to
 | 
			
		||||
                // restart the service automatically
 | 
			
		||||
                if (process.ExitCode == 0)
 | 
			
		||||
                {
 | 
			
		||||
                    try
 | 
			
		||||
                    // if we finished orderly, report that to SCM.
 | 
			
		||||
                    // by not reporting unclean shutdown, we let Windows SCM to decide if it wants to
 | 
			
		||||
                    // restart the service automatically
 | 
			
		||||
                    if (process.ExitCode == 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        this.SignalStopped();
 | 
			
		||||
                    }
 | 
			
		||||
                    catch (Exception e)
 | 
			
		||||
                    {
 | 
			
		||||
                        Log.Error(e);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                Environment.Exit(process.ExitCode);
 | 
			
		||||
                finally
 | 
			
		||||
                {
 | 
			
		||||
                    Environment.Exit(process.ExitCode);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue