public static ExecutionResult Execute(CommandContext commandContext, CompiledModule module, string[] commands) { var result = ExecutionResult.Success; var etlContext = new EtlContext(); try { var listeners = commandContext.HostConfiguration.GetSessionListeners(null); if (listeners?.Count > 0) { etlContext.Listeners.AddRange(listeners); } } catch (Exception ex) { var formattedMessage = ex.FormatExceptionWithDetails(); etlContext.Log(LogSeverity.Fatal, null, "{ErrorMessage}", formattedMessage); etlContext.LogOps(LogSeverity.Fatal, null, "{ErrorMessage}", formattedMessage); } var instance = Environment.MachineName; var arguments = GetArguments(module, instance); var environmentSettings = new EnvironmentSettings(); module.Startup.Configure(environmentSettings); var taskCreators = new Dictionary <string, Func <IEtlSessionArguments, IEtlTask> >(module.Startup.Commands, StringComparer.InvariantCultureIgnoreCase); var sessionId = "s" + DateTime.Now.ToString("yyMMdd-HHmmss-ff", CultureInfo.InvariantCulture); var session = new EtlSession(sessionId, etlContext, arguments); etlContext.TransactionScopeTimeout = environmentSettings.TransactionScopeTimeout; var logger = CreateLogger(environmentSettings, commandContext.DevLogFolder, commandContext.OpsLogFolder); var opsLogger = CreateOpsLogger(environmentSettings, commandContext.DevLogFolder, commandContext.OpsLogFolder); var ioLogger = CreateIoLogger(environmentSettings, commandContext.DevLogFolder, commandContext.OpsLogFolder); var serilogAdapter = new EtlSessionSerilogAdapter(logger, opsLogger, ioLogger, commandContext.DevLogFolder, commandContext.OpsLogFolder); etlContext.Listeners.Add(serilogAdapter); serilogAdapter.Log(LogSeverity.Information, false, null, null, "session {SessionId} started", sessionId); if (!string.IsNullOrEmpty(environmentSettings.SeqSettings.Url)) { etlContext.Log(LogSeverity.Debug, null, "all session logs will be sent to SEQ listening on {SeqUrl}", environmentSettings.SeqSettings.Url); } var sessionStartedOn = Stopwatch.StartNew(); var sessionExceptionCount = 0; var taskResults = new List <KeyValuePair <IEtlTask, TaskResult> >(); try { foreach (var command in commands) { IEtlTask task = null; if (taskCreators.TryGetValue(command, out var taskCreator)) { task = taskCreator.Invoke(arguments); } else { var taskType = module.TaskTypes.Find(x => string.Equals(x.Name, command, StringComparison.InvariantCultureIgnoreCase)); if (taskType != null) { task = (IEtlTask)Activator.CreateInstance(taskType); } } if (task == null) { serilogAdapter.Log(LogSeverity.Error, false, null, null, "unknown task/flow type: " + command); break; } try { try { var taskResult = session.ExecuteTask(null, task); taskResults.Add(new KeyValuePair <IEtlTask, TaskResult>(task, taskResult)); sessionExceptionCount += taskResult.ExceptionCount; if (sessionExceptionCount > 0) { etlContext.Log(LogSeverity.Error, task, "failed, terminating execution"); result = ExecutionResult.ExecutionFailed; etlContext.Close(); break; // stop processing tasks } } catch (Exception ex) { etlContext.Log(LogSeverity.Error, task, "failed, terminating execution, reason: ", task.Statistics.RunTime, ex.Message); result = ExecutionResult.ExecutionFailed; etlContext.Close(); break; // stop processing tasks } } catch (TransactionAbortedException) { } LogTaskCounters(serilogAdapter, task); } session.Stop(); if (taskResults.Count > 0) { serilogAdapter.Log(LogSeverity.Information, false, null, null, "-------"); serilogAdapter.Log(LogSeverity.Information, false, null, null, "SUMMARY"); serilogAdapter.Log(LogSeverity.Information, false, null, null, "-------"); var longestTaskName = taskResults.Max(x => x.Key.Name.Length); foreach (var kvp in taskResults) { LogTaskSummary(serilogAdapter, kvp.Key, kvp.Value, longestTaskName); } } etlContext.Close(); } catch (TransactionAbortedException) { } return(result); }