From b03f3278992c6874879675872ba77756ec0a3f20 Mon Sep 17 00:00:00 2001 From: Silas Benson Date: Fri, 1 Aug 2025 13:00:30 +0100 Subject: [PATCH 01/11] Implemented basic console logging using serilog --- temporal-examples/Directory.Packages.props | 8 ++- .../appsettings.Development.json | 15 ++++-- .../Shared/AutoFac/Modules/LoggingModule.cs | 51 +++++++------------ temporal-examples/temporal-worker/Program.cs | 2 +- .../temporal-worker/temporal-worker.csproj | 5 +- .../workflows/ExampleActivities.cs | 20 ++++++-- .../workflows/ExampleWithChildren.workflow.cs | 2 +- .../workflows/Examples.workflow.cs | 2 +- 8 files changed, 56 insertions(+), 49 deletions(-) diff --git a/temporal-examples/Directory.Packages.props b/temporal-examples/Directory.Packages.props index c443418..a2c948e 100644 --- a/temporal-examples/Directory.Packages.props +++ b/temporal-examples/Directory.Packages.props @@ -1,6 +1,7 @@ - + true @@ -10,6 +11,9 @@ + + + @@ -28,4 +32,4 @@ - + \ No newline at end of file diff --git a/temporal-examples/RestController/appsettings.Development.json b/temporal-examples/RestController/appsettings.Development.json index 0c208ae..958ff5a 100644 --- a/temporal-examples/RestController/appsettings.Development.json +++ b/temporal-examples/RestController/appsettings.Development.json @@ -1,8 +1,13 @@ { - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "Temporal": { + "ClientTargetHost": "host.docker.internal:7233", + "Namespace": "default", + "TaskQueue": "example" } - } } diff --git a/temporal-examples/Shared/AutoFac/Modules/LoggingModule.cs b/temporal-examples/Shared/AutoFac/Modules/LoggingModule.cs index 4b1a1ce..174e0c6 100644 --- a/temporal-examples/Shared/AutoFac/Modules/LoggingModule.cs +++ b/temporal-examples/Shared/AutoFac/Modules/LoggingModule.cs @@ -1,5 +1,8 @@ using Autofac; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; +using Serilog; +using Serilog.Extensions.Logging; namespace Shared.AutoFac.Modules { @@ -8,48 +11,28 @@ namespace Shared.AutoFac.Modules /// public class LoggingModule : Module { - private readonly LogLevel _minimumLevel; + private readonly IConfiguration _configuration; - /// - /// Creates a new instance of the logging module with the specified minimum log level - /// - /// Minimum log level to display - public LoggingModule(LogLevel minimumLevel = LogLevel.Information) + public LoggingModule( + IConfiguration configuration + ) { - _minimumLevel = minimumLevel; + _configuration = configuration; } - /// - /// Configure the logging services with Autofac - /// protected override void Load(ContainerBuilder builder) { - builder.RegisterGeneric(typeof(Logger<>)).As(typeof(ILogger<>)).SingleInstance(); + var loggerConfig = new LoggerConfiguration() + .WriteTo.Console( + outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}"); + var logger = loggerConfig.CreateLogger(); - // Register factory for creating loggers - builder - .Register(c => - { - var factory = LoggerFactory.Create(loggingBuilder => - { - loggingBuilder - .SetMinimumLevel(_minimumLevel) - .AddSimpleConsole(options => - { - options.SingleLine = false; - options.TimestampFormat = "[yyyy-MM-dd HH:mm:ss] "; - options.UseUtcTimestamp = true; - }); - // You can add additional providers here as needed - }); - return factory; - }) - .As() - .SingleInstance(); + Log.Logger = logger; - // Register a filter to respect minimum level - builder - .Register(c => new LoggerFilterOptions { MinLevel = _minimumLevel }) + builder.RegisterInstance(logger).As().SingleInstance(); + + builder.Register(c => new SerilogLoggerFactory(logger, true)) + .As() .SingleInstance(); } } diff --git a/temporal-examples/temporal-worker/Program.cs b/temporal-examples/temporal-worker/Program.cs index 254e861..7bd2aad 100644 --- a/temporal-examples/temporal-worker/Program.cs +++ b/temporal-examples/temporal-worker/Program.cs @@ -17,7 +17,7 @@ private static async Task Main(string[] args) .ConfigureContainer( (context, builder) => { - builder.RegisterModule(new LoggingModule(LogLevel.Information)); + builder.RegisterModule(new LoggingModule(context.Configuration)); builder.RegisterModule( new TemporalWorkerConfigurationModule(context.Configuration) ); diff --git a/temporal-examples/temporal-worker/temporal-worker.csproj b/temporal-examples/temporal-worker/temporal-worker.csproj index 4a689fc..6756349 100644 --- a/temporal-examples/temporal-worker/temporal-worker.csproj +++ b/temporal-examples/temporal-worker/temporal-worker.csproj @@ -1,5 +1,5 @@  - + Exe net9.0 temporal_worker @@ -19,6 +19,9 @@ + + + diff --git a/temporal-examples/workflows/ExampleActivities.cs b/temporal-examples/workflows/ExampleActivities.cs index bc4bedf..923a818 100644 --- a/temporal-examples/workflows/ExampleActivities.cs +++ b/temporal-examples/workflows/ExampleActivities.cs @@ -1,24 +1,36 @@ +using Microsoft.Extensions.Logging; using Temporalio.Activities; namespace workflows; public class ExampleActivities { + private readonly ILogger _logger; + public ExampleActivities(ILogger logg) + { + _logger = logg; + } + [Activity] - public static async Task GenericTask() + public async Task GenericTask() { - await Task.Delay(2000); + var duration = 2000; + _logger.LogInformation($"Starting delay: {@duration}"); + await Task.Delay(duration); + _logger.LogInformation("Finished delay"); return $"generic-task-{DateTime.Now}"; } [Activity] - public static List GenerateChildWorkflowsName() + public List GenerateChildWorkflowsName() { int numberOfChildWorkflows = new Random().Next(1, 10); List childWorkflowsInfo = []; for (int index = 0; index < numberOfChildWorkflows; index++) { - childWorkflowsInfo.Add($"child-{index}-workflow-{DateTime.Now}"); + var name = $"child-{index}-workflow-{DateTime.Now}"; + _logger.LogInformation($"Creating child workflow {@name}"); + childWorkflowsInfo.Add(name); } return childWorkflowsInfo; } diff --git a/temporal-examples/workflows/ExampleWithChildren.workflow.cs b/temporal-examples/workflows/ExampleWithChildren.workflow.cs index ef387b5..90485b0 100644 --- a/temporal-examples/workflows/ExampleWithChildren.workflow.cs +++ b/temporal-examples/workflows/ExampleWithChildren.workflow.cs @@ -19,7 +19,7 @@ public async Task RunAsync() }; List childNames = await Workflow.ExecuteActivityAsync( - () => ExampleActivities.GenerateChildWorkflowsName(), + (ExampleActivities a) => a.GenerateChildWorkflowsName(), new ActivityOptions { StartToCloseTimeout = TimeSpan.FromMinutes(5), diff --git a/temporal-examples/workflows/Examples.workflow.cs b/temporal-examples/workflows/Examples.workflow.cs index 90808c4..f90f1ce 100644 --- a/temporal-examples/workflows/Examples.workflow.cs +++ b/temporal-examples/workflows/Examples.workflow.cs @@ -19,7 +19,7 @@ public async Task RunAsync() }; string result = await Workflow.ExecuteActivityAsync( - () => ExampleActivities.GenericTask(), + (ExampleActivities a) => a.GenericTask(), new ActivityOptions { StartToCloseTimeout = TimeSpan.FromMinutes(5), From 468a0aed58cf261c2284f825e17b9ab8536cadd0 Mon Sep 17 00:00:00 2001 From: Silas Benson Date: Fri, 1 Aug 2025 13:11:03 +0100 Subject: [PATCH 02/11] Log to file --- temporal-examples/Directory.Packages.props | 11 +++-------- .../Shared/AutoFac/Modules/LoggingModule.cs | 4 ++++ temporal-examples/docker-compose.yml | 2 ++ .../temporal-worker/temporal-worker.csproj | 1 + 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/temporal-examples/Directory.Packages.props b/temporal-examples/Directory.Packages.props index a2c948e..7579fda 100644 --- a/temporal-examples/Directory.Packages.props +++ b/temporal-examples/Directory.Packages.props @@ -14,20 +14,15 @@ + - + - + diff --git a/temporal-examples/Shared/AutoFac/Modules/LoggingModule.cs b/temporal-examples/Shared/AutoFac/Modules/LoggingModule.cs index 174e0c6..99e08b8 100644 --- a/temporal-examples/Shared/AutoFac/Modules/LoggingModule.cs +++ b/temporal-examples/Shared/AutoFac/Modules/LoggingModule.cs @@ -24,7 +24,11 @@ protected override void Load(ContainerBuilder builder) { var loggerConfig = new LoggerConfiguration() .WriteTo.Console( + outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}") + .WriteTo.File("logs/log-.txt", + rollingInterval: RollingInterval.Day, outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}"); + var logger = loggerConfig.CreateLogger(); Log.Logger = logger; diff --git a/temporal-examples/docker-compose.yml b/temporal-examples/docker-compose.yml index b40196e..e1dba57 100644 --- a/temporal-examples/docker-compose.yml +++ b/temporal-examples/docker-compose.yml @@ -6,6 +6,8 @@ services: dockerfile: temporal-worker/Dockerfile environment: - Temporal__ClientUrl=temporal:7233 + volumes: + - ./logs:/app/logs depends_on: temporal: condition: service_healthy diff --git a/temporal-examples/temporal-worker/temporal-worker.csproj b/temporal-examples/temporal-worker/temporal-worker.csproj index 6756349..caec9ca 100644 --- a/temporal-examples/temporal-worker/temporal-worker.csproj +++ b/temporal-examples/temporal-worker/temporal-worker.csproj @@ -22,6 +22,7 @@ + From 7b84fa26357a46446e545116543238a1f2a1003c Mon Sep 17 00:00:00 2001 From: Silas Benson Date: Wed, 6 Aug 2025 15:05:52 +0100 Subject: [PATCH 03/11] Completed working structured logging --- .../RestController/SignalController.cs | 2 +- .../Shared/AutoFac/Modules/LoggingModule.cs | 15 +++++++++++++-- .../Modules/TemporalWorkerConfigurationModule.cs | 6 +++--- temporal-examples/temporal-worker/Program.cs | 7 +++---- temporal-examples/workflows/ExampleActivities.cs | 2 +- .../workflows/ExampleWithChildren.workflow.cs | 3 ++- temporal-examples/workflows/Examples.workflow.cs | 2 +- .../workflows/WaitingSignal.workflow.cs | 2 +- 8 files changed, 25 insertions(+), 14 deletions(-) diff --git a/temporal-examples/RestController/SignalController.cs b/temporal-examples/RestController/SignalController.cs index 22bf941..434e2b5 100644 --- a/temporal-examples/RestController/SignalController.cs +++ b/temporal-examples/RestController/SignalController.cs @@ -1,7 +1,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Temporalio.Client; -using workflows; +using Workflows; namespace RestController { diff --git a/temporal-examples/Shared/AutoFac/Modules/LoggingModule.cs b/temporal-examples/Shared/AutoFac/Modules/LoggingModule.cs index 99e08b8..2113fc0 100644 --- a/temporal-examples/Shared/AutoFac/Modules/LoggingModule.cs +++ b/temporal-examples/Shared/AutoFac/Modules/LoggingModule.cs @@ -1,8 +1,11 @@ using Autofac; +using Autofac.Extensions.DependencyInjection; using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Serilog; using Serilog.Extensions.Logging; +using Serilog.Formatting.Json; namespace Shared.AutoFac.Modules { @@ -23,11 +26,14 @@ IConfiguration configuration protected override void Load(ContainerBuilder builder) { var loggerConfig = new LoggerConfiguration() + .Enrich.WithProperty("Environment", Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production") .WriteTo.Console( outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}") - .WriteTo.File("logs/log-.txt", + .WriteTo.File( + new JsonFormatter(renderMessage: true), + "logs/log-.json", rollingInterval: RollingInterval.Day, - outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}"); + shared: true); var logger = loggerConfig.CreateLogger(); @@ -38,6 +44,11 @@ protected override void Load(ContainerBuilder builder) builder.Register(c => new SerilogLoggerFactory(logger, true)) .As() .SingleInstance(); + + var services = new ServiceCollection(); + services.AddLogging(); + + builder.Populate(services); } } } diff --git a/temporal-examples/temporal-worker/AutoFac/Modules/TemporalWorkerConfigurationModule.cs b/temporal-examples/temporal-worker/AutoFac/Modules/TemporalWorkerConfigurationModule.cs index 5360d47..cb410b0 100644 --- a/temporal-examples/temporal-worker/AutoFac/Modules/TemporalWorkerConfigurationModule.cs +++ b/temporal-examples/temporal-worker/AutoFac/Modules/TemporalWorkerConfigurationModule.cs @@ -4,7 +4,8 @@ using Microsoft.Extensions.DependencyInjection; using Temporalio.Extensions.Hosting; using Temporalio.Runtime; -using workflows; +using Workflows; + namespace TemporalWorker.AutoFac.Modules { @@ -14,8 +15,7 @@ public class TemporalWorkerConfigurationModule : Module public TemporalWorkerConfigurationModule(IConfiguration configuration) { - _configuration = - configuration ?? throw new ArgumentNullException(nameof(configuration)); + _configuration = configuration; } protected override void Load(ContainerBuilder builder) diff --git a/temporal-examples/temporal-worker/Program.cs b/temporal-examples/temporal-worker/Program.cs index 7bd2aad..de38702 100644 --- a/temporal-examples/temporal-worker/Program.cs +++ b/temporal-examples/temporal-worker/Program.cs @@ -2,7 +2,6 @@ using Autofac.Extensions.DependencyInjection; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; using Shared.AutoFac.Modules; using TemporalWorker.AutoFac.Modules; @@ -17,10 +16,10 @@ private static async Task Main(string[] args) .ConfigureContainer( (context, builder) => { - builder.RegisterModule(new LoggingModule(context.Configuration)); builder.RegisterModule( - new TemporalWorkerConfigurationModule(context.Configuration) - ); + new TemporalWorkerConfigurationModule(context.Configuration) + ); + builder.RegisterModule(new LoggingModule(context.Configuration)); } ) .Build(); diff --git a/temporal-examples/workflows/ExampleActivities.cs b/temporal-examples/workflows/ExampleActivities.cs index 923a818..a9c58a5 100644 --- a/temporal-examples/workflows/ExampleActivities.cs +++ b/temporal-examples/workflows/ExampleActivities.cs @@ -1,7 +1,7 @@ using Microsoft.Extensions.Logging; using Temporalio.Activities; -namespace workflows; +namespace Workflows; public class ExampleActivities { diff --git a/temporal-examples/workflows/ExampleWithChildren.workflow.cs b/temporal-examples/workflows/ExampleWithChildren.workflow.cs index 90485b0..1da24ec 100644 --- a/temporal-examples/workflows/ExampleWithChildren.workflow.cs +++ b/temporal-examples/workflows/ExampleWithChildren.workflow.cs @@ -1,7 +1,7 @@ using Temporalio.Common; using Temporalio.Workflows; -namespace workflows; +namespace Workflows; [Workflow] public class ExampleWithChildrenWorkflow @@ -34,6 +34,7 @@ await Workflow.ExecuteChildWorkflowAsync( new() { Id = child, TaskQueue = "example" } ); } + return "All child workflows created and run"; } } diff --git a/temporal-examples/workflows/Examples.workflow.cs b/temporal-examples/workflows/Examples.workflow.cs index f90f1ce..d5deca0 100644 --- a/temporal-examples/workflows/Examples.workflow.cs +++ b/temporal-examples/workflows/Examples.workflow.cs @@ -1,7 +1,7 @@ using Temporalio.Common; using Temporalio.Workflows; -namespace workflows; +namespace Workflows; [Workflow] public class ExampleWorkflow diff --git a/temporal-examples/workflows/WaitingSignal.workflow.cs b/temporal-examples/workflows/WaitingSignal.workflow.cs index 774c45c..2be2587 100644 --- a/temporal-examples/workflows/WaitingSignal.workflow.cs +++ b/temporal-examples/workflows/WaitingSignal.workflow.cs @@ -2,7 +2,7 @@ using Temporalio.Common; using Temporalio.Workflows; -namespace workflows; +namespace Workflows; [Workflow] public class WaitingSignalWorkflow From 6f9bfa43b5e2a377110c1efec4e838d48a461224 Mon Sep 17 00:00:00 2001 From: Silas Benson Date: Wed, 6 Aug 2025 15:11:38 +0100 Subject: [PATCH 04/11] Resolve github copilot suggestions --- temporal-examples/workflows/ExampleActivities.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/temporal-examples/workflows/ExampleActivities.cs b/temporal-examples/workflows/ExampleActivities.cs index a9c58a5..c242e6a 100644 --- a/temporal-examples/workflows/ExampleActivities.cs +++ b/temporal-examples/workflows/ExampleActivities.cs @@ -6,16 +6,16 @@ namespace Workflows; public class ExampleActivities { private readonly ILogger _logger; - public ExampleActivities(ILogger logg) + public ExampleActivities(ILogger logger) { - _logger = logg; + _logger = logger; } [Activity] public async Task GenericTask() { var duration = 2000; - _logger.LogInformation($"Starting delay: {@duration}"); + _logger.LogInformation("Starting delay: {Duration}", duration); await Task.Delay(duration); _logger.LogInformation("Finished delay"); return $"generic-task-{DateTime.Now}"; @@ -29,7 +29,7 @@ public List GenerateChildWorkflowsName() for (int index = 0; index < numberOfChildWorkflows; index++) { var name = $"child-{index}-workflow-{DateTime.Now}"; - _logger.LogInformation($"Creating child workflow {@name}"); + _logger.LogInformation("Creating child workflow {Name}", name); childWorkflowsInfo.Add(name); } return childWorkflowsInfo; From cbde90f9ad727427c169b0999f0aa66149a812f5 Mon Sep 17 00:00:00 2001 From: Silas Benson Date: Wed, 6 Aug 2025 15:12:11 +0100 Subject: [PATCH 05/11] Reformat with csharpier --- temporal-examples/Directory.Packages.props | 12 +++++++++--- .../Shared/AutoFac/Modules/LoggingModule.cs | 18 +++++++++++------- .../TemporalWorkerConfigurationModule.cs | 1 - temporal-examples/temporal-worker/Program.cs | 4 ++-- .../temporal-worker/temporal-worker.csproj | 2 +- .../workflows/ExampleActivities.cs | 1 + 6 files changed, 24 insertions(+), 14 deletions(-) diff --git a/temporal-examples/Directory.Packages.props b/temporal-examples/Directory.Packages.props index 7579fda..578f3ae 100644 --- a/temporal-examples/Directory.Packages.props +++ b/temporal-examples/Directory.Packages.props @@ -18,13 +18,19 @@ - + - + - \ No newline at end of file + diff --git a/temporal-examples/Shared/AutoFac/Modules/LoggingModule.cs b/temporal-examples/Shared/AutoFac/Modules/LoggingModule.cs index 2113fc0..fea42f4 100644 --- a/temporal-examples/Shared/AutoFac/Modules/LoggingModule.cs +++ b/temporal-examples/Shared/AutoFac/Modules/LoggingModule.cs @@ -16,9 +16,7 @@ public class LoggingModule : Module { private readonly IConfiguration _configuration; - public LoggingModule( - IConfiguration configuration - ) + public LoggingModule(IConfiguration configuration) { _configuration = configuration; } @@ -26,14 +24,19 @@ IConfiguration configuration protected override void Load(ContainerBuilder builder) { var loggerConfig = new LoggerConfiguration() - .Enrich.WithProperty("Environment", Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production") + .Enrich.WithProperty( + "Environment", + Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production" + ) .WriteTo.Console( - outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}") + outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}" + ) .WriteTo.File( new JsonFormatter(renderMessage: true), "logs/log-.json", rollingInterval: RollingInterval.Day, - shared: true); + shared: true + ); var logger = loggerConfig.CreateLogger(); @@ -41,7 +44,8 @@ protected override void Load(ContainerBuilder builder) builder.RegisterInstance(logger).As().SingleInstance(); - builder.Register(c => new SerilogLoggerFactory(logger, true)) + builder + .Register(c => new SerilogLoggerFactory(logger, true)) .As() .SingleInstance(); diff --git a/temporal-examples/temporal-worker/AutoFac/Modules/TemporalWorkerConfigurationModule.cs b/temporal-examples/temporal-worker/AutoFac/Modules/TemporalWorkerConfigurationModule.cs index cb410b0..779c8d5 100644 --- a/temporal-examples/temporal-worker/AutoFac/Modules/TemporalWorkerConfigurationModule.cs +++ b/temporal-examples/temporal-worker/AutoFac/Modules/TemporalWorkerConfigurationModule.cs @@ -6,7 +6,6 @@ using Temporalio.Runtime; using Workflows; - namespace TemporalWorker.AutoFac.Modules { public class TemporalWorkerConfigurationModule : Module diff --git a/temporal-examples/temporal-worker/Program.cs b/temporal-examples/temporal-worker/Program.cs index de38702..3ead2e0 100644 --- a/temporal-examples/temporal-worker/Program.cs +++ b/temporal-examples/temporal-worker/Program.cs @@ -17,8 +17,8 @@ private static async Task Main(string[] args) (context, builder) => { builder.RegisterModule( - new TemporalWorkerConfigurationModule(context.Configuration) - ); + new TemporalWorkerConfigurationModule(context.Configuration) + ); builder.RegisterModule(new LoggingModule(context.Configuration)); } ) diff --git a/temporal-examples/temporal-worker/temporal-worker.csproj b/temporal-examples/temporal-worker/temporal-worker.csproj index caec9ca..3019163 100644 --- a/temporal-examples/temporal-worker/temporal-worker.csproj +++ b/temporal-examples/temporal-worker/temporal-worker.csproj @@ -1,5 +1,5 @@  - + Exe net9.0 temporal_worker diff --git a/temporal-examples/workflows/ExampleActivities.cs b/temporal-examples/workflows/ExampleActivities.cs index c242e6a..9be7141 100644 --- a/temporal-examples/workflows/ExampleActivities.cs +++ b/temporal-examples/workflows/ExampleActivities.cs @@ -6,6 +6,7 @@ namespace Workflows; public class ExampleActivities { private readonly ILogger _logger; + public ExampleActivities(ILogger logger) { _logger = logger; From fe8bdcd68df093410371cd2607ffd5666f90ccb0 Mon Sep 17 00:00:00 2001 From: Silas Benson Date: Wed, 6 Aug 2025 15:16:53 +0100 Subject: [PATCH 06/11] Update new acitivies to include logging --- temporal-examples/workflows/ExampleActivities.cs | 14 ++++++++++---- .../workflows/WaitingSignal.workflow.cs | 4 ++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/temporal-examples/workflows/ExampleActivities.cs b/temporal-examples/workflows/ExampleActivities.cs index 9be7141..8c7c205 100644 --- a/temporal-examples/workflows/ExampleActivities.cs +++ b/temporal-examples/workflows/ExampleActivities.cs @@ -37,16 +37,22 @@ public List GenerateChildWorkflowsName() } [Activity] - public static async Task TaskTriggeredBySignal() + public async Task TaskTriggeredBySignal() { - await Task.Delay(2000); + var duration = 2000; + _logger.LogInformation("Starting delay: {Duration}", duration); + await Task.Delay(duration); + _logger.LogInformation("Finished delay"); return $"task-triggered-by-signal-{DateTime.Now}"; } [Activity] - public static async Task TaskTriggeredByTimeout() + public async Task TaskTriggeredByTimeout() { - await Task.Delay(2000); + var duration = 2000; + _logger.LogInformation("Starting delay: {Duration}", duration); + await Task.Delay(duration); + _logger.LogInformation("Finished delay"); return $"task-triggered-by-timeout-{DateTime.Now}"; } } diff --git a/temporal-examples/workflows/WaitingSignal.workflow.cs b/temporal-examples/workflows/WaitingSignal.workflow.cs index 2be2587..28b20a0 100644 --- a/temporal-examples/workflows/WaitingSignal.workflow.cs +++ b/temporal-examples/workflows/WaitingSignal.workflow.cs @@ -38,14 +38,14 @@ public async Task RunAsync() if (didNotTimeout) { await Workflow.ExecuteActivityAsync( - () => ExampleActivities.TaskTriggeredBySignal(), + (ExampleActivities a) => a.TaskTriggeredBySignal(), activityOptions ); } else { await Workflow.ExecuteActivityAsync( - () => ExampleActivities.TaskTriggeredByTimeout(), + (ExampleActivities a) => a.TaskTriggeredByTimeout(), activityOptions ); } From f2eef3567c8aba29175efa76664dfa77b833e617 Mon Sep 17 00:00:00 2001 From: Silas Benson Date: Thu, 7 Aug 2025 10:00:42 +0100 Subject: [PATCH 07/11] Tidy up README --- README.md | 46 +++++++++++++++++-------- temporal-examples/temporal-examples.sln | 1 + 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 3e666e4..6e77d34 100644 --- a/README.md +++ b/README.md @@ -2,36 +2,52 @@ ## Purpose of this Repo -This is to show several features of temporal in a way that is easy to understand and run. All you need is docker as everything will run in docker containers. +This is to show several features of Temporal in a way that is easy to understand and run. All you +need is Docker as everything will run in Docker containers. -It will run a swagger page that allows you to start workflows using a rest api. +It will run a [Swagger page](http://localhost:8080/swagger/index.html) that allows you to start +workflows and send signals to paused workflows via a REST API. ## Running the project - you'll need Docker -Make sure your terminal is in the temporal-examples folder and then run docker compose up. This should also run the temporal workers as well. If you ever need to debug the temporal workflows you can debug via a docker container by installing the "Container Tools" extension in VS Code. There is also an option to do the debugging through Visual Studio tooling as well. +Make sure your terminal is in the temporal-examples folder and then run `docker compose up`. This +will start all services. If you ever need to debug the Temporal workflows you can debug via a Docker +container by installing the "Container Tools" extension in VS Code. There is also an option to do +the debugging through Visual Studio tooling as well. -This set of docker containers actually installs the temporal cli to a container. If you want to execute commands using it you should either exec into it or access exec in Docker Desktop. The container is named temporal-cli. If you want examples of this go to the temporal-examples/scripts folder. There is also the documentation here: https://docs.temporal.io/cli#command-set +This set of Docker containers actually installs the Temporal CLI to an isolated. If you want to +execute commands using it you should either exec into it or access exec in Docker Desktop. The +container is named `temporal-cli`. If you want examples of this go to the `temporal-examples/scripts` +folder. There is also the documentation [here](https://docs.temporal.io/cli#command-set) -## The Examples +## Examples -We have several different examples of what Temporal can do in the Workflows files which are in the workflows project. +We have several different examples of what Temporal can do in the Workflows files which are in the +Workflows project. -**Examples.workflow.cs**- shows a default Temporal workflow with a generic activity +**Examples.workflow.cs** - shows a default Temporal workflow with a generic activity -**ExampleWithChildren.workflow.cs** - shows you how you can compose workflows together. This creates 1-10 child workflows and waits for them to finish. +**ExampleWithChildren.workflow.cs** - shows you how you can compose workflows together. This creates +1-10 child workflows and waits for them to finish. -**WaitingSignal.workflow.cs** - shows how you can pause a workflow indefinitely or with a timeout to wait for a "signal". This signal in our example is caused by a rest api. While paused the workflow takes up very few resources. The SignalController inside the rest-controller project is where we send the signal. THis also shows how you can search the Temporal Server for specific workflows. In this case we are using the Workflow ID. +**WaitingSignal.workflow.cs** - shows how you can pause a workflow indefinitely or with a timeout to +wait for a "signal". This signal in our example is caused by a REST API. While paused the workflow +takes up very few resources. The SignalController inside the rest-controller project is where we send +the signal. This also shows how you can search the Temporal Server for specific workflows. In this +case we are using the Workflow ID. ## Monitoring and Metrics -The docker compose file contains [Prometheus](https://prometheus.io/) and [Grafana](https://grafana.com/) services. -Both the Temporal service and all worker services expose metrics to Prometheus, which are collected based on the -settings in `prometheus.yml`. Prometheus can be manually added to Grafana as a data source. +The docker compose file contains [Prometheus](https://prometheus.io/) and +[Grafana](https://grafana.com/) services. Both the Temporal service and all worker services expose +metrics to Prometheus, which are collected based on the settings in `prometheus.yml`. Prometheus can +be manually added to Grafana as a data source. -The Prometheus UI can be accessed at [query page](http://localhost:9090/query), and details of the different scraped metrics -endpoints can be seen at [targets page](http://localhost:9090/targets). +The Prometheus UI can be accessed at [query page](http://localhost:9090/query), and details of the +different scraped metrics endpoints can be seen at [targets page](http://localhost:9090/targets). -The Grafana UI can be accessed at [Grafana login](http://localhost:3000/login) - Login details are admin/admin. +The Grafana UI can be accessed at [Grafana login](http://localhost:3000/login) - Login details are +admin/admin. ## License diff --git a/temporal-examples/temporal-examples.sln b/temporal-examples/temporal-examples.sln index bf39fef..701c159 100644 --- a/temporal-examples/temporal-examples.sln +++ b/temporal-examples/temporal-examples.sln @@ -13,6 +13,7 @@ Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-co EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8EC462FD-D22E-90A8-E5CE-7E832BA40C5D}" ProjectSection(SolutionItems) = preProject + LICENSE.md = LICENSE.md ..\README.md = ..\README.md EndProjectSection EndProject From 7839181adfcc88367446faeffc3020d05df8edb9 Mon Sep 17 00:00:00 2001 From: Silas Benson Date: Thu, 7 Aug 2025 10:13:11 +0100 Subject: [PATCH 08/11] Relocate readme --- temporal-examples/LICENSE.md => LICENSE.md | 0 temporal-examples/temporal-examples.sln | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename temporal-examples/LICENSE.md => LICENSE.md (100%) diff --git a/temporal-examples/LICENSE.md b/LICENSE.md similarity index 100% rename from temporal-examples/LICENSE.md rename to LICENSE.md diff --git a/temporal-examples/temporal-examples.sln b/temporal-examples/temporal-examples.sln index 701c159..5e8b612 100644 --- a/temporal-examples/temporal-examples.sln +++ b/temporal-examples/temporal-examples.sln @@ -13,7 +13,7 @@ Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-co EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8EC462FD-D22E-90A8-E5CE-7E832BA40C5D}" ProjectSection(SolutionItems) = preProject - LICENSE.md = LICENSE.md + ..\LICENSE.md = ..\LICENSE.md ..\README.md = ..\README.md EndProjectSection EndProject From 702bcf38fc348544b4c480bcd50f90697f55cc27 Mon Sep 17 00:00:00 2001 From: Silas Benson Date: Thu, 7 Aug 2025 14:03:18 +0100 Subject: [PATCH 09/11] Fix logging --- temporal-examples/Shared/AutoFac/Modules/LoggingModule.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/temporal-examples/Shared/AutoFac/Modules/LoggingModule.cs b/temporal-examples/Shared/AutoFac/Modules/LoggingModule.cs index fea42f4..c2f99cd 100644 --- a/temporal-examples/Shared/AutoFac/Modules/LoggingModule.cs +++ b/temporal-examples/Shared/AutoFac/Modules/LoggingModule.cs @@ -48,11 +48,6 @@ protected override void Load(ContainerBuilder builder) .Register(c => new SerilogLoggerFactory(logger, true)) .As() .SingleInstance(); - - var services = new ServiceCollection(); - services.AddLogging(); - - builder.Populate(services); } } } From e94da42bc7849e697b963c0b53332fd7f16e4460 Mon Sep 17 00:00:00 2001 From: Silas Benson Date: Thu, 7 Aug 2025 17:52:57 +0100 Subject: [PATCH 10/11] Resolve merge inconsistencies --- temporal-examples/Shared/Shared.csproj | 4 ++++ temporal-examples/workflows/Microservice.workflow.cs | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/temporal-examples/Shared/Shared.csproj b/temporal-examples/Shared/Shared.csproj index 7ea1a47..359b1e3 100644 --- a/temporal-examples/Shared/Shared.csproj +++ b/temporal-examples/Shared/Shared.csproj @@ -6,8 +6,12 @@ + + + + diff --git a/temporal-examples/workflows/Microservice.workflow.cs b/temporal-examples/workflows/Microservice.workflow.cs index 1068af8..5973701 100644 --- a/temporal-examples/workflows/Microservice.workflow.cs +++ b/temporal-examples/workflows/Microservice.workflow.cs @@ -1,5 +1,6 @@ using Temporalio.Common; using Temporalio.Workflows; +using Workflows; namespace workflows; @@ -21,7 +22,7 @@ public async Task RunAsync() }; await Workflow.ExecuteActivityAsync( - () => ExampleActivities.GenericTask(), + (ExampleActivities a) => a.GenericTask(), new ActivityOptions { StartToCloseTimeout = TimeSpan.FromMinutes(5), From f4aff7ca7479311d14a49e5db102edac2550a08a Mon Sep 17 00:00:00 2001 From: Silas Benson Date: Thu, 7 Aug 2025 17:57:02 +0100 Subject: [PATCH 11/11] Part 2 of correcting merge inconsistenciues --- temporal-examples/RestController/MicroserviceController.cs | 2 +- .../AutoFac/Modules/TemporalWorkerConfigurationModule.cs | 2 +- temporal-examples/microservice-worker/Program.cs | 2 +- .../AutoFac/Modules/TemporalWorkerConfigurationModule.cs | 1 + temporal-examples/workflows/Microservice.workflow.cs | 2 +- temporal-examples/workflows/MicroserviceActivities.cs | 2 +- 6 files changed, 6 insertions(+), 5 deletions(-) diff --git a/temporal-examples/RestController/MicroserviceController.cs b/temporal-examples/RestController/MicroserviceController.cs index fb10ffd..f100879 100644 --- a/temporal-examples/RestController/MicroserviceController.cs +++ b/temporal-examples/RestController/MicroserviceController.cs @@ -1,7 +1,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Temporalio.Client; -using workflows; +using Workflows; namespace RestController { diff --git a/temporal-examples/microservice-worker/AutoFac/Modules/TemporalWorkerConfigurationModule.cs b/temporal-examples/microservice-worker/AutoFac/Modules/TemporalWorkerConfigurationModule.cs index 5874f49..1f78316 100644 --- a/temporal-examples/microservice-worker/AutoFac/Modules/TemporalWorkerConfigurationModule.cs +++ b/temporal-examples/microservice-worker/AutoFac/Modules/TemporalWorkerConfigurationModule.cs @@ -4,7 +4,7 @@ using Microsoft.Extensions.DependencyInjection; using Temporalio.Extensions.Hosting; using Temporalio.Runtime; -using workflows; +using Workflows; namespace TemporalWorker.AutoFac.Modules { diff --git a/temporal-examples/microservice-worker/Program.cs b/temporal-examples/microservice-worker/Program.cs index cf375e5..efbcd54 100644 --- a/temporal-examples/microservice-worker/Program.cs +++ b/temporal-examples/microservice-worker/Program.cs @@ -17,7 +17,7 @@ private static async Task Main(string[] args) .ConfigureContainer( (context, builder) => { - builder.RegisterModule(new LoggingModule(LogLevel.Information)); + builder.RegisterModule(new LoggingModule(context.Configuration)); builder.RegisterModule( new TemporalWorkerConfigurationModule(context.Configuration) ); diff --git a/temporal-examples/temporal-worker/AutoFac/Modules/TemporalWorkerConfigurationModule.cs b/temporal-examples/temporal-worker/AutoFac/Modules/TemporalWorkerConfigurationModule.cs index 779c8d5..982410f 100644 --- a/temporal-examples/temporal-worker/AutoFac/Modules/TemporalWorkerConfigurationModule.cs +++ b/temporal-examples/temporal-worker/AutoFac/Modules/TemporalWorkerConfigurationModule.cs @@ -5,6 +5,7 @@ using Temporalio.Extensions.Hosting; using Temporalio.Runtime; using Workflows; +using Workflows; namespace TemporalWorker.AutoFac.Modules { diff --git a/temporal-examples/workflows/Microservice.workflow.cs b/temporal-examples/workflows/Microservice.workflow.cs index 5973701..7c2f11d 100644 --- a/temporal-examples/workflows/Microservice.workflow.cs +++ b/temporal-examples/workflows/Microservice.workflow.cs @@ -2,7 +2,7 @@ using Temporalio.Workflows; using Workflows; -namespace workflows; +namespace Workflows; [Workflow] public class MicroservicesWorkflow diff --git a/temporal-examples/workflows/MicroserviceActivities.cs b/temporal-examples/workflows/MicroserviceActivities.cs index c935f08..8a08c65 100644 --- a/temporal-examples/workflows/MicroserviceActivities.cs +++ b/temporal-examples/workflows/MicroserviceActivities.cs @@ -1,6 +1,6 @@ using Temporalio.Activities; -namespace workflows; +namespace Workflows; // These activities can be calling an external microservice // Arguably these could be added to the generic activities file but this does