Adds debug logging support

This commit is contained in:
benbierens 2023-04-25 11:31:15 +02:00
parent 72bb0132bf
commit f94f4a6d22
No known key found for this signature in database
GPG Key ID: FE44815D96D0A1AA
25 changed files with 172 additions and 73 deletions

View File

@ -1,4 +1,5 @@
using KubernetesWorkflow; using KubernetesWorkflow;
using Logging;
namespace DistTestCore namespace DistTestCore
{ {

View File

@ -21,7 +21,7 @@ namespace DistTestCore
public Logging.LogConfig GetLogConfig() public Logging.LogConfig GetLogConfig()
{ {
return new Logging.LogConfig("CodexTestLogs"); return new Logging.LogConfig("CodexTestLogs", debugEnabled: true);
} }
public string GetFileManagerFolder() public string GetFileManagerFolder()

View File

@ -28,7 +28,7 @@ namespace DistTestCore
{ {
Stopwatch.Measure(fixtureLog, "Global setup", () => Stopwatch.Measure(fixtureLog, "Global setup", () =>
{ {
var wc = new WorkflowCreator(configuration.GetK8sConfiguration()); var wc = new WorkflowCreator(fixtureLog, configuration.GetK8sConfiguration());
wc.CreateWorkflow().DeleteAllResources(); wc.CreateWorkflow().DeleteAllResources();
}); });
} }

View File

@ -33,7 +33,7 @@ namespace DistTestCore
private void TransferInitialBalance(MarketplaceNetwork marketplaceNetwork, MarketplaceInitialConfig marketplaceConfig, GethCompanionNodeInfo[] companionNodes) private void TransferInitialBalance(MarketplaceNetwork marketplaceNetwork, MarketplaceInitialConfig marketplaceConfig, GethCompanionNodeInfo[] companionNodes)
{ {
var interaction = marketplaceNetwork.StartInteraction(); var interaction = marketplaceNetwork.StartInteraction(lifecycle.Log);
var tokenAddress = marketplaceNetwork.Marketplace.TokenAddress; var tokenAddress = marketplaceNetwork.Marketplace.TokenAddress;
foreach (var node in companionNodes) foreach (var node in companionNodes)

View File

@ -34,7 +34,7 @@ namespace DistTestCore.Marketplace
var marketplaceAddress = extractor.ExtractMarketplaceAddress(); var marketplaceAddress = extractor.ExtractMarketplaceAddress();
var abi = extractor.ExtractMarketplaceAbi(); var abi = extractor.ExtractMarketplaceAbi();
var interaction = bootstrapNode.StartInteraction(); var interaction = bootstrapNode.StartInteraction(lifecycle.Log);
var tokenAddress = interaction.GetTokenAddress(marketplaceAddress); var tokenAddress = interaction.GetTokenAddress(marketplaceAddress);
LogEnd("Contracts deployed."); LogEnd("Contracts deployed.");

View File

@ -1,7 +1,5 @@
using IdentityModel.OidcClient; using KubernetesWorkflow;
using KubernetesWorkflow;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Utils; using Utils;

View File

@ -1,4 +1,5 @@
using KubernetesWorkflow; using KubernetesWorkflow;
using Logging;
using NethereumWorkflow; using NethereumWorkflow;
namespace DistTestCore.Marketplace namespace DistTestCore.Marketplace
@ -20,14 +21,14 @@ namespace DistTestCore.Marketplace
public string PrivateKey { get; } public string PrivateKey { get; }
public Port DiscoveryPort { get; } public Port DiscoveryPort { get; }
public NethereumInteraction StartInteraction() public NethereumInteraction StartInteraction(BaseLog log)
{ {
var ip = RunningContainers.RunningPod.Cluster.IP; var ip = RunningContainers.RunningPod.Cluster.IP;
var port = RunningContainers.Containers[0].ServicePorts[0].Number; var port = RunningContainers.Containers[0].ServicePorts[0].Number;
var account = Account; var account = Account;
var privateKey = PrivateKey; var privateKey = PrivateKey;
var creator = new NethereumInteractionCreator(ip, port, account, privateKey); var creator = new NethereumInteractionCreator(log, ip, port, account, privateKey);
return creator.CreateWorkflow(); return creator.CreateWorkflow();
} }
} }

View File

@ -1,4 +1,5 @@
using KubernetesWorkflow; using KubernetesWorkflow;
using Logging;
using NethereumWorkflow; using NethereumWorkflow;
namespace DistTestCore.Marketplace namespace DistTestCore.Marketplace
@ -16,14 +17,14 @@ namespace DistTestCore.Marketplace
public string Account { get; } public string Account { get; }
public string PrivateKey { get; } public string PrivateKey { get; }
public NethereumInteraction StartInteraction() public NethereumInteraction StartInteraction(BaseLog log)
{ {
var ip = RunningContainer.Pod.Cluster.IP; var ip = RunningContainer.Pod.Cluster.IP;
var port = RunningContainer.ServicePorts[0].Number; var port = RunningContainer.ServicePorts[0].Number;
var account = Account; var account = Account;
var privateKey = PrivateKey; var privateKey = PrivateKey;
var creator = new NethereumInteractionCreator(ip, port, account, privateKey); var creator = new NethereumInteractionCreator(log, ip, port, account, privateKey);
return creator.CreateWorkflow(); return creator.CreateWorkflow();
} }
} }

View File

@ -43,7 +43,7 @@ namespace DistTestCore.Marketplace
{ {
try try
{ {
var interaction = node.StartInteraction(); var interaction = node.StartInteraction(lifecycle.Log);
interaction.EnsureSynced(marketplace.Marketplace.Address, marketplace.Marketplace.Abi); interaction.EnsureSynced(marketplace.Marketplace.Address, marketplace.Marketplace.Abi);
} }
catch (Exception e) catch (Exception e)

View File

@ -103,7 +103,7 @@ namespace DistTestCore.Marketplace
public TestToken GetBalance() public TestToken GetBalance()
{ {
var interaction = marketplaceNetwork.StartInteraction(); var interaction = marketplaceNetwork.StartInteraction(log);
var account = companionNode.Account; var account = companionNode.Account;
var amount = interaction.GetBalance(marketplaceNetwork.Marketplace.TokenAddress, account); var amount = interaction.GetBalance(marketplaceNetwork.Marketplace.TokenAddress, account);
var balance = new TestToken(amount); var balance = new TestToken(amount);

View File

@ -1,4 +1,5 @@
using NethereumWorkflow; using Logging;
using NethereumWorkflow;
namespace DistTestCore.Marketplace namespace DistTestCore.Marketplace
{ {
@ -13,9 +14,9 @@ namespace DistTestCore.Marketplace
public GethBootstrapNodeInfo Bootstrap { get; } public GethBootstrapNodeInfo Bootstrap { get; }
public MarketplaceInfo Marketplace { get; } public MarketplaceInfo Marketplace { get; }
public NethereumInteraction StartInteraction() public NethereumInteraction StartInteraction(BaseLog log)
{ {
return Bootstrap.StartInteraction(); return Bootstrap.StartInteraction(log);
} }
} }
} }

View File

@ -1,36 +0,0 @@
using Logging;
using Utils;
namespace DistTestCore
{
public class Stopwatch
{
private readonly DateTime start = DateTime.UtcNow;
private readonly BaseLog log;
private readonly string name;
public Stopwatch(BaseLog log, string name)
{
this.log = log;
this.name = name;
}
public static void Measure(BaseLog log, string name, Action action)
{
var sw = Begin(log, name);
action();
sw.End();
}
public static Stopwatch Begin(BaseLog log, string name)
{
return new Stopwatch(log, name);
}
public void End(string msg = "")
{
var duration = DateTime.UtcNow - start;
log.Log($"{name} {msg} ({Time.FormatDuration(duration)})");
}
}
}

View File

@ -11,7 +11,7 @@ namespace DistTestCore
public TestLifecycle(TestLog log, Configuration configuration) public TestLifecycle(TestLog log, Configuration configuration)
{ {
Log = log; Log = log;
workflowCreator = new WorkflowCreator(configuration.GetK8sConfiguration()); workflowCreator = new WorkflowCreator(log, configuration.GetK8sConfiguration());
FileManager = new FileManager(Log, configuration); FileManager = new FileManager(Log, configuration);
CodexStarter = new CodexStarter(this, workflowCreator); CodexStarter = new CodexStarter(this, workflowCreator);

View File

@ -1,18 +1,21 @@
using k8s; using k8s;
using k8s.Models; using k8s.Models;
using Logging;
using Utils; using Utils;
namespace KubernetesWorkflow namespace KubernetesWorkflow
{ {
public class K8sController public class K8sController
{ {
private readonly BaseLog log;
private readonly K8sCluster cluster; private readonly K8sCluster cluster;
private readonly KnownK8sPods knownPods; private readonly KnownK8sPods knownPods;
private readonly WorkflowNumberSource workflowNumberSource; private readonly WorkflowNumberSource workflowNumberSource;
private readonly Kubernetes client; private readonly Kubernetes client;
public K8sController(K8sCluster cluster, KnownK8sPods knownPods, WorkflowNumberSource workflowNumberSource) public K8sController(BaseLog log, K8sCluster cluster, KnownK8sPods knownPods, WorkflowNumberSource workflowNumberSource)
{ {
this.log = log;
this.cluster = cluster; this.cluster = cluster;
this.knownPods = knownPods; this.knownPods = knownPods;
this.workflowNumberSource = workflowNumberSource; this.workflowNumberSource = workflowNumberSource;
@ -27,6 +30,7 @@ namespace KubernetesWorkflow
public RunningPod BringOnline(ContainerRecipe[] containerRecipes, Location location) public RunningPod BringOnline(ContainerRecipe[] containerRecipes, Location location)
{ {
log.Debug();
EnsureTestNamespace(); EnsureTestNamespace();
var deploymentName = CreateDeployment(containerRecipes, location); var deploymentName = CreateDeployment(containerRecipes, location);
@ -38,6 +42,7 @@ namespace KubernetesWorkflow
public void Stop(RunningPod pod) public void Stop(RunningPod pod)
{ {
log.Debug();
if (!string.IsNullOrEmpty(pod.ServiceName)) DeleteService(pod.ServiceName); if (!string.IsNullOrEmpty(pod.ServiceName)) DeleteService(pod.ServiceName);
DeleteDeployment(pod.DeploymentName); DeleteDeployment(pod.DeploymentName);
WaitUntilDeploymentOffline(pod.DeploymentName); WaitUntilDeploymentOffline(pod.DeploymentName);
@ -46,12 +51,14 @@ namespace KubernetesWorkflow
public void DownloadPodLog(RunningPod pod, ContainerRecipe recipe, ILogHandler logHandler) public void DownloadPodLog(RunningPod pod, ContainerRecipe recipe, ILogHandler logHandler)
{ {
log.Debug();
using var stream = client.ReadNamespacedPodLog(pod.Name, K8sNamespace, recipe.Name); using var stream = client.ReadNamespacedPodLog(pod.Name, K8sNamespace, recipe.Name);
logHandler.Log(stream); logHandler.Log(stream);
} }
public string ExecuteCommand(RunningPod pod, string containerName, string command, params string[] args) public string ExecuteCommand(RunningPod pod, string containerName, string command, params string[] args)
{ {
log.Debug($"{containerName}: {command} ({string.Join(",", args)})");
var runner = new CommandRunner(client, K8sNamespace, pod, containerName, command, args); var runner = new CommandRunner(client, K8sNamespace, pod, containerName, command, args);
runner.Run(); runner.Run();
return runner.GetStdOut(); return runner.GetStdOut();
@ -59,6 +66,7 @@ namespace KubernetesWorkflow
public void DeleteAllResources() public void DeleteAllResources()
{ {
log.Debug();
DeleteNamespace(); DeleteNamespace();
WaitUntilNamespaceDeleted(); WaitUntilNamespaceDeleted();
@ -345,9 +353,17 @@ namespace KubernetesWorkflow
} }
private void WaitUntil(Func<bool> predicate) private void WaitUntil(Func<bool> predicate)
{
var sw = Stopwatch.Begin(log, true);
try
{ {
Time.WaitUntil(predicate, cluster.K8sOperationTimeout(), cluster.WaitForK8sServiceDelay()); Time.WaitUntil(predicate, cluster.K8sOperationTimeout(), cluster.WaitForK8sServiceDelay());
} }
finally
{
sw.End("", 1);
}
}
#endregion #endregion

View File

@ -12,6 +12,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Logging\Logging.csproj" />
<ProjectReference Include="..\Utils\Utils.csproj" /> <ProjectReference Include="..\Utils\Utils.csproj" />
</ItemGroup> </ItemGroup>

View File

@ -1,16 +1,18 @@
using System.IO; using Logging;
namespace KubernetesWorkflow namespace KubernetesWorkflow
{ {
public class StartupWorkflow public class StartupWorkflow
{ {
private readonly BaseLog log;
private readonly WorkflowNumberSource numberSource; private readonly WorkflowNumberSource numberSource;
private readonly K8sCluster cluster; private readonly K8sCluster cluster;
private readonly KnownK8sPods knownK8SPods; private readonly KnownK8sPods knownK8SPods;
private readonly RecipeComponentFactory componentFactory = new RecipeComponentFactory(); private readonly RecipeComponentFactory componentFactory = new RecipeComponentFactory();
internal StartupWorkflow(WorkflowNumberSource numberSource, K8sCluster cluster, KnownK8sPods knownK8SPods) internal StartupWorkflow(BaseLog log, WorkflowNumberSource numberSource, K8sCluster cluster, KnownK8sPods knownK8SPods)
{ {
this.log = log;
this.numberSource = numberSource; this.numberSource = numberSource;
this.cluster = cluster; this.cluster = cluster;
this.knownK8SPods = knownK8SPods; this.knownK8SPods = knownK8SPods;
@ -60,13 +62,15 @@ namespace KubernetesWorkflow
}); });
} }
private static RunningContainer[] CreateContainers(RunningPod runningPod, ContainerRecipe[] recipes) private RunningContainer[] CreateContainers(RunningPod runningPod, ContainerRecipe[] recipes)
{ {
log.Debug();
return recipes.Select(r => new RunningContainer(runningPod, r, runningPod.GetServicePortsForContainerRecipe(r))).ToArray(); return recipes.Select(r => new RunningContainer(runningPod, r, runningPod.GetServicePortsForContainerRecipe(r))).ToArray();
} }
private ContainerRecipe[] CreateRecipes(int numberOfContainers, ContainerRecipeFactory recipeFactory, StartupConfig startupConfig) private ContainerRecipe[] CreateRecipes(int numberOfContainers, ContainerRecipeFactory recipeFactory, StartupConfig startupConfig)
{ {
log.Debug();
var result = new List<ContainerRecipe>(); var result = new List<ContainerRecipe>();
for (var i = 0; i < numberOfContainers; i++) for (var i = 0; i < numberOfContainers; i++)
{ {
@ -78,14 +82,14 @@ namespace KubernetesWorkflow
private void K8s(Action<K8sController> action) private void K8s(Action<K8sController> action)
{ {
var controller = new K8sController(cluster, knownK8SPods, numberSource); var controller = new K8sController(log, cluster, knownK8SPods, numberSource);
action(controller); action(controller);
controller.Dispose(); controller.Dispose();
} }
private T K8s<T>(Func<K8sController, T> action) private T K8s<T>(Func<K8sController, T> action)
{ {
var controller = new K8sController(cluster, knownK8SPods, numberSource); var controller = new K8sController(log, cluster, knownK8SPods, numberSource);
var result = action(controller); var result = action(controller);
controller.Dispose(); controller.Dispose();
return result; return result;

View File

@ -1,4 +1,5 @@
using Utils; using Logging;
using Utils;
namespace KubernetesWorkflow namespace KubernetesWorkflow
{ {
@ -9,10 +10,12 @@ namespace KubernetesWorkflow
private readonly NumberSource containerNumberSource = new NumberSource(0); private readonly NumberSource containerNumberSource = new NumberSource(0);
private readonly KnownK8sPods knownPods = new KnownK8sPods(); private readonly KnownK8sPods knownPods = new KnownK8sPods();
private readonly K8sCluster cluster; private readonly K8sCluster cluster;
private readonly BaseLog log;
public WorkflowCreator(Configuration configuration) public WorkflowCreator(BaseLog log, Configuration configuration)
{ {
cluster = new K8sCluster(configuration); cluster = new K8sCluster(configuration);
this.log = log;
} }
public StartupWorkflow CreateWorkflow() public StartupWorkflow CreateWorkflow()
@ -21,7 +24,7 @@ namespace KubernetesWorkflow
servicePortNumberSource, servicePortNumberSource,
containerNumberSource); containerNumberSource);
return new StartupWorkflow(workflowNumberSource, cluster, knownPods); return new StartupWorkflow(log, workflowNumberSource, cluster, knownPods);
} }
} }
} }

View File

@ -1,9 +1,18 @@
namespace Logging using System.Diagnostics;
using Utils;
namespace Logging
{ {
public abstract class BaseLog public abstract class BaseLog
{ {
private bool hasFailed; private bool hasFailed;
private LogFile? logFile; private LogFile? logFile;
private readonly bool debug;
protected BaseLog(bool debug)
{
this.debug = debug;
}
protected abstract LogFile CreateLogFile(); protected abstract LogFile CreateLogFile();
@ -21,6 +30,15 @@
LogFile.Write(message); LogFile.Write(message);
} }
public void Debug(string message = "", int skipFrames = 0)
{
if (debug)
{
var callerName = DebugStack.GetCallerName(skipFrames);
Log($"(debug)({callerName}) {message}");
}
}
public void Error(string message) public void Error(string message)
{ {
Log($"[ERROR] {message}"); Log($"[ERROR] {message}");

View File

@ -6,18 +6,21 @@ namespace Logging
{ {
private readonly DateTime start; private readonly DateTime start;
private readonly string fullName; private readonly string fullName;
private readonly LogConfig config;
public FixtureLog(LogConfig config) public FixtureLog(LogConfig config)
: base(config.DebugEnabled)
{ {
start = DateTime.UtcNow; start = DateTime.UtcNow;
var folder = DetermineFolder(config); var folder = DetermineFolder(config);
var fixtureName = GetFixtureName(); var fixtureName = GetFixtureName();
fullName = Path.Combine(folder, fixtureName); fullName = Path.Combine(folder, fixtureName);
this.config = config;
} }
public TestLog CreateTestLog() public TestLog CreateTestLog()
{ {
return new TestLog(fullName); return new TestLog(fullName, config.DebugEnabled);
} }
protected override LogFile CreateLogFile() protected override LogFile CreateLogFile()

View File

@ -2,11 +2,13 @@
{ {
public class LogConfig public class LogConfig
{ {
public LogConfig(string logRoot) public LogConfig(string logRoot, bool debugEnabled)
{ {
LogRoot = logRoot; LogRoot = logRoot;
DebugEnabled = debugEnabled;
} }
public string LogRoot { get; } public string LogRoot { get; }
public bool DebugEnabled { get; }
} }
} }

61
Logging/Stopwatch.cs Normal file
View File

@ -0,0 +1,61 @@
using Utils;
namespace Logging
{
public class Stopwatch
{
private readonly DateTime start = DateTime.UtcNow;
private readonly BaseLog log;
private readonly string name;
private readonly bool debug;
private Stopwatch(BaseLog log, string name, bool debug)
{
this.log = log;
this.name = name;
this.debug = debug;
}
public static void Measure(BaseLog log, string name, Action action, bool debug = false)
{
var sw = Begin(log, name, debug);
action();
sw.End();
}
public static Stopwatch Begin(BaseLog log)
{
return Begin(log, "");
}
public static Stopwatch Begin(BaseLog log, string name)
{
return Begin(log, name, false);
}
public static Stopwatch Begin(BaseLog log, bool debug)
{
return Begin(log, "", debug);
}
public static Stopwatch Begin(BaseLog log, string name, bool debug)
{
return new Stopwatch(log, name, debug);
}
public void End(string msg = "", int skipFrames = 0)
{
var duration = DateTime.UtcNow - start;
var entry = $"{name} {msg} ({Time.FormatDuration(duration)})";
if (debug)
{
log.Debug(entry, 1 + skipFrames);
}
else
{
log.Log(entry);
}
}
}
}

View File

@ -9,7 +9,8 @@ namespace Logging
private readonly string methodName; private readonly string methodName;
private readonly string fullName; private readonly string fullName;
public TestLog(string folder) public TestLog(string folder, bool debug)
: base(debug)
{ {
methodName = GetMethodName(); methodName = GetMethodName();
fullName = Path.Combine(folder, methodName); fullName = Path.Combine(folder, methodName);

View File

@ -1,4 +1,5 @@
using Nethereum.ABI.FunctionEncoding.Attributes; using Logging;
using Nethereum.ABI.FunctionEncoding.Attributes;
using Nethereum.Contracts; using Nethereum.Contracts;
using Nethereum.Hex.HexTypes; using Nethereum.Hex.HexTypes;
using Nethereum.Web3; using Nethereum.Web3;
@ -10,17 +11,20 @@ namespace NethereumWorkflow
public class NethereumInteraction public class NethereumInteraction
{ {
private readonly List<Task> openTasks = new List<Task>(); private readonly List<Task> openTasks = new List<Task>();
private readonly BaseLog log;
private readonly Web3 web3; private readonly Web3 web3;
private readonly string rootAccount; private readonly string rootAccount;
internal NethereumInteraction(Web3 web3, string rootAccount) internal NethereumInteraction(BaseLog log, Web3 web3, string rootAccount)
{ {
this.log = log;
this.web3 = web3; this.web3 = web3;
this.rootAccount = rootAccount; this.rootAccount = rootAccount;
} }
public string GetTokenAddress(string marketplaceAddress) public string GetTokenAddress(string marketplaceAddress)
{ {
log.Debug(marketplaceAddress);
var function = new GetTokenFunction(); var function = new GetTokenFunction();
var handler = web3.Eth.GetContractQueryHandler<GetTokenFunction>(); var handler = web3.Eth.GetContractQueryHandler<GetTokenFunction>();
@ -29,6 +33,7 @@ namespace NethereumWorkflow
public void TransferWeiTo(string account, decimal amount) public void TransferWeiTo(string account, decimal amount)
{ {
log.Debug($"{amount} --> {account}");
if (amount < 1 || string.IsNullOrEmpty(account)) throw new ArgumentException("Invalid arguments for AddToBalance"); if (amount < 1 || string.IsNullOrEmpty(account)) throw new ArgumentException("Invalid arguments for AddToBalance");
var value = ToHexBig(amount); var value = ToHexBig(amount);
@ -38,6 +43,7 @@ namespace NethereumWorkflow
public void MintTestTokens(string account, decimal amount, string tokenAddress) public void MintTestTokens(string account, decimal amount, string tokenAddress)
{ {
log.Debug($"({tokenAddress}) {amount} --> {account}");
if (amount < 1 || string.IsNullOrEmpty(account)) throw new ArgumentException("Invalid arguments for MintTestTokens"); if (amount < 1 || string.IsNullOrEmpty(account)) throw new ArgumentException("Invalid arguments for MintTestTokens");
var function = new MintTokensFunction var function = new MintTokensFunction
@ -52,6 +58,7 @@ namespace NethereumWorkflow
public decimal GetBalance(string tokenAddress, string account) public decimal GetBalance(string tokenAddress, string account)
{ {
log.Debug($"({tokenAddress}) {account}");
var function = new GetTokenBalanceFunction var function = new GetTokenBalanceFunction
{ {
Owner = account Owner = account
@ -77,6 +84,7 @@ namespace NethereumWorkflow
private void WaitUntilSynced() private void WaitUntilSynced()
{ {
log.Debug();
Time.WaitUntil(() => Time.WaitUntil(() =>
{ {
var sync = Time.Wait(web3.Eth.Syncing.SendRequestAsync()); var sync = Time.Wait(web3.Eth.Syncing.SendRequestAsync());
@ -89,6 +97,7 @@ namespace NethereumWorkflow
private void WaitForContract(string marketplaceAddress, string marketplaceAbi) private void WaitForContract(string marketplaceAddress, string marketplaceAbi)
{ {
log.Debug();
Time.WaitUntil(() => Time.WaitUntil(() =>
{ {
try try

View File

@ -1,16 +1,19 @@
using Nethereum.Web3; using Logging;
using Nethereum.Web3;
namespace NethereumWorkflow namespace NethereumWorkflow
{ {
public class NethereumInteractionCreator public class NethereumInteractionCreator
{ {
private readonly BaseLog log;
private readonly string ip; private readonly string ip;
private readonly int port; private readonly int port;
private readonly string rootAccount; private readonly string rootAccount;
private readonly string privateKey; private readonly string privateKey;
public NethereumInteractionCreator(string ip, int port, string rootAccount, string privateKey) public NethereumInteractionCreator(BaseLog log, string ip, int port, string rootAccount, string privateKey)
{ {
this.log = log;
this.ip = ip; this.ip = ip;
this.port = port; this.port = port;
this.rootAccount = rootAccount; this.rootAccount = rootAccount;
@ -19,7 +22,7 @@ namespace NethereumWorkflow
public NethereumInteraction CreateWorkflow() public NethereumInteraction CreateWorkflow()
{ {
return new NethereumInteraction(CreateWeb3(), rootAccount); return new NethereumInteraction(log, CreateWeb3(), rootAccount);
} }
private Web3 CreateWeb3() private Web3 CreateWeb3()

12
Utils/DebugStack.cs Normal file
View File

@ -0,0 +1,12 @@
using System.Diagnostics;
namespace Utils
{
public class DebugStack
{
public static string GetCallerName(int skipFrames = 0)
{
return new StackFrame(2 + skipFrames, true).GetMethod()!.Name;
}
}
}