Skip to content
Open
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
00d9c43
GH00839: Initial support for multiple instances of pcs service bus se…
trondlindanger Dec 4, 2024
3d2762b
GH00839: Referring to dedicated infra branch.
trondlindanger Dec 5, 2024
fa62865
GH00839: Remove project name from directory.
trondlindanger Dec 17, 2024
0ad81c7
GH00839: Reintroduced projectName.
trondlindanger Dec 17, 2024
14d1c5b
GH00839: Proper filtering/ loading of configuration from Azure. Inclu…
trondlindanger Dec 17, 2024
6bb56ff
GH00839: InstanceName mock for unit tests.
trondlindanger Dec 18, 2024
99ed30e
GH00839: Locking mechanism for shared wallet resource accessed during…
trondlindanger Dec 18, 2024
a0d5012
GH00839: Logging instance name and assigned plants.
trondlindanger Dec 18, 2024
440e121
GH00839: appsettings.json formatting.
trondlindanger Dec 19, 2024
0bb8143
GH00839: Using separate wallet files for the different service instan…
trondlindanger Dec 19, 2024
0ed9d2f
GH00839: Console logging for wallet registration.
trondlindanger Dec 19, 2024
633c18c
GH00839: Introduction of remainder logic. Handling remainder of plant…
trondlindanger Dec 27, 2024
c9f7942
GH00839: Fixed failing unit test.
trondlindanger Dec 30, 2024
b3b72dc
GH00839: Unit test.
trondlindanger Dec 30, 2024
a14514a
GH00839: Updated unit tests.
trondlindanger Jan 2, 2025
a121b8d
GH00839: Log configuration.
trondlindanger Jan 2, 2025
bd6a93b
GH00839: Additional logging for issue tracing.
trondlindanger Jan 2, 2025
301a4c1
GH00839: Issue tracing.
trondlindanger Jan 2, 2025
ec7afc7
GH00839: Issue tracing.
trondlindanger Jan 2, 2025
0cf7900
GH00839: Issue tracing.
trondlindanger Jan 2, 2025
b0ffd32
GH00839: Issue tracing.
trondlindanger Jan 2, 2025
2958521
GH00839: Adjustments before code review.
trondlindanger Jan 2, 2025
ca2c315
GH00839: PR feedback; changed Azure config attribute name. Added conf…
trondlindanger Jan 6, 2025
70c585e
GH00839: Updates related to feedback from code review. Improved metho…
trondlindanger Jan 14, 2025
59e53cf
GH00839: Updates related to feedback from code review. Improved metho…
trondlindanger Jan 14, 2025
5418c66
GH00839: Configuration of plants for instances is provided as a json …
trondlindanger Jan 21, 2025
a8e7f33
GH00839: Removed unused code.
trondlindanger Jan 22, 2025
2656ff4
GH00839: Using explicit json config for plants handled by distinct in…
trondlindanger Jan 27, 2025
1c8612b
GH00839: Ensure that GetAllPlants is called during startup.
trondlindanger Jan 28, 2025
a7ef7d8
GH00839: Validation added for message chunk size > 0.
trondlindanger Jan 28, 2025
293c268
GH00839: Lazy loading GetAllPlants. We only need this to be called once.
trondlindanger Jan 28, 2025
46dd952
GH00839: Adjustments during code review.
trondlindanger Jan 29, 2025
c2a6bf1
GH00839: Moved calculation of plants for given instance from startup …
trondlindanger Feb 5, 2025
1336ef2
GH00839: Refactored to support multi instance Azure web app instead o…
trondlindanger Feb 14, 2025
c1d056e
Merge branch 'master' into feature/GH00839-Use-two-web-job-instances-…
trondlindanger Feb 14, 2025
ee9fa10
GH00839: Additional logging for issue related to Oracle connections p…
trondlindanger Feb 17, 2025
e32647d
Merge branch 'master' into feature/GH00839-Use-two-web-job-instances-…
trondlindanger Feb 17, 2025
5d54c08
GH00839: Handled two warnings.
trondlindanger Feb 17, 2025
09bfe04
GH00839: Handled some warnings.
trondlindanger Feb 17, 2025
7c58c2b
GH00839: Changed log level related to GetAllPlants.
trondlindanger Feb 17, 2025
f9e8770
GH00839: Commented in temp removed topic.
trondlindanger Feb 18, 2025
9090baa
GH00839: Removed debug logging.
trondlindanger Feb 18, 2025
26296c5
GH00839: Caching of plant lease accross instance loops.
trondlindanger Feb 20, 2025
53ed59d
Moved BlobClient initialization to constructor of BlobLeaseService fo…
trondlindanger Feb 27, 2025
7715f73
Allowing shorter delay between attempts when releasing plant lease.
trondlindanger Feb 27, 2025
f1207b2
Releasing blob lease when there are not plants to lease.
trondlindanger Feb 28, 2025
e358186
Adjustment og logging level.
trondlindanger Mar 3, 2025
c3b8a7a
GH839: Using standard datetime serializer instead of custom.
trondlindanger Mar 11, 2025
cffaff0
GH839: Support for multiple plants per blob item. Feature flag as an …
trondlindanger Mar 12, 2025
2e974b3
GH839: Start immediately on next execution if we did not complete in …
trondlindanger Mar 12, 2025
68b24c7
GH00839: Including tests for when to stick to same plant.
trondlindanger Mar 14, 2025
15fe7c1
GH00839: GetPropertiesAsync is called upfront of AcquireAsync in an a…
trondlindanger Mar 14, 2025
a30b71a
GH00839: Not acquiring lease when reading blob.
trondlindanger Mar 17, 2025
82376c0
GH00839: Jitter included in Polly retry to avoid race conditions. Tim…
trondlindanger Mar 18, 2025
59d7b9a
GH00839: Using CancellationToken.None when releasing blob lease. We w…
trondlindanger Mar 18, 2025
ef6d0a7
GH00839: Include metrics by plant.
trondlindanger Apr 2, 2025
1fbf0b3
GH00839: Also release plant lease if cancellation has been requested.
trondlindanger Apr 3, 2025
4e9baf5
GH00839: Plant lease is provided in seconds. Not millieseconds.
trondlindanger Apr 8, 2025
8ec9f12
GH00839: Properly resetting CancellationToken.
trondlindanger Apr 9, 2025
9c2314f
Upgrade to EF 8.23.80.
trondlindanger Apr 9, 2025
7433c6a
Changed log level.
trondlindanger Apr 10, 2025
2547e65
Merge from master. Conflict handling.
trondlindanger May 7, 2025
1d1c787
GH00839: Fixed failing test.
trondlindanger May 7, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions azure-pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ resources:
type: github
name: equinor/procosys-infra
endpoint: 'equinor'
ref: master
ref: GH00839-Use-two-web-job-instances-to-create-messages-to-Azure-service-bus-based-on-content-in-busevent-table
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be changed before merge I think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. It will.


variables:
- template: src/variables/global-variables.yml@templates
Expand Down Expand Up @@ -59,7 +59,19 @@ stages:
rootFolderOrFile: '$(Build.BinariesDirectory)/build'
solution: '**/*.sln'
sourceFolder: '$(System.DefaultWorkingDirectory)/src/$(projectName)/bin/$(buildConfiguration)/net6.0'
targetFolder: '$(Build.BinariesDirectory)/build/App_Data/jobs/continuous/$(projectName)'
searchFolder: '$(System.DefaultWorkingDirectory)'
targetFolder: '$(Build.BinariesDirectory)/build/App_Data/jobs/continuous'
testSelector: 'testAssemblies'
testAssemblyVer2: |
**/*.Specs/bin/$(buildConfiguration)/*.Specs.dll
testArtifactName: 'test'
testInstances:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this test related, or should just be "instances"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to as for import there are pipeline parameters testInstances and prodInstances for defining artifacts/ web jobs: https://statoildeveloper.visualstudio.com/Statoil.NextGenProCoSys/_wiki/wikis/Statoil.NextGenProCoSys.wiki/1852/Multiple-running-instances

- ServiceA
- ServiceB
prodArtifactName: 'prod'
prodInstances:
- ServiceA
- ServiceB
versionSpec: '6.7.0'
projectName: '$(projectName)'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
</PropertyGroup>

Copy link
Contributor

@TordJoranger TordJoranger Feb 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are all of these changes needed? Double check that we need these dependencies.

<ItemGroup>
<PackageReference Include="Azure.Data.AppConfiguration" Version="1.2.0" />
<PackageReference Include="Azure.Identity" Version="1.11.3" />
<PackageReference Include="Microsoft.ApplicationInsights" Version="2.21.0" />
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.1.1" />
<PackageReference Include="Oracle.EntityFrameworkCore" Version="7.21.12" />
<PackageReference Include="System.Text.Json" Version="7.0.3" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Equinor.ProCoSys.BusSenderWorker.Core.Interfaces;

public interface IPlantRepository
{
List<string> GetAllPlants();
}
10 changes: 10 additions & 0 deletions src/Equinor.ProCoSys.BusSender.Core/Interfaces/IPlantService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Collections.Generic;
using Equinor.ProCoSys.BusSenderWorker.Core.Models;
using Microsoft.Extensions.Configuration;

namespace Equinor.ProCoSys.BusSenderWorker.Core.Interfaces;
public interface IPlantService
{
List<string> GetPlantsHandledByInstance(List<PlantsByInstance>? plantsByInstances, List<string> allPlants,
string instanceName);
}
10 changes: 10 additions & 0 deletions src/Equinor.ProCoSys.BusSender.Core/Models/Plant.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma warning disable CS8618

namespace Equinor.ProCoSys.BusSenderWorker.Core.Models;

public class Plant
{
public string ProjectSchema { get; set; }
public string IsVoided { get; set; }
}

17 changes: 17 additions & 0 deletions src/Equinor.ProCoSys.BusSender.Core/Models/PlantsByInstance.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Text.Json.Serialization;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused usings.

using System.Threading.Tasks;

namespace Equinor.ProCoSys.BusSenderWorker.Core.Models;
public class PlantsByInstance
{
[Required]
public string InstanceName { get; set; } = string.Empty;

[Required]
public string Value { get; set; } = string.Empty;
}
18 changes: 13 additions & 5 deletions src/Equinor.ProCoSys.BusSender.Core/Services/BusSenderService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@
using Equinor.ProCoSys.BusSenderWorker.Core.Mappers;
using Equinor.ProCoSys.BusSenderWorker.Core.Models;
using Equinor.ProCoSys.BusSenderWorker.Core.Telemetry;
using Equinor.ProCoSys.PcsServiceBus;
using Equinor.ProCoSys.PcsServiceBus.Sender.Interfaces;
using Equinor.ProCoSys.PcsServiceBus.Topics;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace Equinor.ProCoSys.BusSenderWorker.Core.Services;

Expand All @@ -27,14 +30,17 @@ public class BusSenderService : IBusSenderService
private readonly Stopwatch _sw;
private readonly ITelemetryClient _telemetryClient;
private readonly IUnitOfWork _unitOfWork;
private readonly string _instanceName;

public BusSenderService(IPcsBusSender pcsBusSender,
IBusEventRepository busEventRepository,
IUnitOfWork unitOfWork,
ILogger<BusSenderService> logger,
ITelemetryClient telemetryClient,
IBusEventService service,
IQueueMonitorService queueMonitor)
IQueueMonitorService queueMonitor,
IConfiguration configuration,
IOptions<InstanceOptions> instanceOptions)
{
_pcsBusSender = pcsBusSender;
_busEventRepository = busEventRepository;
Expand All @@ -44,6 +50,7 @@ public BusSenderService(IPcsBusSender pcsBusSender,
_service = service;
_queueMonitor = queueMonitor;
_sw = new Stopwatch();
_instanceName = instanceOptions.Value.InstanceName;
}

public async Task CloseConnections()
Expand All @@ -62,11 +69,11 @@ public async Task HandleBusEvents()
var events = await _busEventRepository.GetEarliestUnProcessedEventChunk();
if (events.Any())
{
_logger.LogInformation("BusSenderService found {Count} messages to process after {Sw} ms", events.Count,
_logger.LogInformation("[{InstanceName}] BusSenderService found {Count} messages to process after {Sw} ms", _instanceName, events.Count,
_sw.ElapsedMilliseconds);
_telemetryClient.TrackMetric("BusSender Chunk", events.Count);
await ProcessBusEvents(events);
_logger.LogInformation("BusSenderService ProcessBusEvents used {Sw} ms", _sw.ElapsedMilliseconds);
_logger.LogInformation("[{InstanceName}] BusSenderService ProcessBusEvents used {Sw} ms", _instanceName,_sw.ElapsedMilliseconds);
}

_sw.Reset();
Expand Down Expand Up @@ -180,15 +187,15 @@ private async Task ProcessBusEvents(List<BusEvent> events)
var dsw = Stopwatch.StartNew();

var unProcessedEvents = events.Where(busEvent => busEvent.Status == Status.UnProcessed).ToList();
_logger.LogInformation("Amount of messages to process: {Count} ", unProcessedEvents.Count);
_logger.LogInformation("[{InstanceName}] Amount of messages to process: {Count} ", _instanceName, unProcessedEvents.Count);

foreach (var simpleUnprocessedBusEvent in unProcessedEvents.Where(e =>
IsSimpleMessage(e) || e.Event == TagTopic.TopicName))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems out of place? are you sure about this change?

{
await UpdateEventBasedOnTopic(simpleUnprocessedBusEvent);
}

_logger.LogInformation("Update loop finished at at {Sw} ms", dsw.ElapsedMilliseconds);
_logger.LogInformation("[{InstanceName}] Update loop finished at at {Sw} ms", _instanceName, dsw.ElapsedMilliseconds);
await _unitOfWork.SaveChangesAsync();


Expand Down Expand Up @@ -243,6 +250,7 @@ private void TrackMessage(BusEvent busEvent, string busMessageMessageId, string
{"ProjectName", message?.ProjectName ?? "NoProject"},
{"Plant", message?.Plant ?? "NoPlant"},
{"MessageId", busMessageMessageId ?? "NoID" },
{"InstanceName", _instanceName},
//Remove these after debugging
{"BusEventMessageToSend", string.IsNullOrEmpty(message?.ProCoSysGuid) ? "MessageToSend: ( " + busEvent.MessageToSend + " )" : "N/A" },
{"BusEventMessage", string.IsNullOrEmpty(message?.ProCoSysGuid) ? busEvent.Message : "N/A" },
Expand Down
83 changes: 83 additions & 0 deletions src/Equinor.ProCoSys.BusSender.Core/Services/PlantService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Equinor.ProCoSys.BusSenderWorker.Core.Interfaces;
using Equinor.ProCoSys.BusSenderWorker.Core.Models;
using Equinor.ProCoSys.PcsServiceBus;
using Microsoft.Extensions.Logging;


namespace Equinor.ProCoSys.BusSenderWorker.Core.Services;
public class PlantService : IPlantService
{
private readonly ILogger<PlantService> _logger;
private List<string> _plantsHandledByCurrentInstance = new();

public PlantService(ILogger<PlantService> logger) => _logger = logger;

public List<string> GetPlantsHandledByInstance(List<PlantsByInstance>? plantsByInstances, List<string> allPlants, string instanceName)
{
_plantsHandledByCurrentInstance = GetPlantsForInstance(plantsByInstances, instanceName);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possible null reference error.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not think so. ValidatePlantsByInstance is executed after deserialization. This includes a null check for plantsByInstances.

if (_plantsHandledByCurrentInstance.Any())
{
_logger.LogInformation($"[{instanceName}] Plants configured for this instance: {string.Join(",", _plantsHandledByCurrentInstance)}");

var containsRemainingPlants = _plantsHandledByCurrentInstance.Contains(PcsServiceBusInstanceConstants.RemainingPlants);
if (containsRemainingPlants)
{
// We are also handling cases where RemainingPlants constant is used in combination with actual plants. E.g. PCS$TROLL_A, PCS$OSEBERG_C, REMAININGPLANTS.
AddPlantLeftovers(plantsByInstances, allPlants, instanceName);
}
RemoveInvalidPlants(allPlants, instanceName);
}

if (!_plantsHandledByCurrentInstance.Any())
{
var message = $"[{instanceName}] No plants configured for this instance. Hence it will not start.";
_logger.LogError(message);
throw new Exception(message);
}

return _plantsHandledByCurrentInstance;
}


private void AddPlantLeftovers(IEnumerable<PlantsByInstance> plantsByInstances, IEnumerable<string> allPlants, string instanceName)
{
var plantsForAllExceptInstance = GetPlantsForAllExceptInstance(plantsByInstances, instanceName);
var plantLeftovers = GetPlantLeftovers(plantsForAllExceptInstance, allPlants);
_plantsHandledByCurrentInstance = _plantsHandledByCurrentInstance.Union(plantLeftovers).ToList();
}

private static IEnumerable<string> GetPlantsForAllExceptInstance(IEnumerable<PlantsByInstance> plantsByInstances, string instanceName) =>
plantsByInstances
.Where(x => x.InstanceName != instanceName)
.SelectMany(x => x.Value.Split(','))
Copy link
Contributor

@jsoi-eq jsoi-eq Jan 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using trim, to remove whitespace?
Use case insensitive comparison?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trim for plant values is ok, but I do not think it is worth rewriting all handling for InstanceName to support case insensitive. If we do it here, we should do it elsewhere too.

.ToList();

private static List<string> GetPlantsForInstance(IEnumerable<PlantsByInstance> plantsByInstances, string instanceName) =>
plantsByInstances
.First(x => x.InstanceName == instanceName).Value.Split(',')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using trim, to remove whitespace?
Replace .First with .Single to identify duplicates?
Use case insensitive comparison?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Single and trim is ok to implement.

.ToList();

private void RemoveInvalidPlants(IEnumerable<string> allPlants, string instanceName)
{
_plantsHandledByCurrentInstance =
_plantsHandledByCurrentInstance.Except(PcsServiceBusInstanceConstants.AllPlantReplacementConstants).ToList();

var plantsNotPresent = _plantsHandledByCurrentInstance.Except(PcsServiceBusInstanceConstants.AllPlantConstants).Except(allPlants).ToList();
if (plantsNotPresent.Any())
{
_logger.LogWarning(
$"[{instanceName}] The following plant(s) is/ are not valid: {string.Join(",", plantsNotPresent)}. Removing them/ it from plants being processed.");
_plantsHandledByCurrentInstance = _plantsHandledByCurrentInstance.Except(plantsNotPresent).ToList();
}
else
{
_logger.LogInformation($"[{instanceName}] Plants validated: {string.Join(",", _plantsHandledByCurrentInstance)}");
}
}

private static IEnumerable<string> GetPlantLeftovers(IEnumerable<string> handledPlants, IEnumerable<string> allNonVoidedPlants) =>
allNonVoidedPlants.Except(handledPlants);
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Equinor.ProCoSys.BusSenderWorker.Core.Interfaces;
using Equinor.ProCoSys.BusSenderWorker.Core.Telemetry;
using Equinor.ProCoSys.PcsServiceBus;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;

namespace Equinor.ProCoSys.BusSenderWorker.Core.Services;

Expand All @@ -13,15 +16,17 @@ public class QueueMonitorService : IQueueMonitorService
private readonly IConfiguration _configuration;
private readonly ISystemClock _systemClock;
private readonly int _queueWriteIntervalMinutes;
private readonly string _instanceName;


public QueueMonitorService(ITelemetryClient telemetryClient, IBusEventRepository busEventRepository, IConfiguration configuration, ISystemClock systemClock)
public QueueMonitorService(ITelemetryClient telemetryClient, IBusEventRepository busEventRepository, IConfiguration configuration, ISystemClock systemClock, IOptions<InstanceOptions> instanceOptions)
{
_telemetryClient = telemetryClient;
_busEventRepository = busEventRepository;
_configuration = configuration;
_systemClock = systemClock;
_queueWriteIntervalMinutes = string.IsNullOrWhiteSpace(configuration["MonitorQueueIntervalMinutes"]) ? 15 : int.Parse(configuration["MonitorQueueIntervalMinutes"]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know you didn't introduce IConfiguration here, but would it be worth considering moving this to IOptions pattern too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Somebody should do that sometime ;-)

_instanceName = instanceOptions.Value.InstanceName;
}

public async Task WriteQueueMetrics()
Expand All @@ -45,18 +50,26 @@ private async Task WriteQueueAge()
}

var waitTime = _systemClock.UtcNow - queueOldestEvent;
_telemetryClient.TrackMetric("QueueAge", waitTime.TotalMinutes);
var properties = new Dictionary<string, string>
{
{ "InstanceName", _instanceName }
};
_telemetryClient.TrackMetric("QueueAge", waitTime.TotalMinutes, properties);
}

private async Task WriteQueueLength()
{
var queueLength = await _busEventRepository.GetUnProcessedCount();
_telemetryClient.TrackMetric("QueueLength", queueLength);
var properties = new Dictionary<string, string>
{
{ "InstanceName", _instanceName }
};
_telemetryClient.TrackMetric("QueueLength", queueLength, properties);
}

private bool IsTimeToWriteQueueMetric(DateTime lastQueueWrite) =>
_systemClock.UtcNow >= lastQueueWrite.ToUniversalTime().AddMinutes(_queueWriteIntervalMinutes);

private bool NoEventFound(DateTime oldestEvent) =>
private static bool NoEventFound(DateTime oldestEvent) =>
oldestEvent.Equals(default);
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,32 @@
using System;
using System.Collections.Generic;
using Equinor.ProCoSys.PcsServiceBus;
using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;

namespace Equinor.ProCoSys.BusSenderWorker.Core.Telemetry;

public class RunningExecutableTelemetryInitializer : ITelemetryInitializer
{
private readonly string _instanceName;

public RunningExecutableTelemetryInitializer(string instanceName) => _instanceName = instanceName;

public void Initialize(ITelemetry telemetry)
{
telemetry.Context.Cloud.RoleName = AppDomain.CurrentDomain.FriendlyName;
telemetry.Context.GlobalProperties["InstanceName"] = _instanceName;
}
}

public class ApplicationInsightsTelemetryClient : ITelemetryClient
{
private readonly TelemetryClient _ai;

public ApplicationInsightsTelemetryClient(TelemetryConfiguration telemetryConfiguration)
public ApplicationInsightsTelemetryClient(TelemetryConfiguration telemetryConfiguration, IConfiguration configuration, IOptions<InstanceOptions> instanceOptions)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parameter configuration is never used.

{
if (telemetryConfiguration == null)
{
Expand All @@ -21,6 +38,7 @@ public ApplicationInsightsTelemetryClient(TelemetryConfiguration telemetryConfig
// The InstrumentationKey isn't set through the configuration object. Setting it explicitly works.
TelemetryConfiguration = { ConnectionString = telemetryConfiguration.ConnectionString }
};
_ai.TelemetryConfiguration.TelemetryInitializers.Add(new RunningExecutableTelemetryInitializer(instanceOptions.Value.InstanceName));
}

public void Flush() => _ai.Flush();
Expand All @@ -33,5 +51,8 @@ public void TrackMetric(string name, double metric) =>
_ai
.GetMetric(name)
.TrackValue(metric);


public void TrackMetric(string name, double metric, Dictionary<string, string> properties) =>
_ai
.TrackMetric(name, metric, properties);
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,7 @@ public void TrackMetric(string name, double metric, string dimension1Name, strin
public void TrackMetric(string name, double metric, string dimension1Name, string dimension1Value) =>
Console.WriteLine(
$"Metric:\t{name}:{Environment.NewLine}\t{metric}{Environment.NewLine}\t{dimension1Name}: {dimension1Value}");
public void TrackMetric(string name, double metric, Dictionary<string, string> properties) =>
Console.WriteLine(
$"Metric:\t{name}:{Environment.NewLine}\t{string.Join(Environment.NewLine, properties.Select(p => $"\t{p.Key}: {p.Value}"))}{Environment.NewLine}{metric}");
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ public interface ITelemetryClient
void Flush();
void TrackMetric(string name, double metric);

void TrackEvent(string name, Dictionary<string, string> properties);

void TrackEvent(string name, Dictionary<string, string> properties);
void TrackMetric(string name, double metric, Dictionary<string, string> properties);

}
Loading