From 42a98df47b8432ef581d281f61796b4ecdd59255 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Tue, 24 Oct 2017 16:07:44 -0400 Subject: [PATCH] Logging and more Service setup --- .../AdministrativeAuthorizationManager.cs | 8 +- .../ChatProviders/DiscordChatProvider.cs | 5 +- .../ChatProviders/IRCChatProvider.cs | 8 +- TGServerService/DeprecatedInstanceConfig.cs | 8 +- TGServerService/EventID.cs | 9 +- .../ServerInstance/Administration.cs | 4 +- TGServerService/ServerInstance/Byond.cs | 10 +- TGServerService/ServerInstance/Chat.cs | 10 +- TGServerService/ServerInstance/Compiler.cs | 16 +- TGServerService/ServerInstance/Config.cs | 12 +- TGServerService/ServerInstance/DreamDaemon.cs | 20 +-- TGServerService/ServerInstance/Interop.cs | 10 +- .../ServerInstance/PreactionHandler.cs | 4 +- TGServerService/ServerInstance/Repository.cs | 50 +++--- .../ServerInstance/ServerInstance.cs | 48 +++++- TGServerService/Service.cs | 147 ++++++++++++------ 16 files changed, 235 insertions(+), 134 deletions(-) diff --git a/TGServerService/AdministrativeAuthorizationManager.cs b/TGServerService/AdministrativeAuthorizationManager.cs index 8390f64788..e5aaf062d5 100644 --- a/TGServerService/AdministrativeAuthorizationManager.cs +++ b/TGServerService/AdministrativeAuthorizationManager.cs @@ -1,4 +1,6 @@ -using System.Security.Principal; +using System; +using System.Diagnostics; +using System.Security.Principal; using System.ServiceModel; using TGServiceInterface.Components; @@ -7,7 +9,7 @@ namespace TGServerService /// /// A used to determine only if the caller is an admin /// - class AdministrativeAuthorizationManager : ServiceAuthorizationManager + sealed class AdministrativeAuthorizationManager : ServiceAuthorizationManager { string LastSeenUser; protected override bool CheckAccessCore(OperationContext operationContext) @@ -27,7 +29,7 @@ namespace TGServerService if (LastSeenUser != user) { LastSeenUser = user; - Service.WriteAccess(user, authSuccess); + Service.WriteEntry(String.Format("Root access from: {0}", user), EventID.Authentication, authSuccess ? EventLogEntryType.SuccessAudit : EventLogEntryType.FailureAudit, Service.LoggingID); } return authSuccess; } diff --git a/TGServerService/ChatProviders/DiscordChatProvider.cs b/TGServerService/ChatProviders/DiscordChatProvider.cs index 1fb5fa3c77..1b347b0de2 100644 --- a/TGServerService/ChatProviders/DiscordChatProvider.cs +++ b/TGServerService/ChatProviders/DiscordChatProvider.cs @@ -217,7 +217,6 @@ namespace TGServerService.ChatProviders foreach (var J in I.TextChannels) if (J.Id == channel) J.SendMessageAsync(message).Wait(); - Service.WriteInfo(String.Format("Discord Send ({0}): {1}", channelname, message), EventID.ChatSend); return null; } } @@ -237,9 +236,7 @@ namespace TGServerService.ChatProviders client.StopAsync().Wait(); client.LogoutAsync().Wait(); } - catch (Exception e) { - Service.WriteError("Discord failed DnD: " + e.ToString(), EventID.ChatDisconnectFail); - } + catch { } client.Dispose(); } diff --git a/TGServerService/ChatProviders/IRCChatProvider.cs b/TGServerService/ChatProviders/IRCChatProvider.cs index b5e73ac1c1..a41a7fd72b 100644 --- a/TGServerService/ChatProviders/IRCChatProvider.cs +++ b/TGServerService/ChatProviders/IRCChatProvider.cs @@ -74,7 +74,6 @@ namespace TGServerService.ChatProviders channel = channel.Replace(PrivateMessageMarker, ""); irc.SendMessage(SendType.Message, channel, message); } - Service.WriteInfo(String.Format("IRC Send ({0}): {1}", channel, message), EventID.ChatSend); return null; } catch (Exception e) @@ -275,7 +274,7 @@ namespace TGServerService.ChatProviders /// public void Disconnect() - { + { try { lock (IRCLock) @@ -287,10 +286,7 @@ namespace TGServerService.ChatProviders } } } - catch (Exception e) - { - Service.WriteError("IRC failed QnD: " + e.ToString(), EventID.ChatDisconnectFail); - } + catch { } } /// public bool Connected() diff --git a/TGServerService/DeprecatedInstanceConfig.cs b/TGServerService/DeprecatedInstanceConfig.cs index 8376f4b983..0d6a96908f 100644 --- a/TGServerService/DeprecatedInstanceConfig.cs +++ b/TGServerService/DeprecatedInstanceConfig.cs @@ -8,10 +8,10 @@ namespace TGServerService class DeprecatedInstanceConfig : InstanceConfig { /// - /// Convert the 3.1 .NET settings file to a config json + /// Convert the settings version 6 .NET settings file to a config json /// - /// A saved based off the old .NET setting file - public static InstanceConfig CreateFromNETSettings() + /// An based off the old .NET setting file + public static InstanceConfig CreateFromNETSettings(out string instanceDirectory) { var Config = Properties.Settings.Default; var result = new DeprecatedInstanceConfig() @@ -34,7 +34,7 @@ namespace TGServerService AuthorizedUserGroupSID = (string)Config.GetPreviousVersion("AuthorizedGroupSID") }; result.MigrateToCurrentVersion(); - result.Save(); + instanceDirectory = result.InstanceDir; return result; } diff --git a/TGServerService/EventID.cs b/TGServerService/EventID.cs index 867148150d..1e748beb47 100644 --- a/TGServerService/EventID.cs +++ b/TGServerService/EventID.cs @@ -3,7 +3,7 @@ namespace TGServerService { /// - /// Various events and their IDs in no particular order. Found in the Windows event log. These incremented by 100 and are guaranteed to never be reused in the future. Each event ID may be information, a warning, or error and will be documented accordingly. Warnings will occur due to user, data, or network errors. Errors will occur due to filesystem errors or hard faults + /// Various events and their IDs in no particular order. Found in the Windows event log. These key incremented by 100 and are guaranteed to never be reused in the future. In the windows event viewer, these IDs will be offset by the to distinguish events between instances. Each event ID may be information, a warning, or error and will be documented accordingly. Warnings will occur due to user, data, or network errors. Errors will occur due to filesystem errors or hard faults /// public enum EventID : int { @@ -112,10 +112,12 @@ namespace TGServerService /// /// Info: Successful completion of a operation /// + [Obsolete("Not in use anymore", true)] ChatSend = 2600, /// /// Info: Successful completion of a operation /// + [Obsolete("Not in use anymore", true)] ChatBroadcast = 2700, /// /// Not in use anymore @@ -125,6 +127,7 @@ namespace TGServerService /// /// Error: When an error occurs during a operation /// + [Obsolete("Not in use anymore", true)] ChatDisconnectFail = 2900, /// /// Not in use anymore @@ -315,5 +318,9 @@ namespace TGServerService /// Info: Successfully delete of a static path. Warning: An error occurred during a delete of a static path /// StaticDelete = 7500, + /// + /// Info: When an instance's logging ID is first assigned + /// + InstanceIDAssigned = 7600, } } diff --git a/TGServerService/ServerInstance/Administration.cs b/TGServerService/ServerInstance/Administration.cs index 5ce99489de..c5d2c5e38c 100644 --- a/TGServerService/ServerInstance/Administration.cs +++ b/TGServerService/ServerInstance/Administration.cs @@ -109,7 +109,7 @@ namespace TGServerService //only allow the same user the service is running as to use interop, because that's what DD is running as, and don't spam the logs with it unless it fails var result = windowsIdent.User == ServiceSID; if(!result) - Service.WriteAccess(windowsIdent.Name, false); + WriteAccess(windowsIdent.Name, false); return result; } @@ -127,7 +127,7 @@ namespace TGServerService if (LastSeenUser != user) { LastSeenUser = user; - Service.WriteAccess(user, authSuccess); + WriteAccess(user, authSuccess); } } return authSuccess; diff --git a/TGServerService/ServerInstance/Byond.cs b/TGServerService/ServerInstance/Byond.cs index 9a3715ff99..19d22f36ad 100644 --- a/TGServerService/ServerInstance/Byond.cs +++ b/TGServerService/ServerInstance/Byond.cs @@ -225,7 +225,7 @@ namespace TGServerService { SendMessage("BYOND: Update download failed. Does the specified version exist?", MessageType.DeveloperInfo); lastError = String.Format("Download of BYOND version {0}.{1} failed! Does it exist?", major, minor); - Service.WriteWarning(String.Format("Failed to update BYOND to version {0}.{1}!", major, minor), EventID.BYONDUpdateFail); + WriteWarning(String.Format("Failed to update BYOND to version {0}.{1}!", major, minor), EventID.BYONDUpdateFail); lock (ByondLock) { updateStat = ByondStatus.Idle; @@ -267,7 +267,7 @@ namespace TGServerService RequestRestart(); lastError = "Update staged. Awaiting server restart..."; SendMessage(String.Format("BYOND: Staging complete. Awaiting server restart...", major, minor), MessageType.DeveloperInfo); - Service.WriteInfo(String.Format("BYOND update {0}.{1} staged", major, minor), EventID.BYONDUpdateStaged); + WriteInfo(String.Format("BYOND update {0}.{1} staged", major, minor), EventID.BYONDUpdateStaged); break; } } @@ -277,7 +277,7 @@ namespace TGServerService } catch (Exception e) { - Service.WriteError("Revision staging errror: " + e.ToString(), EventID.BYONDUpdateFail); + WriteError("Revision staging errror: " + e.ToString(), EventID.BYONDUpdateFail); lock (ByondLock) { updateStat = ByondStatus.Idle; @@ -328,14 +328,14 @@ namespace TGServerService Program.DeleteDirectory(StagingDirectory); lastError = null; SendMessage("BYOND: Update completed!", MessageType.DeveloperInfo); - Service.WriteInfo(String.Format("BYOND update {0} completed!", GetVersion(ByondVersion.Installed)), EventID.BYONDUpdateComplete); + WriteInfo(String.Format("BYOND update {0} completed!", GetVersion(ByondVersion.Installed)), EventID.BYONDUpdateComplete); return true; } catch (Exception e) { lastError = e.ToString(); SendMessage("BYOND: Update failed!", MessageType.DeveloperInfo); - Service.WriteError("BYOND update failed! Error: " + e.ToString(), EventID.BYONDUpdateFail); + WriteError("BYOND update failed! Error: " + e.ToString(), EventID.BYONDUpdateFail); return false; } finally diff --git a/TGServerService/ServerInstance/Chat.cs b/TGServerService/ServerInstance/Chat.cs index c4df5cf4cf..9c3bddc47e 100644 --- a/TGServerService/ServerInstance/Chat.cs +++ b/TGServerService/ServerInstance/Chat.cs @@ -40,19 +40,19 @@ namespace TGServerService chatProvider = new IRCChatProvider(info); break; default: - Service.WriteError(String.Format("Invalid chat provider: {0}", info.Provider), EventID.InvalidChatProvider); + WriteError(String.Format("Invalid chat provider: {0}", info.Provider), EventID.InvalidChatProvider); continue; } } catch (Exception e) { - Service.WriteError(String.Format("Failed to start chat provider {0}! Error: {1}", info.Provider, e.ToString()), EventID.ChatProviderStartFail); + WriteError(String.Format("Failed to start chat provider {0}! Error: {1}", info.Provider, e.ToString()), EventID.ChatProviderStartFail); continue; } chatProvider.OnChatMessage += ChatProvider_OnChatMessage; var res = chatProvider.Connect(); if (res != null) - Service.WriteWarning(String.Format("Unable to connect to chat! Provider {0}, Error: {1}", chatProvider.GetType().ToString(), res), EventID.ChatConnectFail); + WriteWarning(String.Format("Unable to connect to chat! Provider {0}, Error: {1}", chatProvider.GetType().ToString(), res), EventID.ChatConnectFail); ChatProviders.Add(chatProvider); } } @@ -86,7 +86,7 @@ namespace TGServerService Speaker = speaker, Server = this, }; - Service.WriteInfo(String.Format("Chat Command from {0} ({2}): {1}", speaker, String.Join(" ", asList), channel), EventID.ChatCommand); + WriteInfo(String.Format("Chat Command from {0} ({2}): {1}", speaker, String.Join(" ", asList), channel), EventID.ChatCommand); if (ServerChatCommands == null) LoadServerChatCommands(); new RootChatCommand(ServerChatCommands).DoRun(asList); @@ -229,7 +229,7 @@ namespace TGServerService } catch (Exception e) { - Service.WriteWarning(String.Format("Chat broadcast failed (Provider: {3}) (Flags: {0}) (Message: {1}): {2}", mt, msg, e.ToString(), ChatProvider.ProviderInfo().Provider), EventID.ChatBroadcastFail); + WriteWarning(String.Format("Chat broadcast failed (Provider: {3}) (Flags: {0}) (Message: {1}): {2}", mt, msg, e.ToString(), ChatProvider.ProviderInfo().Provider), EventID.ChatBroadcastFail); } } } diff --git a/TGServerService/ServerInstance/Compiler.cs b/TGServerService/ServerInstance/Compiler.cs index 3f77b7b1a8..0881f1f27d 100644 --- a/TGServerService/ServerInstance/Compiler.cs +++ b/TGServerService/ServerInstance/Compiler.cs @@ -221,7 +221,7 @@ namespace TGServerService lock (CompilerLock) { SendMessage("DM: Setup failed!", MessageType.DeveloperInfo); - Service.WriteError("Compiler Initialization Error: " + e.ToString(), EventID.DMInitializeCrash); + WriteError("Compiler Initialization Error: " + e.ToString(), EventID.DMInitializeCrash); lastCompilerError = e.ToString(); compilerCurrentStatus = CompilerStatus.Uninitialized; return; @@ -414,7 +414,7 @@ namespace TGServerService { var errorMsg = String.Format("Could not find {0}!", dmeName); SendMessage("DM: " + errorMsg, MessageType.DeveloperInfo); - Service.WriteError(errorMsg, EventID.DMCompileCrash); + WriteError(errorMsg, EventID.DMCompileCrash); lock (CompilerLock) { lastCompilerError = errorMsg; @@ -427,7 +427,7 @@ namespace TGServerService { lastCompilerError = "The precompile hook failed"; compilerCurrentStatus = CompilerStatus.Initialized; //still fairly valid - Service.WriteWarning("Precompile hook failed!", EventID.DMCompileError); + WriteWarning("Precompile hook failed!", EventID.DMCompileError); return; } @@ -525,13 +525,13 @@ namespace TGServerService { lastCompilerError = "The postcompile hook failed"; compilerCurrentStatus = CompilerStatus.Initialized; //still fairly valid - Service.WriteWarning("Postcompile hook failed!", EventID.DMCompileError); + WriteWarning("Postcompile hook failed!", EventID.DMCompileError); return; } UpdateLiveSha(CurrentSha); var msg = String.Format("Compile complete!{0}", !staged ? "" : " Server will update next round."); SendMessage("DM: " + msg, MessageType.DeveloperInfo); - Service.WriteInfo(msg, EventID.DMCompileSuccess); + WriteInfo(msg, EventID.DMCompileSuccess); lock (CompilerLock) { if (staged) @@ -543,7 +543,7 @@ namespace TGServerService else { SendMessage("DM: Compile failed!", MessageType.DeveloperInfo); //Also happens for warnings - Service.WriteWarning("Compile error: " + OutputList.ToString(), EventID.DMCompileError); + WriteWarning("Compile error: " + OutputList.ToString(), EventID.DMCompileError); lock (CompilerLock) { lastCompilerError = "DM compile failure"; @@ -560,7 +560,7 @@ namespace TGServerService catch (Exception e) { SendMessage("DM: Compiler thread crashed!", MessageType.DeveloperInfo); - Service.WriteError("Compile manager errror: " + e.ToString(), EventID.DMCompileCrash); + WriteError("Compile manager errror: " + e.ToString(), EventID.DMCompileCrash); lock (CompilerLock) { lastCompilerError = e.ToString(); @@ -577,7 +577,7 @@ namespace TGServerService compilerCurrentStatus = CompilerStatus.Initialized; compilationCancellationRequestation = false; SendMessage("DM: Compile cancelled!", MessageType.DeveloperInfo); - Service.WriteInfo("Compilation cancelled", EventID.DMCompileCancel); + WriteInfo("Compilation cancelled", EventID.DMCompileCancel); } } } diff --git a/TGServerService/ServerInstance/Config.cs b/TGServerService/ServerInstance/Config.cs index 257952cac2..1241a45a43 100644 --- a/TGServerService/ServerInstance/Config.cs +++ b/TGServerService/ServerInstance/Config.cs @@ -81,7 +81,7 @@ namespace TGServerService var output = File.ReadAllText(path); Service.CancelImpersonation(); - Service.WriteInfo("Read of " + path, EventID.StaticRead); + WriteInfo("Read of " + path, EventID.StaticRead); error = null; unauthorized = false; return output; @@ -98,7 +98,7 @@ namespace TGServerService { error = e.ToString(); Service.CancelImpersonation(); - Service.WriteWarning(String.Format("Read of {0} failed! Error: {1}", path, e.ToString()), EventID.StaticRead); + WriteWarning(String.Format("Read of {0} failed! Error: {1}", path, e.ToString()), EventID.StaticRead); unauthorized = false; return null; } @@ -137,7 +137,7 @@ namespace TGServerService Directory.CreateDirectory(destdir); File.WriteAllText(path, data); Service.CancelImpersonation(); - Service.WriteInfo("Write to " + path, EventID.StaticWrite); + WriteInfo("Write to " + path, EventID.StaticWrite); unauthorized = false; return null; } @@ -152,7 +152,7 @@ namespace TGServerService { unauthorized = false; Service.CancelImpersonation(); - Service.WriteWarning(String.Format("Write of {0} failed! Error: {1}", path, e.ToString()), EventID.StaticRead); + WriteWarning(String.Format("Write of {0} failed! Error: {1}", path, e.ToString()), EventID.StaticRead); return e.ToString(); } } @@ -191,7 +191,7 @@ namespace TGServerService else if (Directory.Exists(path)) Program.DeleteDirectory(path); Service.CancelImpersonation(); - Service.WriteInfo("Delete of " + path, EventID.StaticDelete); + WriteInfo("Delete of " + path, EventID.StaticDelete); unauthorized = false; return null; } @@ -206,7 +206,7 @@ namespace TGServerService { unauthorized = false; Service.CancelImpersonation(); - Service.WriteWarning(String.Format("Delete of {0} failed! Error: {1}", path, e.ToString()), EventID.StaticRead); + WriteWarning(String.Format("Delete of {0} failed! Error: {1}", path, e.ToString()), EventID.StaticRead); return e.ToString(); } } diff --git a/TGServerService/ServerInstance/DreamDaemon.cs b/TGServerService/ServerInstance/DreamDaemon.cs index 35529dc2dd..ba68aba344 100644 --- a/TGServerService/ServerInstance/DreamDaemon.cs +++ b/TGServerService/ServerInstance/DreamDaemon.cs @@ -105,7 +105,7 @@ namespace TGServerService Proc = Process.GetProcessById(Config.ReattachProcessID); if (Proc == null) throw new Exception("GetProcessById returned null!"); - Service.WriteInfo("Reattached to running DD process!", EventID.DDReattachSuccess); + WriteInfo("Reattached to running DD process!", EventID.DDReattachSuccess); ThreadPool.QueueUserWorkItem(_ => { Thread.Sleep(5000); @@ -131,7 +131,7 @@ namespace TGServerService } catch (Exception e) { - Service.WriteError(String.Format("Failed to reattach to DreamDaemon! PID: {0}. Exception: {1}", Config.ReattachProcessID, e.ToString()), EventID.DDReattachFail); + WriteError(String.Format("Failed to reattach to DreamDaemon! PID: {0}. Exception: {1}", Config.ReattachProcessID, e.ToString()), EventID.DDReattachFail); } finally { @@ -309,13 +309,13 @@ namespace TGServerService if (!RestartInProgress) { SendMessage("DD: Server started, watchdog active...", MessageType.WatchdogInfo); - Service.WriteInfo("Watchdog started", EventID.DDWatchdogStarted); + WriteInfo("Watchdog started", EventID.DDWatchdogStarted); } else { RestartInProgress = false; if (!ReattachInsteadOfRestart) - Service.WriteInfo("Watchdog restarted", EventID.DDWatchdogRestarted); + WriteInfo("Watchdog restarted", EventID.DDWatchdogRestarted); else ReattachInsteadOfRestart = false; } @@ -383,7 +383,7 @@ namespace TGServerService retries = 0; var msg = "DD: DreamDaemon crashed! Watchdog rebooting DD..."; SendMessage(msg, MessageType.WatchdogInfo); - Service.WriteWarning(msg, EventID.DDWatchdogRebootingServer); + WriteWarning(msg, EventID.DDWatchdogRebootingServer); } } @@ -420,7 +420,7 @@ namespace TGServerService catch (Exception e) { SendMessage("DD: Watchdog thread crashed!", MessageType.WatchdogInfo); - Service.WriteError("Watch dog thread crashed: " + e.ToString(), EventID.DDWatchdogCrash); + WriteError("Watch dog thread crashed: " + e.ToString(), EventID.DDWatchdogCrash); } finally { @@ -435,10 +435,10 @@ namespace TGServerService { if (!Config.ReattachRequired) SendMessage("DD: Server stopped, watchdog exiting...", MessageType.WatchdogInfo); - Service.WriteInfo("Watch dog exited", EventID.DDWatchdogExit); + WriteInfo("Watch dog exited", EventID.DDWatchdogExit); } else - Service.WriteInfo("Watch dog restarting...", EventID.DDWatchdogRestart); + WriteInfo("Watch dog restarting...", EventID.DDWatchdogRestart); } } } @@ -538,7 +538,7 @@ namespace TGServerService return; //no need } File.Copy(InterfacePath, InterfaceDLLName, overwrite); - Service.WriteInfo("Updated interface DLL", EventID.InterfaceDLLUpdated); + WriteInfo("Updated interface DLL", EventID.InterfaceDLLUpdated); } catch { @@ -551,7 +551,7 @@ namespace TGServerService catch (Exception e) { //intentionally using the fi - Service.WriteError("Failed to update interface DLL! Error: " + e.ToString(), EventID.InterfaceDLLUpdateFail); + WriteError("Failed to update interface DLL! Error: " + e.ToString(), EventID.InterfaceDLLUpdateFail); } } } diff --git a/TGServerService/ServerInstance/Interop.cs b/TGServerService/ServerInstance/Interop.cs index 62bd60b49c..6ebf909035 100644 --- a/TGServerService/ServerInstance/Interop.cs +++ b/TGServerService/ServerInstance/Interop.cs @@ -89,7 +89,7 @@ namespace TGServerService SendMessage("RELAY: " + String.Join(" ", splits), MessageType.AdminInfo); break; case SRWorldReboot: - Service.WriteInfo("World Rebooted", EventID.WorldReboot); + WriteInfo("World Rebooted", EventID.WorldReboot); WriteCurrentDDLog("World rebooted"); ServerChatCommands = null; ChatConnectivityCheck(); @@ -102,7 +102,7 @@ namespace TGServerService { GameAPIVersion = null; //needs updating } - Service.WriteInfo("Staged update applied", EventID.ServerUpdateApplied); + WriteInfo("Staged update applied", EventID.ServerUpdateApplied); } } break; @@ -117,7 +117,7 @@ namespace TGServerService } catch { - Service.WriteWarning(String.Format("API version of the game ({0}) is incompatible with the current supported API versions (3.{2}.x.x). Interop disabled.", splits.Count > 1 ? splits[1] : "NULL", AllowedMajorAPIVersion), EventID.APIVersionMismatch); + WriteWarning(String.Format("API version of the game ({0}) is incompatible with the current supported API versions (3.{2}.x.x). Interop disabled.", splits.Count > 1 ? splits[1] : "NULL", AllowedMajorAPIVersion), EventID.APIVersionMismatch); GameAPIVersion = null; break; } @@ -230,7 +230,7 @@ namespace TGServerService serviceCommsKey += tmp; } while (serviceCommsKey.Length < CommsKeyLen); serviceCommsKey = serviceCommsKey.Substring(0, CommsKeyLen); - Service.WriteInfo("Service Comms Key set to: " + serviceCommsKey, EventID.CommsKeySet); + WriteInfo("Service Comms Key set to: " + serviceCommsKey, EventID.CommsKeySet); } /// @@ -243,7 +243,7 @@ namespace TGServerService } catch(Exception e) { - Service.WriteWarning(String.Format("Handle command for \"{0}\" failed: {1}", command, e.ToString()), EventID.InteropCallException); + WriteWarning(String.Format("Handle command for \"{0}\" failed: {1}", command, e.ToString()), EventID.InteropCallException); return false; } } diff --git a/TGServerService/ServerInstance/PreactionHandler.cs b/TGServerService/ServerInstance/PreactionHandler.cs index 7a4ef27723..43e56990d5 100644 --- a/TGServerService/ServerInstance/PreactionHandler.cs +++ b/TGServerService/ServerInstance/PreactionHandler.cs @@ -74,9 +74,9 @@ namespace TGServerService var eventData = String.Format("Preaction Event: {0} @ {1} ran. Stdout:\n{2}\nStderr:\n{3}", eventName, GetEventPath(eventName), stdout, stderr); if (success) - Service.WriteInfo(eventData, EventID.PreactionEvent); + WriteInfo(eventData, EventID.PreactionEvent); else - Service.WriteWarning(eventData, EventID.PreactionFail); + WriteWarning(eventData, EventID.PreactionFail); return success; } diff --git a/TGServerService/ServerInstance/Repository.cs b/TGServerService/ServerInstance/Repository.cs index 03efc8f041..62773930fb 100644 --- a/TGServerService/ServerInstance/Repository.cs +++ b/TGServerService/ServerInstance/Repository.cs @@ -255,7 +255,7 @@ namespace TGServerService InitialConfigureRepository(); SendMessage("REPO: Clone complete!", MessageType.DeveloperInfo); - Service.WriteInfo("Repository {0}:{1} successfully cloned", EventID.RepoClone); + WriteInfo("Repository {0}:{1} successfully cloned", EventID.RepoClone); } finally { @@ -266,7 +266,7 @@ namespace TGServerService { SendMessage("REPO: Setup failed!", MessageType.DeveloperInfo); - Service.WriteWarning(String.Format("Failed to clone {2}:{0}: {1}", BranchName, e.ToString(), RepoURL), EventID.RepoCloneFail); + WriteWarning(String.Format("Failed to clone {2}:{0}: {1}", BranchName, e.ToString(), RepoURL), EventID.RepoCloneFail); } finally { @@ -352,7 +352,7 @@ namespace TGServerService } catch { - Service.WriteError("Could not setup static directory: " + I, EventID.RepoConfigurationFail); + WriteError("Could not setup static directory: " + I, EventID.RepoConfigurationFail); } } foreach(var I in Config.DLLPaths) @@ -362,7 +362,7 @@ namespace TGServerService var source = Path.Combine(RepoPath, I); if (!File.Exists(source)) { - Service.WriteWarning("Could not find DLL: " + I, EventID.RepoConfigurationFail); + WriteWarning("Could not find DLL: " + I, EventID.RepoConfigurationFail); continue; } var dest = Path.Combine(StaticDirs, I); @@ -370,7 +370,7 @@ namespace TGServerService } catch { - Service.WriteError("Could not setup static DLL: " + I, EventID.RepoConfigurationFail); + WriteError("Could not setup static DLL: " + I, EventID.RepoConfigurationFail); } } } @@ -524,13 +524,13 @@ namespace TGServerService var res = ResetNoLock(null); UpdateSubmodules(); SendMessage("REPO: Checkout complete!", MessageType.DeveloperInfo); - Service.WriteInfo("Repo checked out " + sha, EventID.RepoCheckout); + WriteInfo("Repo checked out " + sha, EventID.RepoCheckout); return res; } catch (Exception e) { SendMessage("REPO: Checkout failed!", MessageType.DeveloperInfo); - Service.WriteWarning(String.Format("Repo checkout of {0} failed: {1}", sha, e.ToString()), EventID.RepoCheckoutFail); + WriteWarning(String.Format("Repo checkout of {0} failed: {1}", sha, e.ToString()), EventID.RepoCheckoutFail); return e.ToString(); } } @@ -602,20 +602,20 @@ namespace TGServerService if (error != null) throw new Exception(error); DeletePRList(); - Service.WriteInfo("Repo hard updated to " + originBranch.Tip.Sha, EventID.RepoHardUpdate); + WriteInfo("Repo hard updated to " + originBranch.Tip.Sha, EventID.RepoHardUpdate); return error; } res = MergeBranch(originBranch.FriendlyName); if (res != null) throw new Exception(res); UpdateSubmodules(); - Service.WriteInfo("Repo merge updated to " + originBranch.Tip.Sha, EventID.RepoMergeUpdate); + WriteInfo("Repo merge updated to " + originBranch.Tip.Sha, EventID.RepoMergeUpdate); return null; } catch (Exception E) { SendMessage("REPO: Update failed!", MessageType.DeveloperInfo); - Service.WriteWarning(String.Format("Repo{0} update failed", reset ? " hard" : ""), reset ? EventID.RepoHardUpdateFail : EventID.RepoMergeUpdateFail); + WriteWarning(String.Format("Repo{0} update failed", reset ? " hard" : ""), reset ? EventID.RepoHardUpdateFail : EventID.RepoMergeUpdateFail); return E.ToString(); } } @@ -650,7 +650,7 @@ namespace TGServerService Repo.Submodules.Update(I.Name, suo); var msg = String.Format("I had to reclone submodule {0}. If this is happening a lot find a better hack or fix https://github.com/libgit2/libgit2/issues/3820!", I.Name); SendMessage(String.Format("REPO: {0}", msg), MessageType.DeveloperInfo); - Service.WriteWarning(msg, EventID.SubmoduleReclone); + WriteWarning(msg, EventID.SubmoduleReclone); } } @@ -679,7 +679,7 @@ namespace TGServerService if (tag != null) { - Service.WriteInfo("Repo backup created at tag: " + tagName + " commit: " + HEAD, EventID.RepoBackupTag); + WriteInfo("Repo backup created at tag: " + tagName + " commit: " + HEAD, EventID.RepoBackupTag); return null; } throw new Exception("Tag creation failed!"); @@ -687,7 +687,7 @@ namespace TGServerService } catch (Exception e) { - Service.WriteWarning(String.Format("Failed backup tag creation at commit {0}!", Repo.Head.Tip.Sha), EventID.RepoBackupTagFail); + WriteWarning(String.Format("Failed backup tag creation at commit {0}!", Repo.Head.Tip.Sha), EventID.RepoBackupTagFail); return e.ToString(); } } @@ -732,10 +732,10 @@ namespace TGServerService SendMessage(String.Format("REPO: Hard reset to {0}branch", trackedBranch ? "tracked " : ""), MessageType.DeveloperInfo); if (trackedBranch) DeletePRList(); - Service.WriteInfo(String.Format("Repo branch reset{0}", trackedBranch ? " to tracked branch" : ""), trackedBranch ? EventID.RepoResetTracked : EventID.RepoReset); + WriteInfo(String.Format("Repo branch reset{0}", trackedBranch ? " to tracked branch" : ""), trackedBranch ? EventID.RepoResetTracked : EventID.RepoReset); return null; } - Service.WriteWarning(String.Format("Failed to reset{0}: {1}", trackedBranch ? " to tracked branch" : "", res), trackedBranch ? EventID.RepoResetTrackedFail : EventID.RepoResetFail); + WriteWarning(String.Format("Failed to reset{0}: {1}", trackedBranch ? " to tracked branch" : "", res), trackedBranch ? EventID.RepoResetTrackedFail : EventID.RepoResetFail); return res; } } @@ -761,7 +761,7 @@ namespace TGServerService } catch (Exception e) { - Service.WriteError("Failed to delete PR list: " + e.ToString(), EventID.RepoPRListError); + WriteError("Failed to delete PR list: " + e.ToString(), EventID.RepoPRListError); } } @@ -849,7 +849,7 @@ namespace TGServerService if (Result == null) { - Service.WriteInfo(String.Format("Merged pull request #{0}", PRNumber), EventID.RepoPRMerge); + WriteInfo(String.Format("Merged pull request #{0}", PRNumber), EventID.RepoPRMerge); try { var CurrentPRs = GetCurrentPRList(); @@ -882,7 +882,7 @@ namespace TGServerService } catch (Exception e) { - Service.WriteError("Failed to update PR list", EventID.RepoPRListError); + WriteError("Failed to update PR list", EventID.RepoPRListError); return "PR Merged, JSON update failed: " + e.ToString(); } } @@ -891,7 +891,7 @@ namespace TGServerService catch (Exception E) { SendMessage("REPO: PR merge failed!", MessageType.DeveloperInfo); - Service.WriteWarning(String.Format("Failed to merge pull request #{0}: {1}", PRNumber, E.ToString()), EventID.RepoPRMergeFail); + WriteWarning(String.Format("Failed to merge pull request #{0}: {1}", PRNumber, E.ToString()), EventID.RepoPRMergeFail); return E.ToString(); } } @@ -1054,13 +1054,13 @@ namespace TGServerService var authorandcommitter = MakeSig(); // Commit to the repository - Service.WriteInfo(String.Format("Commit {0} created from changelogs", Repo.Commit(CommitMessage, authorandcommitter, authorandcommitter)), EventID.RepoCommit); + WriteInfo(String.Format("Commit {0} created from changelogs", Repo.Commit(CommitMessage, authorandcommitter, authorandcommitter)), EventID.RepoCommit); DeletePRList(); return null; } catch (Exception e) { - Service.WriteWarning("Repo commit failed: " + e.ToString(), EventID.RepoCommitFail); + WriteWarning("Repo commit failed: " + e.ToString(), EventID.RepoCommitFail); return e.ToString(); } } @@ -1086,12 +1086,12 @@ namespace TGServerService CredentialsProvider = GenerateGitCredentials, }; Repo.Network.Push(Repo.Network.Remotes[SSHPushRemote], Repo.Head.CanonicalName, options); - Service.WriteInfo("Repo pushed up to commit: " + Repo.Head.Tip.Sha, EventID.RepoPush); + WriteInfo("Repo pushed up to commit: " + Repo.Head.Tip.Sha, EventID.RepoPush); return null; } catch (Exception e) { - Service.WriteWarning("Repo push failed: " + e.ToString(), EventID.RepoPushFail); + WriteWarning("Repo push failed: " + e.ToString(), EventID.RepoPushFail); return e.ToString(); } } @@ -1237,13 +1237,13 @@ namespace TGServerService return GenerateChangelogImpl(out error, true); } error = null; - Service.WriteInfo("Changelog generated" + error, EventID.RepoChangelog); + WriteInfo("Changelog generated" + error, EventID.RepoChangelog); return result; } catch (Exception e) { error = e.ToString(); - Service.WriteWarning("Changelog generation failed: " + error, EventID.RepoChangelogFail); + WriteWarning("Changelog generation failed: " + error, EventID.RepoChangelogFail); return null; } } diff --git a/TGServerService/ServerInstance/ServerInstance.cs b/TGServerService/ServerInstance/ServerInstance.cs index 50a3cd7c80..231bcf0a13 100644 --- a/TGServerService/ServerInstance/ServerInstance.cs +++ b/TGServerService/ServerInstance/ServerInstance.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using System.ServiceModel; using TGServiceInterface.Components; @@ -15,6 +16,10 @@ namespace TGServerService [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)] sealed partial class ServerInstance : IDisposable, ITGConnectivity { + /// + /// Used to assign the instance to event IDs + /// + public readonly byte LoggingID; /// /// The configuration settings for the instance /// @@ -22,8 +27,9 @@ namespace TGServerService /// /// Constructs and a /// - public ServerInstance(InstanceConfig config) + public ServerInstance(InstanceConfig config, byte logID) { + LoggingID = logID; Config = config; FindTheDroidsWereLookingFor(); InitEventHandlers(); @@ -46,6 +52,46 @@ namespace TGServerService DisposeChat(); } + /// + /// Writes information to the Windows event log + /// + /// The log message + /// The of the message + void WriteInfo(string message, EventID id) + { + Service.WriteEntry(message, id, EventLogEntryType.Information, LoggingID); + } + + /// + /// Writes an error to the Windows event log + /// + /// The log message + /// The of the message + void WriteError(string message, EventID id) + { + Service.WriteEntry(message, id, EventLogEntryType.Error, LoggingID); + } + + /// + /// Writes a warning to the Windows event log + /// + /// The log message + /// The of the message + void WriteWarning(string message, EventID id) + { + Service.WriteEntry(message, id, EventLogEntryType.Warning, LoggingID); + } + + /// + /// Writes an access event to the Windows event log + /// + /// The (un)authenticated Windows user's name + /// if authenticated sucessfully, otherwise + void WriteAccess(string username, bool authSuccess) + { + Service.WriteEntry(String.Format("Access from: {0}", username), EventID.Authentication, authSuccess ? EventLogEntryType.SuccessAudit : EventLogEntryType.FailureAudit, LoggingID); + } + /// public string Version() { diff --git a/TGServerService/Service.cs b/TGServerService/Service.cs index 8cd43a8c54..fd90609d12 100644 --- a/TGServerService/Service.cs +++ b/TGServerService/Service.cs @@ -15,6 +15,11 @@ namespace TGServerService /// sealed partial class Service : ServiceBase { + /// + /// The logging ID used for events + /// + public const byte LoggingID = 0; + /// /// The service version based on the /// @@ -34,57 +39,44 @@ namespace TGServerService } /// - /// Writes information to Windows the event log + /// Writes an event to Windows the event log /// /// The log message /// The of the message - public static void WriteInfo(string message, EventID id) + /// The of the event + /// The logging source ID for the event + public static void WriteEntry(string message, EventID id, EventLogEntryType eventType, byte loggingID) { - ActiveService.EventLog.WriteEntry(message, EventLogEntryType.Information, (int)id); - } - /// - /// Writes an error to the Windows event log - /// - /// The log message - /// The of the message - public static void WriteError(string message, EventID id) - { - ActiveService.EventLog.WriteEntry(message, EventLogEntryType.Error, (int)id); - } - /// - /// Writes a warning to the Windows event log - /// - /// The log message - /// The of the message - public static void WriteWarning(string message, EventID id) - { - ActiveService.EventLog.WriteEntry(message, EventLogEntryType.Warning, (int)id); - } - - /// - /// Writes an access event to the Windows event log - /// - /// The (un)authenticated Windows user's name - /// if authenticated sucessfully, otherwise - public static void WriteAccess(string username, bool authSuccess) - { - ActiveService.EventLog.WriteEntry(String.Format("Access from: {0}", username), authSuccess ? EventLogEntryType.SuccessAudit : EventLogEntryType.FailureAudit, (int)EventID.Authentication); + ActiveService.EventLog.WriteEntry(message, eventType, (int)id + loggingID); } /// /// The WCF host that contains connects to /// ServiceHost serviceHost; + /// + /// Map of to the respective + /// IDictionary hosts; + /// + /// List of s in use + /// + IList UsedLoggingIDs = new List(); /// - /// Migrates the .NET config from to + /// Migrates the .NET config from to + 1 /// /// The version to migrate from - /// The version to migrate to - void MigrateSettings(int oldVersion, int newVersion) + void MigrateSettings(int oldVersion) { - //Uneeded... So far... + switch (oldVersion) + { + case 6: //switch to per-instance configs + var IC = DeprecatedInstanceConfig.CreateFromNETSettings(out string instanceDir); + IC.Save(); + Properties.Settings.Default.InstancePaths.Add(instanceDir); + break; + } } //you should seriously not add anything here @@ -102,10 +94,11 @@ namespace TGServerService { var newVersion = Config.SettingsVersion; Config.Upgrade(); - var oldVersion = Config.SettingsVersion; - Config.SettingsVersion = newVersion; + + for(var oldVersion = Config.SettingsVersion; oldVersion < newVersion; ++oldVersion) + MigrateSettings(oldVersion); - MigrateSettings(oldVersion, newVersion); + Config.SettingsVersion = newVersion; Config.UpgradeRequired = false; Config.Save(); @@ -120,6 +113,10 @@ namespace TGServerService } } + /// + /// Overrides and saves the configured if requested by command line parameters + /// + /// The command line parameters for the void ChangePortFromCommandLine(string[] args) { var Config = Properties.Settings.Default; @@ -142,7 +139,11 @@ namespace TGServerService break; } } - //when babby is formed + + /// + /// Called by the Windows service manager. Initializes and starts configured s + /// + /// Command line arguments for the protected override void OnStart(string[] args) { ChangePortFromCommandLine(args); @@ -154,6 +155,9 @@ namespace TGServerService OnlineAllHosts(); } + /// + /// Creates the for + /// void SetupService() { serviceHost = CreateHost(this); @@ -161,6 +165,9 @@ namespace TGServerService serviceHost.Authorization.ServiceAuthorizationManager = new AdministrativeAuthorizationManager(); //only admins can diddle us } + /// + /// Opens all created s + /// void OnlineAllHosts() { serviceHost.Open(); @@ -168,6 +175,11 @@ namespace TGServerService I.Value.Open(); } + /// + /// Creates a for using the default pipe, , and the configured + /// + /// The + /// The created static ServiceHost CreateHost(object singleton) { return new ServiceHost(singleton, new Uri[] { new Uri("net.pipe://localhost"), new Uri(String.Format("https://localhost:{0}", Properties.Settings.Default.RemoteAccessPort)) }) @@ -176,13 +188,52 @@ namespace TGServerService }; } + /// + /// Creates s for all s as listed in + /// void SetupInstances() { + hosts = new Dictionary(); var pathsToRemove = new List(); foreach (var I in Properties.Settings.Default.InstancePaths) if (SetupInstance(I) != null) pathsToRemove.Add(I); } + + /// + /// Unlocks a acquired with + /// + /// The to unlock + void UnlockLoggingID(byte ID) + { + lock (UsedLoggingIDs) + { + UsedLoggingIDs.Remove(ID); + } + } + + /// + /// Gets and locks a + /// + /// A logging ID for the must be released using + byte LockLoggingID() + { + lock (UsedLoggingIDs) + { + for (byte I = 1; I < 100; ++I) + if (!UsedLoggingIDs.Contains(I)) + { + return I; + } + } + throw new Exception("All logging IDs in use!"); + } + + /// + /// Creates and starts a for a at + /// + /// The path to the + /// The inactive on success, on failure ServiceHost SetupInstance(string path) { ServerInstance instance; @@ -192,16 +243,18 @@ namespace TGServerService if (hosts.ContainsKey(path)) { var datInstance = ((ServerInstance)hosts[path].SingletonInstance); - WriteError(String.Format("Unable to start instance at path {0}. Has the same name as instance at path {1} ({2}). Detaching...", path, datInstance.ServerDirectory(), datInstance.Config.Name), EventID.InstanceInitializationFailure); + WriteEntry(String.Format("Unable to start instance at path {0}. Has the same name as instance at path {1} ({2}). Detaching...", path, datInstance.ServerDirectory(), datInstance.Config.Name), EventID.InstanceInitializationFailure, EventLogEntryType.Error, LoggingID); return null; } if (!config.Enabled) return null; - instance = new ServerInstance(config); + var ID = LockLoggingID(); + WriteEntry(String.Format("Instance {0} ({1}) assigned logging ID {2}", config.Name, path, ID), EventID.InstanceIDAssigned, EventLogEntryType.Information, ID); + instance = new ServerInstance(config, ID); } catch (Exception e) { - WriteError(String.Format("Unable to start instance at path {0}. Detaching... Error: {1}", path, e.ToString()), EventID.InstanceInitializationFailure); + WriteEntry(String.Format("Unable to start instance at path {0}. Detaching... Error: {1}", path, e.ToString()), EventID.InstanceInitializationFailure, EventLogEntryType.Error, LoggingID); return null; } @@ -217,11 +270,11 @@ namespace TGServerService } /// - /// Adds a WCF endpoint for a component + /// Adds a WCF endpoint for a component /// - /// - /// - /// + /// The service host to add the component to + /// The type of the component + /// The URI prefix for accessing the void AddEndpoint(ServiceHost host, Type typetype, string PipePrefix) { var bindingName = PipePrefix + "/" + typetype.Name; @@ -255,7 +308,7 @@ namespace TGServerService } catch (Exception e) { - WriteError(e.ToString(), EventID.ServiceShutdownFail); + WriteEntry(e.ToString(), EventID.ServiceShutdownFail, EventLogEntryType.Error, LoggingID); } }