Merged in feature/pdc-8 (pull request #11)

pdc-8 : Added PepperDashVersion property to Debug Class
This commit is contained in:
Trevor Payne
2019-05-16 20:08:32 +00:00
committed by Heath Volmer
4 changed files with 421 additions and 419 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -1,419 +1,421 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Crestron.SimplSharp; using Crestron.SimplSharp;
using Crestron.SimplSharp.Reflection; using Crestron.SimplSharp.Reflection;
using Crestron.SimplSharp.CrestronLogger; using Crestron.SimplSharp.CrestronLogger;
using Crestron.SimplSharp.CrestronIO; using Crestron.SimplSharp.CrestronIO;
using Newtonsoft.Json; using Newtonsoft.Json;
using PepperDash.Core.DebugThings; using PepperDash.Core.DebugThings;
namespace PepperDash.Core namespace PepperDash.Core
{ {
public static class Debug public static class Debug
{ {
/// <summary> /// <summary>
/// Describes the folder location where a given program stores it's debug level memory. By default, the /// 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. /// file written will be named appNdebug where N is 1-10.
/// </summary> /// </summary>
public static string FilePathPrefix = @"\nvram\debug\"; public static string FilePathPrefix = @"\nvram\debug\";
/// <summary> /// <summary>
/// The name of the file containing the current debug settings. /// The name of the file containing the current debug settings.
/// </summary> /// </summary>
public static string FileName = string.Format(@"app{0}Debug.json", InitialParametersClass.ApplicationNumber); public static string FileName = string.Format(@"app{0}Debug.json", InitialParametersClass.ApplicationNumber);
public static int Level { get; private set; } public static int Level { get; private set; }
static DebugContextCollection Contexts; static DebugContextCollection Contexts;
static int SaveTimeoutMs = 30000; static int SaveTimeoutMs = 30000;
static CTimer SaveTimer; public static string PepperDashCoreVersion { get; private set; }
/// <summary> static CTimer SaveTimer;
/// When true, the IncludedExcludedKeys dict will contain keys to include.
/// When false (default), IncludedExcludedKeys will contain keys to exclude. /// <summary>
/// </summary> /// When true, the IncludedExcludedKeys dict will contain keys to include.
static bool ExcludeAllMode; /// When false (default), IncludedExcludedKeys will contain keys to exclude.
/// </summary>
//static bool ExcludeNoKeyMessages; static bool ExcludeAllMode;
static Dictionary<string, object> IncludedExcludedKeys; //static bool ExcludeNoKeyMessages;
static Debug() static Dictionary<string, object> IncludedExcludedKeys;
{
// Get the assembly version and print it to console and the log static Debug()
var version = Assembly.GetExecutingAssembly().GetName().Version; {
// Get the assembly version and print it to console and the log
var versionString = string.Format("{0}.{1}.{2}", version.Major, version.Minor, version.Build); var version = Assembly.GetExecutingAssembly().GetName().Version;
var msg = string.Format("[App {0}] Using PepperDash_Core v{1}", InitialParametersClass.ApplicationNumber, versionString); PepperDashCoreVersion = string.Format("{0}.{1}.{2}", version.Major, version.Minor, version.Build);
CrestronConsole.PrintLine(msg); var msg = string.Format("[App {0}] Using PepperDash_Core v{1}", InitialParametersClass.ApplicationNumber, PepperDashCoreVersion);
LogError(ErrorLogLevel.Notice, msg); CrestronConsole.PrintLine(msg);
IncludedExcludedKeys = new Dictionary<string, object>(); LogError(ErrorLogLevel.Notice, msg);
//CrestronDataStoreStatic.InitCrestronDataStore(); IncludedExcludedKeys = new Dictionary<string, object>();
if (CrestronEnvironment.RuntimeEnvironment == eRuntimeEnvironment.SimplSharpPro)
{ //CrestronDataStoreStatic.InitCrestronDataStore();
// Add command to console if (CrestronEnvironment.RuntimeEnvironment == eRuntimeEnvironment.SimplSharpPro)
CrestronConsole.AddNewConsoleCommand(SetDebugFromConsole, "appdebug", {
"appdebug:P [0-2]: Sets the application's console debug message level", // Add command to console
ConsoleAccessLevelEnum.AccessOperator); CrestronConsole.AddNewConsoleCommand(SetDebugFromConsole, "appdebug",
CrestronConsole.AddNewConsoleCommand(ShowDebugLog, "appdebuglog", "appdebug:P [0-2]: Sets the application's console debug message level",
"appdebuglog:P [all] Use \"all\" for full log.", ConsoleAccessLevelEnum.AccessOperator);
ConsoleAccessLevelEnum.AccessOperator); CrestronConsole.AddNewConsoleCommand(ShowDebugLog, "appdebuglog",
CrestronConsole.AddNewConsoleCommand(s => CrestronLogger.Clear(false), "appdebugclear", "appdebuglog:P [all] Use \"all\" for full log.",
"appdebugclear:P Clears the current custom log", ConsoleAccessLevelEnum.AccessOperator);
ConsoleAccessLevelEnum.AccessOperator); CrestronConsole.AddNewConsoleCommand(s => CrestronLogger.Clear(false), "appdebugclear",
CrestronConsole.AddNewConsoleCommand(SetDebugFilterFromConsole, "appdebugfilter", "appdebugclear:P Clears the current custom log",
"appdebugfilter [params]", ConsoleAccessLevelEnum.AccessOperator); ConsoleAccessLevelEnum.AccessOperator);
} CrestronConsole.AddNewConsoleCommand(SetDebugFilterFromConsole, "appdebugfilter",
"appdebugfilter [params]", ConsoleAccessLevelEnum.AccessOperator);
CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironment_ProgramStatusEventHandler; }
LoadMemory(); CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironment_ProgramStatusEventHandler;
Level = Contexts.GetOrCreateItem("DEFAULT").Level;
LoadMemory();
try Level = Contexts.GetOrCreateItem("DEFAULT").Level;
{
if (InitialParametersClass.NumberOfRemovableDrives > 0) try
{ {
CrestronConsole.PrintLine("{0} RM Drive(s) Present.", InitialParametersClass.NumberOfRemovableDrives); if (InitialParametersClass.NumberOfRemovableDrives > 0)
CrestronLogger.Initialize(2, LoggerModeEnum.DEFAULT); // Use RM instead of DEFAULT as not to double-up console messages. {
} CrestronConsole.PrintLine("{0} RM Drive(s) Present.", InitialParametersClass.NumberOfRemovableDrives);
else CrestronLogger.Initialize(2, LoggerModeEnum.DEFAULT); // Use RM instead of DEFAULT as not to double-up console messages.
CrestronConsole.PrintLine("No RM Drive(s) Present."); }
} else
catch (Exception e) CrestronConsole.PrintLine("No RM Drive(s) Present.");
{ }
catch (Exception e)
CrestronConsole.PrintLine("Initializing of CrestronLogger failed: {0}", e); {
}
} CrestronConsole.PrintLine("Initializing of CrestronLogger failed: {0}", e);
}
/// <summary> }
/// Used to save memory when shutting down
/// </summary> /// <summary>
/// <param name="programEventType"></param> /// Used to save memory when shutting down
static void CrestronEnvironment_ProgramStatusEventHandler(eProgramStatusEventType programEventType) /// </summary>
{ /// <param name="programEventType"></param>
if (programEventType == eProgramStatusEventType.Stopping) static void CrestronEnvironment_ProgramStatusEventHandler(eProgramStatusEventType programEventType)
{ {
if (SaveTimer != null) if (programEventType == eProgramStatusEventType.Stopping)
{ {
SaveTimer.Stop(); if (SaveTimer != null)
SaveTimer = null; {
} SaveTimer.Stop();
Console(0, "Saving debug settings"); SaveTimer = null;
SaveMemory(); }
} Console(0, "Saving debug settings");
} SaveMemory();
}
/// <summary> }
/// Callback for console command
/// </summary> /// <summary>
/// <param name="levelString"></param> /// Callback for console command
public static void SetDebugFromConsole(string levelString) /// </summary>
{ /// <param name="levelString"></param>
try public static void SetDebugFromConsole(string levelString)
{ {
if (string.IsNullOrEmpty(levelString.Trim())) try
{ {
CrestronConsole.PrintLine("AppDebug level = {0}", Level); if (string.IsNullOrEmpty(levelString.Trim()))
return; {
} CrestronConsole.PrintLine("AppDebug level = {0}", Level);
return;
SetDebugLevel(Convert.ToInt32(levelString)); }
}
catch SetDebugLevel(Convert.ToInt32(levelString));
{ }
CrestronConsole.PrintLine("Usage: appdebug:P [0-2]"); catch
} {
} CrestronConsole.PrintLine("Usage: appdebug:P [0-2]");
}
public static void SetDebugFilterFromConsole(string items) }
{
var str = items.Trim(); public static void SetDebugFilterFromConsole(string items)
if (str == "?") {
{ var str = items.Trim();
CrestronConsole.ConsoleCommandResponse("Usage:\r APPDEBUGFILTER key1 key2 key3....\r " + if (str == "?")
"+all: at beginning puts filter into 'default include' mode\r" + {
" All keys that follow will be excluded from output.\r" + CrestronConsole.ConsoleCommandResponse("Usage:\r APPDEBUGFILTER key1 key2 key3....\r " +
"-all: at beginning puts filter into 'default excluse all' mode.\r" + "+all: at beginning puts filter into 'default include' mode\r" +
" All keys that follow will be the only keys that are shown\r" + " All keys that follow will be excluded from output.\r" +
"+nokey: Enables messages with no key (default)\r" + "-all: at beginning puts filter into 'default excluse all' mode.\r" +
"-nokey: Disables messages with no key.\r" + " All keys that follow will be the only keys that are shown\r" +
"(nokey settings are independent of all other settings)"); "+nokey: Enables messages with no key (default)\r" +
return; "-nokey: Disables messages with no key.\r" +
} "(nokey settings are independent of all other settings)");
var keys = Regex.Split(str, @"\s*"); return;
foreach (var keyToken in keys) }
{ var keys = Regex.Split(str, @"\s*");
var lkey = keyToken.ToLower(); foreach (var keyToken in keys)
if (lkey == "+all") {
{ var lkey = keyToken.ToLower();
IncludedExcludedKeys.Clear(); if (lkey == "+all")
ExcludeAllMode = false; {
} IncludedExcludedKeys.Clear();
else if (lkey == "-all") ExcludeAllMode = false;
{ }
IncludedExcludedKeys.Clear(); else if (lkey == "-all")
ExcludeAllMode = true; {
} IncludedExcludedKeys.Clear();
//else if (lkey == "+nokey") ExcludeAllMode = true;
//{ }
// ExcludeNoKeyMessages = false; //else if (lkey == "+nokey")
//} //{
//else if (lkey == "-nokey") // ExcludeNoKeyMessages = false;
//{ //}
// ExcludeNoKeyMessages = true; //else if (lkey == "-nokey")
//} //{
else // ExcludeNoKeyMessages = true;
{ //}
string key = null; ; else
if (lkey.StartsWith("-")) {
{ string key = null; ;
key = lkey.Substring(1); if (lkey.StartsWith("-"))
// if in exclude all mode, we need to remove this from the inclusions {
if (ExcludeAllMode) key = lkey.Substring(1);
{ // if in exclude all mode, we need to remove this from the inclusions
if (IncludedExcludedKeys.ContainsKey(key)) if (ExcludeAllMode)
IncludedExcludedKeys.Remove(key); {
} if (IncludedExcludedKeys.ContainsKey(key))
// otherwise include all mode, add to the exclusions IncludedExcludedKeys.Remove(key);
else }
{ // otherwise include all mode, add to the exclusions
IncludedExcludedKeys[key] = new object(); else
} {
} IncludedExcludedKeys[key] = new object();
else if (lkey.StartsWith("+")) }
{ }
key = lkey.Substring(1); else if (lkey.StartsWith("+"))
// if in exclude all mode, we need to add this as inclusion {
if (ExcludeAllMode) key = lkey.Substring(1);
{ // if in exclude all mode, we need to add this as inclusion
if (ExcludeAllMode)
IncludedExcludedKeys[key] = new object(); {
}
// otherwise include all mode, remove this from exclusions IncludedExcludedKeys[key] = new object();
else }
{ // otherwise include all mode, remove this from exclusions
if (IncludedExcludedKeys.ContainsKey(key)) else
IncludedExcludedKeys.Remove(key); {
} if (IncludedExcludedKeys.ContainsKey(key))
} IncludedExcludedKeys.Remove(key);
} }
} }
} }
}
}
/// <summary>
/// Sets the debug level
/// </summary> /// <summary>
/// <param name="level"> Valid values 0 (no debug), 1 (critical), 2 (all messages)</param> /// Sets the debug level
public static void SetDebugLevel(int level) /// </summary>
{ /// <param name="level"> Valid values 0 (no debug), 1 (critical), 2 (all messages)</param>
if (level <= 2) public static void SetDebugLevel(int level)
{ {
Level = level; if (level <= 2)
Contexts.GetOrCreateItem("DEFAULT").Level = level; {
SaveMemoryOnTimeout(); Level = level;
Contexts.GetOrCreateItem("DEFAULT").Level = level;
CrestronConsole.PrintLine("[Application {0}], Debug level set to {1}", SaveMemoryOnTimeout();
InitialParametersClass.ApplicationNumber, Level);
CrestronConsole.PrintLine("[Application {0}], Debug level set to {1}",
//var err = CrestronDataStoreStatic.SetLocalUintValue("DebugLevel", level); InitialParametersClass.ApplicationNumber, Level);
//if (err != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
// CrestronConsole.PrintLine("Error saving console debug level setting: {0}", err); //var err = CrestronDataStoreStatic.SetLocalUintValue("DebugLevel", level);
} //if (err != CrestronDataStore.CDS_ERROR.CDS_SUCCESS)
} // CrestronConsole.PrintLine("Error saving console debug level setting: {0}", err);
}
/// <summary> }
///
/// </summary> /// <summary>
public static void ShowDebugLog(string s) ///
{ /// </summary>
var loglist = CrestronLogger.PrintTheLog(s.ToLower() == "all"); public static void ShowDebugLog(string s)
foreach (var l in loglist) {
CrestronConsole.ConsoleCommandResponse(l + CrestronEnvironment.NewLine); var loglist = CrestronLogger.PrintTheLog(s.ToLower() == "all");
} foreach (var l in loglist)
CrestronConsole.ConsoleCommandResponse(l + CrestronEnvironment.NewLine);
/// <summary> }
/// Prints message to console if current debug level is equal to or higher than the level of this message.
/// Uses CrestronConsole.PrintLine. /// <summary>
/// </summary> /// Prints message to console if current debug level is equal to or higher than the level of this message.
/// <param name="level"></param> /// Uses CrestronConsole.PrintLine.
/// <param name="format">Console format string</param> /// </summary>
/// <param name="items">Object parameters</param> /// <param name="level"></param>
public static void Console(uint level, string format, params object[] items) /// <param name="format">Console format string</param>
{ /// <param name="items">Object parameters</param>
if (Level >= level) public static void Console(uint level, string format, params object[] items)
CrestronConsole.PrintLine("[{0}]App {1}:{2}", DateTime.Now.ToString("HH:mm:ss.fff"), InitialParametersClass.ApplicationNumber, {
string.Format(format, items)); if (Level >= level)
} CrestronConsole.PrintLine("[{0}]App {1}:{2}", DateTime.Now.ToString("HH:mm:ss.fff"), InitialParametersClass.ApplicationNumber,
string.Format(format, items));
/// <summary> }
/// Logs to Console when at-level, and all messages to error log, including device key
/// </summary> /// <summary>
public static void Console(uint level, IKeyed dev, string format, params object[] items) /// Logs to Console when at-level, and all messages to error log, including device key
{ /// </summary>
if (Level >= level) public static void Console(uint level, IKeyed dev, string format, params object[] items)
Console(level, "[{0}] {1}", dev.Key, string.Format(format, items)); {
} if (Level >= level)
Console(level, "[{0}] {1}", dev.Key, string.Format(format, items));
public static void Console(uint level, IKeyed dev, ErrorLogLevel errorLogLevel, }
string format, params object[] items)
{ public static void Console(uint level, IKeyed dev, ErrorLogLevel errorLogLevel,
var str = string.Format("[{0}] {1}", dev.Key, string.Format(format, items)); string format, params object[] items)
LogError(errorLogLevel, str); {
if (Level >= level) var str = string.Format("[{0}] {1}", dev.Key, string.Format(format, items));
{ LogError(errorLogLevel, str);
Console(level, str); if (Level >= level)
} {
} Console(level, str);
}
/// <summary> }
/// Logs to Console when at-level, and all messages to error log
/// </summary> /// <summary>
public static void Console(uint level, ErrorLogLevel errorLogLevel, /// Logs to Console when at-level, and all messages to error log
string format, params object[] items) /// </summary>
{ public static void Console(uint level, ErrorLogLevel errorLogLevel,
var str = string.Format(format, items); string format, params object[] items)
LogError(errorLogLevel, str); {
if (Level >= level) var str = string.Format(format, items);
{ LogError(errorLogLevel, str);
Console(level, str); if (Level >= level)
} {
} Console(level, str);
}
/// <summary> }
/// 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 /// <summary>
/// it will only be written to the log. /// Logs to both console and the custom user log (not the built-in error log). If appdebug level is set at
/// </summary> /// or above the level provided, then the output will be written to both console and the log. Otherwise
/// <param name="level"></param> /// it will only be written to the log.
/// <param name="format"></param> /// </summary>
/// <param name="items"></param> /// <param name="level"></param>
public static void ConsoleWithLog(uint level, string format, params object[] items) /// <param name="format"></param>
{ /// <param name="items"></param>
var str = string.Format(format, items); public static void ConsoleWithLog(uint level, string format, params object[] items)
if (Level >= level) {
CrestronConsole.PrintLine("App {0}:{1}", InitialParametersClass.ApplicationNumber, str); var str = string.Format(format, items);
CrestronLogger.WriteToLog(str, level); if (Level >= level)
} CrestronConsole.PrintLine("App {0}:{1}", InitialParametersClass.ApplicationNumber, str);
CrestronLogger.WriteToLog(str, level);
/// <summary> }
/// 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 /// <summary>
/// it will only be written to the log. /// Logs to both console and the custom user log (not the built-in error log). If appdebug level is set at
/// </summary> /// or above the level provided, then the output will be written to both console and the log. Otherwise
/// <param name="level"></param> /// it will only be written to the log.
/// <param name="dev"></param> /// </summary>
/// <param name="format">String.format string</param> /// <param name="level"></param>
/// <param name="items">Parameters for substitution in the format string.</param> /// <param name="dev"></param>
public static void ConsoleWithLog(uint level, IKeyed dev, string format, params object[] items) /// <param name="format">String.format string</param>
{ /// <param name="items">Parameters for substitution in the format string.</param>
var str = string.Format(format, items); public static void ConsoleWithLog(uint level, IKeyed dev, string format, params object[] items)
if (Level >= level) {
ConsoleWithLog(level, "[{0}] {1}", dev.Key, str); var str = string.Format(format, items);
} if (Level >= level)
ConsoleWithLog(level, "[{0}] {1}", dev.Key, str);
/// <summary> }
/// Prints to log and error log
/// </summary> /// <summary>
/// <param name="errorLogLevel"></param> /// Prints to log and error log
/// <param name="str"></param> /// </summary>
public static void LogError(ErrorLogLevel errorLogLevel, string str) /// <param name="errorLogLevel"></param>
{ /// <param name="str"></param>
string msg = string.Format("App {0}:{1}", InitialParametersClass.ApplicationNumber, str); public static void LogError(ErrorLogLevel errorLogLevel, string str)
switch (errorLogLevel) {
{ string msg = string.Format("App {0}:{1}", InitialParametersClass.ApplicationNumber, str);
case ErrorLogLevel.Error: switch (errorLogLevel)
ErrorLog.Error(msg); {
break; case ErrorLogLevel.Error:
case ErrorLogLevel.Warning: ErrorLog.Error(msg);
ErrorLog.Warn(msg); break;
break; case ErrorLogLevel.Warning:
case ErrorLogLevel.Notice: ErrorLog.Warn(msg);
ErrorLog.Notice(msg); break;
break; case ErrorLogLevel.Notice:
} ErrorLog.Notice(msg);
} break;
}
/// <summary> }
/// Writes the memory object after timeout
/// </summary> /// <summary>
static void SaveMemoryOnTimeout() /// Writes the memory object after timeout
{ /// </summary>
if (SaveTimer == null) static void SaveMemoryOnTimeout()
SaveTimer = new CTimer(o => {
{ if (SaveTimer == null)
SaveTimer = null; SaveTimer = new CTimer(o =>
SaveMemory(); {
}, SaveTimeoutMs); SaveTimer = null;
else SaveMemory();
SaveTimer.Reset(SaveTimeoutMs); }, SaveTimeoutMs);
} else
SaveTimer.Reset(SaveTimeoutMs);
/// <summary> }
/// Writes the memory - use SaveMemoryOnTimeout
/// </summary> /// <summary>
static void SaveMemory() /// Writes the memory - use SaveMemoryOnTimeout
{ /// </summary>
//var dir = @"\NVRAM\debug"; static void SaveMemory()
//if (!Directory.Exists(dir)) {
// Directory.Create(dir); //var dir = @"\NVRAM\debug";
//if (!Directory.Exists(dir))
using (StreamWriter sw = new StreamWriter(GetMemoryFileName())) // Directory.Create(dir);
{
var json = JsonConvert.SerializeObject(Contexts); using (StreamWriter sw = new StreamWriter(GetMemoryFileName()))
sw.Write(json); {
sw.Flush(); var json = JsonConvert.SerializeObject(Contexts);
} sw.Write(json);
} sw.Flush();
}
/// <summary> }
///
/// </summary> /// <summary>
static void LoadMemory() ///
{ /// </summary>
var file = GetMemoryFileName(); static void LoadMemory()
if (File.Exists(file)) {
{ var file = GetMemoryFileName();
using (StreamReader sr = new StreamReader(file)) if (File.Exists(file))
{ {
var json = sr.ReadToEnd(); using (StreamReader sr = new StreamReader(file))
Contexts = JsonConvert.DeserializeObject<DebugContextCollection>(json); {
var json = sr.ReadToEnd();
if (Contexts != null) Contexts = JsonConvert.DeserializeObject<DebugContextCollection>(json);
{
Debug.Console(1, "Debug memory restored from file"); if (Contexts != null)
return; {
} Debug.Console(1, "Debug memory restored from file");
} return;
} }
}
Contexts = new DebugContextCollection(); }
}
Contexts = new DebugContextCollection();
/// <summary> }
/// Helper to get the file path for this app's debug memory
/// </summary> /// <summary>
static string GetMemoryFileName() /// Helper to get the file path for this app's debug memory
{ /// </summary>
return string.Format(@"\NVRAM\debugSettings\program{0}", InitialParametersClass.ApplicationNumber); static string GetMemoryFileName()
} {
return string.Format(@"\NVRAM\debugSettings\program{0}", InitialParametersClass.ApplicationNumber);
public enum ErrorLogLevel }
{
Error, Warning, Notice, None public enum ErrorLogLevel
} {
} Error, Warning, Notice, None
}
}
} }

View File

@@ -4,4 +4,4 @@
[assembly: AssemblyCompany("")] [assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Pepperdash_Core")] [assembly: AssemblyProduct("Pepperdash_Core")]
[assembly: AssemblyCopyright("Copyright © PepperDash 2019")] [assembly: AssemblyCopyright("Copyright © PepperDash 2019")]
[assembly: AssemblyVersion("1.0.17.*")] [assembly: AssemblyVersion("1.0.18.*")]