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…
	
	Add table
		
		Reference in a new issue
	
	 dbuechel
						dbuechel