diff --git a/src/PepperDash.Core/Logging/Debug.cs b/src/PepperDash.Core/Logging/Debug.cs
index 219af2d5..9a405b28 100644
--- a/src/PepperDash.Core/Logging/Debug.cs
+++ b/src/PepperDash.Core/Logging/Debug.cs
@@ -18,87 +18,88 @@ using System.Text.RegularExpressions;
namespace PepperDash.Core;
- ///
- /// Contains debug commands for use in various situations
- ///
- public static class Debug
+///
+/// Contains debug commands for use in various situations
+///
+public static class Debug
+{
+ private static readonly string LevelStoreKey = "ConsoleDebugLevel";
+ private static readonly string WebSocketLevelStoreKey = "WebsocketDebugLevel";
+ private static readonly string ErrorLogLevelStoreKey = "ErrorLogDebugLevel";
+ private static readonly string FileLevelStoreKey = "FileDebugLevel";
+ private static readonly string DoNotLoadOnNextBootKey = "DoNotLoadOnNextBoot";
+
+ private static readonly Dictionary _logLevels = new Dictionary()
{
- private static readonly string LevelStoreKey = "ConsoleDebugLevel";
- private static readonly string WebSocketLevelStoreKey = "WebsocketDebugLevel";
- private static readonly string ErrorLogLevelStoreKey = "ErrorLogDebugLevel";
- private static readonly string FileLevelStoreKey = "FileDebugLevel";
+ {0, LogEventLevel.Information },
+ {3, LogEventLevel.Warning },
+ {4, LogEventLevel.Error },
+ {5, LogEventLevel.Fatal },
+ {1, LogEventLevel.Debug },
+ {2, LogEventLevel.Verbose },
+ };
- private static readonly Dictionary _logLevels = new Dictionary()
- {
- {0, LogEventLevel.Information },
- {3, LogEventLevel.Warning },
- {4, LogEventLevel.Error },
- {5, LogEventLevel.Fatal },
- {1, LogEventLevel.Debug },
- {2, LogEventLevel.Verbose },
- };
+ private static ILogger _logger;
- private static ILogger _logger;
+ private static readonly LoggingLevelSwitch _consoleLoggingLevelSwitch;
- private static readonly LoggingLevelSwitch _consoleLoggingLevelSwitch;
+ private static readonly LoggingLevelSwitch _websocketLoggingLevelSwitch;
- private static readonly LoggingLevelSwitch _websocketLoggingLevelSwitch;
+ private static readonly LoggingLevelSwitch _errorLogLevelSwitch;
- private static readonly LoggingLevelSwitch _errorLogLevelSwitch;
+ private static readonly LoggingLevelSwitch _fileLevelSwitch;
- private static readonly LoggingLevelSwitch _fileLevelSwitch;
+ public static LogEventLevel WebsocketMinimumLogLevel
+ {
+ get { return _websocketLoggingLevelSwitch.MinimumLevel; }
+ }
- public static LogEventLevel WebsocketMinimumLogLevel
- {
- get { return _websocketLoggingLevelSwitch.MinimumLevel; }
- }
+ private static readonly DebugWebsocketSink _websocketSink;
- private static readonly DebugWebsocketSink _websocketSink;
+ public static DebugWebsocketSink WebsocketSink
+ {
+ get { return _websocketSink; }
+ }
- public static DebugWebsocketSink WebsocketSink
- {
- get { return _websocketSink; }
- }
+ ///
+ /// Describes the folder location where a given program stores it's debug level memory. By default, the
+ /// file written will be named appNdebug where N is 1-10.
+ ///
+ public static string OldFilePathPrefix = @"\nvram\debug\";
- ///
- /// Describes the folder location where a given program stores it's debug level memory. By default, the
- /// file written will be named appNdebug where N is 1-10.
- ///
- public static string OldFilePathPrefix = @"\nvram\debug\";
+ ///
+ /// Describes the new folder location where a given program stores it's debug level memory. By default, the
+ /// file written will be named appNdebug where N is 1-10.
+ ///
+ public static string NewFilePathPrefix = @"\user\debug\";
- ///
- /// Describes the new folder location where a given program stores it's debug level memory. By default, the
- /// file written will be named appNdebug where N is 1-10.
- ///
- public static string NewFilePathPrefix = @"\user\debug\";
+ ///
+ /// The name of the file containing the current debug settings.
+ ///
+ public static string FileName = string.Format(@"app{0}Debug.json", InitialParametersClass.ApplicationNumber);
- ///
- /// The name of the file containing the current debug settings.
- ///
- public static string FileName = string.Format(@"app{0}Debug.json", InitialParametersClass.ApplicationNumber);
+ ///
+ /// Debug level to set for a given program.
+ ///
+ public static int Level { get; private set; }
- ///
- /// Debug level to set for a given program.
- ///
- public static int Level { get; private set; }
+ ///
+ /// When this is true, the configuration file will NOT be loaded until triggered by either a console command or a signal
+ ///
+ public static bool DoNotLoadConfigOnNextBoot { get; private set; }
- ///
- /// When this is true, the configuration file will NOT be loaded until triggered by either a console command or a signal
- ///
- public static bool DoNotLoadConfigOnNextBoot { get; private set; }
+ private static DebugContextCollection _contexts;
- private static DebugContextCollection _contexts;
+ private const int SaveTimeoutMs = 30000;
- private const int SaveTimeoutMs = 30000;
+ public static bool IsRunningOnAppliance = CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance;
- public static bool IsRunningOnAppliance = CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance;
+ ///
+ /// Version for the currently loaded PepperDashCore dll
+ ///
+ public static string PepperDashCoreVersion { get; private set; }
- ///
- /// Version for the currently loaded PepperDashCore dll
- ///
- public static string PepperDashCoreVersion { get; private set; }
-
- private static CTimer _saveTimer;
+ private static CTimer _saveTimer;
///
/// When true, the IncludedExcludedKeys dict will contain keys to include.
@@ -110,360 +111,361 @@ namespace PepperDash.Core;
private static readonly Dictionary IncludedExcludedKeys;
- private static readonly LoggerConfiguration _defaultLoggerConfiguration;
+ private static readonly LoggerConfiguration _defaultLoggerConfiguration;
- private static LoggerConfiguration _loggerConfiguration;
+ private static LoggerConfiguration _loggerConfiguration;
- public static LoggerConfiguration LoggerConfiguration => _loggerConfiguration;
+ public static LoggerConfiguration LoggerConfiguration => _loggerConfiguration;
- static Debug()
+ static Debug()
+ {
+ try
+ {
+ CrestronDataStoreStatic.InitCrestronDataStore();
+
+ var defaultConsoleLevel = GetStoredLogEventLevel(LevelStoreKey);
+
+ var defaultWebsocketLevel = GetStoredLogEventLevel(WebSocketLevelStoreKey);
+
+ var defaultErrorLogLevel = GetStoredLogEventLevel(ErrorLogLevelStoreKey);
+
+ var defaultFileLogLevel = GetStoredLogEventLevel(FileLevelStoreKey);
+
+ _consoleLoggingLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultConsoleLevel);
+
+ _websocketLoggingLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultWebsocketLevel);
+
+ _errorLogLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultErrorLogLevel);
+
+ _fileLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultFileLogLevel);
+
+ _websocketSink = new DebugWebsocketSink(new JsonFormatter(renderMessage: true));
+
+ var logFilePath = CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance ?
+ $@"{Directory.GetApplicationRootDirectory()}{Path.DirectorySeparatorChar}user{Path.DirectorySeparatorChar}debug{Path.DirectorySeparatorChar}app{InitialParametersClass.ApplicationNumber}{Path.DirectorySeparatorChar}global-log.log" :
+ $@"{Directory.GetApplicationRootDirectory()}{Path.DirectorySeparatorChar}user{Path.DirectorySeparatorChar}debug{Path.DirectorySeparatorChar}room{InitialParametersClass.RoomId}{Path.DirectorySeparatorChar}global-log.log";
+
+ CrestronConsole.PrintLine($"Saving log files to {logFilePath}");
+
+ var errorLogTemplate = CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance
+ ? "{@t:fff}ms [{@l:u4}]{#if Key is not null}[{Key}]{#end} {@m}{#if @x is not null}\r\n{@x}{#end}"
+ : "[{@t:yyyy-MM-dd HH:mm:ss.fff}][{@l:u4}][{App}]{#if Key is not null}[{Key}]{#end} {@m}{#if @x is not null}\r\n{@x}{#end}";
+
+ _defaultLoggerConfiguration = new LoggerConfiguration()
+ .MinimumLevel.Verbose()
+ .Enrich.FromLogContext()
+ .Enrich.With(new CrestronEnricher())
+ .WriteTo.Sink(new DebugConsoleSink(new ExpressionTemplate("[{@t:yyyy-MM-dd HH:mm:ss.fff}][{@l:u4}][{App}]{#if Key is not null}[{Key}]{#end} {@m}{#if @x is not null}\r\n{@x}{#end}")), levelSwitch: _consoleLoggingLevelSwitch)
+ .WriteTo.Sink(_websocketSink, levelSwitch: _websocketLoggingLevelSwitch)
+ .WriteTo.Sink(new DebugErrorLogSink(new ExpressionTemplate(errorLogTemplate)), levelSwitch: _errorLogLevelSwitch)
+ .WriteTo.File(new RenderedCompactJsonFormatter(), logFilePath,
+ rollingInterval: RollingInterval.Day,
+ restrictedToMinimumLevel: LogEventLevel.Debug,
+ retainedFileCountLimit: CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance ? 30 : 60,
+ levelSwitch: _fileLevelSwitch
+ );
+
+ // Instantiate the root logger
+ _loggerConfiguration = _defaultLoggerConfiguration;
+
+ _logger = _loggerConfiguration.CreateLogger();
+ // Get the assembly version and print it to console and the log
+ GetVersion();
+
+ string msg = $"[App {InitialParametersClass.ApplicationNumber}] Using PepperDash_Core v{PepperDashCoreVersion}";
+
+ if (CrestronEnvironment.DevicePlatform == eDevicePlatform.Server)
+ {
+ msg = $"[Room {InitialParametersClass.RoomId}] Using PepperDash_Core v{PepperDashCoreVersion}";
+ }
+
+ CrestronConsole.PrintLine(msg);
+
+ LogMessage(LogEventLevel.Information, msg);
+
+ IncludedExcludedKeys = new Dictionary();
+
+ if (CrestronEnvironment.RuntimeEnvironment == eRuntimeEnvironment.SimplSharpPro)
+ {
+ // Add command to console
+ CrestronConsole.AddNewConsoleCommand(SetDoNotLoadOnNextBootFromConsole, "donotloadonnextboot",
+ "donotloadonnextboot:P [true/false]: Should the application load on next boot", ConsoleAccessLevelEnum.AccessOperator);
+
+ CrestronConsole.AddNewConsoleCommand(SetDebugFromConsole, "appdebug",
+ "appdebug:P [0-5]: Sets the application's console debug message level",
+ ConsoleAccessLevelEnum.AccessOperator);
+ CrestronConsole.AddNewConsoleCommand(ShowDebugLog, "appdebuglog",
+ "appdebuglog:P [all] Use \"all\" for full log.",
+ ConsoleAccessLevelEnum.AccessOperator);
+ CrestronConsole.AddNewConsoleCommand(s => CrestronLogger.Clear(false), "appdebugclear",
+ "appdebugclear:P Clears the current custom log",
+ ConsoleAccessLevelEnum.AccessOperator);
+ CrestronConsole.AddNewConsoleCommand(SetDebugFilterFromConsole, "appdebugfilter",
+ "appdebugfilter [params]", ConsoleAccessLevelEnum.AccessOperator);
+ }
+
+ CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironment_ProgramStatusEventHandler;
+
+ DoNotLoadConfigOnNextBoot = GetDoNotLoadOnNextBoot();
+
+ if (DoNotLoadConfigOnNextBoot)
+ CrestronConsole.PrintLine(string.Format("Program {0} will not load config after next boot. Use console command go:{0} to load the config manually", InitialParametersClass.ApplicationNumber));
+
+ _consoleLoggingLevelSwitch.MinimumLevelChanged += (sender, args) =>
+ {
+ LogMessage(LogEventLevel.Information, "Console debug level set to {minimumLevel}", _consoleLoggingLevelSwitch.MinimumLevel);
+ };
+ }
+ catch (Exception ex)
{
- CrestronDataStoreStatic.InitCrestronDataStore();
-
- var defaultConsoleLevel = GetStoredLogEventLevel(LevelStoreKey);
-
- var defaultWebsocketLevel = GetStoredLogEventLevel(WebSocketLevelStoreKey);
-
- var defaultErrorLogLevel = GetStoredLogEventLevel(ErrorLogLevelStoreKey);
-
- var defaultFileLogLevel = GetStoredLogEventLevel(FileLevelStoreKey);
-
- _consoleLoggingLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultConsoleLevel);
-
- _websocketLoggingLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultWebsocketLevel);
-
- _errorLogLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultErrorLogLevel);
-
- _fileLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultFileLogLevel);
-
- _websocketSink = new DebugWebsocketSink(new JsonFormatter(renderMessage: true));
-
- var logFilePath = CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance ?
- $@"{Directory.GetApplicationRootDirectory()}{Path.DirectorySeparatorChar}user{Path.DirectorySeparatorChar}debug{Path.DirectorySeparatorChar}app{InitialParametersClass.ApplicationNumber}{Path.DirectorySeparatorChar}global-log.log" :
- $@"{Directory.GetApplicationRootDirectory()}{Path.DirectorySeparatorChar}user{Path.DirectorySeparatorChar}debug{Path.DirectorySeparatorChar}room{InitialParametersClass.RoomId}{Path.DirectorySeparatorChar}global-log.log";
-
- CrestronConsole.PrintLine($"Saving log files to {logFilePath}");
-
- var errorLogTemplate = CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance
- ? "{@t:fff}ms [{@l:u4}]{#if Key is not null}[{Key}]{#end} {@m}{#if @x is not null}\r\n{@x}{#end}"
- : "[{@t:yyyy-MM-dd HH:mm:ss.fff}][{@l:u4}][{App}]{#if Key is not null}[{Key}]{#end} {@m}{#if @x is not null}\r\n{@x}{#end}";
-
- _defaultLoggerConfiguration = new LoggerConfiguration()
- .MinimumLevel.Verbose()
- .Enrich.FromLogContext()
- .Enrich.With(new CrestronEnricher())
- .WriteTo.Sink(new DebugConsoleSink(new ExpressionTemplate("[{@t:yyyy-MM-dd HH:mm:ss.fff}][{@l:u4}][{App}]{#if Key is not null}[{Key}]{#end} {@m}{#if @x is not null}\r\n{@x}{#end}")), levelSwitch: _consoleLoggingLevelSwitch)
- .WriteTo.Sink(_websocketSink, levelSwitch: _websocketLoggingLevelSwitch)
- .WriteTo.Sink(new DebugErrorLogSink(new ExpressionTemplate(errorLogTemplate)), levelSwitch: _errorLogLevelSwitch)
- .WriteTo.File(new RenderedCompactJsonFormatter(), logFilePath,
- rollingInterval: RollingInterval.Day,
- restrictedToMinimumLevel: LogEventLevel.Debug,
- retainedFileCountLimit: CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance ? 30 : 60,
- levelSwitch: _fileLevelSwitch
- );
-
- try
- {
- if (InitialParametersClass.NumberOfRemovableDrives > 0)
- {
- CrestronConsole.PrintLine("{0} RM Drive(s) Present. Initializing CrestronLogger", InitialParametersClass.NumberOfRemovableDrives);
- _defaultLoggerConfiguration.WriteTo.Sink(new DebugCrestronLoggerSink());
- }
- else
- CrestronConsole.PrintLine("No RM Drive(s) Present. Not using Crestron Logger");
- }
- catch (Exception e)
- {
- CrestronConsole.PrintLine("Initializing of CrestronLogger failed: {0}", e);
- }
-
- // Instantiate the root logger
- _loggerConfiguration = _defaultLoggerConfiguration;
-
- _logger = _loggerConfiguration.CreateLogger();
- // Get the assembly version and print it to console and the log
- GetVersion();
-
- string msg = $"[App {InitialParametersClass.ApplicationNumber}] Using PepperDash_Core v{PepperDashCoreVersion}";
-
- if (CrestronEnvironment.DevicePlatform == eDevicePlatform.Server)
- {
- msg = $"[Room {InitialParametersClass.RoomId}] Using PepperDash_Core v{PepperDashCoreVersion}";
- }
-
- CrestronConsole.PrintLine(msg);
-
- LogMessage(LogEventLevel.Information,msg);
-
- IncludedExcludedKeys = new Dictionary();
-
- if (CrestronEnvironment.RuntimeEnvironment == eRuntimeEnvironment.SimplSharpPro)
- {
- // Add command to console
- CrestronConsole.AddNewConsoleCommand(SetDoNotLoadOnNextBootFromConsole, "donotloadonnextboot",
- "donotloadonnextboot:P [true/false]: Should the application load on next boot", ConsoleAccessLevelEnum.AccessOperator);
-
- CrestronConsole.AddNewConsoleCommand(SetDebugFromConsole, "appdebug",
- "appdebug:P [0-5]: Sets the application's console debug message level",
- ConsoleAccessLevelEnum.AccessOperator);
- CrestronConsole.AddNewConsoleCommand(ShowDebugLog, "appdebuglog",
- "appdebuglog:P [all] Use \"all\" for full log.",
- ConsoleAccessLevelEnum.AccessOperator);
- CrestronConsole.AddNewConsoleCommand(s => CrestronLogger.Clear(false), "appdebugclear",
- "appdebugclear:P Clears the current custom log",
- ConsoleAccessLevelEnum.AccessOperator);
- CrestronConsole.AddNewConsoleCommand(SetDebugFilterFromConsole, "appdebugfilter",
- "appdebugfilter [params]", ConsoleAccessLevelEnum.AccessOperator);
- }
-
- CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironment_ProgramStatusEventHandler;
-
- LoadMemory();
-
- var context = _contexts.GetOrCreateItem("DEFAULT");
- Level = context.Level;
- DoNotLoadConfigOnNextBoot = context.DoNotLoadOnNextBoot;
-
- if(DoNotLoadConfigOnNextBoot)
- CrestronConsole.PrintLine(string.Format("Program {0} will not load config after next boot. Use console command go:{0} to load the config manually", InitialParametersClass.ApplicationNumber));
-
- _consoleLoggingLevelSwitch.MinimumLevelChanged += (sender, args) =>
- {
- LogMessage(LogEventLevel.Information, "Console debug level set to {minimumLevel}", _consoleLoggingLevelSwitch.MinimumLevel);
- };
+ LogError(ex, "Exception in Debug static constructor: {message}", ex.Message);
}
+ }
- public static void UpdateLoggerConfiguration(LoggerConfiguration config)
+ private static bool GetDoNotLoadOnNextBoot()
+ {
+ var err = CrestronDataStoreStatic.GetLocalBoolValue(DoNotLoadOnNextBootKey, out var doNotLoad);
+
+ if (err != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
+ {
+ LogError("Error retrieving DoNotLoadOnNextBoot value: {err}", err);
+ doNotLoad = false;
+ }
+
+ return doNotLoad;
+ }
+
+ public static void UpdateLoggerConfiguration(LoggerConfiguration config)
+ {
+ _loggerConfiguration = config;
+
+ _logger = config.CreateLogger();
+ }
+
+ public static void ResetLoggerConfiguration()
+ {
+ _loggerConfiguration = _defaultLoggerConfiguration;
+
+ _logger = _loggerConfiguration.CreateLogger();
+ }
+
+ private static LogEventLevel GetStoredLogEventLevel(string levelStoreKey)
+ {
+ try
{
- _loggerConfiguration = config;
+ var result = CrestronDataStoreStatic.GetLocalIntValue(levelStoreKey, out int logLevel);
- _logger = config.CreateLogger();
- }
-
- public static void ResetLoggerConfiguration()
- {
- _loggerConfiguration = _defaultLoggerConfiguration;
-
- _logger = _loggerConfiguration.CreateLogger();
- }
-
- private static LogEventLevel GetStoredLogEventLevel(string levelStoreKey)
- {
- try
+ if (result != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
{
- var result = CrestronDataStoreStatic.GetLocalIntValue(levelStoreKey, out int logLevel);
-
- if (result != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
- {
- CrestronConsole.Print($"Unable to retrieve stored log level for {levelStoreKey}.\r\nError: {result}.\r\nSetting level to {LogEventLevel.Information}\r\n");
- return LogEventLevel.Information;
- }
-
- if(logLevel < 0 || logLevel > 5)
- {
- CrestronConsole.PrintLine($"Stored Log level not valid for {levelStoreKey}: {logLevel}. Setting level to {LogEventLevel.Information}");
- return LogEventLevel.Information;
- }
-
- return (LogEventLevel)logLevel;
- } catch (Exception ex)
- {
- CrestronConsole.PrintLine($"Exception retrieving log level for {levelStoreKey}: {ex.Message}");
+ CrestronConsole.Print($"Unable to retrieve stored log level for {levelStoreKey}.\r\nError: {result}.\r\nSetting level to {LogEventLevel.Information}\r\n");
return LogEventLevel.Information;
}
- }
- private static void GetVersion()
- {
- var assembly = Assembly.GetExecutingAssembly();
- var ver =
- assembly
- .GetCustomAttributes(typeof (AssemblyInformationalVersionAttribute), false);
-
- if (ver != null && ver.Length > 0)
+ if(logLevel < 0 || logLevel > 5)
{
- if (ver[0] is AssemblyInformationalVersionAttribute verAttribute)
- {
- PepperDashCoreVersion = verAttribute.InformationalVersion;
- }
+ CrestronConsole.PrintLine($"Stored Log level not valid for {levelStoreKey}: {logLevel}. Setting level to {LogEventLevel.Information}");
+ return LogEventLevel.Information;
}
- else
+
+ return (LogEventLevel)logLevel;
+ } catch (Exception ex)
+ {
+ CrestronConsole.PrintLine($"Exception retrieving log level for {levelStoreKey}: {ex.Message}");
+ return LogEventLevel.Information;
+ }
+ }
+
+ private static void GetVersion()
+ {
+ var assembly = Assembly.GetExecutingAssembly();
+ var ver =
+ assembly
+ .GetCustomAttributes(typeof (AssemblyInformationalVersionAttribute), false);
+
+ if (ver != null && ver.Length > 0)
+ {
+ if (ver[0] is AssemblyInformationalVersionAttribute verAttribute)
{
- var version = assembly.GetName().Version;
- PepperDashCoreVersion = version.ToString();
+ PepperDashCoreVersion = verAttribute.InformationalVersion;
}
}
-
- ///
- /// Used to save memory when shutting down
- ///
- ///
- static void CrestronEnvironment_ProgramStatusEventHandler(eProgramStatusEventType programEventType)
+ else
{
-
- if (programEventType == eProgramStatusEventType.Stopping)
- {
- Log.CloseAndFlush();
-
- if (_saveTimer != null)
- {
- _saveTimer.Stop();
- _saveTimer = null;
- }
- LogMessage(LogEventLevel.Information, "Saving debug settings");
- SaveMemory();
- }
+ var version = assembly.GetName().Version;
+ PepperDashCoreVersion = version.ToString();
}
+ }
- ///
- /// Callback for console command
- ///
- ///
- public static void SetDebugFromConsole(string levelString)
+ ///
+ /// Used to save memory when shutting down
+ ///
+ ///
+ static void CrestronEnvironment_ProgramStatusEventHandler(eProgramStatusEventType programEventType)
+ {
+
+ if (programEventType == eProgramStatusEventType.Stopping)
{
- try
+ Log.CloseAndFlush();
+
+ if (_saveTimer != null)
{
- if (levelString.Trim() == "?")
- {
- CrestronConsole.ConsoleCommandResponse(
- $@"Used to set the minimum level of debug messages to be printed to the console:
+ _saveTimer.Stop();
+ _saveTimer = null;
+ }
+ LogMessage(LogEventLevel.Information, "Saving debug settings");
+ SaveMemory();
+ }
+ }
+
+ ///
+ /// Callback for console command
+ ///
+ ///
+ public static void SetDebugFromConsole(string levelString)
+ {
+ try
+ {
+ if (levelString.Trim() == "?")
+ {
+ CrestronConsole.ConsoleCommandResponse(
+ $@"Used to set the minimum level of debug messages to be printed to the console:
{_logLevels[0]} = 0
{_logLevels[1]} = 1
{_logLevels[2]} = 2
{_logLevels[3]} = 3
{_logLevels[4]} = 4
{_logLevels[5]} = 5");
- return;
- }
-
- if (string.IsNullOrEmpty(levelString.Trim()))
- {
- CrestronConsole.ConsoleCommandResponse("AppDebug level = {0}", _consoleLoggingLevelSwitch.MinimumLevel);
- return;
- }
-
- if(int.TryParse(levelString, out var levelInt))
- {
- if(levelInt < 0 || levelInt > 5)
- {
- CrestronConsole.ConsoleCommandResponse($"Error: Unable to parse {levelString} to valid log level. If using a number, value must be between 0-5");
- return;
- }
- SetDebugLevel((uint) levelInt);
- return;
- }
-
- if(Enum.TryParse(levelString, out var levelEnum))
- {
- SetDebugLevel(levelEnum);
- return;
- }
-
- CrestronConsole.ConsoleCommandResponse($"Error: Unable to parse {levelString} to valid log level");
- }
- catch
- {
- CrestronConsole.ConsoleCommandResponse("Usage: appdebug:P [0-5]");
+ return;
}
- }
- ///
- /// Sets the debug level
- ///
- /// Valid values 0-5
- public static void SetDebugLevel(uint level)
+ if (string.IsNullOrEmpty(levelString.Trim()))
+ {
+ CrestronConsole.ConsoleCommandResponse("AppDebug level = {0}", _consoleLoggingLevelSwitch.MinimumLevel);
+ return;
+ }
+
+ if(int.TryParse(levelString, out var levelInt))
+ {
+ if(levelInt < 0 || levelInt > 5)
+ {
+ CrestronConsole.ConsoleCommandResponse($"Error: Unable to parse {levelString} to valid log level. If using a number, value must be between 0-5");
+ return;
+ }
+ SetDebugLevel((uint) levelInt);
+ return;
+ }
+
+ if(Enum.TryParse(levelString, out var levelEnum))
+ {
+ SetDebugLevel(levelEnum);
+ return;
+ }
+
+ CrestronConsole.ConsoleCommandResponse($"Error: Unable to parse {levelString} to valid log level");
+ }
+ catch
{
- if(!_logLevels.TryGetValue(level, out var logLevel))
- {
- logLevel = LogEventLevel.Information;
+ CrestronConsole.ConsoleCommandResponse("Usage: appdebug:P [0-5]");
+ }
+ }
- CrestronConsole.ConsoleCommandResponse($"{level} not valid. Setting level to {logLevel}");
+ ///
+ /// Sets the debug level
+ ///
+ /// Valid values 0-5
+ public static void SetDebugLevel(uint level)
+ {
+ if(!_logLevels.TryGetValue(level, out var logLevel))
+ {
+ logLevel = LogEventLevel.Information;
- SetDebugLevel(logLevel);
- }
+ CrestronConsole.ConsoleCommandResponse($"{level} not valid. Setting level to {logLevel}");
SetDebugLevel(logLevel);
}
- public static void SetDebugLevel(LogEventLevel level)
+ SetDebugLevel(logLevel);
+ }
+
+ public static void SetDebugLevel(LogEventLevel level)
+ {
+ _consoleLoggingLevelSwitch.MinimumLevel = level;
+
+ CrestronConsole.ConsoleCommandResponse("[Application {0}], Debug level set to {1}\r\n",
+ InitialParametersClass.ApplicationNumber, _consoleLoggingLevelSwitch.MinimumLevel);
+
+ CrestronConsole.ConsoleCommandResponse($"Storing level {level}:{(int) level}");
+
+ var err = CrestronDataStoreStatic.SetLocalIntValue(LevelStoreKey, (int) level);
+
+ CrestronConsole.ConsoleCommandResponse($"Store result: {err}:{(int)level}");
+
+ if (err != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
+ CrestronConsole.PrintLine($"Error saving console debug level setting: {err}");
+ }
+
+ public static void SetWebSocketMinimumDebugLevel(LogEventLevel level)
+ {
+ _websocketLoggingLevelSwitch.MinimumLevel = level;
+
+ var err = CrestronDataStoreStatic.SetLocalUintValue(WebSocketLevelStoreKey, (uint) level);
+
+ if (err != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
+ LogMessage(LogEventLevel.Information, "Error saving websocket debug level setting: {erro}", err);
+
+ LogMessage(LogEventLevel.Information, "Websocket debug level set to {0}", _websocketLoggingLevelSwitch.MinimumLevel);
+ }
+
+ public static void SetErrorLogMinimumDebugLevel(LogEventLevel level)
+ {
+ _errorLogLevelSwitch.MinimumLevel = level;
+
+ var err = CrestronDataStoreStatic.SetLocalUintValue(ErrorLogLevelStoreKey, (uint)level);
+
+ if (err != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
+ LogMessage(LogEventLevel.Information, "Error saving Error Log debug level setting: {error}", err);
+
+ LogMessage(LogEventLevel.Information, "Error log debug level set to {0}", _websocketLoggingLevelSwitch.MinimumLevel);
+ }
+
+ public static void SetFileMinimumDebugLevel(LogEventLevel level)
+ {
+ _errorLogLevelSwitch.MinimumLevel = level;
+
+ var err = CrestronDataStoreStatic.SetLocalUintValue(ErrorLogLevelStoreKey, (uint)level);
+
+ if (err != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
+ LogMessage(LogEventLevel.Information, "Error saving File debug level setting: {error}", err);
+
+ LogMessage(LogEventLevel.Information, "File debug level set to {0}", _websocketLoggingLevelSwitch.MinimumLevel);
+ }
+
+ ///
+ /// Callback for console command
+ ///
+ ///
+ public static void SetDoNotLoadOnNextBootFromConsole(string stateString)
+ {
+ try
{
- _consoleLoggingLevelSwitch.MinimumLevel = level;
-
- CrestronConsole.ConsoleCommandResponse("[Application {0}], Debug level set to {1}\r\n",
- InitialParametersClass.ApplicationNumber, _consoleLoggingLevelSwitch.MinimumLevel);
-
- CrestronConsole.ConsoleCommandResponse($"Storing level {level}:{(int) level}");
-
- var err = CrestronDataStoreStatic.SetLocalIntValue(LevelStoreKey, (int) level);
-
- CrestronConsole.ConsoleCommandResponse($"Store result: {err}:{(int)level}");
-
- if (err != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
- CrestronConsole.PrintLine($"Error saving console debug level setting: {err}");
- }
-
- public static void SetWebSocketMinimumDebugLevel(LogEventLevel level)
- {
- _websocketLoggingLevelSwitch.MinimumLevel = level;
-
- var err = CrestronDataStoreStatic.SetLocalUintValue(WebSocketLevelStoreKey, (uint) level);
-
- if (err != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
- LogMessage(LogEventLevel.Information, "Error saving websocket debug level setting: {erro}", err);
-
- LogMessage(LogEventLevel.Information, "Websocket debug level set to {0}", _websocketLoggingLevelSwitch.MinimumLevel);
- }
-
- public static void SetErrorLogMinimumDebugLevel(LogEventLevel level)
- {
- _errorLogLevelSwitch.MinimumLevel = level;
-
- var err = CrestronDataStoreStatic.SetLocalUintValue(ErrorLogLevelStoreKey, (uint)level);
-
- if (err != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
- LogMessage(LogEventLevel.Information, "Error saving Error Log debug level setting: {error}", err);
-
- LogMessage(LogEventLevel.Information, "Error log debug level set to {0}", _websocketLoggingLevelSwitch.MinimumLevel);
- }
-
- public static void SetFileMinimumDebugLevel(LogEventLevel level)
- {
- _errorLogLevelSwitch.MinimumLevel = level;
-
- var err = CrestronDataStoreStatic.SetLocalUintValue(ErrorLogLevelStoreKey, (uint)level);
-
- if (err != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
- LogMessage(LogEventLevel.Information, "Error saving File debug level setting: {error}", err);
-
- LogMessage(LogEventLevel.Information, "File debug level set to {0}", _websocketLoggingLevelSwitch.MinimumLevel);
- }
-
- ///
- /// Callback for console command
- ///
- ///
- public static void SetDoNotLoadOnNextBootFromConsole(string stateString)
- {
- try
+ if (string.IsNullOrEmpty(stateString.Trim()))
{
- if (string.IsNullOrEmpty(stateString.Trim()))
- {
- CrestronConsole.ConsoleCommandResponse("DoNotLoadOnNextBoot = {0}", DoNotLoadConfigOnNextBoot);
- return;
- }
+ CrestronConsole.ConsoleCommandResponse("DoNotLoadOnNextBoot = {0}", DoNotLoadConfigOnNextBoot);
+ return;
+ }
- SetDoNotLoadConfigOnNextBoot(bool.Parse(stateString));
- }
- catch
- {
- CrestronConsole.ConsoleCommandResponse("Usage: donotloadonnextboot:P [true/false]");
- }
+ SetDoNotLoadConfigOnNextBoot(bool.Parse(stateString));
}
+ catch
+ {
+ CrestronConsole.ConsoleCommandResponse("Usage: donotloadonnextboot:P [true/false]");
+ }
+ }
- ///
- /// Callback for console command
- ///
- ///
+ ///
+ /// Callback for console command
+ ///
+ ///
public static void SetDebugFilterFromConsole(string items)
{
var str = items.Trim();
@@ -542,486 +544,488 @@ namespace PepperDash.Core;
- ///
- /// sets the settings for a device or creates a new entry
- ///
- ///
- ///
- ///
- public static void SetDeviceDebugSettings(string deviceKey, object settings)
+ ///
+ /// sets the settings for a device or creates a new entry
+ ///
+ ///
+ ///
+ ///
+ public static void SetDeviceDebugSettings(string deviceKey, object settings)
+ {
+ _contexts.SetDebugSettingsForKey(deviceKey, settings);
+ SaveMemoryOnTimeout();
+ }
+
+ ///
+ /// Gets the device settings for a device by key or returns null
+ ///
+ ///
+ ///
+ public static object GetDeviceDebugSettingsForKey(string deviceKey)
+ {
+ return _contexts.GetDebugSettingsForKey(deviceKey);
+ }
+
+ ///
+ /// Sets the flag to prevent application starting on next boot
+ ///
+ ///
+ public static void SetDoNotLoadConfigOnNextBoot(bool state)
+ {
+ DoNotLoadConfigOnNextBoot = state;
+
+ var err = CrestronDataStoreStatic.SetLocalBoolValue(DoNotLoadOnNextBootKey, state);
+
+ if (err != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
+ LogError("Error saving console debug level setting: {err}", err);
+
+ LogInformation("Do Not Load Config on Next Boot set to {state}", DoNotLoadConfigOnNextBoot);
+ }
+
+ ///
+ ///
+ ///
+ public static void ShowDebugLog(string s)
+ {
+ var loglist = CrestronLogger.PrintTheLog(s.ToLower() == "all");
+ foreach (var l in loglist)
+ CrestronConsole.ConsoleCommandResponse(l + CrestronEnvironment.NewLine);
+ }
+
+ ///
+ /// Log an Exception as an Error
+ ///
+ /// Exception to log
+ /// Message template
+ /// Optional IKeyed device. If provided, the Key of the device will be added to the log message
+ /// Args to put into message template
+ public static void LogMessage(Exception ex, string message, IKeyed device = null, params object[] args)
+ {
+ using (LogContext.PushProperty("Key", device?.Key))
{
- _contexts.SetDebugSettingsForKey(deviceKey, settings);
- SaveMemoryOnTimeout();
+ _logger.Error(ex, message, args);
}
+ }
- ///
- /// Gets the device settings for a device by key or returns null
- ///
- ///
- ///
- public static object GetDeviceDebugSettingsForKey(string deviceKey)
+ ///
+ /// Log a message
+ ///
+ /// Level to log at
+ /// Message template
+ /// Optional IKeyed device. If provided, the Key of the device will be added to the log message
+ /// Args to put into message template
+ public static void LogMessage(LogEventLevel level, string message, IKeyed device = null, params object[] args)
+ {
+ using (LogContext.PushProperty("Key", device?.Key))
{
- return _contexts.GetDebugSettingsForKey(deviceKey);
- }
-
- ///
- /// Sets the flag to prevent application starting on next boot
- ///
- ///
- public static void SetDoNotLoadConfigOnNextBoot(bool state)
- {
- DoNotLoadConfigOnNextBoot = state;
- _contexts.GetOrCreateItem("DEFAULT").DoNotLoadOnNextBoot = state;
- SaveMemoryOnTimeout();
-
- CrestronConsole.ConsoleCommandResponse("[Application {0}], Do Not Load Config on Next Boot set to {1}",
- InitialParametersClass.ApplicationNumber, DoNotLoadConfigOnNextBoot);
+ _logger.Write(level, message, args);
}
+ }
- ///
- ///
- ///
- public static void ShowDebugLog(string s)
- {
- var loglist = CrestronLogger.PrintTheLog(s.ToLower() == "all");
- foreach (var l in loglist)
- CrestronConsole.ConsoleCommandResponse(l + CrestronEnvironment.NewLine);
- }
+ public static void LogMessage(LogEventLevel level, string message, params object[] args)
+ {
+ _logger.Write(level, message, args);
+ }
- ///
- /// Log an Exception as an Error
- ///
- /// Exception to log
- /// Message template
- /// Optional IKeyed device. If provided, the Key of the device will be added to the log message
- /// Args to put into message template
- public static void LogMessage(Exception ex, string message, IKeyed device = null, params object[] args)
- {
- using (LogContext.PushProperty("Key", device?.Key))
- {
- _logger.Error(ex, message, args);
- }
- }
+ public static void LogMessage(LogEventLevel level, Exception ex, string message, params object[] args)
+ {
+ _logger.Write(level, ex, message, args);
+ }
- ///
- /// Log a message
- ///
- /// Level to log at
- /// Message template
- /// Optional IKeyed device. If provided, the Key of the device will be added to the log message
- /// Args to put into message template
- public static void LogMessage(LogEventLevel level, string message, IKeyed device = null, params object[] args)
- {
- using (LogContext.PushProperty("Key", device?.Key))
- {
- _logger.Write(level, message, args);
- }
- }
+ public static void LogMessage(LogEventLevel level, IKeyed keyed, string message, params object[] args)
+ {
+ LogMessage(level, message, keyed, args);
+ }
- public static void LogMessage(LogEventLevel level, string message, params object[] args)
- {
- _logger.Write(level, message, args);
- }
-
- public static void LogMessage(LogEventLevel level, Exception ex, string message, params object[] args)
+ public static void LogMessage(LogEventLevel level, Exception ex, IKeyed device, string message, params object[] args)
+ {
+ using (LogContext.PushProperty("Key", device?.Key))
{
_logger.Write(level, ex, message, args);
}
+ }
- public static void LogMessage(LogEventLevel level, IKeyed keyed, string message, params object[] args)
- {
- LogMessage(level, message, keyed, args);
- }
-
- public static void LogMessage(LogEventLevel level, Exception ex, IKeyed device, string message, params object[] args)
- {
- using (LogContext.PushProperty("Key", device?.Key))
- {
- _logger.Write(level, ex, message, args);
- }
- }
-
- #region Explicit methods for logging levels
- public static void LogVerbose(IKeyed keyed, string message, params object[] args)
- {
- using(LogContext.PushProperty("Key", keyed?.Key))
- {
- _logger.Write(LogEventLevel.Verbose, message, args);
- }
- }
-
- public static void LogVerbose(Exception ex, IKeyed keyed, string message, params object[] args)
- {
- using(LogContext.PushProperty("Key", keyed?.Key))
- {
- _logger.Write(LogEventLevel.Verbose, ex, message, args);
- }
- }
-
- public static void LogVerbose(string message, params object[] args)
+ #region Explicit methods for logging levels
+ public static void LogVerbose(IKeyed keyed, string message, params object[] args)
+ {
+ using(LogContext.PushProperty("Key", keyed?.Key))
{
_logger.Write(LogEventLevel.Verbose, message, args);
}
+ }
- public static void LogVerbose(Exception ex, string message, params object[] args)
+ public static void LogVerbose(Exception ex, IKeyed keyed, string message, params object[] args)
+ {
+ using(LogContext.PushProperty("Key", keyed?.Key))
{
- _logger.Write(LogEventLevel.Verbose, ex, null, message, args);
+ _logger.Write(LogEventLevel.Verbose, ex, message, args);
}
+ }
- public static void LogDebug(IKeyed keyed, string message, params object[] args)
- {
- using (LogContext.PushProperty("Key", keyed?.Key))
- {
- _logger.Write(LogEventLevel.Debug, message, args);
- }
- }
+ public static void LogVerbose(string message, params object[] args)
+ {
+ _logger.Write(LogEventLevel.Verbose, message, args);
+ }
- public static void LogDebug(Exception ex, IKeyed keyed, string message, params object[] args)
- {
- using (LogContext.PushProperty("Key", keyed?.Key))
- {
- _logger.Write(LogEventLevel.Debug, ex, message, args);
- }
- }
+ public static void LogVerbose(Exception ex, string message, params object[] args)
+ {
+ _logger.Write(LogEventLevel.Verbose, ex, null, message, args);
+ }
- public static void LogDebug(string message, params object[] args)
+ public static void LogDebug(IKeyed keyed, string message, params object[] args)
+ {
+ using (LogContext.PushProperty("Key", keyed?.Key))
{
_logger.Write(LogEventLevel.Debug, message, args);
}
+ }
- public static void LogDebug(Exception ex, string message, params object[] args)
+ public static void LogDebug(Exception ex, IKeyed keyed, string message, params object[] args)
+ {
+ using (LogContext.PushProperty("Key", keyed?.Key))
{
- _logger.Write(LogEventLevel.Debug, ex, null, message, args);
+ _logger.Write(LogEventLevel.Debug, ex, message, args);
}
+ }
- public static void LogInformation(IKeyed keyed, string message, params object[] args)
- {
- using (LogContext.PushProperty("Key", keyed?.Key))
- {
- _logger.Write(LogEventLevel.Information, message, args);
- }
- }
+ public static void LogDebug(string message, params object[] args)
+ {
+ _logger.Write(LogEventLevel.Debug, message, args);
+ }
- public static void LogInformation(Exception ex, IKeyed keyed, string message, params object[] args)
- {
- using (LogContext.PushProperty("Key", keyed?.Key))
- {
- _logger.Write(LogEventLevel.Information, ex, message, args);
- }
- }
+ public static void LogDebug(Exception ex, string message, params object[] args)
+ {
+ _logger.Write(LogEventLevel.Debug, ex, null, message, args);
+ }
- public static void LogInformation(string message, params object[] args)
+ public static void LogInformation(IKeyed keyed, string message, params object[] args)
+ {
+ using (LogContext.PushProperty("Key", keyed?.Key))
{
_logger.Write(LogEventLevel.Information, message, args);
}
+ }
- public static void LogInformation(Exception ex, string message, params object[] args)
+ public static void LogInformation(Exception ex, IKeyed keyed, string message, params object[] args)
+ {
+ using (LogContext.PushProperty("Key", keyed?.Key))
{
- _logger.Write(LogEventLevel.Information, ex, null, message, args);
+ _logger.Write(LogEventLevel.Information, ex, message, args);
}
+ }
- public static void LogWarning(IKeyed keyed, string message, params object[] args)
- {
- using (LogContext.PushProperty("Key", keyed?.Key))
- {
- _logger.Write(LogEventLevel.Warning, message, args);
- }
- }
+ public static void LogInformation(string message, params object[] args)
+ {
+ _logger.Write(LogEventLevel.Information, message, args);
+ }
- public static void LogWarning(Exception ex, IKeyed keyed, string message, params object[] args)
- {
- using (LogContext.PushProperty("Key", keyed?.Key))
- {
- _logger.Write(LogEventLevel.Warning, ex, message, args);
- }
- }
+ public static void LogInformation(Exception ex, string message, params object[] args)
+ {
+ _logger.Write(LogEventLevel.Information, ex, null, message, args);
+ }
- public static void LogWarning(string message, params object[] args)
+ public static void LogWarning(IKeyed keyed, string message, params object[] args)
+ {
+ using (LogContext.PushProperty("Key", keyed?.Key))
{
_logger.Write(LogEventLevel.Warning, message, args);
}
+ }
- public static void LogWarning(Exception ex, string message, params object[] args)
+ public static void LogWarning(Exception ex, IKeyed keyed, string message, params object[] args)
+ {
+ using (LogContext.PushProperty("Key", keyed?.Key))
{
- _logger.Write(LogEventLevel.Warning, ex, null, message, args);
+ _logger.Write(LogEventLevel.Warning, ex, message, args);
}
+ }
- public static void LogError(IKeyed keyed, string message, params object[] args)
- {
- using (LogContext.PushProperty("Key", keyed?.Key))
- {
- _logger.Write(LogEventLevel.Error, message, args);
- }
- }
+ public static void LogWarning(string message, params object[] args)
+ {
+ _logger.Write(LogEventLevel.Warning, message, args);
+ }
- public static void LogError(Exception ex, IKeyed keyed, string message, params object[] args)
- {
- using (LogContext.PushProperty("Key", keyed?.Key))
- {
- _logger.Write(LogEventLevel.Error, ex, message, args);
- }
- }
+ public static void LogWarning(Exception ex, string message, params object[] args)
+ {
+ _logger.Write(LogEventLevel.Warning, ex, null, message, args);
+ }
- public static void LogError(string message, params object[] args)
+ public static void LogError(IKeyed keyed, string message, params object[] args)
+ {
+ using (LogContext.PushProperty("Key", keyed?.Key))
{
_logger.Write(LogEventLevel.Error, message, args);
}
+ }
- public static void LogError(Exception ex, string message, params object[] args)
+ public static void LogError(Exception ex, IKeyed keyed, string message, params object[] args)
+ {
+ using (LogContext.PushProperty("Key", keyed?.Key))
{
- _logger.Write(LogEventLevel.Error, ex, null, message, args);
+ _logger.Write(LogEventLevel.Error, ex, message, args);
}
+ }
- public static void LogFatal(IKeyed keyed, string message, params object[] args)
- {
- using (LogContext.PushProperty("Key", keyed?.Key))
- {
- _logger.Write(LogEventLevel.Fatal, message, args);
- }
- }
+ public static void LogError(string message, params object[] args)
+ {
+ _logger.Write(LogEventLevel.Error, message, args);
+ }
- public static void LogFatal(Exception ex, IKeyed keyed, string message, params object[] args)
- {
- using (LogContext.PushProperty("Key", keyed?.Key))
- {
- _logger.Write(LogEventLevel.Fatal, ex, message, args);
- }
- }
+ public static void LogError(Exception ex, string message, params object[] args)
+ {
+ _logger.Write(LogEventLevel.Error, ex, null, message, args);
+ }
- public static void LogFatal(string message, params object[] args)
+ public static void LogFatal(IKeyed keyed, string message, params object[] args)
+ {
+ using (LogContext.PushProperty("Key", keyed?.Key))
{
_logger.Write(LogEventLevel.Fatal, message, args);
}
+ }
- public static void LogFatal(Exception ex, string message, params object[] args)
+ public static void LogFatal(Exception ex, IKeyed keyed, string message, params object[] args)
+ {
+ using (LogContext.PushProperty("Key", keyed?.Key))
{
- _logger.Write(LogEventLevel.Fatal, ex, null, message, args);
+ _logger.Write(LogEventLevel.Fatal, ex, message, args);
}
+ }
- #endregion
+ public static void LogFatal(string message, params object[] args)
+ {
+ _logger.Write(LogEventLevel.Fatal, message, args);
+ }
+
+ public static void LogFatal(Exception ex, string message, params object[] args)
+ {
+ _logger.Write(LogEventLevel.Fatal, ex, null, message, args);
+ }
+
+ #endregion
- private static void LogMessage(uint level, string format, params object[] items)
- {
- if (!_logLevels.ContainsKey(level)) return;
+ private static void LogMessage(uint level, string format, params object[] items)
+ {
+ if (!_logLevels.ContainsKey(level)) return;
- var logLevel = _logLevels[level];
-
- LogMessage(logLevel, format, items);
- }
+ var logLevel = _logLevels[level];
+
+ LogMessage(logLevel, format, items);
+ }
- private static void LogMessage(uint level, IKeyed keyed, string format, params object[] items)
- {
- if (!_logLevels.ContainsKey(level)) return;
+ private static void LogMessage(uint level, IKeyed keyed, string format, params object[] items)
+ {
+ if (!_logLevels.ContainsKey(level)) return;
- var logLevel = _logLevels[level];
+ var logLevel = _logLevels[level];
- LogMessage(logLevel, keyed, format, items);
- }
+ LogMessage(logLevel, keyed, format, items);
+ }
- ///
- /// Prints message to console if current debug level is equal to or higher than the level of this message.
- /// Uses CrestronConsole.PrintLine.
- ///
- ///
- /// Console format string
- /// Object parameters
- [Obsolete("Use LogMessage methods. Will be removed in 2.2.0 and later versions")]
- public static void Console(uint level, string format, params object[] items)
- {
+ ///
+ /// Prints message to console if current debug level is equal to or higher than the level of this message.
+ /// Uses CrestronConsole.PrintLine.
+ ///
+ ///
+ /// Console format string
+ /// Object parameters
+ [Obsolete("Use LogMessage methods. Will be removed in 2.2.0 and later versions")]
+ public static void Console(uint level, string format, params object[] items)
+ {
- LogMessage(level, format, items);
+ LogMessage(level, format, items);
- //if (IsRunningOnAppliance)
- //{
- // CrestronConsole.PrintLine("[{0}]App {1} Lvl {2}:{3}", DateTime.Now.ToString("HH:mm:ss.fff"),
- // InitialParametersClass.ApplicationNumber,
- // level,
- // string.Format(format, items));
- //}
- }
+ //if (IsRunningOnAppliance)
+ //{
+ // CrestronConsole.PrintLine("[{0}]App {1} Lvl {2}:{3}", DateTime.Now.ToString("HH:mm:ss.fff"),
+ // InitialParametersClass.ApplicationNumber,
+ // level,
+ // string.Format(format, items));
+ //}
+ }
- ///
+ ///
/// Logs to Console when at-level, and all messages to error log, including device key
- ///
- [Obsolete("Use LogMessage methods, Will be removed in 2.2.0 and later versions")]
- public static void Console(uint level, IKeyed dev, string format, params object[] items)
+ ///
+ [Obsolete("Use LogMessage methods, Will be removed in 2.2.0 and later versions")]
+ public static void Console(uint level, IKeyed dev, string format, params object[] items)
+ {
+ LogMessage(level, dev, format, items);
+
+ //if (Level >= level)
+ // Console(level, "[{0}] {1}", dev.Key, message);
+ }
+
+ ///
+ /// Prints message to console if current debug level is equal to or higher than the level of this message. Always sends message to Error Log.
+ /// Uses CrestronConsole.PrintLine.
+ ///
+ [Obsolete("Use LogMessage methods, Will be removed in 2.2.0 and later versions")]
+ public static void Console(uint level, IKeyed dev, ErrorLogLevel errorLogLevel,
+ string format, params object[] items)
+ {
+ LogMessage(level, dev, format, items);
+ }
+
+ ///
+ /// Logs to Console when at-level, and all messages to error log
+ ///
+ [Obsolete("Use LogMessage methods, Will be removed in 2.2.0 and later versions")]
+ public static void Console(uint level, ErrorLogLevel errorLogLevel,
+ string format, params object[] items)
+ {
+ LogMessage(level, format, items);
+ }
+
+ ///
+ /// Logs to both console and the custom user log (not the built-in error log). If appdebug level is set at
+ /// or above the level provided, then the output will be written to both console and the log. Otherwise
+ /// it will only be written to the log.
+ ///
+ [Obsolete("Use LogMessage methods, Will be removed in 2.2.0 and later versions")]
+ public static void ConsoleWithLog(uint level, string format, params object[] items)
+ {
+ LogMessage(level, format, items);
+
+ // var str = string.Format(format, items);
+ //if (Level >= level)
+ // CrestronConsole.PrintLine("App {0}:{1}", InitialParametersClass.ApplicationNumber, str);
+ // CrestronLogger.WriteToLog(str, level);
+ }
+
+ ///
+ /// Logs to both console and the custom user log (not the built-in error log). If appdebug level is set at
+ /// or above the level provided, then the output will be written to both console and the log. Otherwise
+ /// it will only be written to the log.
+ ///
+ [Obsolete("Use LogMessage methods, Will be removed in 2.2.0 and later versions")]
+ public static void ConsoleWithLog(uint level, IKeyed dev, string format, params object[] items)
+ {
+ LogMessage(level, dev, format, items);
+
+ // var str = string.Format(format, items);
+ // CrestronLogger.WriteToLog(string.Format("[{0}] {1}", dev.Key, str), level);
+ }
+
+ ///
+ /// Prints to log and error log
+ ///
+ ///
+ ///
+ [Obsolete("Use LogMessage methods, Will be removed in 2.2.0 and later versions")]
+ public static void LogError(ErrorLogLevel errorLogLevel, string str)
+ {
+ switch (errorLogLevel)
{
- LogMessage(level, dev, format, items);
-
- //if (Level >= level)
- // Console(level, "[{0}] {1}", dev.Key, message);
+ case ErrorLogLevel.Error:
+ LogMessage(LogEventLevel.Error, str);
+ break;
+ case ErrorLogLevel.Warning:
+ LogMessage(LogEventLevel.Warning, str);
+ break;
+ case ErrorLogLevel.Notice:
+ LogMessage(LogEventLevel.Information, str);
+ break;
}
+ }
- ///
- /// Prints message to console if current debug level is equal to or higher than the level of this message. Always sends message to Error Log.
- /// Uses CrestronConsole.PrintLine.
- ///
- [Obsolete("Use LogMessage methods, Will be removed in 2.2.0 and later versions")]
- public static void Console(uint level, IKeyed dev, ErrorLogLevel errorLogLevel,
- string format, params object[] items)
- {
- LogMessage(level, dev, format, items);
- }
-
- ///
- /// Logs to Console when at-level, and all messages to error log
- ///
- [Obsolete("Use LogMessage methods, Will be removed in 2.2.0 and later versions")]
- public static void Console(uint level, ErrorLogLevel errorLogLevel,
- string format, params object[] items)
- {
- LogMessage(level, format, items);
- }
-
- ///
- /// Logs to both console and the custom user log (not the built-in error log). If appdebug level is set at
- /// or above the level provided, then the output will be written to both console and the log. Otherwise
- /// it will only be written to the log.
- ///
- [Obsolete("Use LogMessage methods, Will be removed in 2.2.0 and later versions")]
- public static void ConsoleWithLog(uint level, string format, params object[] items)
- {
- LogMessage(level, format, items);
-
- // var str = string.Format(format, items);
- //if (Level >= level)
- // CrestronConsole.PrintLine("App {0}:{1}", InitialParametersClass.ApplicationNumber, str);
- // CrestronLogger.WriteToLog(str, level);
- }
-
- ///
- /// Logs to both console and the custom user log (not the built-in error log). If appdebug level is set at
- /// or above the level provided, then the output will be written to both console and the log. Otherwise
- /// it will only be written to the log.
- ///
- [Obsolete("Use LogMessage methods, Will be removed in 2.2.0 and later versions")]
- public static void ConsoleWithLog(uint level, IKeyed dev, string format, params object[] items)
- {
- LogMessage(level, dev, format, items);
-
- // var str = string.Format(format, items);
- // CrestronLogger.WriteToLog(string.Format("[{0}] {1}", dev.Key, str), level);
- }
-
- ///
- /// Prints to log and error log
- ///
- ///
- ///
- [Obsolete("Use LogMessage methods, Will be removed in 2.2.0 and later versions")]
- public static void LogError(ErrorLogLevel errorLogLevel, string str)
- {
- switch (errorLogLevel)
+ ///
+ /// Writes the memory object after timeout
+ ///
+ static void SaveMemoryOnTimeout()
+ {
+ Console(0, "Saving debug settings");
+ if (_saveTimer == null)
+ _saveTimer = new CTimer(o =>
{
- case ErrorLogLevel.Error:
- LogMessage(LogEventLevel.Error, str);
- break;
- case ErrorLogLevel.Warning:
- LogMessage(LogEventLevel.Warning, str);
- break;
- case ErrorLogLevel.Notice:
- LogMessage(LogEventLevel.Information, str);
- break;
- }
- }
+ _saveTimer = null;
+ SaveMemory();
+ }, SaveTimeoutMs);
+ else
+ _saveTimer.Reset(SaveTimeoutMs);
+ }
- ///
- /// Writes the memory object after timeout
- ///
- static void SaveMemoryOnTimeout()
+ ///
+ /// Writes the memory - use SaveMemoryOnTimeout
+ ///
+ static void SaveMemory()
+ {
+ //var dir = @"\NVRAM\debug";
+ //if (!Directory.Exists(dir))
+ // Directory.Create(dir);
+
+ var fileName = GetMemoryFileName();
+
+ LogMessage(LogEventLevel.Information, "Loading debug settings file from {fileName}", fileName);
+
+ using (var sw = new StreamWriter(fileName))
{
- Console(0, "Saving debug settings");
- if (_saveTimer == null)
- _saveTimer = new CTimer(o =>
+ var json = JsonConvert.SerializeObject(_contexts);
+ sw.Write(json);
+ sw.Flush();
+ }
+ }
+
+ ///
+ ///
+ ///
+ static void LoadMemory()
+ {
+ var file = GetMemoryFileName();
+ if (File.Exists(file))
+ {
+ using (var sr = new StreamReader(file))
+ {
+ var json = sr.ReadToEnd();
+ _contexts = JsonConvert.DeserializeObject(json);
+
+ if (_contexts != null)
{
- _saveTimer = null;
- SaveMemory();
- }, SaveTimeoutMs);
- else
- _saveTimer.Reset(SaveTimeoutMs);
- }
-
- ///
- /// Writes the memory - use SaveMemoryOnTimeout
- ///
- static void SaveMemory()
- {
- //var dir = @"\NVRAM\debug";
- //if (!Directory.Exists(dir))
- // Directory.Create(dir);
-
- var fileName = GetMemoryFileName();
-
- LogMessage(LogEventLevel.Information, "Loading debug settings file from {fileName}", fileName);
-
- using (var sw = new StreamWriter(fileName))
- {
- var json = JsonConvert.SerializeObject(_contexts);
- sw.Write(json);
- sw.Flush();
- }
- }
-
- ///
- ///
- ///
- static void LoadMemory()
- {
- var file = GetMemoryFileName();
- if (File.Exists(file))
- {
- using (var sr = new StreamReader(file))
- {
- var json = sr.ReadToEnd();
- _contexts = JsonConvert.DeserializeObject(json);
-
- if (_contexts != null)
- {
- LogMessage(LogEventLevel.Debug, "Debug memory restored from file");
- return;
- }
+ LogMessage(LogEventLevel.Debug, "Debug memory restored from file");
+ return;
}
}
-
- _contexts = new DebugContextCollection();
}
- ///
- /// Helper to get the file path for this app's debug memory
- ///
- static string GetMemoryFileName()
- {
- if (CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance)
- {
- // CheckForMigration();
- return string.Format(@"\user\debugSettings\program{0}", InitialParametersClass.ApplicationNumber);
- }
+ _contexts = new DebugContextCollection();
+ }
- return string.Format("{0}{1}user{1}debugSettings{1}{2}.json",Directory.GetApplicationRootDirectory(), Path.DirectorySeparatorChar, InitialParametersClass.RoomId);
+ ///
+ /// Helper to get the file path for this app's debug memory
+ ///
+ static string GetMemoryFileName()
+ {
+ if (CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance)
+ {
+ // CheckForMigration();
+ return string.Format(@"\user\debugSettings\program{0}", InitialParametersClass.ApplicationNumber);
}
+ return string.Format("{0}{1}user{1}debugSettings{1}{2}.json",Directory.GetApplicationRootDirectory(), Path.DirectorySeparatorChar, InitialParametersClass.RoomId);
+ }
+
+ ///
+ /// Error level to for message to be logged at
+ ///
+ public enum ErrorLogLevel
+ {
///
- /// Error level to for message to be logged at
+ /// Error
///
- public enum ErrorLogLevel
- {
- ///
- /// Error
- ///
- Error,
- ///
- /// Warning
- ///
- Warning,
- ///
- /// Notice
- ///
- Notice,
- ///
- /// None
- ///
- None,
+ Error,
+ ///
+ /// Warning
+ ///
+ Warning,
+ ///
+ /// Notice
+ ///
+ Notice,
+ ///
+ /// None
+ ///
+ None,
}
}
\ No newline at end of file
diff --git a/src/PepperDash.Core/Logging/DebugWebsocketSink.cs b/src/PepperDash.Core/Logging/DebugWebsocketSink.cs
index af479cfa..d80d1c7b 100644
--- a/src/PepperDash.Core/Logging/DebugWebsocketSink.cs
+++ b/src/PepperDash.Core/Logging/DebugWebsocketSink.cs
@@ -15,316 +15,318 @@ using X509Certificate2 = System.Security.Cryptography.X509Certificates.X509Certi
namespace PepperDash.Core;
- ///
- /// Provides a WebSocket-based logging sink for debugging purposes, allowing log events to be broadcast to connected
- /// WebSocket clients.
+///
+/// Provides a WebSocket-based logging sink for debugging purposes, allowing log events to be broadcast to connected
+/// WebSocket clients.
+///
+/// This class implements the interface and is designed to send
+/// formatted log events to WebSocket clients connected to a secure WebSocket server. The server is hosted locally
+/// and uses a self-signed certificate for SSL/TLS encryption.
+public class DebugWebsocketSink : ILogEventSink, IKeyed
+{
+ private HttpServer _httpsServer;
+
+ private readonly string _path = "/debug/join/";
+ private const string _certificateName = "selfCres";
+ private const string _certificatePassword = "cres12345";
+
+ ///
+ /// Gets the port number on which the HTTPS server is currently running.
///
- /// This class implements the interface and is designed to send
- /// formatted log events to WebSocket clients connected to a secure WebSocket server. The server is hosted locally
- /// and uses a self-signed certificate for SSL/TLS encryption.
- public class DebugWebsocketSink : ILogEventSink, IKeyed
+ public int Port
+ { get
+ {
+
+ if(_httpsServer == null) return 0;
+ return _httpsServer.Port;
+ }
+ }
+
+ ///
+ /// Gets the WebSocket URL for the current server instance.
+ ///
+ /// The URL is dynamically constructed based on the server's current IP address, port,
+ /// and WebSocket path.
+ public string Url
{
- private HttpServer _httpsServer;
-
- private readonly string _path = "/debug/join/";
- private const string _certificateName = "selfCres";
- private const string _certificatePassword = "cres12345";
-
- ///
- /// Gets the port number on which the HTTPS server is currently running.
- ///
- public int Port
- { get
- {
-
- if(_httpsServer == null) return 0;
- return _httpsServer.Port;
- }
- }
-
- ///
- /// Gets the WebSocket URL for the current server instance.
- ///
- /// The URL is dynamically constructed based on the server's current IP address, port,
- /// and WebSocket path.
- public string Url
+ get
{
- get
+ if (_httpsServer == null) return "";
+ return $"wss://{CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0)}:{_httpsServer.Port}{_httpsServer.WebSocketServices[_path].Path}";
+ }
+ }
+
+ ///
+ /// Gets a value indicating whether the HTTPS server is currently listening for incoming connections.
+ ///
+ public bool IsRunning { get => _httpsServer?.IsListening ?? false; }
+
+ ///
+ public string Key => "DebugWebsocketSink";
+
+ private readonly ITextFormatter _textFormatter;
+
+ ///
+ /// Initializes a new instance of the class with the specified text formatter.
+ ///
+ /// This constructor initializes the WebSocket sink and ensures that a certificate is
+ /// available for secure communication. If the required certificate does not exist, it will be created
+ /// automatically. Additionally, the sink is configured to stop the server when the program is
+ /// stopping.
+ /// The text formatter used to format log messages. If null, a default JSON formatter is used.
+ public DebugWebsocketSink(ITextFormatter formatProvider)
+ {
+
+ _textFormatter = formatProvider ?? new JsonFormatter();
+
+ if (!File.Exists($"\\user\\{_certificateName}.pfx"))
+ CreateCert();
+
+ CrestronEnvironment.ProgramStatusEventHandler += type =>
+ {
+ if (type == eProgramStatusEventType.Stopping)
{
- if (_httpsServer == null) return "";
- return $"wss://{CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0)}:{_httpsServer.Port}{_httpsServer.WebSocketServices[_path].Path}";
+ StopServer();
}
+ };
+ }
+
+ private static void CreateCert()
+ {
+ try
+ {
+ var utility = new BouncyCertificate();
+
+ var ipAddress = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0);
+ var hostName = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, 0);
+ var domainName = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DOMAIN_NAME, 0);
+
+ CrestronConsole.PrintLine(string.Format("DomainName: {0} | HostName: {1} | {1}.{0}@{2}", domainName, hostName, ipAddress));
+
+ var certificate = utility.CreateSelfSignedCertificate(string.Format("CN={0}.{1}", hostName, domainName), [string.Format("{0}.{1}", hostName, domainName), ipAddress], [KeyPurposeID.id_kp_serverAuth, KeyPurposeID.id_kp_clientAuth]);
+
+ //Crestron fails to let us do this...perhaps it should be done through their Dll's but haven't tested
+
+ var separator = Path.DirectorySeparatorChar;
+
+ utility.CertificatePassword = _certificatePassword;
+ utility.WriteCertificate(certificate, @$"{separator}user{separator}", _certificateName);
}
-
- ///
- /// Gets a value indicating whether the HTTPS server is currently listening for incoming connections.
- ///
- public bool IsRunning { get => _httpsServer?.IsListening ?? false; }
-
- ///
- public string Key => "DebugWebsocketSink";
-
- private readonly ITextFormatter _textFormatter;
-
- ///
- /// Initializes a new instance of the class with the specified text formatter.
- ///
- /// This constructor initializes the WebSocket sink and ensures that a certificate is
- /// available for secure communication. If the required certificate does not exist, it will be created
- /// automatically. Additionally, the sink is configured to stop the server when the program is
- /// stopping.
- /// The text formatter used to format log messages. If null, a default JSON formatter is used.
- public DebugWebsocketSink(ITextFormatter formatProvider)
+ catch (Exception ex)
{
+ //Debug.Console(0, "WSS CreateCert Failed\r\n{0}\r\n{1}", ex.Message, ex.StackTrace);
+ CrestronConsole.PrintLine("WSS CreateCert Failed\r\n{0}\r\n{1}", ex.Message, ex.StackTrace);
+ }
+ }
- _textFormatter = formatProvider ?? new JsonFormatter();
+ ///
+ /// Sends a log event to all connected WebSocket clients.
+ ///
+ /// The log event is formatted using the configured text formatter and then broadcasted
+ /// to all clients connected to the WebSocket server. If the WebSocket server is not initialized or not
+ /// listening, the method exits without performing any action.
+ /// The log event to be formatted and broadcasted. Cannot be null.
+ public void Emit(LogEvent logEvent)
+ {
+ if (_httpsServer == null || !_httpsServer.IsListening) return;
- if (!File.Exists($"\\user\\{_certificateName}.pfx"))
- CreateCert();
+ var sw = new StringWriter();
+ _textFormatter.Format(logEvent, sw);
- CrestronEnvironment.ProgramStatusEventHandler += type =>
+ _httpsServer.WebSocketServices[_path].Sessions.Broadcast(sw.ToString());
+ }
+
+ ///
+ /// Starts the WebSocket server on the specified port and configures it with the appropriate certificate.
+ ///
+ /// This method initializes the WebSocket server and binds it to the specified port. It
+ /// also applies the server's certificate for secure communication. Ensure that the port is not already in use
+ /// and that the certificate file is accessible.
+ /// The port number on which the WebSocket server will listen. Must be a valid, non-negative port number.
+ public void StartServerAndSetPort(int port)
+ {
+ Debug.Console(0, "Starting Websocket Server on port: {0}", port);
+
+
+ Start(port, $"\\user\\{_certificateName}.pfx", _certificatePassword);
+ }
+
+ private void Start(int port, string certPath = "", string certPassword = "")
+ {
+ try
+ {
+ _httpsServer = new HttpServer(port, true);
+
+ if (!string.IsNullOrWhiteSpace(certPath))
{
- if (type == eProgramStatusEventType.Stopping)
- {
- StopServer();
- }
- };
- }
+ Debug.Console(0, "Assigning SSL Configuration");
- private static void CreateCert()
- {
- try
- {
- var utility = new BouncyCertificate();
-
- var ipAddress = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0);
- var hostName = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_HOSTNAME, 0);
- var domainName = CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_DOMAIN_NAME, 0);
-
- CrestronConsole.PrintLine(string.Format("DomainName: {0} | HostName: {1} | {1}.{0}@{2}", domainName, hostName, ipAddress));
-
- var certificate = utility.CreateSelfSignedCertificate(string.Format("CN={0}.{1}", hostName, domainName), [string.Format("{0}.{1}", hostName, domainName), ipAddress], [KeyPurposeID.id_kp_serverAuth, KeyPurposeID.id_kp_clientAuth]);
-
- //Crestron fails to let us do this...perhaps it should be done through their Dll's but haven't tested
-
- utility.CertificatePassword = _certificatePassword;
- utility.WriteCertificate(certificate, @"\user\", _certificateName);
- }
- catch (Exception ex)
- {
- //Debug.Console(0, "WSS CreateCert Failed\r\n{0}\r\n{1}", ex.Message, ex.StackTrace);
- CrestronConsole.PrintLine("WSS CreateCert Failed\r\n{0}\r\n{1}", ex.Message, ex.StackTrace);
- }
- }
-
- ///
- /// Sends a log event to all connected WebSocket clients.
- ///
- /// The log event is formatted using the configured text formatter and then broadcasted
- /// to all clients connected to the WebSocket server. If the WebSocket server is not initialized or not
- /// listening, the method exits without performing any action.
- /// The log event to be formatted and broadcasted. Cannot be null.
- public void Emit(LogEvent logEvent)
- {
- if (_httpsServer == null || !_httpsServer.IsListening) return;
-
- var sw = new StringWriter();
- _textFormatter.Format(logEvent, sw);
-
- _httpsServer.WebSocketServices[_path].Sessions.Broadcast(sw.ToString());
- }
-
- ///
- /// Starts the WebSocket server on the specified port and configures it with the appropriate certificate.
- ///
- /// This method initializes the WebSocket server and binds it to the specified port. It
- /// also applies the server's certificate for secure communication. Ensure that the port is not already in use
- /// and that the certificate file is accessible.
- /// The port number on which the WebSocket server will listen. Must be a valid, non-negative port number.
- public void StartServerAndSetPort(int port)
- {
- Debug.Console(0, "Starting Websocket Server on port: {0}", port);
-
-
- Start(port, $"\\user\\{_certificateName}.pfx", _certificatePassword);
- }
-
- private void Start(int port, string certPath = "", string certPassword = "")
- {
- try
- {
- _httpsServer = new HttpServer(port, true);
-
- if (!string.IsNullOrWhiteSpace(certPath))
- {
- Debug.Console(0, "Assigning SSL Configuration");
-
- _httpsServer.SslConfiguration.ServerCertificate = new X509Certificate2(certPath, certPassword);
- _httpsServer.SslConfiguration.ClientCertificateRequired = false;
- _httpsServer.SslConfiguration.CheckCertificateRevocation = false;
- _httpsServer.SslConfiguration.EnabledSslProtocols = SslProtocols.Tls12;
- //this is just to test, you might want to actually validate
- _httpsServer.SslConfiguration.ClientCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
- {
- Debug.Console(0, "HTTPS ClientCerticateValidation Callback triggered");
- return true;
- };
- }
- Debug.Console(0, "Adding Debug Client Service");
- _httpsServer.AddWebSocketService(_path);
- Debug.Console(0, "Assigning Log Info");
- _httpsServer.Log.Level = LogLevel.Trace;
- _httpsServer.Log.Output = (d, s) =>
- {
- uint level;
-
- switch(d.Level)
+ _httpsServer.SslConfiguration.ServerCertificate = new X509Certificate2(certPath, certPassword);
+ _httpsServer.SslConfiguration.ClientCertificateRequired = false;
+ _httpsServer.SslConfiguration.CheckCertificateRevocation = false;
+ _httpsServer.SslConfiguration.EnabledSslProtocols = SslProtocols.Tls12;
+ //this is just to test, you might want to actually validate
+ _httpsServer.SslConfiguration.ClientCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
{
- case WebSocketSharp.LogLevel.Fatal:
- level = 3;
- break;
- case WebSocketSharp.LogLevel.Error:
- level = 2;
- break;
- case WebSocketSharp.LogLevel.Warn:
- level = 1;
- break;
- case WebSocketSharp.LogLevel.Info:
- level = 0;
- break;
- case WebSocketSharp.LogLevel.Debug:
- level = 4;
- break;
- case WebSocketSharp.LogLevel.Trace:
- level = 5;
- break;
- default:
- level = 4;
- break;
- }
-
- Debug.Console(level, "{1} {0}\rCaller:{2}\rMessage:{3}\rs:{4}", d.Level.ToString(), d.Date.ToString(), d.Caller.ToString(), d.Message, s);
- };
- Debug.Console(0, "Starting");
-
- _httpsServer.Start();
- Debug.Console(0, "Ready");
+ Debug.Console(0, "HTTPS ClientCerticateValidation Callback triggered");
+ return true;
+ };
}
- catch (Exception ex)
+ Debug.Console(0, "Adding Debug Client Service");
+ _httpsServer.AddWebSocketService(_path);
+ Debug.Console(0, "Assigning Log Info");
+ _httpsServer.Log.Level = LogLevel.Trace;
+ _httpsServer.Log.Output = (d, s) =>
{
- Debug.Console(0, "WebSocket Failed to start {0}", ex.Message);
- }
+ uint level;
+
+ switch(d.Level)
+ {
+ case WebSocketSharp.LogLevel.Fatal:
+ level = 3;
+ break;
+ case WebSocketSharp.LogLevel.Error:
+ level = 2;
+ break;
+ case WebSocketSharp.LogLevel.Warn:
+ level = 1;
+ break;
+ case WebSocketSharp.LogLevel.Info:
+ level = 0;
+ break;
+ case WebSocketSharp.LogLevel.Debug:
+ level = 4;
+ break;
+ case WebSocketSharp.LogLevel.Trace:
+ level = 5;
+ break;
+ default:
+ level = 4;
+ break;
+ }
+
+ Debug.Console(level, "{1} {0}\rCaller:{2}\rMessage:{3}\rs:{4}", d.Level.ToString(), d.Date.ToString(), d.Caller.ToString(), d.Message, s);
+ };
+ Debug.Console(0, "Starting");
+
+ _httpsServer.Start();
+ Debug.Console(0, "Ready");
}
-
- ///
- /// Stops the WebSocket server if it is currently running.
- ///
- /// This method halts the WebSocket server and releases any associated resources. After
- /// calling this method, the server will no longer accept or process incoming connections.
- public void StopServer()
+ catch (Exception ex)
{
- Debug.Console(0, "Stopping Websocket Server");
- _httpsServer?.Stop();
-
- _httpsServer = null;
+ Debug.Console(0, "WebSocket Failed to start {0}", ex.Message);
}
}
- ///
- /// Configures the logger to write log events to a debug WebSocket sink.
+ ///
+ /// Stops the WebSocket server if it is currently running.
///
- /// This extension method allows you to direct log events to a WebSocket sink for debugging
- /// purposes.
- public static class DebugWebsocketSinkExtensions
+ /// This method halts the WebSocket server and releases any associated resources. After
+ /// calling this method, the server will no longer accept or process incoming connections.
+ public void StopServer()
{
- ///
- /// Configures a logger to write log events to a debug WebSocket sink.
- ///
- /// This method adds a sink that writes log events to a WebSocket for debugging purposes.
- /// It is typically used during development to stream log events in real-time.
- /// The logger sink configuration to apply the WebSocket sink to.
- /// An optional text formatter to format the log events. If not provided, a default formatter will be used.
- /// A object that can be used to further configure the logger.
- public static LoggerConfiguration DebugWebsocketSink(
- this LoggerSinkConfiguration loggerConfiguration,
- ITextFormatter formatProvider = null)
- {
- return loggerConfiguration.Sink(new DebugWebsocketSink(formatProvider));
- }
- }
+ Debug.Console(0, "Stopping Websocket Server");
+ _httpsServer?.Stop();
- ///
- /// Represents a WebSocket client for debugging purposes, providing connection lifecycle management and message
- /// handling functionality.
- ///
- /// The class extends to handle
- /// WebSocket connections, including events for opening, closing, receiving messages, and errors. It tracks the
- /// duration of the connection and logs relevant events for debugging.
- public class DebugClient : WebSocketBehavior
- {
- private DateTime _connectionTime;
-
- ///
- /// Gets the duration of time the WebSocket connection has been active.
- ///
- public TimeSpan ConnectedDuration
- {
- get
- {
- if (Context.WebSocket.IsAlive)
- {
- return DateTime.Now - _connectionTime;
- }
- else
- {
- return new TimeSpan(0);
- }
- }
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// This constructor creates a new instance and logs its
- /// creation using the method with a debug level of 0.
- public DebugClient()
- {
- Debug.Console(0, "DebugClient Created");
- }
-
- ///
- protected override void OnOpen()
- {
- base.OnOpen();
-
- var url = Context.WebSocket.Url;
- Debug.Console(0, Debug.ErrorLogLevel.Notice, "New WebSocket Connection from: {0}", url);
-
- _connectionTime = DateTime.Now;
- }
-
- ///
- protected override void OnMessage(MessageEventArgs e)
- {
- base.OnMessage(e);
-
- Debug.Console(0, "WebSocket UiClient Message: {0}", e.Data);
- }
-
- ///
- protected override void OnClose(CloseEventArgs e)
- {
- base.OnClose(e);
-
- Debug.Console(0, Debug.ErrorLogLevel.Notice, "WebSocket UiClient Closing: {0} reason: {1}", e.Code, e.Reason);
-
- }
-
- ///
- protected override void OnError(WebSocketSharp.ErrorEventArgs e)
- {
- base.OnError(e);
-
- Debug.Console(2, Debug.ErrorLogLevel.Notice, "WebSocket UiClient Error: {0} message: {1}", e.Exception, e.Message);
+ _httpsServer = null;
+ }
+}
+
+///
+/// Configures the logger to write log events to a debug WebSocket sink.
+///
+/// This extension method allows you to direct log events to a WebSocket sink for debugging
+/// purposes.
+public static class DebugWebsocketSinkExtensions
+{
+ ///
+ /// Configures a logger to write log events to a debug WebSocket sink.
+ ///
+ /// This method adds a sink that writes log events to a WebSocket for debugging purposes.
+ /// It is typically used during development to stream log events in real-time.
+ /// The logger sink configuration to apply the WebSocket sink to.
+ /// An optional text formatter to format the log events. If not provided, a default formatter will be used.
+ /// A object that can be used to further configure the logger.
+ public static LoggerConfiguration DebugWebsocketSink(
+ this LoggerSinkConfiguration loggerConfiguration,
+ ITextFormatter formatProvider = null)
+ {
+ return loggerConfiguration.Sink(new DebugWebsocketSink(formatProvider));
+ }
+}
+
+///
+/// Represents a WebSocket client for debugging purposes, providing connection lifecycle management and message
+/// handling functionality.
+///
+/// The class extends to handle
+/// WebSocket connections, including events for opening, closing, receiving messages, and errors. It tracks the
+/// duration of the connection and logs relevant events for debugging.
+public class DebugClient : WebSocketBehavior
+{
+ private DateTime _connectionTime;
+
+ ///
+ /// Gets the duration of time the WebSocket connection has been active.
+ ///
+ public TimeSpan ConnectedDuration
+ {
+ get
+ {
+ if (Context.WebSocket.IsAlive)
+ {
+ return DateTime.Now - _connectionTime;
+ }
+ else
+ {
+ return new TimeSpan(0);
+ }
+ }
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// This constructor creates a new instance and logs its
+ /// creation using the method with a debug level of 0.
+ public DebugClient()
+ {
+ Debug.Console(0, "DebugClient Created");
+ }
+
+ ///
+ protected override void OnOpen()
+ {
+ base.OnOpen();
+
+ var url = Context.WebSocket.Url;
+ Debug.Console(0, Debug.ErrorLogLevel.Notice, "New WebSocket Connection from: {0}", url);
+
+ _connectionTime = DateTime.Now;
+ }
+
+ ///
+ protected override void OnMessage(MessageEventArgs e)
+ {
+ base.OnMessage(e);
+
+ Debug.Console(0, "WebSocket UiClient Message: {0}", e.Data);
+ }
+
+ ///
+ protected override void OnClose(CloseEventArgs e)
+ {
+ base.OnClose(e);
+
+ Debug.Console(0, Debug.ErrorLogLevel.Notice, "WebSocket UiClient Closing: {0} reason: {1}", e.Code, e.Reason);
+
+ }
+
+ ///
+ protected override void OnError(WebSocketSharp.ErrorEventArgs e)
+ {
+ base.OnError(e);
+
+ Debug.Console(2, Debug.ErrorLogLevel.Notice, "WebSocket UiClient Error: {0} message: {1}", e.Exception, e.Message);
}
}