diff --git a/src/PepperDash.Core/Logging/Debug.cs b/src/PepperDash.Core/Logging/Debug.cs
index 6e4fb37d..b3e7452a 100644
--- a/src/PepperDash.Core/Logging/Debug.cs
+++ b/src/PepperDash.Core/Logging/Debug.cs
@@ -22,95 +22,88 @@ using Serilog.Templates;
namespace PepperDash.Core;
- ///
- ///
- 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 _consoleLogLevelSwitch;
+ private static readonly LoggingLevelSwitch _websocketLoggingLevelSwitch;
- private static readonly LoggingLevelSwitch _websocketLogLevelSwitch;
+ private static readonly LoggingLevelSwitch _errorLogLevelSwitch;
- private static readonly LoggingLevelSwitch _errorLogLevelSwitch;
+ private static readonly LoggingLevelSwitch _fileLevelSwitch;
- private static readonly LoggingLevelSwitch _fileLogLevelSwitch;
+ public static LogEventLevel WebsocketMinimumLogLevel
+ {
+ get { return _websocketLoggingLevelSwitch.MinimumLevel; }
+ }
- ///
- /// Gets the minimum log level for the websocket sink.
- ///
- public static LogEventLevel WebsocketMinimumLogLevel
- {
- get { return _websocketLogLevelSwitch.MinimumLevel; }
- }
+ private static readonly DebugWebsocketSink _websocketSink;
- private static readonly DebugWebsocketSink _websocketSink;
+ public static DebugWebsocketSink WebsocketSink
+ {
+ get { return _websocketSink; }
+ }
- ///
- /// Gets the websocket sink for debug logging.
- ///
- 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; }
- ///
- /// Gets or sets the Level
- ///
- 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; }
- ///
- /// Gets or sets the DoNotLoadConfigOnNextBoot
- ///
- 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;
- ///
- /// Indicates whether the system is running on an appliance.
- ///
- public static bool IsRunningOnAppliance = CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance;
+ ///
+ /// Version for the currently loaded PepperDashCore dll
+ ///
+ public static string PepperDashCoreVersion { get; private set; }
- ///
- /// Gets or sets the PepperDashCoreVersion
- ///
- 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.
@@ -120,16 +113,15 @@ 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;
- ///
- /// Gets the logger configuration for the debug logging.
- ///
- public static LoggerConfiguration LoggerConfiguration => _loggerConfiguration;
+ public static LoggerConfiguration LoggerConfiguration => _loggerConfiguration;
- static Debug()
+ static Debug()
+ {
+ try
{
CrestronDataStoreStatic.InitCrestronDataStore();
@@ -141,13 +133,13 @@ namespace PepperDash.Core;
var defaultFileLogLevel = GetStoredLogEventLevel(FileLevelStoreKey);
- _consoleLogLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultConsoleLevel);
+ _consoleLoggingLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultConsoleLevel);
- _websocketLogLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultWebsocketLevel);
+ _websocketLoggingLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultWebsocketLevel);
_errorLogLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultErrorLogLevel);
- _fileLogLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultFileLogLevel);
+ _fileLevelSwitch = new LoggingLevelSwitch(initialMinimumLevel: defaultFileLogLevel);
_websocketSink = new DebugWebsocketSink(new JsonFormatter(renderMessage: true));
@@ -165,31 +157,16 @@ namespace PepperDash.Core;
.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: _consoleLogLevelSwitch)
- .WriteTo.Sink(_websocketSink, levelSwitch: _websocketLogLevelSwitch)
+ .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 ? 7 : 14,
- levelSwitch: _fileLogLevelSwitch
+ 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;
@@ -231,422 +208,327 @@ namespace PepperDash.Core;
CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironment_ProgramStatusEventHandler;
- LoadMemory();
-
- var context = _contexts.GetOrCreateItem("DEFAULT");
- Level = context.Level;
- DoNotLoadConfigOnNextBoot = context.DoNotLoadOnNextBoot;
+ 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));
- _errorLogLevelSwitch.MinimumLevelChanged += (sender, args) =>
+ _consoleLoggingLevelSwitch.MinimumLevelChanged += (sender, args) =>
{
- LogMessage(LogEventLevel.Information, "Error log debug level set to {minimumLevel}", _errorLogLevelSwitch.MinimumLevel);
+ LogMessage(LogEventLevel.Information, "Console debug level set to {minimumLevel}", _consoleLoggingLevelSwitch.MinimumLevel);
};
+ }
+ catch (Exception ex)
+ {
+ LogError(ex, "Exception in Debug static constructor: {message}", ex.Message);
+ }
+ }
- // Set initial error log level based on platform && stored level. If appliance, use stored level, otherwise default to verbose
- SetErrorLogMinimumDebugLevel(CrestronEnvironment.DevicePlatform == eDevicePlatform.Appliance ? _errorLogLevelSwitch.MinimumLevel : LogEventLevel.Verbose);
+ 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;
}
- ///
- /// UpdateLoggerConfiguration method
- ///
- public static void UpdateLoggerConfiguration(LoggerConfiguration config)
+ 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();
- }
-
- ///
- /// ResetLoggerConfiguration method
- ///
- 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");
-
- CrestronDataStoreStatic.SetLocalIntValue(levelStoreKey, levelStoreKey == ErrorLogLevelStoreKey ? (int)LogEventLevel.Warning : (int)LogEventLevel.Information);
-
- return levelStoreKey == ErrorLogLevelStoreKey ? LogEventLevel.Warning : 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;
- }
-
- CrestronConsole.PrintLine($"Stored log level for {levelStoreKey} is {logLevel}");
-
- 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
- ///
- ///
- ///
- /// SetDebugFromConsole method
- ///
- 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:\r\n" +
- "Usage: appdebug:P [sink] [level]\r\n" +
- " sink: console (default), errorlog, file, all\r\n" +
- " all: sets all sinks to the specified level\r\n" +
- " level: 0-5 or LogEventLevel name\r\n" +
- $"{_logLevels[0]} = 0\r\n" +
- $"{_logLevels[1]} = 1\r\n" +
- $"{_logLevels[2]} = 2\r\n" +
- $"{_logLevels[3]} = 3\r\n" +
- $"{_logLevels[4]} = 4\r\n" +
- $"{_logLevels[5]} = 5");
- return;
- }
-
- if (string.IsNullOrEmpty(levelString.Trim()))
- {
- CrestronConsole.ConsoleCommandResponse("Console log level = {0}\r\n", _consoleLogLevelSwitch.MinimumLevel);
- CrestronConsole.ConsoleCommandResponse("File log level = {0}\r\n", _fileLogLevelSwitch.MinimumLevel);
- CrestronConsole.ConsoleCommandResponse("Error log level = {0}\r\n", _errorLogLevelSwitch.MinimumLevel);
- return;
- }
-
- // Parse tokens: first token is sink (defaults to console), second token is level
- var tokens = levelString.Trim().Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
-
- string sinkName;
- string levelToken;
-
- if (tokens.Length == 1)
- {
- // Single token - assume it's a level for console sink
- sinkName = "console";
- levelToken = tokens[0];
- }
- else if (tokens.Length == 2)
- {
- // Two tokens - first is sink, second is level
- sinkName = tokens[0].ToLowerInvariant();
- levelToken = tokens[1];
- }
- else
- {
- CrestronConsole.ConsoleCommandResponse("Usage: appdebug:P [sink] [level]");
- return;
- }
-
- // Parse the level using the same logic as before
- LogEventLevel level;
-
- if (int.TryParse(levelToken, out var levelInt))
- {
- if (levelInt < 0 || levelInt > 5)
- {
- CrestronConsole.ConsoleCommandResponse($"Error: Unable to parse {levelToken} to valid log level. If using a number, value must be between 0-5");
- return;
- }
-
- if (!_logLevels.TryGetValue((uint)levelInt, out level))
- {
- level = LogEventLevel.Information;
- CrestronConsole.ConsoleCommandResponse($"{levelInt} not valid. Setting level to {level}");
- }
- }
- else if (Enum.TryParse(levelToken, true, out level))
- {
- // Successfully parsed as LogEventLevel enum
- }
- else
- {
- CrestronConsole.ConsoleCommandResponse($"Error: Unable to parse {levelToken} to valid log level");
- return;
- }
-
- // Set the level for the specified sink
- switch (sinkName)
- {
- case "console":
- SetDebugLevel(level);
- break;
- case "errorlog":
- SetErrorLogMinimumDebugLevel(level);
- break;
- case "file":
- SetFileMinimumDebugLevel(level);
- break;
- case "all":
- SetDebugLevel(level);
- SetErrorLogMinimumDebugLevel(level);
- SetFileMinimumDebugLevel(level);
- break;
- default:
- CrestronConsole.ConsoleCommandResponse($"Error: Unknown sink '{sinkName}'. Valid sinks: console, errorlog, file");
- break;
- }
- }
- catch
- {
- CrestronConsole.ConsoleCommandResponse("Usage: appdebug:P [sink] [level]");
+ _saveTimer.Stop();
+ _saveTimer = null;
}
+ LogMessage(LogEventLevel.Information, "Saving debug settings");
+ SaveMemory();
}
+ }
- ///
- /// Sets the debug level
- ///
- /// Valid values 0-5
- ///
- /// SetDebugLevel method
- ///
- public static void SetDebugLevel(uint level)
+ ///
+ /// Callback for console command
+ ///
+ ///
+ public static void SetDebugFromConsole(string levelString)
+ {
+ try
{
- if (!_logLevels.TryGetValue(level, out var logLevel))
+ if (levelString.Trim() == "?")
{
- logLevel = LogEventLevel.Information;
-
- CrestronConsole.ConsoleCommandResponse($"{level} not valid. Setting level to {logLevel}");
-
- SetDebugLevel(logLevel);
+ 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]");
+ }
+ }
+
+ ///
+ /// Sets the debug level
+ ///
+ /// Valid values 0-5
+ public static void SetDebugLevel(uint level)
+ {
+ if(!_logLevels.TryGetValue(level, out var logLevel))
+ {
+ logLevel = LogEventLevel.Information;
+
+ CrestronConsole.ConsoleCommandResponse($"{level} not valid. Setting level to {logLevel}");
+
SetDebugLevel(logLevel);
}
- ///
- /// SetDebugLevel method
- ///
- 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
{
- _consoleLogLevelSwitch.MinimumLevel = level;
-
- CrestronConsole.ConsoleCommandResponse("[Application {0}] Debug level set to {1}\r\n",
- InitialParametersClass.ApplicationNumber, _consoleLogLevelSwitch.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}");
- }
-
- ///
- /// SetWebSocketMinimumDebugLevel method
- ///
- public static void SetWebSocketMinimumDebugLevel(LogEventLevel level)
- {
- _websocketLogLevelSwitch.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}", _websocketLogLevelSwitch.MinimumLevel);
- }
-
- ///
- /// SetErrorLogMinimumDebugLevel method
- ///
- public static void SetErrorLogMinimumDebugLevel(LogEventLevel level)
- {
- _errorLogLevelSwitch.MinimumLevel = level;
-
- CrestronConsole.ConsoleCommandResponse("[Application {0}] Error log level set to {1}\r\n",
- InitialParametersClass.ApplicationNumber, _errorLogLevelSwitch.MinimumLevel);
-
- CrestronConsole.ConsoleCommandResponse($"Storing level {level}:{(int)level}");
-
- var err = CrestronDataStoreStatic.SetLocalIntValue(ErrorLogLevelStoreKey, (int)level);
-
- CrestronConsole.ConsoleCommandResponse($"Store result: {err}:{(int)level}");
-
- if (err != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
- CrestronConsole.PrintLine($"Error saving error log debug level setting: {err}");
- }
-
- ///
- /// SetFileMinimumDebugLevel method
- ///
- public static void SetFileMinimumDebugLevel(LogEventLevel level)
- {
- _fileLogLevelSwitch.MinimumLevel = level;
-
- CrestronConsole.ConsoleCommandResponse("[Application {0}] File log level set to {1}\r\n",
- InitialParametersClass.ApplicationNumber, _fileLogLevelSwitch.MinimumLevel);
-
- CrestronConsole.ConsoleCommandResponse($"Storing level {level}:{(int)level}");
-
- var err = CrestronDataStoreStatic.SetLocalIntValue(FileLevelStoreKey, (int)level);
-
- CrestronConsole.ConsoleCommandResponse($"Store result: {err}:{(int)level}");
-
- if (err != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
- CrestronConsole.PrintLine($"Error saving file debug level setting: {err}");
- }
-
- ///
- /// Callback for console command
- ///
- ///
- ///
- /// SetDoNotLoadOnNextBootFromConsole method
- ///
- public static void SetDoNotLoadOnNextBootFromConsole(string stateString)
- {
- try
+ if (string.IsNullOrEmpty(stateString.Trim()))
{
- if (string.IsNullOrEmpty(stateString.Trim()))
- {
- CrestronConsole.ConsoleCommandResponse("DoNotLoadOnNextBoot = {0}", DoNotLoadConfigOnNextBoot);
- return;
- }
-
- SetDoNotLoadConfigOnNextBoot(bool.Parse(stateString));
- }
- catch
- {
- CrestronConsole.ConsoleCommandResponse("Usage: donotloadonnextboot:P [true/false]");
- }
- }
-
- ///
- /// Callback for console command
- ///
- ///
- ///
- /// SetDebugFilterFromConsole method
- ///
- public static void SetDebugFilterFromConsole(string items)
- {
- var str = items.Trim();
- if (str == "?")
- {
- CrestronConsole.ConsoleCommandResponse("Usage:\r APPDEBUGFILTER key1 key2 key3....\r " +
- "+all: at beginning puts filter into 'default include' mode\r" +
- " All keys that follow will be excluded from output.\r" +
- "-all: at beginning puts filter into 'default exclude all' mode.\r" +
- " All keys that follow will be the only keys that are shown\r" +
- "+nokey: Enables messages with no key (default)\r" +
- "-nokey: Disables messages with no key.\r" +
- "(nokey settings are independent of all other settings)");
+ CrestronConsole.ConsoleCommandResponse("DoNotLoadOnNextBoot = {0}", DoNotLoadConfigOnNextBoot);
return;
}
- var keys = Regex.Split(str, @"\s*");
- foreach (var keyToken in keys)
- {
- var lkey = keyToken.ToLower();
- if (lkey == "+all")
- {
- IncludedExcludedKeys.Clear();
- _excludeAllMode = false;
- }
- else if (lkey == "-all")
- {
- IncludedExcludedKeys.Clear();
- _excludeAllMode = true;
- }
- //else if (lkey == "+nokey")
- //{
- // ExcludeNoKeyMessages = false;
- //}
- //else if (lkey == "-nokey")
- //{
- // ExcludeNoKeyMessages = true;
- //}
- else
- {
- string key;
- if (lkey.StartsWith("-"))
- {
- key = lkey.Substring(1);
- // if in exclude all mode, we need to remove this from the inclusions
- if (_excludeAllMode)
- {
- if (IncludedExcludedKeys.ContainsKey(key))
- IncludedExcludedKeys.Remove(key);
- }
- // otherwise include all mode, add to the exclusions
- else
- {
- IncludedExcludedKeys[key] = new object();
- }
- }
- else if (lkey.StartsWith("+"))
- {
- key = lkey.Substring(1);
- // if in exclude all mode, we need to add this as inclusion
- if (_excludeAllMode)
- {
+
+ SetDoNotLoadConfigOnNextBoot(bool.Parse(stateString));
+ }
+ catch
+ {
+ CrestronConsole.ConsoleCommandResponse("Usage: donotloadonnextboot:P [true/false]");
+ }
+ }
+
+ ///
+ /// Callback for console command
+ ///
+ ///
+ public static void SetDebugFilterFromConsole(string items)
+ {
+ var str = items.Trim();
+ if (str == "?")
+ {
+ CrestronConsole.ConsoleCommandResponse("Usage:\r APPDEBUGFILTER key1 key2 key3....\r " +
+ "+all: at beginning puts filter into 'default include' mode\r" +
+ " All keys that follow will be excluded from output.\r" +
+ "-all: at beginning puts filter into 'default exclude all' mode.\r" +
+ " All keys that follow will be the only keys that are shown\r" +
+ "+nokey: Enables messages with no key (default)\r" +
+ "-nokey: Disables messages with no key.\r" +
+ "(nokey settings are independent of all other settings)");
+ return;
+ }
+ var keys = Regex.Split(str, @"\s*");
+ foreach (var keyToken in keys)
+ {
+ var lkey = keyToken.ToLower();
+ if (lkey == "+all")
+ {
+ IncludedExcludedKeys.Clear();
+ _excludeAllMode = false;
+ }
+ else if (lkey == "-all")
+ {
+ IncludedExcludedKeys.Clear();
+ _excludeAllMode = true;
+ }
+ //else if (lkey == "+nokey")
+ //{
+ // ExcludeNoKeyMessages = false;
+ //}
+ //else if (lkey == "-nokey")
+ //{
+ // ExcludeNoKeyMessages = true;
+ //}
+ else
+ {
+ string key;
+ if (lkey.StartsWith("-"))
+ {
+ key = lkey.Substring(1);
+ // if in exclude all mode, we need to remove this from the inclusions
+ if (_excludeAllMode)
+ {
+ if (IncludedExcludedKeys.ContainsKey(key))
+ IncludedExcludedKeys.Remove(key);
+ }
+ // otherwise include all mode, add to the exclusions
+ else
+ {
+ IncludedExcludedKeys[key] = new object();
+ }
+ }
+ else if (lkey.StartsWith("+"))
+ {
+ key = lkey.Substring(1);
+ // if in exclude all mode, we need to add this as inclusion
+ if (_excludeAllMode)
+ {
IncludedExcludedKeys[key] = new object();
}
@@ -664,579 +546,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
- ///
- ///
- ///
- ///
- /// GetDeviceDebugSettingsForKey method
- ///
- 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;
- _contexts.GetOrCreateItem("DEFAULT").DoNotLoadOnNextBoot = state;
- SaveMemoryOnTimeout();
-
- CrestronConsole.ConsoleCommandResponse("[Application {0}], Do Not Load Config on Next Boot set to {1}",
- InitialParametersClass.ApplicationNumber, DoNotLoadConfigOnNextBoot);
- }
-
- ///
- /// ShowDebugLog method
- ///
- 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
- ///
- /// LogMessage method
- ///
- 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);
- }
- }
-
- ///
- /// 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);
- }
- }
-
- ///
- /// Logs a message at the specified log level.
- ///
- /// Level to log at
- /// Message template
- /// Args to put into message template
- public static void LogMessage(LogEventLevel level, string message, params object[] 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);
}
+ }
- ///
- /// LogMessage method
- ///
- public static void LogMessage(LogEventLevel level, Exception ex, string message, params object[] 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)
+ {
+ _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);
}
+ }
- ///
- /// LogMessage method
- ///
- public static void LogMessage(LogEventLevel level, IKeyed keyed, string message, params object[] args)
- {
- LogMessage(level, message, keyed, args);
- }
-
- ///
- /// LogMessage method
- ///
- 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
- ///
- /// LogVerbose method
- ///
- public static void LogVerbose(IKeyed keyed, string message, params object[] args)
- {
- using (LogContext.PushProperty("Key", keyed?.Key))
- {
- _logger.Write(LogEventLevel.Verbose, message, args);
- }
- }
-
- ///
- /// LogVerbose method
- ///
- 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);
- }
- }
-
- ///
- /// LogVerbose method
- ///
- 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);
}
+ }
- ///
- /// LogVerbose method
- ///
- 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, message, args);
}
+ }
- ///
- /// LogDebug method
- ///
- 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);
+ }
- ///
- /// LogDebug method
- ///
- 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);
+ }
- ///
- /// LogDebug method
- ///
- 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);
}
+ }
- ///
- /// LogDebug method
- ///
- 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);
}
+ }
- ///
- /// LogInformation method
- ///
- 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);
+ }
- ///
- /// LogInformation method
- ///
- 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);
+ }
- ///
- /// LogInformation method
- ///
- 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);
}
+ }
- ///
- /// LogInformation method
- ///
- 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, message, args);
}
+ }
- ///
- /// LogWarning method
- ///
- 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);
+ }
- ///
- /// LogWarning method
- ///
- 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);
+ }
- ///
- /// LogWarning method
- ///
- 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);
}
+ }
- ///
- /// LogWarning method
- ///
- 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, message, args);
}
+ }
- ///
- /// LogError method
- ///
- 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);
+ }
- ///
- /// LogError method
- ///
- 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);
+ }
- ///
- /// LogError method
- ///
- 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);
}
+ }
- ///
- /// LogError method
- ///
- 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, message, args);
}
+ }
- ///
- /// LogFatal method
- ///
- 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);
+ }
- ///
- /// LogFatal method
- ///
- 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);
+ }
- ///
- /// LogFatal method
- ///
- 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);
}
+ }
- ///
- /// LogFatal method
- ///
- 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, 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];
+ var logLevel = _logLevels[level];
+
+ LogMessage(logLevel, format, items);
+ }
- 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)
- {
- LogMessage(level, dev, format, 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);
+ //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)
+ {
+ 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
+ {
///
- /// Enumeration of ErrorLogLevel values
+ /// 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 d62b3c8b..f6e5a2f4 100644
--- a/src/PepperDash.Core/Logging/DebugWebsocketSink.cs
+++ b/src/PepperDash.Core/Logging/DebugWebsocketSink.cs
@@ -17,326 +17,320 @@ using WebSocketSharp.Server;
using X509Certificate2 = System.Security.Cryptography.X509Certificates.X509Certificate2;
using WebSocketSharp.Net;
-namespace PepperDash.Core
+namespace PepperDash.Core;
+
+///
+/// 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";
+
///
- /// Provides a WebSocket-based logging sink for debugging purposes, allowing log events to be broadcast to connected
- /// WebSocket clients.
+ /// 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 WebSocketServer _wsServer;
-
- 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(_wsServer == null) return 0;
- return _wsServer.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 (_wsServer == null) return "";
- return $"wss://{CrestronEthernetHelper.GetEthernetParameter(CrestronEthernetHelper.ETHERNET_PARAMETER_TO_GET.GET_CURRENT_IP_ADDRESS, 0)}:{_wsServer.Port}{_wsServer.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 WebSocket server is currently listening for incoming connections.
- ///
- public bool IsRunning { get => _wsServer?.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);
- Debug.LogError("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 (_wsServer == null || !_wsServer.IsListening) return;
-
- var sw = new StringWriter();
- _textFormatter.Format(logEvent, sw);
-
- _wsServer.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.LogInformation("Starting Websocket Server on port: {0}", port);
-
-
- Start(port, $"\\user\\{_certificateName}.pfx", _certificatePassword);
- }
-
- private void Start(int port, string certPath = "", string certPassword = "")
- {
- try
- {
- ServerSslConfiguration sslConfig = null;
-
- if (!string.IsNullOrWhiteSpace(certPath))
- {
- Debug.LogInformation("Assigning SSL Configuration");
- sslConfig = new ServerSslConfiguration(new X509Certificate2(certPath, certPassword))
+ _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) =>
{
- ClientCertificateRequired = false,
- CheckCertificateRevocation = false,
- EnabledSslProtocols = SslProtocols.Tls12,
- //this is just to test, you might want to actually validate
- ClientCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
- {
- Debug.LogInformation("HTTPS ClientCerticateValidation Callback triggered");
- return true;
- }
+ 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;
- _wsServer = new WebSocketServer(port, true);
- if (sslConfig != null)
+ switch(d.Level)
{
- _wsServer.SslConfiguration.ServerCertificate = sslConfig.ServerCertificate;
+ 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.LogInformation("Adding Debug Client Service");
- _wsServer.AddWebSocketService(_path);
- Debug.LogInformation("Assigning Log Info");
- _wsServer.Log.Level = LogLevel.Trace;
- _wsServer.Log.Output = (d, s) =>
- {
- uint level;
+ 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");
- 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.LogInformation("{1} {0}\rCaller:{2}\rMessage:{3}\rs:{4}", d.Level.ToString(), d.Date.ToString(), d.Caller.ToString(), d.Message, s);
- };
- Debug.LogInformation("Starting");
-
- _wsServer.Start();
- Debug.LogInformation("Ready");
- }
- catch (Exception ex)
- {
- Debug.LogError("WebSocket Failed to start {0}", ex.Message);
- }
+ _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.LogInformation("Stopping Websocket Server");
- _wsServer?.Stop();
-
- _wsServer = 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.
- public DebugClient()
- {
- Debug.LogInformation("DebugClient Created");
- }
-
- ///
- protected override void OnOpen()
- {
- base.OnOpen();
-
- var url = Context.WebSocket.Url;
- Debug.LogInformation("New WebSocket Connection from: {0}", url);
-
- _connectionTime = DateTime.Now;
- }
-
- ///
- protected override void OnMessage(MessageEventArgs e)
- {
- base.OnMessage(e);
-
- Debug.LogInformation("WebSocket UiClient Message: {0}", e.Data);
- }
-
- ///
- protected override void OnClose(CloseEventArgs e)
- {
- base.OnClose(e);
-
- Debug.LogInformation("WebSocket UiClient Closing: {0} reason: {1}", e.Code, e.Reason);
-
- }
-
- ///
- protected override void OnError(WebSocketSharp.ErrorEventArgs e)
- {
- base.OnError(e);
-
- Debug.LogError("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);
}
}