Skip to content

Commit

Permalink
fix: debug all devices when devices array is empty
Browse files Browse the repository at this point in the history
  • Loading branch information
ngenovese11 committed Nov 8, 2024
1 parent 4f01ff1 commit 1f51c3e
Show file tree
Hide file tree
Showing 2 changed files with 188 additions and 179 deletions.
150 changes: 81 additions & 69 deletions src/Pepperdash.Core/Logging/DebugConsoleSink.cs
Original file line number Diff line number Diff line change
@@ -1,69 +1,81 @@
using System.IO;
using System.Text;
using Crestron.SimplSharp;
using Serilog;
using Serilog.Configuration;
using Serilog.Core;
using Serilog.Events;
using Serilog.Formatting;
using Serilog.Formatting.Json;

namespace PepperDash.Core.Logging
{
public class DebugConsoleSink : ILogEventSink
{
private readonly ITextFormatter textFormatter;

public void Emit(LogEvent logEvent)
{

/*string message = $"[{logEvent.Timestamp}][{logEvent.Level}][App {InitialParametersClass.ApplicationNumber}]{logEvent.RenderMessage()}";
if(logEvent.Properties.TryGetValue("Key",out var value) && value is ScalarValue sv && sv.Value is string rawValue)
{
message = $"[{logEvent.Timestamp}][{logEvent.Level}][App {InitialParametersClass.ApplicationNumber}][{rawValue,3}]: {logEvent.RenderMessage()}";
}*/

var buffer = new StringWriter(new StringBuilder(256));

textFormatter.Format(logEvent, buffer);

var message = buffer.ToString();

CrestronConsole.PrintLine(message);
}

public DebugConsoleSink(ITextFormatter formatProvider)
{
textFormatter = formatProvider ?? new JsonFormatter();
}
}

public static class DebugConsoleSinkExtensions
{
public static LoggerConfiguration DebugConsoleSink(
this LoggerSinkConfiguration loggerConfiguration,
ITextFormatter formatProvider = null,
LoggingLevelSwitch levelSwitch = null)
{
var sink = new DebugConsoleSink(formatProvider);
return loggerConfiguration.Conditional(Predicate, c => c.Sink(sink, levelSwitch: levelSwitch));

static bool Predicate(LogEvent @event)
{
if (!Debug.IsRunningOnAppliance)
{
return false;
}

if (@event.Properties.TryGetValue("Key", out var value) &&
value is ScalarValue { Value: string rawValue })
{
return DebugContext.DeviceExistsInContext(Debug.ConsoleLevelStoreKey, rawValue);
}

return true;
}
}
}
}
using System.IO;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Serilog;
using Serilog.Configuration;
using Serilog.Core;
using Serilog.Events;
using Serilog.Formatting;
using Serilog.Formatting.Json;

namespace PepperDash.Core.Logging
{
public class DebugConsoleSink : ILogEventSink
{
private readonly ITextFormatter textFormatter;

public void Emit(LogEvent logEvent)
{

/*string message = $"[{logEvent.Timestamp}][{logEvent.Level}][App {InitialParametersClass.ApplicationNumber}]{logEvent.RenderMessage()}";
if(logEvent.Properties.TryGetValue("Key",out var value) && value is ScalarValue sv && sv.Value is string rawValue)
{
message = $"[{logEvent.Timestamp}][{logEvent.Level}][App {InitialParametersClass.ApplicationNumber}][{rawValue,3}]: {logEvent.RenderMessage()}";
}*/

var buffer = new StringWriter(new StringBuilder(256));

textFormatter.Format(logEvent, buffer);

var message = buffer.ToString();

CrestronConsole.PrintLine(message);
}

public DebugConsoleSink(ITextFormatter formatProvider)
{
textFormatter = formatProvider ?? new JsonFormatter();
}
}

public static class DebugConsoleSinkExtensions
{
public static LoggerConfiguration DebugConsoleSink(
this LoggerSinkConfiguration loggerConfiguration,
ITextFormatter formatProvider = null,
LoggingLevelSwitch levelSwitch = null)
{
var sink = new DebugConsoleSink(formatProvider);
return loggerConfiguration.Conditional(Predicate, c => c.Sink(sink, levelSwitch: levelSwitch));

static bool Predicate(LogEvent @event)
{
if (!Debug.IsRunningOnAppliance)
{
return false;
}

if (@event.Properties.TryGetValue("Key", out var value) && value is ScalarValue { Value: string rawValue }
&& DebugContext.TryGetDataForKey(Debug.ConsoleLevelStoreKey, out var data)
&& data.Devices != null)
{
if (data.Devices.Length == 0)
{
return true;
}

if (data.Devices.Any(d => d == rawValue))
{
return true;
}

return false;
}

return true;
}
}
}
}
217 changes: 107 additions & 110 deletions src/Pepperdash.Core/Logging/DebugContext.cs
Original file line number Diff line number Diff line change
@@ -1,110 +1,107 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using Serilog;
using Serilog.Events;

namespace PepperDash.Core.Logging
{
/// <summary>
/// Represents a debugging context
/// </summary>
public static class DebugContext
{
private static readonly CTimer SaveTimer;
private static readonly Dictionary<string, DebugContextData> CurrentData;

public static readonly string ApplianceFilePath = Path.Combine("/", "user", "debug", $"app{InitialParametersClass.ApplicationNumber.ToString().PadLeft(2, '0')}-debug.json");
public static readonly string ServerFilePath = Path.Combine("/", "User", "debug", $"{InitialParametersClass.RoomId}-debug.json");

/// <summary>
/// The name of the file containing the current debug settings.
/// </summary>
public static readonly string FileName = CrestronEnvironment.DevicePlatform switch
{
eDevicePlatform.Appliance => ApplianceFilePath,
eDevicePlatform.Server => ServerFilePath,
_ => string.Empty
};

static DebugContext()
{
CurrentData = LoadData();
SaveTimer = new CTimer(_ => SaveData(), Timeout.Infinite);

CrestronEnvironment.ProgramStatusEventHandler += args =>
{
if (args == eProgramStatusEventType.Stopping)
{
using (SaveTimer)
{
SaveData();
SaveTimer.Stop();
}
}
};
}

public static DebugContextData GetDataForKey(string key, LogEventLevel defaultLevel) =>
CurrentData.TryGetValue(key, out var data) ? data : new DebugContextData(defaultLevel);

public static bool DeviceExistsInContext(string contextKey, string deviceKey) =>
CurrentData.TryGetValue(contextKey, out var data) switch
{
true when data.Devices != null => data.Devices.Any(key => string.Equals(key, deviceKey, StringComparison.OrdinalIgnoreCase)),
_ => false
};

public static void SetDataForKey(string key, LogEventLevel defaultLevel, string[] devices = null)
{
if (CurrentData.ContainsKey(key))
{
CurrentData[key] = new DebugContextData(defaultLevel, devices);
}
else
{
CurrentData.Add(key, new DebugContextData(defaultLevel, devices));
}

SaveTimer.Reset(5000);
}

private static void SaveData()
{
Log.Information("Saving debug data to file:{File}", FileName);

try
{
var debugDirectory = Path.GetDirectoryName(FileName) ??
throw new Exception("File directory is root");

Directory.CreateDirectory(debugDirectory);
var json = JsonConvert.SerializeObject(CurrentData);
File.WriteAllText(FileName, json);
}
catch (Exception e)
{
Log.Error(e, "Failed to save debug data");
}
}

private static Dictionary<string, DebugContextData> LoadData()
{
if (!File.Exists(FileName))
{
return new Dictionary<string, DebugContextData>();
}

var json = File.ReadAllText(FileName);
return JsonConvert.DeserializeObject<Dictionary<string, DebugContextData>>(json);
}
}

/// <summary>
///
/// </summary>
public record DebugContextData(LogEventLevel Level, string[] Devices = null);
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Crestron.SimplSharp;
using Newtonsoft.Json;
using Serilog;
using Serilog.Events;

namespace PepperDash.Core.Logging
{
/// <summary>
/// Represents a debugging context
/// </summary>
public static class DebugContext
{
private static readonly CTimer SaveTimer;
private static readonly Dictionary<string, DebugContextData> CurrentData;

public static readonly string ApplianceFilePath = Path.Combine("/", "user", "debug", $"app{InitialParametersClass.ApplicationNumber.ToString().PadLeft(2, '0')}-debug.json");
public static readonly string ServerFilePath = Path.Combine("/", "User", "debug", $"{InitialParametersClass.RoomId}-debug.json");

/// <summary>
/// The name of the file containing the current debug settings.
/// </summary>
public static readonly string FileName = CrestronEnvironment.DevicePlatform switch
{
eDevicePlatform.Appliance => ApplianceFilePath,
eDevicePlatform.Server => ServerFilePath,
_ => string.Empty
};

static DebugContext()
{
CurrentData = LoadData();
SaveTimer = new CTimer(_ => SaveData(), Timeout.Infinite);

CrestronEnvironment.ProgramStatusEventHandler += args =>
{
if (args == eProgramStatusEventType.Stopping)
{
using (SaveTimer)
{
SaveData();
SaveTimer.Stop();
}
}
};
}

public static bool TryGetDataForKey(string key, out DebugContextData data) =>
CurrentData.TryGetValue(key, out var data);

public static DebugContextData GetOrCreateDataForKey(string key, LogEventLevel defaultLevel) =>
CurrentData.TryGetValue(key, out var data) ? data : new DebugContextData(defaultLevel);


public static void SetDataForKey(string key, LogEventLevel defaultLevel, string[] devices = null)
{
if (CurrentData.ContainsKey(key))
{
CurrentData[key] = new DebugContextData(defaultLevel, devices);
}
else
{
CurrentData.Add(key, new DebugContextData(defaultLevel, devices));
}

SaveTimer.Reset(5000);
}

private static void SaveData()
{
Log.Information("Saving debug data to file:{File}", FileName);

try
{
var debugDirectory = Path.GetDirectoryName(FileName) ??
throw new Exception("File directory is root");

Directory.CreateDirectory(debugDirectory);
var json = JsonConvert.SerializeObject(CurrentData);
File.WriteAllText(FileName, json);
}
catch (Exception e)
{
Log.Error(e, "Failed to save debug data");
}
}

private static Dictionary<string, DebugContextData> LoadData()
{
if (!File.Exists(FileName))
{
return new Dictionary<string, DebugContextData>();
}

var json = File.ReadAllText(FileName);
return JsonConvert.DeserializeObject<Dictionary<string, DebugContextData>>(json);
}
}

/// <summary>
///
/// </summary>
public record DebugContextData(LogEventLevel Level, string[] Devices = null);
}

0 comments on commit 1f51c3e

Please sign in to comment.