mirror of https://github.com/winsw/winsw
Logging subsystem refactoring - use log4net (#145)
* Save the progress * Add log4net Log appender for Windows service events * Get rid of the IEventLogger API, we use log4net nowpull/165/head
parent
2db4fb2c31
commit
12c16e40a7
|
@ -0,0 +1,28 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using winsw.Logging;
|
||||
|
||||
namespace winsw.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements caching of the WindowsService reference in WinSW.
|
||||
/// </summary>
|
||||
public class WrapperServiceEventLogProvider : IServiceEventLogProvider
|
||||
{
|
||||
public WrapperService service {get; set;}
|
||||
|
||||
public EventLog locate()
|
||||
{
|
||||
WrapperService _service = service;
|
||||
if (_service != null && !_service.IsShuttingDown)
|
||||
{
|
||||
return _service.EventLog;
|
||||
}
|
||||
|
||||
// By default return null
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,10 +20,11 @@ using WMI;
|
|||
using ServiceType = WMI.ServiceType;
|
||||
using winsw.Native;
|
||||
using System.Reflection;
|
||||
using winsw.Logging;
|
||||
|
||||
namespace winsw
|
||||
{
|
||||
public class WrapperService : ServiceBase, EventLogger, IEventWriter
|
||||
public class WrapperService : ServiceBase, EventLogger
|
||||
{
|
||||
private SERVICE_STATUS _wrapperServiceStatus;
|
||||
|
||||
|
@ -34,6 +35,7 @@ namespace winsw
|
|||
internal WinSWExtensionManager ExtensionManager { private set; get; }
|
||||
|
||||
private static readonly ILog Log = LogManager.GetLogger("WinSW");
|
||||
private static readonly WrapperServiceEventLogProvider eventLogProvider = new WrapperServiceEventLogProvider();
|
||||
|
||||
/// <summary>
|
||||
/// Indicates to the watch dog thread that we are going to terminate the process,
|
||||
|
@ -53,6 +55,13 @@ namespace winsw
|
|||
get { return Assembly.GetExecutingAssembly().GetName().Version; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the system is shutting down.
|
||||
/// </summary>
|
||||
public bool IsShuttingDown {
|
||||
get { return _systemShuttingdown; }
|
||||
}
|
||||
|
||||
public WrapperService(ServiceDescriptor descriptor)
|
||||
{
|
||||
_descriptor = descriptor;
|
||||
|
@ -63,6 +72,9 @@ namespace winsw
|
|||
CanPauseAndContinue = false;
|
||||
AutoLog = true;
|
||||
_systemShuttingdown = false;
|
||||
|
||||
// Register the event log provider
|
||||
eventLogProvider.service = this;
|
||||
}
|
||||
|
||||
public WrapperService() : this (new ServiceDescriptor())
|
||||
|
@ -135,7 +147,7 @@ namespace winsw
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
WriteEvent("Thread failed unexpectedly",e);
|
||||
Log.Error("Thread failed unexpectedly",e);
|
||||
}
|
||||
}).Start();
|
||||
}
|
||||
|
@ -171,7 +183,7 @@ namespace winsw
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
WriteEvent("Failed to log event in Windows Event Log: " + message + "; Reason: ", e);
|
||||
Log.Error("Failed to log event in Windows Event Log: " + message + "; Reason: ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -190,28 +202,11 @@ namespace winsw
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
WriteEvent("Failed to log event in Windows Event Log. Reason: ", e);
|
||||
Log.Error("Failed to log event in Windows Event Log. Reason: ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteEvent(Exception exception)
|
||||
{
|
||||
//TODO: pass exception to logger
|
||||
WriteEvent(exception.Message + "\nStacktrace:" + exception.StackTrace, Level.Error);
|
||||
}
|
||||
|
||||
private void WriteEvent(String message, Exception exception)
|
||||
{
|
||||
//TODO: pass exception to logger
|
||||
WriteEvent(message + "\nMessage:" + exception.Message + "\nStacktrace:" + exception.StackTrace, Level.Error);
|
||||
}
|
||||
|
||||
private void WriteEvent(String message, Level logLevel = null, Exception ex = null)
|
||||
{
|
||||
Log.Logger.Log(GetType(), logLevel ?? Level.Info, message, ex);
|
||||
}
|
||||
|
||||
protected override void OnStart(string[] _)
|
||||
{
|
||||
_envs = _descriptor.EnvironmentVariables;
|
||||
|
@ -233,7 +228,7 @@ namespace winsw
|
|||
catch (Exception e)
|
||||
{
|
||||
LogEvent("Failed to download " + d.From + " to " + d.To + "\n" + e.Message);
|
||||
WriteEvent("Failed to download " + d.From +" to "+d.To, e);
|
||||
Log.Error("Failed to download " + d.From +" to "+d.To, e);
|
||||
// but just keep going
|
||||
}
|
||||
}
|
||||
|
@ -250,23 +245,14 @@ namespace winsw
|
|||
}
|
||||
|
||||
LogEvent("Starting " + _descriptor.Executable + ' ' + startarguments);
|
||||
WriteEvent("Starting " + _descriptor.Executable + ' ' + startarguments);
|
||||
Log.Info("Starting " + _descriptor.Executable + ' ' + startarguments);
|
||||
|
||||
// Load and start extensions
|
||||
ExtensionManager.LoadExtensions(this);
|
||||
try
|
||||
{
|
||||
ExtensionManager.OnStart(this);
|
||||
}
|
||||
catch (ExtensionException ex)
|
||||
{
|
||||
LogEvent("Failed to start extension " + ex.ExtensionId + "\n" + ex.Message, EventLogEntryType.Error);
|
||||
WriteEvent("Failed to start extension " + ex.ExtensionId, ex);
|
||||
//TODO: Exit on error?
|
||||
}
|
||||
ExtensionManager.LoadExtensions();
|
||||
ExtensionManager.FireOnWrapperStarted();
|
||||
|
||||
LogEvent("Starting " + _descriptor.Executable + ' ' + startarguments);
|
||||
WriteEvent("Starting " + _descriptor.Executable + ' ' + startarguments);
|
||||
Log.Info("Starting " + _descriptor.Executable + ' ' + startarguments);
|
||||
|
||||
StartProcess(_process, startarguments, _descriptor.Executable);
|
||||
ExtensionManager.FireOnProcessStarted(_process);
|
||||
|
@ -288,7 +274,7 @@ namespace winsw
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
WriteEvent("Shutdown exception", ex);
|
||||
Log.Error("Shutdown exception", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -302,7 +288,7 @@ namespace winsw
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
WriteEvent("Stop exception", ex);
|
||||
Log.Error("Cannot stop exception", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -313,14 +299,14 @@ namespace winsw
|
|||
{
|
||||
string stoparguments = _descriptor.Stoparguments;
|
||||
LogEvent("Stopping " + _descriptor.Id);
|
||||
WriteEvent("Stopping " + _descriptor.Id);
|
||||
Log.Info("Stopping " + _descriptor.Id);
|
||||
_orderlyShutdown = true;
|
||||
|
||||
if (stoparguments == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
WriteEvent("ProcessKill " + _process.Id);
|
||||
Log.Debug("ProcessKill " + _process.Id);
|
||||
ProcessHelper.StopProcessAndChildren(_process.Id, _descriptor.StopTimeout, _descriptor.StopParentProcessFirst);
|
||||
ExtensionManager.FireOnProcessTerminated(_process);
|
||||
}
|
||||
|
@ -345,29 +331,21 @@ namespace winsw
|
|||
|
||||
StartProcess(stopProcess, stoparguments, executable);
|
||||
|
||||
WriteEvent("WaitForProcessToExit "+_process.Id+"+"+stopProcess.Id);
|
||||
Log.Debug("WaitForProcessToExit " + _process.Id + "+" + stopProcess.Id);
|
||||
WaitForProcessToExit(_process);
|
||||
WaitForProcessToExit(stopProcess);
|
||||
SignalShutdownComplete();
|
||||
}
|
||||
|
||||
// Stop extensions
|
||||
try
|
||||
{
|
||||
ExtensionManager.OnStop(this);
|
||||
}
|
||||
catch (ExtensionException ex)
|
||||
{
|
||||
LogEvent("Failed to stop extension " + ex.ExtensionId + "\n" + ex.Message, EventLogEntryType.Error);
|
||||
WriteEvent("Failed to stop extension " + ex.ExtensionId, ex);
|
||||
}
|
||||
ExtensionManager.FireBeforeWrapperStopped();
|
||||
|
||||
if (_systemShuttingdown && _descriptor.BeepOnShutdown)
|
||||
{
|
||||
Console.Beep();
|
||||
}
|
||||
|
||||
WriteEvent("Finished " + _descriptor.Id);
|
||||
Log.Info("Finished " + _descriptor.Id);
|
||||
}
|
||||
|
||||
private void WaitForProcessToExit(Process processoWait)
|
||||
|
@ -458,7 +436,7 @@ namespace winsw
|
|||
ps.EnvironmentVariables[WinSWSystem.ENVVAR_NAME_SERVICE_ID.ToLower()] = _descriptor.Id;
|
||||
|
||||
processToStart.Start();
|
||||
WriteEvent("Started " + processToStart.Id);
|
||||
Log.Info("Started " + processToStart.Id);
|
||||
|
||||
var priority = _descriptor.Priority;
|
||||
if (priority != ProcessPriorityClass.Normal)
|
||||
|
@ -509,6 +487,7 @@ namespace winsw
|
|||
try
|
||||
{
|
||||
Run(args);
|
||||
Log.Info("Completed. Exit code is 0");
|
||||
return 0;
|
||||
}
|
||||
catch (WmiException e)
|
||||
|
@ -554,7 +533,7 @@ namespace winsw
|
|||
|
||||
if (isCLIMode) // CLI mode, in-service mode otherwise
|
||||
{
|
||||
Log.Debug("Starting ServiceWrapper in CLI mode");
|
||||
Log.Info("Starting ServiceWrapper in the CLI mode");
|
||||
|
||||
// Get service info for the future use
|
||||
Win32Services svc = new WmiRoot().GetCollection<Win32Services>();
|
||||
|
@ -761,17 +740,25 @@ namespace winsw
|
|||
throw new Exception("Unknown command: " + args[0]);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Info("Starting ServiceWrapper in the service mode");
|
||||
}
|
||||
Run(new WrapperService());
|
||||
}
|
||||
|
||||
private static void InitLoggers(ServiceDescriptor d, bool enableCLILogging)
|
||||
{
|
||||
// TODO: Make logging levels configurable
|
||||
Level logLevel = Level.Debug;
|
||||
Level eventLogLevel = Level.Warn;
|
||||
|
||||
// Legacy format from winsw-1.x: (DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " - " + message);
|
||||
PatternLayout pl = new PatternLayout { ConversionPattern = "%d %-5p - %m%n" };
|
||||
pl.ActivateOptions();
|
||||
|
||||
List<IAppender> appenders = new List<IAppender>();
|
||||
|
||||
// wrapper.log
|
||||
String wrapperLogPath = Path.Combine(d.LogDirectory, d.BaseName + ".wrapper.log");
|
||||
var wrapperLog = new FileAppender
|
||||
|
@ -785,7 +772,7 @@ namespace winsw
|
|||
Layout = pl
|
||||
};
|
||||
wrapperLog.ActivateOptions();
|
||||
BasicConfigurator.Configure(wrapperLog);
|
||||
appenders.Add(wrapperLog);
|
||||
|
||||
// Also display logs in CLI if required
|
||||
if (enableCLILogging)
|
||||
|
@ -794,11 +781,23 @@ namespace winsw
|
|||
{
|
||||
Name = "Wrapper console log",
|
||||
Threshold = logLevel,
|
||||
Layout = pl
|
||||
Layout = pl,
|
||||
};
|
||||
consoleAppender.ActivateOptions();
|
||||
((Logger)Log.Logger).AddAppender(consoleAppender);
|
||||
appenders.Add(consoleAppender);
|
||||
}
|
||||
|
||||
// System log
|
||||
var systemEventLogger = new ServiceEventLogAppender
|
||||
{
|
||||
Name = "System event log",
|
||||
Threshold = eventLogLevel,
|
||||
provider = eventLogProvider
|
||||
};
|
||||
systemEventLogger.ActivateOptions();
|
||||
appenders.Add(systemEventLogger);
|
||||
|
||||
BasicConfigurator.Configure(appenders.ToArray());
|
||||
}
|
||||
|
||||
private static string ReadPassword()
|
||||
|
|
|
@ -79,6 +79,7 @@
|
|||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SigIntHelper.cs" />
|
||||
<Compile Include="Logging\WrapperServiceEventLogProvider.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="manifest.xml" />
|
||||
|
|
|
@ -9,17 +9,17 @@ namespace winsw.Extensions
|
|||
public abstract String DisplayName { get; }
|
||||
public WinSWExtensionDescriptor Descriptor { get; set; }
|
||||
|
||||
public virtual void Configure(ServiceDescriptor descriptor, XmlNode node, IEventWriter logger)
|
||||
public virtual void Configure(ServiceDescriptor descriptor, XmlNode node)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
public virtual void OnStart(IEventWriter eventWriter)
|
||||
public virtual void OnWrapperStarted()
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
public virtual void OnStop(IEventWriter eventWriter)
|
||||
public virtual void BeforeWrapperStopped()
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
|
|
@ -29,14 +29,14 @@ namespace winsw.Extensions
|
|||
/// </summary>
|
||||
/// <param name="descriptor">Service descriptor</param>
|
||||
/// <param name="node">Configuration node</param>
|
||||
void Configure(ServiceDescriptor descriptor, XmlNode node, IEventWriter logger);
|
||||
void Configure(ServiceDescriptor descriptor, XmlNode node);
|
||||
|
||||
/// <summary>
|
||||
/// Start handler. Called during startup of the service before the child process.
|
||||
/// </summary>
|
||||
/// <param name="logger">Logger</param>
|
||||
/// <exception cref="ExtensionException">Any error during execution</exception>
|
||||
void OnStart(IEventWriter logger);
|
||||
void OnWrapperStarted();
|
||||
|
||||
/// <summary>
|
||||
/// Handler, which is being invoked once the child process is started.
|
||||
|
@ -59,6 +59,6 @@ namespace winsw.Extensions
|
|||
/// </summary>
|
||||
/// <param name="logger">Logger</param>
|
||||
/// <exception cref="ExtensionException">Any error during execution</exception>
|
||||
void OnStop(IEventWriter logger);
|
||||
void BeforeWrapperStopped();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,26 +22,43 @@ namespace winsw.Extensions
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts all extensions
|
||||
/// Notifies all extensions that the wrapper is being started.
|
||||
/// They are supposed to run the initialization logic.
|
||||
/// If any extensions fails, WinSW startup should be interrupted.
|
||||
/// </summary>
|
||||
/// <exception cref="ExtensionException">Start failure</exception>
|
||||
public void OnStart(IEventWriter logger)
|
||||
/// <exception cref="Exception">Start failure</exception>
|
||||
public void FireOnWrapperStarted()
|
||||
{
|
||||
foreach (var ext in Extensions)
|
||||
{
|
||||
ext.Value.OnStart(logger);
|
||||
try
|
||||
{
|
||||
ext.Value.OnWrapperStarted();
|
||||
}
|
||||
catch (ExtensionException ex)
|
||||
{
|
||||
Log.Fatal("onWrapperStarted() handler failed for " + ext.Value.DisplayName, ex);
|
||||
throw ex; // Propagate error to stop the startup
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops all extensions
|
||||
/// Notifies all extensions that the wrapper is being stopped.
|
||||
/// If an error happens, further extensions will be tried
|
||||
/// </summary>
|
||||
/// <exception cref="ExtensionException">Stop failure</exception>
|
||||
public void OnStop(IEventWriter logger)
|
||||
public void FireBeforeWrapperStopped()
|
||||
{
|
||||
foreach (var ext in Extensions)
|
||||
{
|
||||
ext.Value.OnStop(logger);
|
||||
{
|
||||
try
|
||||
{
|
||||
ext.Value.BeforeWrapperStopped();
|
||||
}
|
||||
catch (ExtensionException ex)
|
||||
{
|
||||
Log.Error("beforeWrapperStopped() handler failed for " + ext.Value.DisplayName, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,17 +103,17 @@ namespace winsw.Extensions
|
|||
//TODO: Implement loading of external extensions. Current version supports internal hack
|
||||
#region Extension load management
|
||||
|
||||
/// <summary>
|
||||
|
||||
/// Loads extensions according to the configuration file.
|
||||
/// </summary>
|
||||
/// <param name="logger">Logger</param>
|
||||
/// <exception cref="Exception">Loading failure</exception>
|
||||
public void LoadExtensions(IEventWriter logger)
|
||||
public void LoadExtensions()
|
||||
{
|
||||
var extensionIds = ServiceDescriptor.ExtensionIds;
|
||||
foreach (String extensionId in extensionIds)
|
||||
{
|
||||
LoadExtension(extensionId, logger);
|
||||
LoadExtension(extensionId);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,7 +123,7 @@ namespace winsw.Extensions
|
|||
/// <param name="id">Extension ID</param>
|
||||
/// <param name="logger">Logger</param>
|
||||
/// <exception cref="Exception">Loading failure</exception>
|
||||
private void LoadExtension(string id, IEventWriter logger)
|
||||
private void LoadExtension(string id)
|
||||
{
|
||||
if (Extensions.ContainsKey(id))
|
||||
{
|
||||
|
@ -127,7 +144,7 @@ namespace winsw.Extensions
|
|||
extension.Descriptor = descriptor;
|
||||
try
|
||||
{
|
||||
extension.Configure(ServiceDescriptor, configNode, logger);
|
||||
extension.Configure(ServiceDescriptor, configNode);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{ // Consider any unexpected exception as fatal
|
||||
|
@ -135,11 +152,11 @@ namespace winsw.Extensions
|
|||
throw ex;
|
||||
}
|
||||
Extensions.Add(id, extension);
|
||||
logger.LogEvent("Extension loaded: "+id, EventLogEntryType.Information);
|
||||
Log.Info("Extension loaded: " + id);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogEvent("Extension is disabled: " + id, EventLogEntryType.Warning);
|
||||
Log.Warn("Extension is disabled: " + id);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
|
||||
namespace winsw.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that the class may reference the event log
|
||||
/// </summary>
|
||||
public interface IServiceEventLogProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Locates Event Log for the service.
|
||||
/// </summary>
|
||||
/// <returns>Event Log or null if it is not avilable</returns>
|
||||
EventLog locate();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
using log4net.Appender;
|
||||
using log4net.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
|
||||
namespace winsw.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// Implementes service Event log appender for log4j.
|
||||
/// The implementation presumes that service gets initialized after the logging.
|
||||
/// </summary>
|
||||
public class ServiceEventLogAppender : AppenderSkeleton
|
||||
{
|
||||
public IServiceEventLogProvider provider { get; set; }
|
||||
|
||||
override protected void Append(LoggingEvent loggingEvent)
|
||||
{
|
||||
EventLog eventLog = provider.locate();
|
||||
if (eventLog != null)
|
||||
{
|
||||
// We write the event iff the provider is ready
|
||||
eventLog.WriteEntry(loggingEvent.RenderedMessage, toEventLogEntryType(loggingEvent.Level));
|
||||
}
|
||||
}
|
||||
|
||||
private static EventLogEntryType toEventLogEntryType(Level level)
|
||||
{
|
||||
if (level.Value >= Level.Error.Value)
|
||||
{
|
||||
return EventLogEntryType.Error;
|
||||
}
|
||||
if (level.Value >= Level.Warn.Value)
|
||||
{
|
||||
return EventLogEntryType.Warning;
|
||||
}
|
||||
|
||||
// All other events will be posted as information
|
||||
return EventLogEntryType.Information;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace winsw.Util
|
||||
{
|
||||
public interface IEventWriter
|
||||
{
|
||||
void LogEvent(String message);
|
||||
void LogEvent(String message, EventLogEntryType type);
|
||||
}
|
||||
}
|
|
@ -54,12 +54,13 @@
|
|||
<Compile Include="Extensions\WinSWExtensionDescriptor.cs" />
|
||||
<Compile Include="Extensions\WinSWExtensionManager.cs" />
|
||||
<Compile Include="LogAppenders.cs" />
|
||||
<Compile Include="Logging\ServiceEventLogAppender.cs" />
|
||||
<Compile Include="Logging\IServiceEventLogProvider.cs" />
|
||||
<Compile Include="Native\Advapi32.cs" />
|
||||
<Compile Include="Native\Kernel32.cs" />
|
||||
<Compile Include="PeriodicRollingCalendar.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ServiceDescriptor.cs" />
|
||||
<Compile Include="Util\IEventWriter.cs" />
|
||||
<Compile Include="Util\ProcessHelper.cs" />
|
||||
<Compile Include="Util\SigIntHelper.cs" />
|
||||
<Compile Include="Util\XmlHelper.cs" />
|
||||
|
@ -71,6 +72,7 @@
|
|||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace winsw.Plugins.RunawayProcessKiller
|
|||
this.Pidfile = pidfile;
|
||||
}
|
||||
|
||||
public override void Configure(ServiceDescriptor descriptor, XmlNode node, IEventWriter logger)
|
||||
public override void Configure(ServiceDescriptor descriptor, XmlNode node)
|
||||
{
|
||||
// We expect the upper logic to process any errors
|
||||
// TODO: a better parser API for types would be useful
|
||||
|
@ -57,7 +57,7 @@ namespace winsw.Plugins.RunawayProcessKiller
|
|||
/// This method checks if the PID file is stored on the disk and then terminates runaway processes if they exist.
|
||||
/// </summary>
|
||||
/// <param name="logger">Unused logger</param>
|
||||
public override void OnStart(IEventWriter logger)
|
||||
public override void OnWrapperStarted()
|
||||
{
|
||||
// Read PID file from the disk
|
||||
int pid;
|
||||
|
|
|
@ -4,6 +4,7 @@ using System.Xml;
|
|||
using System.Diagnostics;
|
||||
using winsw.Extensions;
|
||||
using winsw.Util;
|
||||
using log4net;
|
||||
|
||||
namespace winsw.Plugins.SharedDirectoryMapper
|
||||
{
|
||||
|
@ -14,6 +15,8 @@ namespace winsw.Plugins.SharedDirectoryMapper
|
|||
|
||||
public override String DisplayName { get { return "Shared Directory Mapper"; } }
|
||||
|
||||
private static readonly ILog Logger = LogManager.GetLogger(typeof(SharedDirectoryMapper));
|
||||
|
||||
public SharedDirectoryMapper()
|
||||
{
|
||||
}
|
||||
|
@ -24,7 +27,7 @@ namespace winsw.Plugins.SharedDirectoryMapper
|
|||
_entries.Add(config);
|
||||
}
|
||||
|
||||
public override void Configure(ServiceDescriptor descriptor, XmlNode node, IEventWriter logger)
|
||||
public override void Configure(ServiceDescriptor descriptor, XmlNode node)
|
||||
{
|
||||
var nodes = XmlHelper.SingleNode(node, "mapping", false).SelectNodes("map");
|
||||
if (nodes != null)
|
||||
|
@ -41,30 +44,30 @@ namespace winsw.Plugins.SharedDirectoryMapper
|
|||
}
|
||||
}
|
||||
|
||||
public override void OnStart(IEventWriter eventWriter)
|
||||
public override void OnWrapperStarted()
|
||||
{
|
||||
foreach (SharedDirectoryMapperConfig config in _entries)
|
||||
{
|
||||
if (config.EnableMapping)
|
||||
{
|
||||
eventWriter.LogEvent(DisplayName + ": Mapping shared directory " + config.UNCPath + " to " + config.Label, EventLogEntryType.Information);
|
||||
Logger.Info(DisplayName + ": Mapping shared directory " + config.UNCPath + " to " + config.Label);
|
||||
try
|
||||
{
|
||||
_mapper.MapDirectory(config.Label, config.UNCPath);
|
||||
}
|
||||
catch (MapperException ex)
|
||||
{
|
||||
HandleMappingError(config, eventWriter, ex);
|
||||
HandleMappingError(config, ex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
eventWriter.LogEvent(DisplayName + ": Mapping of " + config.Label + " is disabled", EventLogEntryType.Warning);
|
||||
Logger.Warn(DisplayName + ": Mapping of " + config.Label + " is disabled");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnStop(IEventWriter eventWriter)
|
||||
public override void BeforeWrapperStopped()
|
||||
{
|
||||
foreach (SharedDirectoryMapperConfig config in _entries)
|
||||
{
|
||||
|
@ -76,18 +79,16 @@ namespace winsw.Plugins.SharedDirectoryMapper
|
|||
}
|
||||
catch (MapperException ex)
|
||||
{
|
||||
HandleMappingError(config, eventWriter, ex);
|
||||
HandleMappingError(config, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleMappingError(SharedDirectoryMapperConfig config, IEventWriter eventWriter, MapperException ex) {
|
||||
String prefix = "Mapping of " + config.Label+ " ";
|
||||
eventWriter.LogEvent(prefix + "STDOUT: " + ex.Process.StandardOutput.ReadToEnd(), EventLogEntryType.Information);
|
||||
eventWriter.LogEvent(prefix + "STDERR: " + ex.Process.StandardError.ReadToEnd(), EventLogEntryType.Information);
|
||||
|
||||
throw new ExtensionException(Descriptor.Id, DisplayName + ": " + prefix + "failed", ex);
|
||||
private void HandleMappingError(SharedDirectoryMapperConfig config, MapperException ex) {
|
||||
Logger.Error("Mapping of " + config.Label + " failed. STDOUT: " + ex.Process.StandardOutput.ReadToEnd()
|
||||
+ " \r\nSTDERR: " + ex.Process.StandardError.ReadToEnd(), ex);
|
||||
throw new ExtensionException(Descriptor.Id, DisplayName + ": Mapping of " + config.Label + "failed", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
<AssemblyName>SharedDirectoryMapper</AssemblyName>
|
||||
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
|
||||
<RestorePackages>true</RestorePackages>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
|
@ -34,6 +36,9 @@
|
|||
<AssemblyOriginatorKeyFile>$(SolutionDir)..\winsw_key.snk</AssemblyOriginatorKeyFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="log4net">
|
||||
<HintPath>..\..\packages\log4net.2.0.3\lib\net20-full\log4net.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
|
@ -50,7 +55,17 @@
|
|||
<Name>WinSWCore</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
|
||||
</Target>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="log4net" version="2.0.3" targetFramework="net20" />
|
||||
</packages>
|
|
@ -2,7 +2,6 @@
|
|||
using NUnit.Framework;
|
||||
using winsw.Extensions;
|
||||
using winsw.Plugins.SharedDirectoryMapper;
|
||||
using winswTests.util;
|
||||
using winsw.Plugins.RunawayProcessKiller;
|
||||
|
||||
namespace winswTests.Extensions
|
||||
|
@ -11,7 +10,6 @@ namespace winswTests.Extensions
|
|||
class RunawayProcessKillerExtensionTest : ExtensionTestBase
|
||||
{
|
||||
ServiceDescriptor _testServiceDescriptor;
|
||||
readonly TestLogger _logger = new TestLogger();
|
||||
|
||||
string testExtension = getExtensionClassNameWithAssembly(typeof(RunawayProcessKillerExtension));
|
||||
|
||||
|
@ -41,7 +39,7 @@ namespace winswTests.Extensions
|
|||
public void LoadExtensions()
|
||||
{
|
||||
WinSWExtensionManager manager = new WinSWExtensionManager(_testServiceDescriptor);
|
||||
manager.LoadExtensions(_logger);
|
||||
manager.LoadExtensions();
|
||||
Assert.AreEqual(1, manager.Extensions.Count, "One extension should be loaded");
|
||||
|
||||
// Check the file is correct
|
||||
|
@ -56,9 +54,9 @@ namespace winswTests.Extensions
|
|||
public void StartStopExtension()
|
||||
{
|
||||
WinSWExtensionManager manager = new WinSWExtensionManager(_testServiceDescriptor);
|
||||
manager.LoadExtensions(_logger);
|
||||
manager.OnStart(_logger);
|
||||
manager.OnStop(_logger);
|
||||
manager.LoadExtensions();
|
||||
manager.FireOnWrapperStarted();
|
||||
manager.FireBeforeWrapperStopped();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
using NUnit.Framework;
|
||||
using winsw.Extensions;
|
||||
using winsw.Plugins.SharedDirectoryMapper;
|
||||
using winswTests.util;
|
||||
|
||||
namespace winswTests.Extensions
|
||||
{
|
||||
|
@ -10,7 +9,6 @@ namespace winswTests.Extensions
|
|||
class SharedDirectoryMapperTest : ExtensionTestBase
|
||||
{
|
||||
ServiceDescriptor _testServiceDescriptor;
|
||||
readonly TestLogger _logger = new TestLogger();
|
||||
|
||||
string testExtension = getExtensionClassNameWithAssembly(typeof(SharedDirectoryMapper));
|
||||
|
||||
|
@ -48,7 +46,7 @@ namespace winswTests.Extensions
|
|||
public void LoadExtensions()
|
||||
{
|
||||
WinSWExtensionManager manager = new WinSWExtensionManager(_testServiceDescriptor);
|
||||
manager.LoadExtensions(_logger);
|
||||
manager.LoadExtensions();
|
||||
Assert.AreEqual(2, manager.Extensions.Count, "Two extensions should be loaded");
|
||||
}
|
||||
|
||||
|
@ -56,9 +54,9 @@ namespace winswTests.Extensions
|
|||
public void StartStopExtension()
|
||||
{
|
||||
WinSWExtensionManager manager = new WinSWExtensionManager(_testServiceDescriptor);
|
||||
manager.LoadExtensions(_logger);
|
||||
manager.OnStart(_logger);
|
||||
manager.OnStop(_logger);
|
||||
manager.LoadExtensions();
|
||||
manager.FireOnWrapperStarted();
|
||||
manager.FireBeforeWrapperStopped();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using winsw.Util;
|
||||
|
||||
namespace winswTests.util
|
||||
{
|
||||
class TestLogger : IEventWriter
|
||||
{
|
||||
public void LogEvent(String message)
|
||||
{
|
||||
Console.WriteLine(message);
|
||||
}
|
||||
|
||||
public void LogEvent(String message, EventLogEntryType type)
|
||||
{
|
||||
Console.WriteLine("[" + type + "]" + message);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -61,7 +61,6 @@
|
|||
<Compile Include="MainTest.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ServiceDescriptorTests.cs" />
|
||||
<Compile Include="Util\TestLogger.cs" />
|
||||
<Compile Include="Util\CLITestHelper.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -3,5 +3,6 @@
|
|||
<repository path="..\Core\ServiceWrapper\packages.config" />
|
||||
<repository path="..\Core\WinSWCore\packages.config" />
|
||||
<repository path="..\Plugins\RunawayProcessKiller\packages.config" />
|
||||
<repository path="..\Plugins\SharedDirectoryMapper\packages.config" />
|
||||
<repository path="..\Test\winswTests\packages.config" />
|
||||
</repositories>
|
Loading…
Reference in New Issue