diff --git a/AppScaffolding/AppScaffolding.csproj b/AppScaffolding/AppScaffolding.csproj
index f882dccf..be1ba58c 100644
--- a/AppScaffolding/AppScaffolding.csproj
+++ b/AppScaffolding/AppScaffolding.csproj
@@ -3,7 +3,7 @@
net6.0
- 6.6.8.1
+ 6.6.9.1
diff --git a/AppScaffolding/LibationScaffolding.cs b/AppScaffolding/LibationScaffolding.cs
index 1d871842..a4de712c 100644
--- a/AppScaffolding/LibationScaffolding.cs
+++ b/AppScaffolding/LibationScaffolding.cs
@@ -56,7 +56,7 @@ namespace AppScaffolding
// migrations go below here
//
- Migrations.migrate_to_v6_5_2(config);
+ Migrations.migrate_to_v6_6_9(config);
}
public static void PopulateMissingConfigValues(Configuration config)
@@ -107,29 +107,12 @@ namespace AppScaffolding
if (config.GetObject("Serilog") != null)
return;
- // "Serilog": {
- // "MinimumLevel": "Information"
- // "WriteTo": [
- // {
- // "Name": "Console"
- // },
- // {
- // "Name": "File",
- // "Args": {
- // "rollingInterval": "Day",
- // "outputTemplate": ...
- // }
- // }
- // ],
- // "Using": [ "Dinah.Core" ],
- // "Enrich": [ "WithCaller" ]
- // }
var serilogObj = new JObject
{
{ "MinimumLevel", "Information" },
{ "WriteTo", new JArray
{
- new JObject { {"Name", "Console" } },
+ // new JObject { {"Name", "Console" } }, // this has caused more problems than it's solved
new JObject
{
{ "Name", "File" },
@@ -144,14 +127,16 @@ namespace AppScaffolding
// output example: 2019-11-26 08:48:40.224 -05:00 [DBG] Begin Libation
// - with class and method info: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] (at {Caller}) {Message:lj}{NewLine}{Exception}";
// output example: 2019-11-26 08:48:40.224 -05:00 [DBG] (at LibationWinForms.Program.init()) Begin Libation
- { "outputTemplate", "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] (at {Caller}) {Message:lj}{NewLine}{Exception}" }
+ // {Properties:j} needed for expanded exception logging
+ { "outputTemplate", "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] (at {Caller}) {Message:lj}{NewLine}{Exception} {Properties:j}" }
}
}
}
}
},
- { "Using", new JArray{ "Dinah.Core" } }, // dll's name, NOT namespace
- { "Enrich", new JArray{ "WithCaller" } },
+ // better exception logging with: Serilog.Exceptions library -- WithExceptionDetails
+ { "Using", new JArray{ "Dinah.Core", "Serilog.Exceptions" } }, // dll's name, NOT namespace
+ { "Enrich", new JArray{ "WithCaller", "WithExceptionDetails" } },
};
config.SetObject("Serilog", serilogObj);
}
@@ -166,9 +151,9 @@ namespace AppScaffolding
// capture most Console.WriteLine() and write to serilog. See below tests for details.
// Some dependencies print helpful info via Console.WriteLine. We'd like to log it.
//
- // Serilog also writes to Console so this might be asking for trouble. ie: infinite loops.
- // SerilogTextWriter needs to be more robust and tested. Esp the Write() methods.
- // Empirical testing so far has shown no issues.
+ // If Serilog also writes to Console, this might be asking for trouble. ie: infinite loops.
+ // To use that way, SerilogTextWriter needs to be more robust and tested. Esp the Write() methods.
+ // However, empirical testing so far has shown no issues.
Console.SetOut(new MultiTextWriter(origOut, new SerilogTextWriter()));
#region Console => Serilog tests
@@ -346,9 +331,51 @@ namespace AppScaffolding
};
#endregion
- public static void migrate_to_v6_5_2(Configuration config)
+ public static void migrate_to_v6_6_9(Configuration config)
{
- // example
+ var writeToPath = $"Serilog.WriteTo";
+
+ // remove WriteTo[].Name == Console
+ {
+ if (UNSAFE_MigrationHelper.Settings_TryGetArrayLength(writeToPath, out var length1))
+ {
+ for (var i = length1 - 1; i >= 0; i--)
+ {
+ var exists = UNSAFE_MigrationHelper.Settings_TryGetFromJsonPath($"{writeToPath}[{i}].Name", out var value);
+
+ if (exists && value == "Console")
+ UNSAFE_MigrationHelper.Settings_RemoveFromArray(writeToPath, i);
+ }
+ }
+ }
+
+ // add Serilog.Exceptions -- WithExceptionDetails
+ {
+ // outputTemplate should contain "{Properties:j}"
+ {
+ // re-calculate. previous loop may have changed the length
+ if (UNSAFE_MigrationHelper.Settings_TryGetArrayLength(writeToPath, out var length2))
+ {
+ var propertyName = "outputTemplate";
+ for (var i = 0; i < length2; i++)
+ {
+ var jsonPath = $"{writeToPath}[{i}].Args";
+ var exists = UNSAFE_MigrationHelper.Settings_TryGetFromJsonPath($"{jsonPath}.{propertyName}", out var value);
+
+ var newValue = "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] (at {Caller}) {Message:lj}{NewLine}{Exception} {Properties:j}";
+
+ if (exists && value != newValue)
+ UNSAFE_MigrationHelper.Settings_SetWithJsonPath(jsonPath, propertyName, newValue);
+ }
+ }
+ }
+
+ // Serilog.Using must include "Serilog.Exceptions"
+ UNSAFE_MigrationHelper.Settings_AddUniqueToArray("Serilog.Using", "Serilog.Exceptions");
+
+ // Serilog.Enrich must include "WithExceptionDetails"
+ UNSAFE_MigrationHelper.Settings_AddUniqueToArray("Serilog.Enrich", "WithExceptionDetails");
+ }
}
}
}
diff --git a/AppScaffolding/UNSAFE_MigrationHelper.cs b/AppScaffolding/UNSAFE_MigrationHelper.cs
index cd5e332b..b44a80d1 100644
--- a/AppScaffolding/UNSAFE_MigrationHelper.cs
+++ b/AppScaffolding/UNSAFE_MigrationHelper.cs
@@ -113,6 +113,108 @@ namespace AppScaffolding
return success;
}
+ public static bool Settings_JsonPathIsType(string jsonPath, JTokenType jTokenType)
+ {
+ JToken val = null;
+
+ process_SettingsJson(jObj => val = jObj.SelectToken(jsonPath), false);
+
+ return val?.Type == jTokenType;
+ }
+
+ public static bool Settings_TryGetFromJsonPath(string jsonPath, out string value)
+ {
+ JToken val = null;
+
+ process_SettingsJson(jObj => val = jObj.SelectToken(jsonPath), false);
+
+ if (val?.Type == JTokenType.String)
+ {
+ value = val.Value();
+ return true;
+ }
+ else
+ {
+ value = null;
+ return false;
+ }
+ }
+
+ public static void Settings_SetWithJsonPath(string jsonPath, string propertyName, string newValue)
+ {
+ if (!Settings_TryGetFromJsonPath($"{jsonPath}.{propertyName}", out _))
+ return;
+
+ process_SettingsJson(jObj =>
+ {
+ var token = jObj.SelectToken(jsonPath);
+ if (token is null
+ || token is not JObject o
+ || o[propertyName] is null)
+ return;
+
+ var oldValue = token.Value(propertyName);
+ if (oldValue != newValue)
+ token[propertyName] = newValue;
+ });
+ }
+
+ public static bool Settings_TryGetArrayLength(string jsonPath, out int length)
+ {
+ length = 0;
+
+ if (!Settings_JsonPathIsType(jsonPath, JTokenType.Array))
+ return false;
+
+ JArray array = null;
+ process_SettingsJson(jObj => array = (JArray)jObj.SelectToken(jsonPath));
+
+ length = array.Count;
+ return true;
+ }
+
+ public static void Settings_AddToArray(string jsonPath, string newValue)
+ {
+ if (!Settings_JsonPathIsType(jsonPath, JTokenType.Array))
+ return;
+
+ process_SettingsJson(jObj =>
+ {
+ var array = (JArray)jObj.SelectToken(jsonPath);
+ array.Add(newValue);
+ });
+ }
+
+ /// Do not add if already exists
+ public static void Settings_AddUniqueToArray(string arrayPath, string newValue)
+ {
+ if (!Settings_TryGetArrayLength(arrayPath, out var qty))
+ return;
+
+ for (var i = 0; i < qty; i++)
+ {
+ var exists = Settings_TryGetFromJsonPath($"{arrayPath}[{i}]", out var value);
+ if (exists && value == newValue)
+ return;
+ }
+
+ Settings_AddToArray(arrayPath, newValue);
+ }
+
+ /// only remove if not exists
+ public static void Settings_RemoveFromArray(string jsonPath, int position)
+ {
+ if (!Settings_JsonPathIsType(jsonPath, JTokenType.Array))
+ return;
+
+ process_SettingsJson(jObj =>
+ {
+ var array = (JArray)jObj.SelectToken(jsonPath);
+ if (position < array.Count)
+ array.RemoveAt(position);
+ });
+ }
+
/// only insert if not exists
public static void Settings_Insert(string key, string value)
=> process_SettingsJson(jObj => jObj.TryAdd(key, value));
diff --git a/LibationFileManager/Configuration.cs b/LibationFileManager/Configuration.cs
index 17be2109..fa38ddc5 100644
--- a/LibationFileManager/Configuration.cs
+++ b/LibationFileManager/Configuration.cs
@@ -270,7 +270,7 @@ namespace LibationFileManager
var valueWasChanged = persistentDictionary.SetWithJsonPath("Serilog", "MinimumLevel", value.ToString());
if (!valueWasChanged)
{
- Log.Logger.Information("LogLevel.set attempt. No change");
+ Log.Logger.Debug("LogLevel.set attempt. No change");
return;
}
diff --git a/LibationFileManager/LibationFileManager.csproj b/LibationFileManager/LibationFileManager.csproj
index 8142aac2..9849e96d 100644
--- a/LibationFileManager/LibationFileManager.csproj
+++ b/LibationFileManager/LibationFileManager.csproj
@@ -6,6 +6,7 @@
+