Skip to content

Commit 46efa40

Browse files
committed
Added diagnostic
1 parent 514f4ea commit 46efa40

24 files changed

+175
-45
lines changed

.vscode/launch.json

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"version": "0.2.0",
3+
"configurations": [
4+
{
5+
// Use IntelliSense to find out which attributes exist for C# debugging
6+
// Use hover for the description of the existing attributes
7+
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
8+
"name": ".NET Core Launch (console)",
9+
"type": "coreclr",
10+
"request": "launch",
11+
"preLaunchTask": "build",
12+
// If you have changed target frameworks, make sure to update the program path.
13+
"program": "${workspaceFolder}/src/PainKiller.PowerCommands/PainKiller.PowerCommands.PowerCommandsConsole/bin/Debug/net6.0/PainKiller.PowerCommands.PowerCommandsConsole.dll",
14+
"args": [],
15+
"cwd": "${workspaceFolder}/src/PainKiller.PowerCommands/PainKiller.PowerCommands.PowerCommandsConsole",
16+
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
17+
"console": "internalConsole",
18+
"stopAtEntry": false
19+
},
20+
{
21+
"name": ".NET Core Attach",
22+
"type": "coreclr",
23+
"request": "attach"
24+
}
25+
]
26+
}

.vscode/tasks.json

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"version": "2.0.0",
3+
"tasks": [
4+
{
5+
"label": "build",
6+
"command": "dotnet",
7+
"type": "process",
8+
"args": [
9+
"build",
10+
"${workspaceFolder}/src/PainKiller.PowerCommands/PainKiller.PowerCommands.PowerCommandsConsole/PainKiller.PowerCommands.PowerCommandsConsole.csproj",
11+
"/property:GenerateFullPaths=true",
12+
"/consoleloggerparameters:NoSummary"
13+
],
14+
"problemMatcher": "$msCompile"
15+
},
16+
{
17+
"label": "publish",
18+
"command": "dotnet",
19+
"type": "process",
20+
"args": [
21+
"publish",
22+
"${workspaceFolder}/src/PainKiller.PowerCommands/PainKiller.PowerCommands.PowerCommandsConsole/PainKiller.PowerCommands.PowerCommandsConsole.csproj",
23+
"/property:GenerateFullPaths=true",
24+
"/consoleloggerparameters:NoSummary"
25+
],
26+
"problemMatcher": "$msCompile"
27+
},
28+
{
29+
"label": "watch",
30+
"command": "dotnet",
31+
"type": "process",
32+
"args": [
33+
"watch",
34+
"run",
35+
"--project",
36+
"${workspaceFolder}/src/PainKiller.PowerCommands/PainKiller.PowerCommands.PowerCommandsConsole/PainKiller.PowerCommands.PowerCommandsConsole.csproj"
37+
],
38+
"problemMatcher": "$msCompile"
39+
}
40+
]
41+
}

PowerCommands Design Principles.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,13 @@ As the name of the PowerCommand class is used as an identifier, their name must
4040
### Store secrets outside the application path
4141
PowerCommands handles export and imports of environment variables using YAML files it is the preferred way to store secrets. Dont store sensitive information inside the application path as it will be to easy to steal with a simple copy and paste operation.
4242

43-
# EXCEPTIONS HANDLING AND LOGGING
43+
# EXCEPTIONS HANDLING, DIAGNOSTIC AND LOGGING
4444
## Reduce coad bloat by avoiding try and catch
4545
No need for try catch in PowerCommands Run method as the call already is encapsulated in a try catch block, to reduce coad bload let custom code just crasch and handle that by the PowerCommands runtime, it will be logged, it will be presented for the user in a generic way that not reveal sensitive informaiton that could be the case if you just use Console.WriteLine(ex.Message).
4646
## Reduce coad bloat by avoiding logging
4747
The runtime always logg information about the input and output from a PowerCommand execution, if you want to pass information from the PowerCommand to the log, you could use Output to to that.
48+
## Use Diagnostic to display information to user
49+
The Diagnostic service has the purpose to print out messages so use that rather then use Console.WriteLine, that way you can controll just how this messages should be handled. You could easaly swap or extend the standard Diagnostic service component. The Diagnostic service also has the funtionallity to time a method call and display it to the user.
4850

4951
# CONFIGURATION
5052
## Use YAML

src/PainKiller.PowerCommands/PainKiller.PowerCommands.Bootstrap/Extensions/ServiceConfigurationExtensions.cs

+18-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using PainKiller.PowerCommands.MyExampleCommands;
1+
using Microsoft.Extensions.Logging;
2+
using PainKiller.PowerCommands.MyExampleCommands;
23
using PainKiller.PowerCommands.Security.DomainObjects;
34
using PainKiller.PowerCommands.Shared.DomainObjects.Configuration;
45

@@ -11,10 +12,26 @@ public static PowerCommandServices ShowDiagnostic(this PowerCommandServices serv
1112
services.Configuration.ShowDiagnosticInformation = showDiagnostic;
1213
return services;
1314
}
15+
public static PowerCommandServices SetMetadata(this PowerCommandServices services, Metadata metadata)
16+
{
17+
services.Configuration.Metadata = metadata;
18+
return services;
19+
}
20+
public static PowerCommandServices SetLogMinimumLevel(this PowerCommandServices services, LogLevel logLevel)
21+
{
22+
services.Configuration.Log.RestrictedToMinimumLevel = logLevel.ToString();
23+
return services;
24+
}
1425
public static PowerCommandServices AddComponent(this PowerCommandServices services, string name, string assemblyName)
1526
{
1627
var fileCheckSum = new FileChecksum(assemblyName).Mde5Hash;
1728
services.Configuration.Components.Add(new BaseComponentConfiguration{Checksum = fileCheckSum,Component = assemblyName,Name = name});
1829
return services;
1930
}
31+
32+
public static PowerCommandServices SaveConfiguration(this PowerCommandServices services)
33+
{
34+
// TODO: Implement save configuration
35+
return services;
36+
}
2037
}

src/PainKiller.PowerCommands/PainKiller.PowerCommands.Bootstrap/PowerCommandsConfiguration.yaml

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ configuration:
1010
component: "PainKiller.SerilogExtensions.dll"
1111
checksum: "173831af7e77b8bd33e32fce0b4e646d"
1212
fileName: "powercommands.log"
13+
filePath: "logs"
1314
rollingIntervall: "Day" # Infinite,Year,Month,Day,Hour,Minute
14-
restrictedToMinimumLevel: "Information" # Verbose, Debug,Information,Warning,Error,Fatal
15+
restrictedToMinimumLevel: "Information" # Verbose, Debug,Information,Warning,Error,Critical
1516
outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}"
1617
components:
1718
- component: "PainKiller.PowerCommands.Core.dll"

src/PainKiller.PowerCommands/PainKiller.PowerCommands.Bootstrap/PowerCommandsManager.cs

+2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ public void Run()
2323
var input = Console.ReadLine();
2424
var interpretedInput = $"{input}".Interpret();
2525
_services.Logger.LogInformation($"Console input Identifier:{interpretedInput.Identifier} raw {interpretedInput.Raw}");
26+
_services.Diagnostic.Start();
2627
runResult = _services.Runtime.ExecuteCommand($"{input}");
28+
_services.Diagnostic.Stop();
2729
_services.Logger.LogInformation($"Command {runResult.ExecutingCommand?.Identifier} run with input: [{runResult.Input.Raw}] output: [{runResult.Output}] status: [{runResult.Status}]");
2830
}
2931
catch (ArgumentOutOfRangeException ex)

src/PainKiller.PowerCommands/PainKiller.PowerCommands.Bootstrap/Startup.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public static PowerCommandsManager ConfigureServices()
1717

1818
services.Logger.LogInformation("Program started, configuration read");
1919

20-
var componentManager = new ComponentManager<PowerCommandsConfiguration>(services.Configuration);
20+
var componentManager = new ComponentManager<PowerCommandsConfiguration>(services.Configuration, services.Diagnostic);
2121
try
2222
{
2323
var validatePlugins = componentManager.ValidateConfigurationWithComponents();

src/PainKiller.PowerCommands/PainKiller.PowerCommands.Core/BaseClasses/EncryptionCommandBase.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66

77
namespace PainKiller.PowerCommands.Core.BaseClasses;
88

9-
public abstract class EncryptionCommandBase : CommandBase<BasicCommandsConfiguration>
9+
public abstract class EncryptionCommandBase : CommandBase<CommandsConfiguration>
1010
{
11-
public EncryptionCommandBase(string identifier, BasicCommandsConfiguration configuration) : base(identifier, configuration)
11+
public EncryptionCommandBase(string identifier, CommandsConfiguration configuration) : base(identifier, configuration)
1212
{
1313
SecurityConfiguration1 = ConfigurationManager.GetAppDataConfiguration(new SecurityConfiguration { Encryption = new EncryptionConfiguration { SharedSecretEnvironmentKey = nameof(IEncryptionManager), SharedSecretSalt = "-- salt --" } }, ConfigurationConstants.SecurityFileName).Configuration;
1414
Salt = SecurityConfiguration1.Encryption.SharedSecretSalt;

src/PainKiller.PowerCommands/PainKiller.PowerCommands.Core/BaseClasses/EnvironmentCommandBase.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ namespace PainKiller.PowerCommands.Core.BaseClasses;
44

55
public abstract class EnvironmentCommandBase : EncryptionCommandBase
66
{
7-
public EnvironmentCommandBase(string identifier, BasicCommandsConfiguration configuration) : base(identifier, configuration) { }
7+
public EnvironmentCommandBase(string identifier, CommandsConfiguration configuration) : base(identifier, configuration) { }
88
protected string GetEnvironmentVariable(string variableName, bool decrypt = false)
99
{
1010
var retVal = Environment.GetEnvironmentVariable(variableName, EnvironmentVariableTarget.User) ?? "";

src/PainKiller.PowerCommands/PainKiller.PowerCommands.Core/Commands/ConfigurationCommand.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@
66

77
namespace PainKiller.PowerCommands.Core.Commands;
88

9-
public class ConfigurationCommand : CommandBase<BasicCommandsConfiguration>
9+
public class ConfigurationCommand : CommandBase<CommandsConfiguration>
1010
{
11-
public ConfigurationCommand(string identifier, BasicCommandsConfiguration configuration) : base(identifier, configuration) { }
11+
public ConfigurationCommand(string identifier, CommandsConfiguration configuration) : base(identifier, configuration) { }
1212

1313
public override RunResult Run(CommandLineInput input)
1414
{
1515
if (input?.SingleArgument == "create")
1616
{
17-
var fileName = ConfigurationManager.Update(new BasicCommandsConfiguration());
17+
var fileName = ConfigurationManager.Update(new CommandsConfiguration());
1818
AddOutput($"A new default file named {fileName} has been created in the root directory",true);
1919
return CreateRunResult(this, input, RunResultStatus.Ok);
2020
}

src/PainKiller.PowerCommands/PainKiller.PowerCommands.Core/Commands/ExitCommand.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55

66
namespace PainKiller.PowerCommands.Core.Commands;
77

8-
public class ExitCommand : CommandBase<BasicCommandsConfiguration>
8+
public class ExitCommand : CommandBase<CommandsConfiguration>
99
{
10-
public ExitCommand(string identifier, BasicCommandsConfiguration configuration) : base(identifier, configuration) { }
10+
public ExitCommand(string identifier, CommandsConfiguration configuration) : base(identifier, configuration) { }
1111

1212
public override RunResult Run(CommandLineInput input)
1313
{

src/PainKiller.PowerCommands/PainKiller.PowerCommands.Core/Managers/ComponentManager.cs

+8-5
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,20 @@
33
using PainKiller.PowerCommands.Core.Extensions;
44
using PainKiller.PowerCommands.Security.DomainObjects;
55
using PainKiller.PowerCommands.Security.Extensions;
6+
using PainKiller.PowerCommands.Shared.Contracts;
67
using PainKiller.PowerCommands.Shared.DomainObjects.Configuration;
78

89
namespace PainKiller.PowerCommands.Core.Managers;
910

10-
public class ComponentManager<TConfiguration> where TConfiguration : BasicCommandsConfiguration
11+
public class ComponentManager<TConfiguration> where TConfiguration : CommandsConfiguration
1112
{
1213
private readonly TConfiguration _configuration;
14+
private readonly IDiagnosticManager _diagnostic;
1315

14-
public ComponentManager(TConfiguration configuration)
16+
public ComponentManager(TConfiguration configuration, IDiagnosticManager diagnostic)
1517
{
1618
_configuration = configuration;
19+
_diagnostic = diagnostic;
1720
}
1821
public bool ValidateConfigurationWithComponents()
1922
{
@@ -27,20 +30,20 @@ public bool ValidateConfigurationWithComponents()
2730
var fileCheckSum = new FileChecksum(component.Component);
2831
var validateCheckSum = fileCheckSum.CompareFileChecksum(component.Checksum);
2932
if(!validateCheckSum) retVal = false;
30-
if(_configuration.ShowDiagnosticInformation) Console.WriteLine($"{component.Name} Checksum {fileCheckSum.Mde5Hash} {validateCheckSum}");
33+
_diagnostic.Message($"{component.Name} Checksum {fileCheckSum.Mde5Hash} {validateCheckSum}");
3134
}
3235
return retVal;
3336
}
3437

3538
//TODO: Create a util application that uses this
36-
public string AutofixConfigurationComponents<T>(T configuration) where T : BasicCommandsConfiguration, new()
39+
public string AutofixConfigurationComponents<T>(T configuration) where T : CommandsConfiguration, new()
3740
{
3841
var retVal = new StringBuilder();
3942
foreach (var component in configuration.Components)
4043
{
4144
var fileCheckSum = new FileChecksum(component.Component);
4245
var validateCheckSum = fileCheckSum.CompareFileChecksum(component.Checksum);
43-
if (_configuration.ShowDiagnosticInformation) Console.WriteLine($"{component.Name} Checksum {fileCheckSum.Mde5Hash} {validateCheckSum}");
46+
_diagnostic.Message($"{component.Name} Checksum {fileCheckSum.Mde5Hash} {validateCheckSum}");
4447
if (!validateCheckSum)
4548
{
4649
component.Checksum = fileCheckSum.Mde5Hash;
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,32 @@
1-
namespace PainKiller.PowerCommands.Core.Managers;
1+
using System.Diagnostics;
2+
using PainKiller.PowerCommands.Shared.Contracts;
23

3-
public static class DiagnosticManager
4-
{
4+
namespace PainKiller.PowerCommands.Core.Managers;
55

6+
public class DiagnosticManager : IDiagnosticManager
7+
{
8+
private readonly bool _showDiagnostic;
9+
private readonly Stopwatch _stopWatch = new();
10+
public DiagnosticManager(bool showDiagnostic)
11+
{
12+
_showDiagnostic = showDiagnostic;
13+
}
14+
public void Message(string diagnostic)
15+
{
16+
if (!_showDiagnostic) return;
17+
Console.WriteLine(diagnostic);
18+
}
19+
public void Start()
20+
{
21+
if (!_showDiagnostic) return;
22+
_stopWatch.Start();
23+
}
24+
public void Stop()
25+
{
26+
if (!_showDiagnostic) return;
27+
var ts = _stopWatch.Elapsed;
28+
_stopWatch.Reset();
29+
var elapsedTime = $"{ts.Hours:00}hh:{ts.Minutes:00}mm:{ts.Seconds:00}ss.{ts.Milliseconds / 10:00}ms";
30+
Console.WriteLine($"RunTime:{elapsedTime}");
31+
}
632
}

src/PainKiller.PowerCommands/PainKiller.PowerCommands.Core/Managers/ReflectionManager.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ namespace PainKiller.PowerCommands.Core.Managers;
66

77
public class ReflectionManager
88
{
9-
public List<IConsoleCommand> GetCommands<TConfiguration>(BaseComponentConfiguration pluginInfo, TConfiguration configuration) where TConfiguration : BasicCommandsConfiguration
9+
public List<IConsoleCommand> GetCommands<TConfiguration>(BaseComponentConfiguration pluginInfo, TConfiguration configuration) where TConfiguration : CommandsConfiguration
1010
{
1111
var currentAssembly = Assembly.Load($"{pluginInfo.Component}".Replace(".dll",""));
1212
return GetCommands(currentAssembly, configuration);
1313
}
1414

15-
public List<IConsoleCommand> GetCommands<TConfiguration>(Assembly assembly, TConfiguration configuration) where TConfiguration : BasicCommandsConfiguration
15+
public List<IConsoleCommand> GetCommands<TConfiguration>(Assembly assembly, TConfiguration configuration) where TConfiguration : CommandsConfiguration
1616
{
1717
var retVal = new List<IConsoleCommand>();
1818

@@ -22,7 +22,7 @@ public List<IConsoleCommand> GetCommands<TConfiguration>(Assembly assembly, TCon
2222
foreach (var commandType in types)
2323
{
2424
var constructorInfo = commandType.GetConstructors()[0];
25-
Object[] args = { commandType.Name.ToLower(), (constructorInfo.GetParameters()[1].ParameterType == typeof(BasicCommandsConfiguration) ? configuration as BasicCommandsConfiguration : configuration)! };
25+
Object[] args = { commandType.Name.ToLower(), (constructorInfo.GetParameters()[1].ParameterType == typeof(CommandsConfiguration) ? configuration as CommandsConfiguration : configuration)! };
2626
var command = (IConsoleCommand)Activator.CreateInstance(commandType, args)!;
2727
retVal.Add(command);
2828
}

src/PainKiller.PowerCommands/PainKiller.PowerCommands.Core/PowerCommandsRuntime.cs

+5-3
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,23 @@
77

88
namespace PainKiller.PowerCommands.Core;
99

10-
public class PowerCommandsRuntime<TConfig> : IPowerCommandsRuntime where TConfig : BasicCommandsConfiguration
10+
public class PowerCommandsRuntime<TConfig> : IPowerCommandsRuntime where TConfig : CommandsConfiguration
1111
{
1212
private readonly TConfig _configuration;
13+
private readonly IDiagnosticManager _diagnostic;
1314
private readonly List<IConsoleCommand> _commands = new();
1415

15-
public PowerCommandsRuntime(TConfig configuration)
16+
public PowerCommandsRuntime(TConfig configuration, IDiagnosticManager diagnosticManager)
1617
{
1718
_configuration = configuration;
19+
_diagnostic = diagnosticManager;
1820
Initialize();
1921
}
2022
private void Initialize()
2123
{
2224
var reflectionManager = new ReflectionManager();
2325
foreach (var component in _configuration.Components) _commands.AddRange(reflectionManager.GetCommands(component, _configuration));
24-
if(_configuration.ShowDiagnosticInformation) foreach (var consoleCommand in _commands) Console.WriteLine(consoleCommand.Identifier);
26+
if(_configuration.ShowDiagnosticInformation) foreach (var consoleCommand in _commands) _diagnostic.Message(consoleCommand.Identifier);
2527
}
2628
public RunResult ExecuteCommand(string rawInput)
2729
{

src/PainKiller.PowerCommands/PainKiller.PowerCommands.MyExampleCommands/Commands/DecryptionCommand.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55

66
namespace PainKiller.PowerCommands.MyExampleCommands.Commands;
77

8-
public class DecryptionCommand : EncryptionCommandBase
8+
public class DecryptCommand : EncryptionCommandBase
99
{
10-
public DecryptionCommand(string identifier, BasicCommandsConfiguration configuration) : base(identifier, configuration)
10+
public DecryptCommand(string identifier, CommandsConfiguration configuration) : base(identifier, configuration)
1111
{
1212
}
1313

src/PainKiller.PowerCommands/PainKiller.PowerCommands.MyExampleCommands/Commands/EncryptionCommand.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55

66
namespace PainKiller.PowerCommands.MyExampleCommands.Commands;
77

8-
public class EncryptionCommand : EncryptionCommandBase
8+
public class EncryptCommand : EncryptionCommandBase
99
{
10-
public EncryptionCommand(string identifier, BasicCommandsConfiguration configuration) : base(identifier, configuration) { }
10+
public EncryptCommand(string identifier, CommandsConfiguration configuration) : base(identifier, configuration) { }
1111

1212
public override RunResult Run(CommandLineInput input)
1313
{

src/PainKiller.PowerCommands/PainKiller.PowerCommands.MyExampleCommands/Configuration/PowerCommandsConfiguration.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace PainKiller.PowerCommands.MyExampleCommands.Configuration;
44

5-
public class PowerCommandsConfiguration : BasicCommandsConfiguration
5+
public class PowerCommandsConfiguration : CommandsConfiguration
66
{
77
//Here is the placeholder for your custom configuration, you need to add the change to the PowerCommandsConfiguration.yaml file as well
88
}

0 commit comments

Comments
 (0)