Skip to content

Commit

Permalink
Adds Logging level control to UICatalog (gui-cs#3938)
Browse files Browse the repository at this point in the history
* Tons of API doc updates

* Added logging control to UICatalog

* Added logging control to UICatalog - more

* fixed minor issues

* removed logs from .gitignore

* Fixed log file path

* Fixed app desc
  • Loading branch information
tig authored Feb 28, 2025
1 parent c88c772 commit 79cd4e9
Show file tree
Hide file tree
Showing 20 changed files with 398 additions and 196 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,5 @@ demo.*
*.tui/

*.dotCover

logs/
1 change: 1 addition & 0 deletions Terminal.Gui/Application/ApplicationImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ public virtual void Shutdown ()

bool wasInitialized = Application.Initialized;
Application.ResetState ();
LogJsonErrors ();
PrintJsonErrors ();

if (wasInitialized)
Expand Down
4 changes: 2 additions & 2 deletions Terminal.Gui/Configuration/AttributeJsonConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ public override Attribute Read (ref Utf8JsonReader reader, Type typeToConvert, J
switch (propertyName?.ToLower ())
{
case "foreground":
foreground = JsonSerializer.Deserialize (color, _serializerContext.Color);
foreground = JsonSerializer.Deserialize (color, SerializerContext.Color);

break;
case "background":
background = JsonSerializer.Deserialize (color, _serializerContext.Color);
background = JsonSerializer.Deserialize (color, SerializerContext.Color);

break;

Expand Down
2 changes: 1 addition & 1 deletion Terminal.Gui/Configuration/ColorSchemeJsonConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public override ColorScheme Read (ref Utf8JsonReader reader, Type typeToConvert,

string propertyName = reader.GetString ();
reader.Read ();
var attribute = JsonSerializer.Deserialize (ref reader, _serializerContext.Attribute);
var attribute = JsonSerializer.Deserialize (ref reader, SerializerContext.Attribute);

switch (propertyName.ToLower ())
{
Expand Down
43 changes: 28 additions & 15 deletions Terminal.Gui/Configuration/ConfigurationManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.Extensions.Logging;

#nullable enable

Expand Down Expand Up @@ -65,7 +66,7 @@ public static class ConfigurationManager
internal static Dictionary<string, ConfigProperty>? _allConfigProperties;

[SuppressMessage ("Style", "IDE1006:Naming Styles", Justification = "<Pending>")]
internal static readonly JsonSerializerOptions _serializerOptions = new ()
internal static readonly JsonSerializerOptions SerializerOptions = new ()
{
ReadCommentHandling = JsonCommentHandling.Skip,
PropertyNameCaseInsensitive = true,
Expand All @@ -87,7 +88,7 @@ public static class ConfigurationManager
};

[SuppressMessage ("Style", "IDE1006:Naming Styles", Justification = "<Pending>")]
internal static readonly SourceGenerationContext _serializerContext = new (_serializerOptions);
internal static readonly SourceGenerationContext SerializerContext = new (SerializerOptions);

[SuppressMessage ("Style", "IDE1006:Naming Styles", Justification = "<Pending>")]
internal static StringBuilder _jsonErrors = new ();
Expand Down Expand Up @@ -209,7 +210,7 @@ public static string GetEmptyJson ()
var emptyScope = new SettingsScope ();
emptyScope.Clear ();

return JsonSerializer.Serialize (emptyScope, typeof (SettingsScope), _serializerContext);
return JsonSerializer.Serialize (emptyScope, typeof (SettingsScope), SerializerContext);
}

/// <summary>
Expand All @@ -235,7 +236,7 @@ public static string GetEmptyJson ()
[RequiresDynamicCode ("AOT")]
public static void Load (bool reset = false)
{
Debug.WriteLine ("ConfigurationManager.Load()");
Logging.Trace ($"reset = {reset}");

if (reset)
{
Expand Down Expand Up @@ -292,7 +293,7 @@ public static void Load (bool reset = false)
/// </summary>
public static void OnApplied ()
{
Debug.WriteLine ("ConfigurationManager.OnApplied()");
//Logging.Trace ("");

Applied?.Invoke (null, new ());

Expand All @@ -308,7 +309,7 @@ public static void OnApplied ()
/// </summary>
public static void OnUpdated ()
{
Debug.WriteLine (@"ConfigurationManager.OnUpdated()");
//Logging.Trace (@"");
Updated?.Invoke (null, new ());
}

Expand All @@ -324,6 +325,18 @@ public static void PrintJsonErrors ()
}
}


public static void LogJsonErrors ()
{
if (_jsonErrors.Length > 0)
{
Logging.Warning (
@"Encountered the following errors while deserializing configuration files:"
);
Logging.Warning (_jsonErrors.ToString ());
}
}

/// <summary>
/// Resets the state of <see cref="ConfigurationManager"/>. Should be called whenever a new app session (e.g. in
/// <see cref="Application.Init"/> starts. Called by <see cref="Load"/> if the <c>reset</c> parameter is
Expand All @@ -334,7 +347,7 @@ public static void PrintJsonErrors ()
[RequiresDynamicCode ("AOT")]
public static void Reset ()
{
Debug.WriteLine (@"ConfigurationManager.Reset()");
Logging.Trace ($"_allConfigProperties = {_allConfigProperties}");

if (_allConfigProperties is null)
{
Expand Down Expand Up @@ -369,7 +382,7 @@ public static void Reset ()

internal static void AddJsonError (string error)
{
Debug.WriteLine ($"ConfigurationManager: {error}");
Logging.Trace ($"error = {error}");
_jsonErrors.AppendLine (error);
}

Expand Down Expand Up @@ -541,8 +554,8 @@ where type.GetProperties ()
classesWithConfigProps.Add (classWithConfig.Name, classWithConfig);
}

//Debug.WriteLine ($"ConfigManager.getConfigProperties found {classesWithConfigProps.Count} classes:");
classesWithConfigProps.ToList ().ForEach (x => Debug.WriteLine ($" Class: {x.Key}"));
//Logging.Trace ($"ConfigManager.getConfigProperties found {classesWithConfigProps.Count} classes:");
classesWithConfigProps.ToList ().ForEach (x => Logging.Trace ($" Class: {x.Key}"));

foreach (PropertyInfo? p in from c in classesWithConfigProps
let props = c.Value
Expand Down Expand Up @@ -595,9 +608,9 @@ from p in enumerable
StringComparer.InvariantCultureIgnoreCase
);

//Debug.WriteLine ($"ConfigManager.Initialize found {_allConfigProperties.Count} properties:");
//Logging.Trace ($"Found {_allConfigProperties.Count} properties:");

//_allConfigProperties.ToList ().ForEach (x => Debug.WriteLine ($" Property: {x.Key}"));
//_allConfigProperties.ToList ().ForEach (x => Logging.Trace ($" Property: {x.Key}"));

AppSettings = new ();
}
Expand All @@ -608,16 +621,16 @@ from p in enumerable
[RequiresDynamicCode ("AOT")]
internal static string ToJson ()
{
//Debug.WriteLine ("ConfigurationManager.ToJson()");
//Logging.Trace ("ConfigurationManager.ToJson()");

return JsonSerializer.Serialize (Settings!, typeof (SettingsScope), _serializerContext);
return JsonSerializer.Serialize (Settings!, typeof (SettingsScope), SerializerContext);
}

[RequiresUnreferencedCode ("AOT")]
[RequiresDynamicCode ("AOT")]
internal static Stream ToStream ()
{
string json = JsonSerializer.Serialize (Settings!, typeof (SettingsScope), _serializerContext);
string json = JsonSerializer.Serialize (Settings!, typeof (SettingsScope), SerializerContext);

// turn it into a stream
var stream = new MemoryStream ();
Expand Down
4 changes: 2 additions & 2 deletions Terminal.Gui/Configuration/DictionaryJsonConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ JsonSerializerOptions options
{
string key = reader.GetString ();
reader.Read ();
var value = JsonSerializer.Deserialize (ref reader, typeof (T), _serializerContext);
var value = JsonSerializer.Deserialize (ref reader, typeof (T), SerializerContext);
dictionary.Add (key, (T)value);
}
}
Expand All @@ -51,7 +51,7 @@ public override void Write (Utf8JsonWriter writer, Dictionary<string, T> value,

//writer.WriteString (item.Key, item.Key);
writer.WritePropertyName (item.Key);
JsonSerializer.Serialize (writer, item.Value, typeof (T), _serializerContext);
JsonSerializer.Serialize (writer, item.Value, typeof (T), SerializerContext);
writer.WriteEndObject ();
}

Expand Down
10 changes: 5 additions & 5 deletions Terminal.Gui/Configuration/ScopeJsonConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,11 @@ public override scopeT Read (ref Utf8JsonReader reader, Type typeToConvert, Json
try
{
scope! [propertyName].PropertyValue =
JsonSerializer.Deserialize (ref reader, propertyType!, _serializerContext);
JsonSerializer.Deserialize (ref reader, propertyType!, SerializerContext);
}
catch (Exception ex)

Check warning on line 94 in Terminal.Gui/Configuration/ScopeJsonConverter.cs

View workflow job for this annotation

GitHub Actions / Build and Publish to Nuget.org

The variable 'ex' is declared but never used

Check warning on line 94 in Terminal.Gui/Configuration/ScopeJsonConverter.cs

View workflow job for this annotation

GitHub Actions / build_release

The variable 'ex' is declared but never used

Check warning on line 94 in Terminal.Gui/Configuration/ScopeJsonConverter.cs

View workflow job for this annotation

GitHub Actions / build_and_test_debug (macos-latest)

The variable 'ex' is declared but never used

Check warning on line 94 in Terminal.Gui/Configuration/ScopeJsonConverter.cs

View workflow job for this annotation

GitHub Actions / build_and_test_debug (ubuntu-latest)

The variable 'ex' is declared but never used
{
Debug.WriteLine ($"scopeT Read: {ex}");
// Logging.Trace ($"scopeT Read: {ex}");
}
}
}
Expand Down Expand Up @@ -137,7 +137,7 @@ public override scopeT Read (ref Utf8JsonReader reader, Type typeToConvert, Json
if (property is { })
{
PropertyInfo prop = scope.GetType ().GetProperty (propertyName!)!;
prop.SetValue (scope, JsonSerializer.Deserialize (ref reader, prop.PropertyType, _serializerContext));
prop.SetValue (scope, JsonSerializer.Deserialize (ref reader, prop.PropertyType, SerializerContext));
}
else
{
Expand Down Expand Up @@ -165,7 +165,7 @@ public override void Write (Utf8JsonWriter writer, scopeT scope, JsonSerializerO
{
writer.WritePropertyName (ConfigProperty.GetJsonPropertyName (p));
object? prop = scope.GetType ().GetProperty (p.Name)?.GetValue (scope);
JsonSerializer.Serialize (writer, prop, prop!.GetType (), _serializerContext);
JsonSerializer.Serialize (writer, prop, prop!.GetType (), SerializerContext);
}

foreach (KeyValuePair<string, ConfigProperty> p in from p in scope
Expand Down Expand Up @@ -211,7 +211,7 @@ SerializableConfigurationProperty scp
else
{
object? prop = p.Value.PropertyValue;
JsonSerializer.Serialize (writer, prop, prop!.GetType (), _serializerContext);
JsonSerializer.Serialize (writer, prop, prop!.GetType (), SerializerContext);
}
}

Expand Down
8 changes: 4 additions & 4 deletions Terminal.Gui/Configuration/SettingsScope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ public class SettingsScope : Scope<SettingsScope>
// Update the existing settings with the new settings.
try
{
Update ((SettingsScope)JsonSerializer.Deserialize (stream, typeof (SettingsScope), _serializerOptions)!);
Update ((SettingsScope)JsonSerializer.Deserialize (stream, typeof (SettingsScope), SerializerOptions)!);
OnUpdated ();
Debug.WriteLine ($"ConfigurationManager: Read configuration from \"{source}\"");
Logging.Trace ($"Read from \"{source}\"");
if (!Sources.ContainsValue (source))
{
Sources.Add (location, source);
Expand Down Expand Up @@ -79,7 +79,7 @@ public class SettingsScope : Scope<SettingsScope>

if (!File.Exists (realPath))
{
Debug.WriteLine ($"ConfigurationManager: Configuration file \"{realPath}\" does not exist.");
Logging.Warning ($"\"{realPath}\" does not exist.");
if (!Sources.ContainsValue (filePath))
{
Sources.Add (location, filePath);
Expand All @@ -105,7 +105,7 @@ public class SettingsScope : Scope<SettingsScope>
}
catch (IOException ioe)
{
Debug.WriteLine ($"Couldn't open {filePath}. Retrying...: {ioe}");
Logging.Warning ($"Couldn't open {filePath}. Retrying...: {ioe}");
Task.Delay (100);
retryCount++;
}
Expand Down
6 changes: 3 additions & 3 deletions Terminal.Gui/Configuration/ThemeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ internal static string SelectedTheme
[RequiresDynamicCode ("Calls Terminal.Gui.ThemeManager.Themes")]
internal static void GetHardCodedDefaults ()
{
//Debug.WriteLine ("Themes.GetHardCodedDefaults()");
//Logging.Trace ("Themes.GetHardCodedDefaults()");
var theme = new ThemeScope ();
theme.RetrieveValues ();

Expand All @@ -141,15 +141,15 @@ internal static void GetHardCodedDefaults ()
/// <summary>Called when the selected theme has changed. Fires the <see cref="ThemeChanged"/> event.</summary>
internal void OnThemeChanged (string theme)
{
//Debug.WriteLine ($"Themes.OnThemeChanged({theme}) -> {Theme}");
//Logging.Trace ($"Themes.OnThemeChanged({theme}) -> {Theme}");
ThemeChanged?.Invoke (this, new ThemeManagerEventArgs (theme));
}

[RequiresUnreferencedCode ("Calls Terminal.Gui.ThemeManager.Themes")]
[RequiresDynamicCode ("Calls Terminal.Gui.ThemeManager.Themes")]
internal static void Reset ()
{
Debug.WriteLine ("Themes.Reset()");
//Logging.Trace ("Themes.Reset()");
Colors.Reset ();
Themes?.Clear ();
SelectedTheme = string.Empty;
Expand Down
84 changes: 82 additions & 2 deletions Terminal.Gui/ConsoleDrivers/V2/Logging.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace Terminal.Gui;
/// <remarks>
/// Also contains the
/// <see cref="Meter"/> instance that should be used for internal metrics
/// (iteration timing etc).
/// (iteration timing etc.).
/// </remarks>
public static class Logging
{
Expand Down Expand Up @@ -51,7 +51,71 @@ public static class Logging
public static readonly Histogram<int> DrainInputStream = Meter.CreateHistogram<int> ("Drain Input (ms)");

/// <summary>
/// Logs a trace message including the
/// Logs an error message including the class and method name.
/// </summary>
/// <param name="message"></param>
/// <param name="caller"></param>
/// <param name="filePath"></param>
public static void Error (
string message,
[CallerMemberName] string caller = "",
[CallerFilePath] string filePath = ""
)
{
string className = Path.GetFileNameWithoutExtension (filePath);
Logger.LogError ($"[{className}] [{caller}] {message}");
}

/// <summary>
/// Logs a critical message including the class and method name.
/// </summary>
/// <param name="message"></param>
/// <param name="caller"></param>
/// <param name="filePath"></param>
public static void Critical (
string message,
[CallerMemberName] string caller = "",
[CallerFilePath] string filePath = ""
)
{
string className = Path.GetFileNameWithoutExtension (filePath);
Logger.LogCritical ($"[{className}] [{caller}] {message}");
}

/// <summary>
/// Logs a debug message including the class and method name.
/// </summary>
/// <param name="message"></param>
/// <param name="caller"></param>
/// <param name="filePath"></param>
public static void Debug (
string message,
[CallerMemberName] string caller = "",
[CallerFilePath] string filePath = ""
)
{
string className = Path.GetFileNameWithoutExtension (filePath);
Logger.LogDebug ($"[{className}] [{caller}] {message}");
}

/// <summary>
/// Logs an informational message including the class and method name.
/// </summary>
/// <param name="message"></param>
/// <param name="caller"></param>
/// <param name="filePath"></param>
public static void Information (
string message,
[CallerMemberName] string caller = "",
[CallerFilePath] string filePath = ""
)
{
string className = Path.GetFileNameWithoutExtension (filePath);
Logger.LogInformation ($"[{className}] [{caller}] {message}");
}

/// <summary>
/// Logs a trace message including the class and method name.
/// </summary>
/// <param name="message"></param>
/// <param name="caller"></param>
Expand All @@ -65,4 +129,20 @@ public static void Trace (
string className = Path.GetFileNameWithoutExtension (filePath);
Logger.LogTrace ($"[{className}] [{caller}] {message}");
}

/// <summary>
/// Logs a warning message including the class and method name.
/// </summary>
/// <param name="message"></param>
/// <param name="caller"></param>
/// <param name="filePath"></param>
public static void Warning (
string message,
[CallerMemberName] string caller = "",
[CallerFilePath] string filePath = ""
)
{
string className = Path.GetFileNameWithoutExtension (filePath);
Logger.LogWarning ($"[{className}] [{caller}] {message}");
}
}
Loading

0 comments on commit 79cd4e9

Please sign in to comment.