SEBWIN-301: Implemented service log file persistence in user directory.
This commit is contained in:
parent
6b24554abc
commit
3589b92b9d
8 changed files with 61 additions and 22 deletions
|
@ -68,6 +68,8 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
|
|||
appConfig.SebUriScheme = "seb";
|
||||
appConfig.SebUriSchemeSecure = "sebs";
|
||||
appConfig.ServiceAddress = $"{BASE_ADDRESS}/service";
|
||||
appConfig.ServiceEventName = $@"Global\{nameof(SafeExamBrowser)}-{Guid.NewGuid()}";
|
||||
appConfig.ServiceLogFilePath = Path.Combine(logFolder, $"{logFilePrefix}_Service.log");
|
||||
|
||||
return appConfig;
|
||||
}
|
||||
|
|
|
@ -121,6 +121,11 @@ namespace SafeExamBrowser.Contracts.Configuration
|
|||
/// </summary>
|
||||
public string ServiceEventName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The file path under which the log for the current session of the service component is to be stored.
|
||||
/// </summary>
|
||||
public string ServiceLogFilePath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a shallow clone.
|
||||
/// </summary>
|
||||
|
|
|
@ -29,11 +29,11 @@ namespace SafeExamBrowser.Logging
|
|||
|
||||
public void Initialize()
|
||||
{
|
||||
var logFolder = Path.GetDirectoryName(filePath);
|
||||
var directory = Path.GetDirectoryName(filePath);
|
||||
|
||||
if (!Directory.Exists(logFolder))
|
||||
if (!Directory.Exists(directory))
|
||||
{
|
||||
Directory.CreateDirectory(logFolder);
|
||||
Directory.CreateDirectory(directory);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ namespace SafeExamBrowser.Service
|
|||
bootstrapOperations.Enqueue(new CommunicationHostOperation(serviceHost, logger));
|
||||
bootstrapOperations.Enqueue(new ServiceEventCleanupOperation(logger, sessionContext));
|
||||
|
||||
sessionOperations.Enqueue(new SessionInitializationOperation(logger, serviceHost, sessionContext));
|
||||
sessionOperations.Enqueue(new SessionInitializationOperation(logger, CreateLogWriter, serviceHost, sessionContext));
|
||||
// TODO: sessionOperations.Enqueue(new RegistryOperation());
|
||||
// sessionOperations.Enqueue(new WindowsUpdateOperation());
|
||||
sessionOperations.Enqueue(new SessionActivationOperation(logger, sessionContext));
|
||||
|
@ -81,5 +81,14 @@ namespace SafeExamBrowser.Service
|
|||
logger.Subscribe(logFileWriter);
|
||||
logFileWriter.Initialize();
|
||||
}
|
||||
|
||||
private ILogObserver CreateLogWriter(string filePath)
|
||||
{
|
||||
var writer = new LogFileWriter(new DefaultLogFormatter(), filePath);
|
||||
|
||||
writer.Initialize();
|
||||
|
||||
return writer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,10 +33,10 @@ namespace SafeExamBrowser.Service.Operations
|
|||
|
||||
public OperationResult Revert()
|
||||
{
|
||||
if (sessionContext.EventWaitHandle != null)
|
||||
if (sessionContext.ServiceEvent != null)
|
||||
{
|
||||
logger.Info("Closing service event...");
|
||||
sessionContext.EventWaitHandle.Close();
|
||||
sessionContext.ServiceEvent.Close();
|
||||
logger.Info("Service event successfully closed.");
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace SafeExamBrowser.Service.Operations
|
|||
|
||||
public override OperationResult Perform()
|
||||
{
|
||||
var success = Context.EventWaitHandle.Set();
|
||||
var success = Context.ServiceEvent.Set();
|
||||
|
||||
if (success)
|
||||
{
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Security.AccessControl;
|
||||
using System.Security.Principal;
|
||||
using System.Threading;
|
||||
|
@ -18,16 +19,25 @@ namespace SafeExamBrowser.Service.Operations
|
|||
internal class SessionInitializationOperation : SessionOperation
|
||||
{
|
||||
private ILogger logger;
|
||||
private Func<string, ILogObserver> createLogWriter;
|
||||
private IServiceHost serviceHost;
|
||||
private ILogObserver sessionWriter;
|
||||
|
||||
public SessionInitializationOperation(ILogger logger, IServiceHost serviceHost, SessionContext sessionContext) : base(sessionContext)
|
||||
public SessionInitializationOperation(
|
||||
ILogger logger,
|
||||
Func<string, ILogObserver> createLogWriter,
|
||||
IServiceHost serviceHost,
|
||||
SessionContext sessionContext) : base(sessionContext)
|
||||
{
|
||||
this.logger = logger;
|
||||
this.createLogWriter = createLogWriter;
|
||||
this.serviceHost = serviceHost;
|
||||
}
|
||||
|
||||
public override OperationResult Perform()
|
||||
{
|
||||
InitializeSessionWriter();
|
||||
|
||||
logger.Info("Initializing new session...");
|
||||
|
||||
serviceHost.AllowConnection = false;
|
||||
|
@ -35,33 +45,40 @@ namespace SafeExamBrowser.Service.Operations
|
|||
logger.Info($" -> Runtime-ID: {Context.Configuration.AppConfig.RuntimeId}");
|
||||
logger.Info($" -> Session-ID: {Context.Configuration.SessionId}");
|
||||
|
||||
InitializeEventWaitHandle();
|
||||
InitializeServiceEvent();
|
||||
|
||||
return OperationResult.Success;
|
||||
}
|
||||
|
||||
public override OperationResult Revert()
|
||||
{
|
||||
var success = true;
|
||||
|
||||
logger.Info("Finalizing current session...");
|
||||
|
||||
var success = Context.EventWaitHandle?.Set() == true;
|
||||
if (Context.ServiceEvent != null)
|
||||
{
|
||||
success = Context.ServiceEvent.Set();
|
||||
|
||||
if (success)
|
||||
{
|
||||
logger.Info("Successfully informed runtime about session termination.");
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Error("Failed to inform runtime about session termination!");
|
||||
if (success)
|
||||
{
|
||||
logger.Info("Successfully informed runtime about session termination.");
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Error("Failed to inform runtime about session termination!");
|
||||
}
|
||||
}
|
||||
|
||||
Context.Configuration = null;
|
||||
logger.Unsubscribe(sessionWriter);
|
||||
sessionWriter = null;
|
||||
serviceHost.AllowConnection = true;
|
||||
|
||||
return success ? OperationResult.Success : OperationResult.Failed;
|
||||
}
|
||||
|
||||
private void InitializeEventWaitHandle()
|
||||
private void InitializeServiceEvent()
|
||||
{
|
||||
var securityIdentifier = new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null);
|
||||
var accessRule = new EventWaitHandleAccessRule(securityIdentifier, EventWaitHandleRights.Synchronize, AccessControlType.Allow);
|
||||
|
@ -69,16 +86,22 @@ namespace SafeExamBrowser.Service.Operations
|
|||
|
||||
security.AddAccessRule(accessRule);
|
||||
|
||||
if (Context.EventWaitHandle != null)
|
||||
if (Context.ServiceEvent != null)
|
||||
{
|
||||
logger.Info("Closing service event from previous session...");
|
||||
Context.EventWaitHandle.Close();
|
||||
Context.ServiceEvent.Close();
|
||||
logger.Info("Service event successfully closed.");
|
||||
}
|
||||
|
||||
logger.Info("Attempting to create new service event...");
|
||||
Context.EventWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Context.Configuration.AppConfig.ServiceEventName, out _, security);
|
||||
Context.ServiceEvent = new EventWaitHandle(false, EventResetMode.AutoReset, Context.Configuration.AppConfig.ServiceEventName, out _, security);
|
||||
logger.Info("Service event successfully created.");
|
||||
}
|
||||
|
||||
private void InitializeSessionWriter()
|
||||
{
|
||||
sessionWriter = createLogWriter.Invoke(Context.Configuration.AppConfig.ServiceLogFilePath);
|
||||
logger.Subscribe(sessionWriter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,6 @@ namespace SafeExamBrowser.Service
|
|||
/// <summary>
|
||||
/// The global inter-process event used for status synchronization with the runtime component.
|
||||
/// </summary>
|
||||
internal EventWaitHandle EventWaitHandle { get; set; }
|
||||
internal EventWaitHandle ServiceEvent { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue