Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions src/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
<PackageVersion Include="ReactiveUI.WPF" Version="20.1.63" />
<PackageVersion Include="Seq.Extensions.Logging" Version="8.0.0" />
<PackageVersion Include="ServiceControl.Contracts" Version="5.1.0" />
<PackageVersion Include="ServicePulse.Core" Version="2.5.0-alpha.0.60" />
<PackageVersion Include="System.Configuration.ConfigurationManager" Version="8.0.1" />
<PackageVersion Include="System.Diagnostics.PerformanceCounter" Version="8.0.1" />
<PackageVersion Include="System.DirectoryServices.AccountManagement" Version="8.0.1" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,24 @@ public override async Task ExecuteAsync(InstanceDetailsViewModel model)
}
}

if (!instance.AppConfig.AppSettingExists(ServiceControlSettings.EnableEmbeddedServicePulse.Name))
{
var result = await windowManager.ShowYesNoCancelDialog("INPUT REQUIRED - EMBEDDED SERVICEPULSE",
"ServiceControl can host an embedded version of ServicePulse which allows you to monitor your ServiceControl instance without needing to install ServicePulse separately.",
"Would you like to enable the embedded ServicePulse for this instance?",
"Enable Embedded ServicePulse",
"Do NOT enable Embedded ServicePulse");

if (!result.HasValue)
{
//Dialog was cancelled
await eventAggregator.PublishOnUIThreadAsync(new RefreshInstances());
return;
}

upgradeOptions.EnableEmbeddedServicePulse = result.Value;
}

if (await commandChecks.StopBecauseInstanceIsRunning(instance))
{
return;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace ServiceControl.Config.UI.InstanceAdd
{
public class EnableEmbeddedServicePulseOption
{
public string Name { get; set; }
public bool Value { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ async Task Add()
serviceControlNewInstance.ServiceAccount = viewModel.ServiceControl.ServiceAccount;
serviceControlNewInstance.ServiceAccountPwd = viewModel.ServiceControl.Password;
serviceControlNewInstance.EnableFullTextSearchOnBodies = viewModel.ServiceControl.EnableFullTextSearchOnBodies.Value;
serviceControlNewInstance.EnableEmbeddedServicePulse = viewModel.ServiceControl.EnableEmbeddedServicePulse.Value;
}

var auditNewInstance = viewModel.InstallAuditInstance ? ServiceControlAuditNewInstance.CreateWithDefaultPersistence() : null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,12 @@
Header="FULL TEXT SEARCH ON MESSAGE BODIES"
ItemsSource="{Binding ErrorEnableFullTextSearchOnBodiesOptions}"
SelectedValue="{Binding ErrorEnableFullTextSearchOnBodies}" />
<controls:FormComboBox HorizontalAlignment="Stretch"
VerticalAlignment="Top"
DisplayMemberPath="Name"
Header="ENABLE EMBEDDED SERVICEPULSE"
ItemsSource="{Binding ErrorEnableEmbeddedServicePulseOptions}"
SelectedValue="{Binding ErrorEnableEmbeddedServicePulse}" />
</StackPanel>
</Expander>
</Grid>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,15 @@ public EnableFullTextSearchOnBodiesOption ErrorEnableFullTextSearchOnBodies
set => ServiceControl.EnableFullTextSearchOnBodies = value;
}

public IEnumerable<EnableEmbeddedServicePulseOption> ErrorEnableEmbeddedServicePulseOptions =>
ServiceControl.EnableEmbeddedServicePulseOptions;

public EnableEmbeddedServicePulseOption ErrorEnableEmbeddedServicePulse
{
get => ServiceControl.EnableEmbeddedServicePulse;
set => ServiceControl.EnableEmbeddedServicePulse = value;
}

/* Add Audit Instance */

public string AuditInstanceName
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,19 @@ public ServiceControlInformation(ServiceControlEditorViewModel viewModelParent)
Value = false
}
};
EnableEmbeddedServicePulseOptions = new[]
{
new EnableEmbeddedServicePulseOption
{
Name = "On",
Value = true
},
new EnableEmbeddedServicePulseOption
{
Name = "Off",
Value = false
}
};
ErrorRetention = SettingConstants.ErrorRetentionPeriodDefaultInDaysForUI;
Description = "ServiceControl Service";
HostName = "localhost";
Expand All @@ -48,6 +61,7 @@ public ServiceControlInformation(ServiceControlEditorViewModel viewModelParent)
PortNumber = "33333";
DatabaseMaintenancePortNumber = "33334";
EnableFullTextSearchOnBodies = EnableFullTextSearchOnBodiesOptions.First(p => p.Value); //Default to On.
EnableEmbeddedServicePulse = EnableEmbeddedServicePulseOptions.First(p => p.Value); //Default to On.
ViewModelParent = viewModelParent;
}

Expand Down Expand Up @@ -92,6 +106,10 @@ public ForwardingOption ErrorForwarding

public EnableFullTextSearchOnBodiesOption EnableFullTextSearchOnBodies { get; set; }

public IEnumerable<EnableEmbeddedServicePulseOption> EnableEmbeddedServicePulseOptions { get; }

public EnableEmbeddedServicePulseOption EnableEmbeddedServicePulse { get; set; }

protected void UpdateErrorRetention(TimeSpan value)
{
ErrorRetention = ErrorRetentionUnits == TimeSpanUnits.Days ? value.TotalDays : value.TotalHours;
Expand Down Expand Up @@ -122,6 +140,7 @@ public void UpdateFromInstance(ServiceControlInstance instance)
ErrorForwardingQueueName = instance.ErrorLogQueue;
UpdateErrorRetention(instance.ErrorRetentionPeriod);
EnableFullTextSearchOnBodies = EnableFullTextSearchOnBodiesOptions.FirstOrDefault(p => p.Value == instance.EnableFullTextSearchOnBodies);
EnableEmbeddedServicePulse = EnableEmbeddedServicePulseOptions.FirstOrDefault(p => p.Value == instance.EnableEmbeddedServicePulse);
}

ForwardingOption errorForwarding;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@
<GroupBox Grid.Row="4"
Grid.Column="1"
Visibility="{Binding HasBrowsableUrl, Converter={StaticResource boolToVis}}"
Header="URL"
Header="{Binding UrlHeading}"
HeaderTemplate="{StaticResource SimpleHeaderedGroupBox}">
<Hyperlink Command="{Binding OpenUrl}" CommandParameter="{Binding BrowsableUrl}">
<Hyperlink.ContextMenu>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,22 @@ public string BrowsableUrl

public bool HasBrowsableUrl => ServiceInstance is IURLInfo;

public string UrlHeading
{
get
{
if (IsServiceControlInstance)
{
if (ServiceControlInstance.EnableEmbeddedServicePulse)
{
return "SERVICEPULSE";
}
}

return "URL";
}
}

public string InstallPath => ((IServicePaths)ServiceInstance).InstallPath;

public string DBPath => GetDBPathIfAvailable();
Expand Down Expand Up @@ -291,6 +307,7 @@ public Task HandleAsync(PostRefreshInstances message, CancellationToken cancella
NotifyOfPropertyChange("HasNewVersion");
NotifyOfPropertyChange("Transport");
NotifyOfPropertyChange("BrowsableUrl");
NotifyOfPropertyChange("UrlHeading");
return Task.CompletedTask;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ async Task Save()
instance.DatabaseMaintenancePort = !string.IsNullOrWhiteSpace(viewModel.ServiceControl.DatabaseMaintenancePortNumber) ? Convert.ToInt32(viewModel.ServiceControl.DatabaseMaintenancePortNumber) : null;
instance.VirtualDirectory = null;
instance.ForwardErrorMessages = viewModel.ServiceControl.ErrorForwarding.Value;
instance.EnableEmbeddedServicePulse = viewModel.ServiceControl.EnableEmbeddedServicePulse.Value;
instance.ErrorQueue = viewModel.ServiceControl.ErrorQueueName;
instance.ErrorLogQueue = viewModel.ServiceControl.ErrorForwardingQueueName;
instance.ErrorRetentionPeriod = viewModel.ServiceControl.ErrorRetentionPeriod;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,12 @@
Header="FULL TEXT SEARCH ON MESSAGE BODIES"
ItemsSource="{Binding EnableFullTextSearchOnBodiesOptions}"
SelectedValue="{Binding EnableFullTextSearchOnBodies}" />
<controls:FormComboBox HorizontalAlignment="Stretch"
VerticalAlignment="Top"
DisplayMemberPath="Name"
Header="ENABLE EMBEDDED SERVICEPULSE"
ItemsSource="{Binding EnableEmbeddedServicePulseOptions}"
SelectedValue="{Binding EnableEmbeddedServicePulse}" />
</StackPanel>
</sie:SharedServiceControlEditorView.SharedContent>
</sie:SharedServiceControlEditorView>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public void UpdateInstanceFromViewModel(ServiceControlInstance instance)
instance.ConnectionString = ConnectionString;
instance.DatabaseMaintenancePort = Convert.ToInt32(ServiceControl.DatabaseMaintenancePortNumber);
instance.EnableFullTextSearchOnBodies = ServiceControl.EnableFullTextSearchOnBodies.Value;
instance.EnableEmbeddedServicePulse = ServiceControl.EnableEmbeddedServicePulse.Value;
}

public string InstanceName => ServiceControl.InstanceName;
Expand Down Expand Up @@ -189,6 +190,15 @@ public EnableFullTextSearchOnBodiesOption EnableFullTextSearchOnBodies
set => ServiceControl.EnableFullTextSearchOnBodies = value;
}

public IEnumerable<EnableEmbeddedServicePulseOption> EnableEmbeddedServicePulseOptions =>
ServiceControl.EnableEmbeddedServicePulseOptions;

public EnableEmbeddedServicePulseOption EnableEmbeddedServicePulse
{
get => ServiceControl.EnableEmbeddedServicePulse;
set => ServiceControl.EnableEmbeddedServicePulse = value;
}

public bool SubmitAttempted { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ public class NewServiceControlInstance : PSCmdlet
[Parameter(Mandatory = false, HelpMessage = "Specify whether to enable full text search on error messages.")]
public SwitchParameter EnableFullTextSearchOnBodies { get; set; } = true;

[Parameter(Mandatory = false, HelpMessage = "Specify whether to enable embedded ServicePulse instance.")]
public SwitchParameter EnableEmbeddedServicePulse { get; set; }

[Parameter(Mandatory = false, HelpMessage = "Reuse the specified log, db, and install paths even if they are not empty")]
public SwitchParameter Force { get; set; }

Expand Down Expand Up @@ -172,6 +175,7 @@ protected override void ProcessRecord()
details.TransportPackage = ServiceControlCoreTransports.Find(Transport);
details.SkipQueueCreation = SkipQueueCreation;
details.EnableFullTextSearchOnBodies = EnableFullTextSearchOnBodies;
details.EnableEmbeddedServicePulse = EnableEmbeddedServicePulse;

var modulePath = Path.GetDirectoryName(MyInvocation.MyCommand.Module.Path);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2655,6 +2655,13 @@
</maml:description>
<command:parameterValue required="false" variableLength="false">SwitchParameter</command:parameterValue>
</command:parameter>
<command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="named">
<maml:name>EnableEmbeddedServicePulse</maml:name>
<maml:description>
<maml:para>Enable the embedded version of ServicePulse that ships with ServiceControl.</maml:para>
</maml:description>
<command:parameterValue required="false" variableLength="false">SwitchParameter</command:parameterValue>
</command:parameter>
<command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="named">
<maml:name>Force</maml:name>
<maml:description>
Expand Down Expand Up @@ -2942,6 +2949,18 @@
</dev:type>
<dev:defaultValue></dev:defaultValue>
</command:parameter>
<command:parameter required="false" variableLength="false" globbing="false" pipelineInput="false" position="named">
<maml:name>EnableEmbeddedServicePulse</maml:name>
<maml:description>
<maml:para>Enable the embedded version of ServicePulse that ships with ServiceControl</maml:para>
</maml:description>
<command:parameterValue required="false" variableLength="false">SwitchParameter</command:parameterValue>
<dev:type>
<maml:name>SwitchParameter</maml:name>
<maml:uri/>
</dev:type>
<dev:defaultValue></dev:defaultValue>
</command:parameter>
</command:parameters>
<command:inputTypes>
<command:inputType>
Expand Down Expand Up @@ -2998,7 +3017,8 @@
-DisplayName &apos;ServiceControl Test&apos; `
-AuditRetentionPeriod $AuditRetention `
-ErrorRetentionPeriod $ErrorRetention `
-ForwardErrorMessages:$false
-ForwardErrorMessages:$false `
-EnableEmbeddedServicePulse
</dev:code>
<dev:remarks>
<maml:para>Add a servicecontrol instance</maml:para>
Expand Down
4 changes: 4 additions & 0 deletions src/ServiceControl/Hosting/Commands/RunCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ public override async Task Execute(HostArguments args, Settings settings)

var app = hostBuilder.Build();
app.UseServiceControl(settings.ForwardedHeadersSettings, settings.HttpsSettings);
if (settings.EnableEmbeddedServicePulse)
{
app.UseServicePulse(settings.ServicePulseSettings);
}
app.UseServiceControlAuthentication(settings.OpenIdConnectSettings.Enabled);

await app.RunAsync(settings.RootUrl);
Expand Down
10 changes: 10 additions & 0 deletions src/ServiceControl/Infrastructure/Settings/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ namespace ServiceBus.Management.Infrastructure.Settings
using ServiceControl.Infrastructure.WebApi;
using ServiceControl.Persistence;
using ServiceControl.Transports;
using ServicePulse;
using JsonSerializer = System.Text.Json.JsonSerializer;

public class Settings
Expand Down Expand Up @@ -65,6 +66,12 @@ public Settings(
MaximumConcurrencyLevel = SettingsReader.Read<int?>(SettingsRootNamespace, "MaximumConcurrencyLevel");
RetryHistoryDepth = SettingsReader.Read(SettingsRootNamespace, "RetryHistoryDepth", 10);
AllowMessageEditing = SettingsReader.Read<bool>(SettingsRootNamespace, "AllowMessageEditing");
EnableEmbeddedServicePulse = SettingsReader.Read(SettingsRootNamespace, "EnableEmbeddedServicePulse", false);
ServicePulseSettings = ServicePulseSettings.GetFromEnvironmentVariables() with
{
ServiceControlUrl = $"{ApiUrl}/",
IsEmbedded = true
};
NotificationsFilter = SettingsReader.Read<string>(SettingsRootNamespace, "NotificationsFilter");
RemoteInstances = GetRemoteInstances().ToArray();
TimeToRestartErrorIngestionAfterFailure = GetTimeToRestartErrorIngestionAfterFailure();
Expand All @@ -91,6 +98,9 @@ public Settings(

public bool AllowMessageEditing { get; set; }

public bool EnableEmbeddedServicePulse { get; set; }
public ServicePulseSettings ServicePulseSettings { get; set; }

//HINT: acceptance tests only
public Func<MessageContext, bool> MessageFilter { get; set; }

Expand Down
1 change: 1 addition & 0 deletions src/ServiceControl/ServiceControl.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
<PackageReference Include="NServiceBus.Extensions.Hosting" />
<PackageReference Include="NServiceBus.Extensions.Logging" />
<PackageReference Include="ServiceControl.Contracts" />
<PackageReference Include="ServicePulse.Core" />
<PackageReference Include="System.Reactive.Linq" />
<PackageReference Include="Yarp.ReverseProxy" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class FakeServiceControlInstance : IServiceControlInstance

public bool ForwardErrorMessages { get; set; }

public bool EnableEmbeddedServicePulse { get; set; }

public TimeSpan ErrorRetentionPeriod { get; set; }

public TimeSpan? AuditRetentionPeriod { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ protected override void UpdateSettings()
settings.Set(ServiceControlSettings.ErrorRetentionPeriod, details.ErrorRetentionPeriod.ToString(), version);
settings.Set(ServiceControlSettings.EnableFullTextSearchOnBodies, details.EnableFullTextSearchOnBodies.ToString(), version);
settings.Set(ServiceControlSettings.RemoteInstances, RemoteInstanceConverter.ToJson(details.RemoteInstances), version);
settings.Set(ServiceControlSettings.EnableEmbeddedServicePulse, details.EnableEmbeddedServicePulse.ToString(), version);

// Windows services allow a maximum of 125 seconds when stopping a service.
// When shutting down or restarting the OS we have no control over the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,5 +113,11 @@ public static class ServiceControlSettings
Name = "LicensingComponent/RabbitMQ/Password",
RemovedFrom = new SemanticVersion(6, 5, 0)
};

public static readonly SettingInfo EnableEmbeddedServicePulse = new()
{
Name = "ServiceControl/EnableEmbeddedServicePulse",
SupportedFrom = new SemanticVersion(6, 9, 0)
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -85,26 +85,29 @@ public string AclMaintenanceUrl
public TimeSpan ErrorRetentionPeriod { get; set; }
public bool SkipQueueCreation { get; set; }
public bool EnableFullTextSearchOnBodies { get; set; }
public bool EnableEmbeddedServicePulse { get; set; }

protected abstract string BaseServiceName { get; }

public string Url
{
get
{
var suffix = EnableEmbeddedServicePulse ? "" : "api/";
if (string.IsNullOrWhiteSpace(VirtualDirectory))
{
return $"http://{HostName}:{Port}/api/";
return $"http://{HostName}:{Port}/{suffix}";
}

return $"http://{HostName}:{Port}/{VirtualDirectory}{(VirtualDirectory.EndsWith("/") ? string.Empty : "/")}api/";
return $"http://{HostName}:{Port}/{VirtualDirectory}{(VirtualDirectory.EndsWith("/") ? string.Empty : "/")}{suffix}";
}
}

public string BrowsableUrl
{
get
{
var suffix = EnableEmbeddedServicePulse ? "" : "api/";
string host = HostName switch
{
"*" => "localhost",
Expand All @@ -113,10 +116,10 @@ public string BrowsableUrl
};
if (string.IsNullOrWhiteSpace(VirtualDirectory))
{
return $"http://{host}:{Port}/api/";
return $"http://{host}:{Port}/{suffix}";
}

return $"http://{host}:{Port}/{VirtualDirectory}{(VirtualDirectory.EndsWith("/") ? string.Empty : "/")}api/";
return $"http://{host}:{Port}/{VirtualDirectory}{(VirtualDirectory.EndsWith("/") ? string.Empty : "/")}{suffix}/";
}
}

Expand Down
Loading
Loading