diff --git a/Build-COSFPkgs.ps1 b/Build-COSFPkgs.ps1 index b62704cb..bab7a4e7 100644 --- a/Build-COSFPkgs.ps1 +++ b/Build-COSFPkgs.ps1 @@ -23,11 +23,11 @@ function Build-SFPkg { try { Push-Location $scriptPath - Build-SFPkg "Microsoft.ServiceFabricApps.ClusterObserver.Linux.SelfContained.2.2.6" "$scriptPath\bin\release\ClusterObserver\linux-x64\self-contained\ClusterObserverType" - Build-SFPkg "Microsoft.ServiceFabricApps.ClusterObserver.Linux.FrameworkDependent.2.2.6" "$scriptPath\bin\release\ClusterObserver\linux-x64\framework-dependent\ClusterObserverType" + Build-SFPkg "Microsoft.ServiceFabricApps.ClusterObserver.Linux.SelfContained.2.2.7" "$scriptPath\bin\release\ClusterObserver\linux-x64\self-contained\ClusterObserverType" + Build-SFPkg "Microsoft.ServiceFabricApps.ClusterObserver.Linux.FrameworkDependent.2.2.7" "$scriptPath\bin\release\ClusterObserver\linux-x64\framework-dependent\ClusterObserverType" - Build-SFPkg "Microsoft.ServiceFabricApps.ClusterObserver.Windows.SelfContained.2.2.6" "$scriptPath\bin\release\ClusterObserver\win-x64\self-contained\ClusterObserverType" - Build-SFPkg "Microsoft.ServiceFabricApps.ClusterObserver.Windows.FrameworkDependent.2.2.6" "$scriptPath\bin\release\ClusterObserver\win-x64\framework-dependent\ClusterObserverType" + Build-SFPkg "Microsoft.ServiceFabricApps.ClusterObserver.Windows.SelfContained.2.2.7" "$scriptPath\bin\release\ClusterObserver\win-x64\self-contained\ClusterObserverType" + Build-SFPkg "Microsoft.ServiceFabricApps.ClusterObserver.Windows.FrameworkDependent.2.2.7" "$scriptPath\bin\release\ClusterObserver\win-x64\framework-dependent\ClusterObserverType" } finally { Pop-Location diff --git a/Build-SFPkgs.ps1 b/Build-SFPkgs.ps1 index 7cdf5f16..4020e442 100644 --- a/Build-SFPkgs.ps1 +++ b/Build-SFPkgs.ps1 @@ -23,11 +23,11 @@ function Build-SFPkg { try { Push-Location $scriptPath - Build-SFPkg "Microsoft.ServiceFabricApps.FabricObserver.Linux.SelfContained.3.2.11" "$scriptPath\bin\release\FabricObserver\linux-x64\self-contained\FabricObserverType" - Build-SFPkg "Microsoft.ServiceFabricApps.FabricObserver.Linux.FrameworkDependent.3.2.11" "$scriptPath\bin\release\FabricObserver\linux-x64\framework-dependent\FabricObserverType" + Build-SFPkg "Microsoft.ServiceFabricApps.FabricObserver.Linux.SelfContained.3.2.12" "$scriptPath\bin\release\FabricObserver\linux-x64\self-contained\FabricObserverType" + Build-SFPkg "Microsoft.ServiceFabricApps.FabricObserver.Linux.FrameworkDependent.3.2.12" "$scriptPath\bin\release\FabricObserver\linux-x64\framework-dependent\FabricObserverType" - Build-SFPkg "Microsoft.ServiceFabricApps.FabricObserver.Windows.SelfContained.3.2.11" "$scriptPath\bin\release\FabricObserver\win-x64\self-contained\FabricObserverType" - Build-SFPkg "Microsoft.ServiceFabricApps.FabricObserver.Windows.FrameworkDependent.3.2.11" "$scriptPath\bin\release\FabricObserver\win-x64\framework-dependent\FabricObserverType" + Build-SFPkg "Microsoft.ServiceFabricApps.FabricObserver.Windows.SelfContained.3.2.12" "$scriptPath\bin\release\FabricObserver\win-x64\self-contained\FabricObserverType" + Build-SFPkg "Microsoft.ServiceFabricApps.FabricObserver.Windows.FrameworkDependent.3.2.12" "$scriptPath\bin\release\FabricObserver\win-x64\framework-dependent\FabricObserverType" } finally { Pop-Location diff --git a/ClusterObserver.nuspec.template b/ClusterObserver.nuspec.template index cc009255..976b802c 100644 --- a/ClusterObserver.nuspec.template +++ b/ClusterObserver.nuspec.template @@ -2,9 +2,9 @@ %PACKAGE_ID% - 2.2.6 + 2.2.7 -- Bug Fix in App Parameter Version-less Upgrade feature. +- Bug Fixes. - Performance and Code improvements. Microsoft diff --git a/ClusterObserver/ClusterObserver.cs b/ClusterObserver/ClusterObserver.cs index 7d3fc3de..f3f86b7a 100644 --- a/ClusterObserver/ClusterObserver.cs +++ b/ClusterObserver/ClusterObserver.cs @@ -28,7 +28,7 @@ public sealed class ClusterObserver : ObserverBase private readonly Uri fabricSystemAppUri = new(ObserverConstants.SystemAppName); private readonly bool ignoreDefaultQueryTimeout; - private HealthState LastKnownClusterHealthState + private HealthState LastKnownClusterAggregatedHealthState { get; set; } = HealthState.Unknown; @@ -185,7 +185,7 @@ private async Task ReportClusterHealthAsync() HealthState = HealthState.Ok, Description = repairState, Metric = "RepairJobs", - Source = ObserverName + ObserverName = ObserverName }; // Telemetry. @@ -243,19 +243,17 @@ await FabricClientRetryHelper.ExecuteFabricActionWithRetryAsync( Token); // Previous aggregated cluster health state was Error or Warning. It's now Ok. - if (clusterHealth.AggregatedHealthState == HealthState.Ok && (LastKnownClusterHealthState == HealthState.Error - || (EmitWarningDetails && LastKnownClusterHealthState == HealthState.Warning))) + if (clusterHealth.AggregatedHealthState == HealthState.Ok && (LastKnownClusterAggregatedHealthState == HealthState.Error + || (EmitWarningDetails && LastKnownClusterAggregatedHealthState == HealthState.Warning))) { - LastKnownClusterHealthState = HealthState.Ok; - var telemetry = new ClusterTelemetryData() { ClusterId = ClusterInformation.ClusterInfoTuple.ClusterId, EntityType = EntityType.Cluster, HealthState = HealthState.Ok, - Description = $"Cluster has recovered from previous {LastKnownClusterHealthState} state.", + Description = $"Cluster has recovered from previous {LastKnownClusterAggregatedHealthState} state.", Metric = "AggregatedClusterHealth", - Source = ObserverName + ObserverName = ObserverName }; // Telemetry. @@ -273,6 +271,9 @@ await FabricClientRetryHelper.ExecuteFabricActionWithRetryAsync( ObserverLogger.LogEtw(ClusterObserverConstants.ClusterObserverETWEventName, telemetry); } + // Reset last known Cluster aggregated health state. + LastKnownClusterAggregatedHealthState = HealthState.Ok; + return; } @@ -350,7 +351,7 @@ await FabricClientInstance.HealthManager.GetApplicationHealthAsync( } // Track current aggregated health state for use in next run. - LastKnownClusterHealthState = clusterHealth.AggregatedHealthState; + LastKnownClusterAggregatedHealthState = clusterHealth.AggregatedHealthState; } catch (Exception e) when (e is FabricException or TimeoutException) { @@ -372,7 +373,7 @@ await FabricClientInstance.HealthManager.GetApplicationHealthAsync( EntityType = EntityType.Cluster, HealthState = HealthState.Warning, Description = msg, - Source = ObserverName + ObserverName = ObserverName }; // Send Telemetry. @@ -763,7 +764,7 @@ await FabricClientRetryHelper.ExecuteFabricActionWithRetryAsync( EntityType = EntityType.Node, NodeName = targetNode?.NodeName ?? node.NodeName, NodeType = targetNode?.NodeType, - Source = ObserverName, + ObserverName = ObserverName, HealthState = targetNode?.HealthState ?? node.AggregatedHealthState, Description = telemetryDescription }; @@ -814,7 +815,8 @@ private async Task ProcessEntityHealthAsync(EntityHealth entityHea Property = healthEvent.HealthInformation.Property, Description = healthEvent.HealthInformation.Description, HealthState = healthEvent.HealthInformation.HealthState, - Source = healthEvent.HealthInformation.SourceId + Source = healthEvent.HealthInformation.SourceId, + ObserverName = ClusterObserverConstants.ClusterObserverName }; // Telemetry. @@ -853,7 +855,8 @@ private async Task ProcessEntityHealthAsync(EntityHealth entityHea Property = healthEvent.HealthInformation.Property, Description = healthEvent.HealthInformation.Description, HealthState = healthEvent.HealthInformation.HealthState, - Source = healthEvent.HealthInformation.SourceId + Source = healthEvent.HealthInformation.SourceId, + ObserverName = ClusterObserverConstants.ClusterObserverName }; // Telemetry. @@ -905,7 +908,8 @@ await FabricClientInstance.QueryManager.GetDeployedServicePackageListAsync( Property = healthEvent.HealthInformation.Property, Description = healthEvent.HealthInformation.Description, HealthState = healthEvent.HealthInformation.HealthState, - Source = healthEvent.HealthInformation.SourceId + Source = healthEvent.HealthInformation.SourceId, + ObserverName = ClusterObserverConstants.ClusterObserverName }; // Telemetry. @@ -943,7 +947,8 @@ await FabricClientInstance.QueryManager.GetDeployedServicePackageListAsync( Property = healthEvent.HealthInformation.Property, Description = healthEvent.HealthInformation.Description, HealthState = healthEvent.HealthInformation.HealthState, - Source = healthEvent.HealthInformation.SourceId + Source = healthEvent.HealthInformation.SourceId, + ObserverName = ClusterObserverConstants.ClusterObserverName }; // Telemetry. @@ -981,7 +986,8 @@ await FabricClientInstance.QueryManager.GetDeployedServicePackageListAsync( PartitionId = partitionHealth.PartitionId.ToString(), Description = healthEvent.HealthInformation.Description, HealthState = healthEvent.HealthInformation.HealthState, - Source = healthEvent.HealthInformation.SourceId + Source = healthEvent.HealthInformation.SourceId, + ObserverName = ClusterObserverConstants.ClusterObserverName }; // Telemetry. @@ -1037,7 +1043,8 @@ await FabricClientInstance.QueryManager.GetReplicaListAsync( Description = healthEvent.HealthInformation.Description, HealthState = healthEvent.HealthInformation.HealthState, ServiceKind = serviceKind, - Source = healthEvent.HealthInformation.SourceId + Source = healthEvent.HealthInformation.SourceId, + ObserverName = ClusterObserverConstants.ClusterObserverName }; // Telemetry. @@ -1096,7 +1103,8 @@ await FabricClientInstance.QueryManager.GetReplicaListAsync( ServiceTypeVersion = serviceList[0].ServiceManifestVersion, Description = healthEvent.HealthInformation.Description, HealthState = healthEvent.HealthInformation.HealthState, - Source = healthEvent.HealthInformation.SourceId + Source = healthEvent.HealthInformation.SourceId, + ObserverName = ClusterObserverConstants.ClusterObserverName }; // Telemetry. @@ -1153,7 +1161,7 @@ private async Task MonitorNodeStatusAsync(CancellationToken Token, bool isTest = Metric = "NodeStatus", NodeName = nodeDictItem.Key, NodeType = nodeList.Any(n => n.NodeName == nodeDictItem.Key) ? nodeList.First(n => n.NodeName == nodeDictItem.Key).NodeType : null, - Source = ObserverName, + ObserverName = ObserverName, Value = 0 }; @@ -1221,7 +1229,7 @@ or NodeStatus.Disabling Metric = "NodeStatus", NodeName = kvp.Key, NodeType = nodeList.Any(n => n.NodeName == kvp.Key) ? nodeList.First(n => n.NodeName == kvp.Key).NodeType : null, - Source = ObserverName, + ObserverName = ObserverName, Value = 1, }; diff --git a/ClusterObserver/ClusterObserver.csproj b/ClusterObserver/ClusterObserver.csproj index f7dd701d..fe803570 100644 --- a/ClusterObserver/ClusterObserver.csproj +++ b/ClusterObserver/ClusterObserver.csproj @@ -10,8 +10,8 @@ win-x64;linux-x64 True ClusterObserver - 2.2.6 - 2.2.6 + 2.2.7 + 2.2.7 true false ClusterObserver.Program diff --git a/ClusterObserver/ClusterObserverManager.cs b/ClusterObserver/ClusterObserverManager.cs index ced9b77a..529bd501 100644 --- a/ClusterObserver/ClusterObserverManager.cs +++ b/ClusterObserver/ClusterObserverManager.cs @@ -10,7 +10,6 @@ using System.Fabric.Health; using System.IO; using System.Linq; -using System.Net.Http.Headers; using System.Threading; using System.Threading.Tasks; using ClusterObserver.Utilities; @@ -40,7 +39,7 @@ public sealed class ClusterObserverManager : IDisposable private bool appParamsUpdating; // Folks often use their own version numbers. This is for internal diagnostic telemetry. - private const string InternalVersionNumber = "2.2.6"; + private const string InternalVersionNumber = "2.2.7"; public bool EnableOperationalTelemetry { diff --git a/ClusterObserver/PackageRoot/Config/Settings.xml b/ClusterObserver/PackageRoot/Config/Settings.xml index 1d68c29a..cb44f382 100644 --- a/ClusterObserver/PackageRoot/Config/Settings.xml +++ b/ClusterObserver/PackageRoot/Config/Settings.xml @@ -2,19 +2,19 @@
+ setting is not greater than 0. --> + then the offending observer will be marked as broken and will not run again. + Below setting represents 60 minutes. --> + ClusterObserver will write to its own directory on this path. + **NOTE: For Linux runtime target, just supply the name of the directory (not a path with drive letter like you for Windows).** --> + will be locally logged. This is the recommended setting. Note that file logging is generally + only useful for FabricObserverWebApi, which is an optional log reader service that ships in this repo. --> @@ -46,27 +46,27 @@
+ The Values for these will be overriden by ApplicationManifest Parameter settings. Set DefaultValue for each + overridable parameter in that file, not here, as the parameter DefaultValues in ApplicationManifest.xml will be used, by default. + This design is to enable unversioned application-parameter-only updates. This means you will be able to change + any of the MustOverride parameters below at runtime by doing an ApplicationUpdate with ApplicationParameters flag. + See: https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-application-upgrade-advanced#upgrade-application-parameters-independently-of-version -->
+ will be locally logged. This is the recommended setting. Note that file logging is generally + only useful for FabricObserverWebApi, which is an optional log reader service that ships in this repo. --> + Aggregated Error evaluations will always be transmitted regardless of this setting. --> + emitting a Warning signal.--> @@ -76,12 +76,13 @@
- + ClusterObserver @@ -21,11 +21,11 @@ - + - + diff --git a/ClusterObserver/Readme.md b/ClusterObserver/Readme.md index fc3908bc..de11e459 100644 --- a/ClusterObserver/Readme.md +++ b/ClusterObserver/Readme.md @@ -1,4 +1,4 @@ -### ClusterObserver 2.2.6 +### ClusterObserver 2.2.7 #### This version - and all subsequent versions - requires SF Runtime >= 9.0 and targets .NET 6 ClusterObserver (CO) is a stateless singleton Service Fabric .NET 6 service that runs on one node in a cluster. CO observes cluster health (aggregated) @@ -30,7 +30,7 @@ Application Parameter Upgrade Example: ```Powershell $appName = "fabric:/ClusterObserver" -$appVersion = "2.2.6" +$appVersion = "2.2.7" $application = Get-ServiceFabricApplication -ApplicationName $appName @@ -161,7 +161,7 @@ Start-ServiceFabricApplicationUpgrade -ApplicationName $appName -ApplicationType ``` XML - + @@ -190,7 +190,7 @@ Start-ServiceFabricApplicationUpgrade -ApplicationName $appName -ApplicationType should match the Name and Version attributes of the ServiceManifest element defined in the ServiceManifest.xml file. --> - + diff --git a/ClusterObserverApp/ApplicationPackageRoot/ApplicationManifest.xml b/ClusterObserverApp/ApplicationPackageRoot/ApplicationManifest.xml index a8b0bf2e..f7b9f90f 100644 --- a/ClusterObserverApp/ApplicationPackageRoot/ApplicationManifest.xml +++ b/ClusterObserverApp/ApplicationPackageRoot/ApplicationManifest.xml @@ -1,5 +1,5 @@  - + @@ -10,7 +10,7 @@ - + @@ -20,15 +20,15 @@ - - + + - + diff --git a/Documentation/Deployment/service-fabric-cluster-observer.json b/Documentation/Deployment/service-fabric-cluster-observer.json index a83e7a43..b05dbab9 100644 --- a/Documentation/Deployment/service-fabric-cluster-observer.json +++ b/Documentation/Deployment/service-fabric-cluster-observer.json @@ -11,7 +11,7 @@ }, "applicationTypeVersionClusterObserver": { "type": "string", - "defaultValue": "2.2.6", + "defaultValue": "2.2.7", "metadata": { "description": "Provide the app version number of ClusterObserver. This must be identical to the version specified in the corresponding sfpkg." } diff --git a/Documentation/Deployment/service-fabric-cluster-observer.v2.2.6.parameters.json b/Documentation/Deployment/service-fabric-cluster-observer.v2.2.7.parameters.json similarity index 90% rename from Documentation/Deployment/service-fabric-cluster-observer.v2.2.6.parameters.json rename to Documentation/Deployment/service-fabric-cluster-observer.v2.2.7.parameters.json index 8693d46c..b0d523c0 100644 --- a/Documentation/Deployment/service-fabric-cluster-observer.v2.2.6.parameters.json +++ b/Documentation/Deployment/service-fabric-cluster-observer.v2.2.7.parameters.json @@ -6,7 +6,7 @@ "value": "" }, "applicationTypeVersionClusterObserver": { - "value": "2.2.6" + "value": "2.2.7" }, "packageUrlClusterObserver": { "value": "" diff --git a/Documentation/Deployment/service-fabric-observer.json b/Documentation/Deployment/service-fabric-observer.json index 83a36658..85dbed8f 100644 --- a/Documentation/Deployment/service-fabric-observer.json +++ b/Documentation/Deployment/service-fabric-observer.json @@ -11,16 +11,16 @@ }, "applicationTypeVersionFabricObserver": { "type": "string", - "defaultValue": "3.2.11", + "defaultValue": "3.2.12", "metadata": { - "description": "Provide the app version number of FabricObserver. This must be identical to the version, 3.2.11, in the referenced sfpkg specified in packageUrlFabricObserver." + "description": "Provide the app version number of FabricObserver. This must be identical to the version, 3.2.12, in the referenced sfpkg specified in packageUrlFabricObserver." } }, "packageUrlFabricObserver": { "type": "string", "defaultValue": "", "metadata": { - "description": "This has to be a public accessible URL for the sfpkg file which contains the FabricObserver app package. Example: https://github.com/microsoft/service-fabric-observer/releases/download/[xxxxxxxx]/Microsoft.ServiceFabricApps.FabricObserver.Windows.SelfContained.3.2.11.sfpkg" + "description": "This has to be a public accessible URL for the sfpkg file which contains the FabricObserver app package. Example: https://github.com/microsoft/service-fabric-observer/releases/download/[xxxxxxxx]/Microsoft.ServiceFabricApps.FabricObserver.Windows.SelfContained.3.2.12.sfpkg" } } }, diff --git a/Documentation/Deployment/service-fabric-observer.v3.2.11.parameters.json b/Documentation/Deployment/service-fabric-observer.v3.2.12.parameters.json similarity index 90% rename from Documentation/Deployment/service-fabric-observer.v3.2.11.parameters.json rename to Documentation/Deployment/service-fabric-observer.v3.2.12.parameters.json index 6e2a4060..8a27a87c 100644 --- a/Documentation/Deployment/service-fabric-observer.v3.2.11.parameters.json +++ b/Documentation/Deployment/service-fabric-observer.v3.2.12.parameters.json @@ -6,7 +6,7 @@ "value": "" }, "applicationTypeVersionFabricObserver": { - "value": "3.2.11" + "value": "3.2.12" }, "packageUrlFabricObserver": { "value": "" diff --git a/Documentation/OperationalTelemetry.md b/Documentation/OperationalTelemetry.md index 68b5a0b0..2659f337 100644 --- a/Documentation/OperationalTelemetry.md +++ b/Documentation/OperationalTelemetry.md @@ -18,7 +18,7 @@ As with most of FabricObserver's application settings, you can also do this with Connect-ServiceFabricCluster ... $appParams = @{ "ObserverManagerEnableOperationalFOTelemetry" = "false"; } -Start-ServiceFabricApplicationUpgrade -ApplicationName fabric:/FabricObserver -ApplicationParameter $appParams -ApplicationTypeVersion 3.2.11 -UnMonitoredAuto +Start-ServiceFabricApplicationUpgrade -ApplicationName fabric:/FabricObserver -ApplicationParameter $appParams -ApplicationTypeVersion 3.2.12 -UnMonitoredAuto ``` @@ -44,7 +44,7 @@ Here is a full example of exactly what is sent in one of these telemetry events, "ClusterId": "00000000-1111-1111-0000-00f00d000d", "ClusterType": "SFRP", "NodeNameHash": "3e83569d4c6aad78083cd081215dafc81e5218556b6a46cb8dd2b183ed0095ad", - "FOVersion": "3.2.11", + "FOVersion": "3.2.12", "HasPlugins": "False", "SFRuntimeVersion":"9.0.1028.9590" "UpTime": "1.00:30:18.8058379", diff --git a/Documentation/Plugins.md b/Documentation/Plugins.md index d5ce627a..b3c4577d 100644 --- a/Documentation/Plugins.md +++ b/Documentation/Plugins.md @@ -52,7 +52,7 @@ You must implement ObserverBase's two abstract functions: } ``` -5. Build your observer project, drop the output dll and *ALL* of its dependencies, both managed and native (this is *very* important), into the Config/Data/Plugins folder in FabricObserver/PackageRoot. +5. Build your observer project, drop the output dll and *ALL* of its dependencies, both managed and native (this is *very* important), into the Data/Plugins folder in FabricObserver/PackageRoot. You can place your plugin dll and all of its dependencies in its own (*same*) folder under the Plugins directory (useful if you have multiple plugins). Again, ALL plugin dll dependencies (and their dependencies, if any) need to live in the *same* folder as the plugin dll. @@ -72,5 +72,5 @@ cd C:\Users\me\source\repos\service-fabric-observer ./Build-FabricObserver ./Build-NugetPackages ``` -The output from the above commands contains FabricObserver platform-specific nupkgs and a nupkg you have to use for plugin authoring named Microsoft.ServiceFabricApps.FabricObserver.Extensibility.3.2.11.nupkg. Nuget packages will be located in +The output from the above commands contains FabricObserver platform-specific nupkgs and a nupkg you have to use for plugin authoring named Microsoft.ServiceFabricApps.FabricObserver.Extensibility.3.2.12.nupkg. Nuget packages will be located in C:\Users\me\source\repos\service-fabric-observer\bin\release\FabricObserver\Nugets. \ No newline at end of file diff --git a/Documentation/Using.md b/Documentation/Using.md index 18303fe2..4c4d1f77 100644 --- a/Documentation/Using.md +++ b/Documentation/Using.md @@ -710,7 +710,7 @@ $appParams = @{ "FabricSystemObserverEnabled" = "true"; "FabricSystemObserverMem Then execute the application upgrade with ```Powershell -Start-ServiceFabricApplicationUpgrade -ApplicationName fabric:/FabricObserver -ApplicationTypeVersion 3.2.11 -ApplicationParameter $appParams -Monitored -FailureAction rollback +Start-ServiceFabricApplicationUpgrade -ApplicationName fabric:/FabricObserver -ApplicationTypeVersion 3.2.12 -ApplicationParameter $appParams -Monitored -FailureAction rollback ``` **Important**: This action will overwrite previous app paramemter changes that were made in an earlier application upgrade, for example. If you want to preserve any earlier changes, then you will need to @@ -718,7 +718,7 @@ supply those parameter values again along with the new ones. You do this in the ```PowerShell $appName = "fabric:/FabricObserver" -$appVersion = "3.2.11" +$appVersion = "3.2.12" $application = Get-ServiceFabricApplication -ApplicationName $appName $appParamCollection = $application.ApplicationParameters $applicationParameterMap = @{} diff --git a/FabricObserver.Extensibility.nuspec.template b/FabricObserver.Extensibility.nuspec.template index 82a7320a..c829ffe8 100644 --- a/FabricObserver.Extensibility.nuspec.template +++ b/FabricObserver.Extensibility.nuspec.template @@ -2,9 +2,11 @@ %PACKAGE_ID% - 3.2.11 + 3.2.12 -Note: This is library is required for observer plugins that target FabricObserver 3.2.11. +Note: This is library is required for observer plugins that target FabricObserver 3.2.12. +- Updated LVID count monitor to support ESE database performance category change in SF 10.x versions. +- Adding a warning health event to inform customer if there is an issue with loading plugins. Microsoft MIT diff --git a/FabricObserver.Extensibility/FabricObserver.Extensibility.csproj b/FabricObserver.Extensibility/FabricObserver.Extensibility.csproj index 660c5d75..e74877f5 100644 --- a/FabricObserver.Extensibility/FabricObserver.Extensibility.csproj +++ b/FabricObserver.Extensibility/FabricObserver.Extensibility.csproj @@ -5,8 +5,8 @@ FabricObserver Copyright © 2023 FabricObserver - 3.2.11 - 3.2.11 + 3.2.12 + 3.2.12 CA1416 diff --git a/FabricObserver.Extensibility/Utilities/ProcessInfo/WindowsProcessInfoProvider.cs b/FabricObserver.Extensibility/Utilities/ProcessInfo/WindowsProcessInfoProvider.cs index af45faed..1ac15418 100644 --- a/FabricObserver.Extensibility/Utilities/ProcessInfo/WindowsProcessInfoProvider.cs +++ b/FabricObserver.Extensibility/Utilities/ProcessInfo/WindowsProcessInfoProvider.cs @@ -25,13 +25,28 @@ public class WindowsProcessInfoProvider : ProcessInfoProvider private const string ProcessCategoryName = "Process"; private const string ProcessMemoryCounterName = "Working Set - Private"; private const string ProcessIDCounterName = "ID Process"; - private const string WinFabDbCategoryName = "Windows Fabric Database"; - private const string LvidCounterName = "Long-Value Maximum LID"; + private const string LVIDCounterName = "Long-Value Maximum LID"; private static readonly object lockObj = new(); - private volatile bool hasWarnedProcessNameLength = false; private static PerformanceCounterCategory performanceCounterCategory = null; + private volatile bool hasWarnedProcessNameLength = false; public readonly static ConcurrentDictionary InstanceNameDictionary = new(); + private static string WinFabDbCategoryName + { + get + { + try + { + return ServiceFabricConfiguration.Instance.FabricVersion.StartsWith("1") ? "MSExchange Database" : "Windows Fabric Database"; + } + catch (ArgumentException ae) + { + ProcessInfoLogger.LogWarning("WinFabDbCategoryName property failure: " + ae.Message); + return null; + } + } + } + private static PerformanceCounterCategory PerfCounterProcessCategory { get @@ -290,7 +305,7 @@ public override double GetProcessKvsLvidsUsagePercentage(string procName, Cancel /* Check to see if the supplied instance (process) exists in the category. */ - if (!PerformanceCounterCategory.InstanceExists(internalProcName, WinFabDbCategoryName)) + if (!string.IsNullOrEmpty(WinFabDbCategoryName) && !PerformanceCounterCategory.InstanceExists(internalProcName, WinFabDbCategoryName)) { return -1; } @@ -302,7 +317,7 @@ The target counter is accessible to processes running as Network User (so, no Un categoryName and counterName are never null (they are const strings). Only two possible exceptions can happen here: IOE and Win32Exception. */ - using PerformanceCounter LvidCounter = new(WinFabDbCategoryName, LvidCounterName, internalProcName, true); + using PerformanceCounter LvidCounter = new(WinFabDbCategoryName, LVIDCounterName, internalProcName, true); float result = LvidCounter.NextValue(); double usedPct = (double)(result * 100) / int.MaxValue; return usedPct; diff --git a/FabricObserver.Extensibility/Utilities/ServiceFabric/FabricClientUtilities.cs b/FabricObserver.Extensibility/Utilities/ServiceFabric/FabricClientUtilities.cs index 994045ef..f274832f 100644 --- a/FabricObserver.Extensibility/Utilities/ServiceFabric/FabricClientUtilities.cs +++ b/FabricObserver.Extensibility/Utilities/ServiceFabric/FabricClientUtilities.cs @@ -1212,7 +1212,8 @@ private async Task RemoveServiceHealthReportsAsync(ServiceHealthState service, b State = HealthState.Ok, NodeName = nodeName, ServiceName = service.ServiceName, - EntityType = EntityType.Service + EntityType = EntityType.Service, + HealthReportTimeToLive = TimeSpan.FromSeconds(1) }; ObserverHealthReporter healthReporter = new(logger); @@ -1264,7 +1265,8 @@ private async Task RemoveApplicationHealthReportsAsync(ApplicationHealthState ap State = HealthState.Ok, NodeName = nodeName, AppName = app.ApplicationName, - EntityType = EntityType.Application + EntityType = EntityType.Application, + HealthReportTimeToLive = TimeSpan.FromSeconds(1) }; ObserverHealthReporter healthReporter = new(logger); @@ -1319,7 +1321,8 @@ private async Task RemoveNodeHealthReportsAsync(IEnumerable nod HealthMessage = $"Clearing existing FabricObserver Health Reports as the service is stopping or starting.", State = HealthState.Ok, NodeName = this.nodeName, - EntityType = EntityType.Machine + EntityType = EntityType.Machine, + HealthReportTimeToLive = TimeSpan.FromSeconds(1) }; ObserverHealthReporter healthReporter = new(logger); diff --git a/FabricObserver.nuspec.template b/FabricObserver.nuspec.template index 968f564a..d6697888 100644 --- a/FabricObserver.nuspec.template +++ b/FabricObserver.nuspec.template @@ -2,12 +2,10 @@ %PACKAGE_ID% - 3.2.11 + 3.2.12 -- Bug fix in OSObserver's Windows Update Automatic Download check. -- Bug fix in Windows dynamic port range detection (rare occurences, but still a bug). -- Memory usage improvement in Github release version check implementation. -- Updated package dependencies. +- ESE LVID count monitor updated to support ESE database performance category change in SF 10.x versions. +- Adding a warning health event to inform customer if there is an issue with loading plugins. Microsoft MIT @@ -16,7 +14,7 @@ icon.png fonuget.md en-US - This package contains the FabricObserver(FO) Application - built for .NET 6.0 and SF Runtime 9.x. FO a highly configurable and extensible resource usage watchdog service that is designed to be run in Azure Service Fabric Windows and Linux clusters. This package contains the entire application and can be used to build .NET Standard 2.0 observer plugins. NOTE: If you want to target .NET 6 for your plugins, then you must use Microsoft.ServiceFabricApps.FabricObserver.Extensibility.3.2.11 nuget package to build them. + This package contains the FabricObserver(FO) Application - built for .NET 6.0 and SF Runtime 9.x. FO a highly configurable and extensible resource usage watchdog service that is designed to be run in Azure Service Fabric Windows and Linux clusters. This package contains the entire application and can be used to build .NET Standard 2.0 observer plugins. NOTE: If you want to target .NET 6 for your plugins, then you must use Microsoft.ServiceFabricApps.FabricObserver.Extensibility.3.2.12 nuget package to build them. diff --git a/FabricObserver.sln b/FabricObserver.sln index 9b318c8a..447d6a31 100644 --- a/FabricObserver.sln +++ b/FabricObserver.sln @@ -36,8 +36,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution SECURITY.md = SECURITY.md Documentation\Deployment\service-fabric-cluster-observer.json = Documentation\Deployment\service-fabric-cluster-observer.json Documentation\Deployment\service-fabric-observer.json = Documentation\Deployment\service-fabric-observer.json - Documentation\Deployment\service-fabric-cluster-observer.v2.2.6.parameters.json = Documentation\Deployment\service-fabric-cluster-observer.v2.2.6.parameters.json - Documentation\Deployment\service-fabric-observer.v3.2.11.parameters.json = Documentation\Deployment\service-fabric-observer.v3.2.11.parameters.json + Documentation\Deployment\service-fabric-cluster-observer.v2.2.7.parameters.json = Documentation\Deployment\service-fabric-cluster-observer.v2.2.7.parameters.json + Documentation\Deployment\service-fabric-observer.v3.2.12.parameters.json = Documentation\Deployment\service-fabric-observer.v3.2.12.parameters.json Documentation\Using.md = Documentation\Using.md EndProjectSection EndProject diff --git a/FabricObserver/FabricObserver.cs b/FabricObserver/FabricObserver.cs index e669e27a..6906356b 100644 --- a/FabricObserver/FabricObserver.cs +++ b/FabricObserver/FabricObserver.cs @@ -11,6 +11,7 @@ using System.Threading; using System.Threading.Tasks; using FabricObserver.Observers; +using FabricObserver.Observers.Utilities; using FabricObserver.Utilities; using McMaster.NETCore.Plugins; using Microsoft.Extensions.DependencyInjection; @@ -24,6 +25,7 @@ namespace FabricObserver internal sealed class FabricObserverService : StatelessService { private ObserverManager observerManager; + private readonly Logger logger; /// /// Initializes a new instance of the type. @@ -31,7 +33,7 @@ internal sealed class FabricObserverService : StatelessService /// StatelessServiceContext instance. public FabricObserverService(StatelessServiceContext context) : base(context) { - + logger = new Logger("FabricObserverService"); } /// @@ -70,7 +72,7 @@ private void ConfigureServices(IServiceCollection services) LoadObserversFromPlugins(services); } - // When deleting a stateless instance (like the FabricObserver instance), the SF runtime will call this override. + // Stateless instance restarted (via Remove-ServiceFabricReplica or RemoveReplicaAsync called *without* ForceRemove flag). // This ensures that any health report that FO created will be cleared. protected override void OnAbort() { @@ -78,9 +80,9 @@ protected override void OnAbort() { observerManager.ShutDownAsync().GetAwaiter().GetResult(); } - catch (Exception e) when (e is AggregateException or ObjectDisposedException) + catch (Exception e) when (e is not OutOfMemoryException) { - + // Don't crash in Abort unless it's OOM.. } base.OnAbort(); @@ -108,10 +110,11 @@ private void LoadObserversFromPlugins(IServiceCollection services) PluginLoader[] pluginLoaders = new PluginLoader[pluginDlls.Length]; Type[] sharedTypes = { typeof(FabricObserverStartupAttribute), typeof(IFabricObserverStartup), typeof(IServiceCollection) }; + string dll = ""; for (int i = 0; i < pluginDlls.Length; ++i) { - string dll = pluginDlls[i]; + dll = pluginDlls[i]; PluginLoader loader = PluginLoader.CreateFromAssemblyFile(dll, sharedTypes, a => a.IsUnloadable = false); pluginLoaders[i] = loader; } @@ -148,8 +151,33 @@ private void LoadObserversFromPlugins(IServiceCollection services) } catch (Exception e) when (e is ArgumentException or BadImageFormatException or IOException) { + if (e is IOException) + { + string error = $"Plugin dll {dll} could not be loaded. {e.Message}"; + HealthReport healthReport = new() + { + AppName = new Uri($"{Context.CodePackageActivationContext.ApplicationName}"), + EmitLogEvent = true, + HealthMessage = error, + EntityType = Observers.Utilities.Telemetry.EntityType.Application, + HealthReportTimeToLive = TimeSpan.FromMinutes(10), + State = System.Fabric.Health.HealthState.Warning, + Property = "FabricObserverPluginLoadError", + SourceId = $"FabricObserverService-{Context.NodeContext.NodeName}", + NodeName = Context.NodeContext.NodeName, + }; + + ObserverHealthReporter observerHealth = new(logger); + observerHealth.ReportHealthToServiceFabric(healthReport); + } + continue; } + catch (Exception e) when (e is not OutOfMemoryException) + { + logger.LogError($"Unhandled exception in FabricObserverService Instance: {e.Message}"); + throw; + } } } } diff --git a/FabricObserver/FabricObserver.csproj b/FabricObserver/FabricObserver.csproj index d5414c77..94aed618 100644 --- a/FabricObserver/FabricObserver.csproj +++ b/FabricObserver/FabricObserver.csproj @@ -11,8 +11,8 @@ True Copyright © 2022 FabricObserver - 3.2.11 - 3.2.11 + 3.2.12 + 3.2.12 true true FabricObserver.Program @@ -31,7 +31,7 @@ - + diff --git a/FabricObserver/Observers/ObserverManager.cs b/FabricObserver/Observers/ObserverManager.cs index 9eed658e..51fbcd08 100644 --- a/FabricObserver/Observers/ObserverManager.cs +++ b/FabricObserver/Observers/ObserverManager.cs @@ -39,6 +39,7 @@ private List Observers get; set; } + private const string LVIDCounterName = "Long-Value Maximum LID"; private readonly string nodeName; private readonly TimeSpan OperationalTelemetryRunInterval = TimeSpan.FromDays(1); private readonly CancellationToken runAsyncToken; @@ -53,7 +54,7 @@ private List Observers private CancellationTokenSource linkedSFRuntimeObserverTokenSource; // Folks often use their own version numbers. This is for internal diagnostic telemetry. - private const string InternalVersionNumber = "3.2.11"; + private const string InternalVersionNumber = "3.2.12"; private static FabricClient FabricClientInstance => FabricClientUtilities.FabricClientSingleton; @@ -404,143 +405,167 @@ public async Task StopObserversAsync(bool isShutdownSignaled = true, bool isConf } } - private async Task ClearHealthReportsAsync(string configUpdateLinux) + public async Task ClearHealthReportsAsync(string configUpdateLinux) { - var healthReport = new HealthReport + HealthReport healthReport = new() { Code = FOErrorWarningCodes.Ok, HealthMessage = $"Clearing existing FabricObserver Health Reports as the service is stopping, starting, or updating.{configUpdateLinux}.", State = HealthState.Ok, - NodeName = nodeName + NodeName = nodeName, + HealthReportTimeToLive = TimeSpan.FromSeconds(1) }; - foreach (var obs in Observers) + foreach (var observer in Observers) { - if (obs.ObserverName == ObserverConstants.AppObserverName || - obs.ObserverName == ObserverConstants.ContainerObserverName || - obs.ObserverName == ObserverConstants.NetworkObserverName) + try { - // Service Health reports. - if (obs.ServiceNames.Any(a => !string.IsNullOrWhiteSpace(a) && a.Contains("fabric:/"))) + if (observer.ObserverName == ObserverConstants.ContainerObserverName) { - foreach (var service in obs.ServiceNames) + ServiceHealth serviceHealth = await FabricClientInstance.HealthManager.GetServiceHealthAsync(FabricServiceContext.ServiceName); + IEnumerable fabricObserverServiceHealthEvents = + serviceHealth.HealthEvents?.Where(s => s.HealthInformation.SourceId.Contains(observer.ObserverName)); + + if (fabricObserverServiceHealthEvents != null && fabricObserverServiceHealthEvents.Any()) { - try + foreach (var evt in fabricObserverServiceHealthEvents) { - // App Health reports. NetworkObserver only generates App health reports and stores app name in ServiceNames field (TODO: Change that). - if (obs.ObserverName == ObserverConstants.NetworkObserverName) + try { - Uri appName = new(service); - var appHealth = await FabricClientInstance.HealthManager.GetApplicationHealthAsync(appName); - var fabricObserverAppHealthEvents = - appHealth?.HealthEvents?.Where(s => s.HealthInformation.SourceId.Contains(obs.ObserverName)); + healthReport.ServiceName = FabricServiceContext.ServiceName; + healthReport.EntityType = EntityType.Service; + healthReport.Property = evt.HealthInformation.Property; + healthReport.SourceId = evt.HealthInformation.SourceId; - if (fabricObserverAppHealthEvents != null && fabricObserverAppHealthEvents.Any()) + var healthReporter = new ObserverHealthReporter(Logger); + healthReporter.ReportHealthToServiceFabric(healthReport); + } + catch (FabricException) + { + + } + } + } + } + else if (observer.ObserverName == ObserverConstants.AppObserverName || observer.ObserverName == ObserverConstants.NetworkObserverName) + { + // Service Health reports. + if (observer.ServiceNames.Any(a => !string.IsNullOrWhiteSpace(a) && a.Contains("fabric:/"))) + { + foreach (var service in observer.ServiceNames) + { + try + { + // App Health reports. NetworkObserver only generates App health reports and stores app name in ServiceNames field (TODO: Change that). + if (observer.ObserverName == ObserverConstants.NetworkObserverName) { - foreach (var evt in fabricObserverAppHealthEvents) - { - try - { - healthReport.AppName = appName; - healthReport.EntityType = EntityType.Application; - healthReport.Property = evt.HealthInformation.Property; - healthReport.SourceId = evt.HealthInformation.SourceId; + Uri appName = new(service); + var appHealth = await FabricClientInstance.HealthManager.GetApplicationHealthAsync(appName); + var fabricObserverAppHealthEvents = + appHealth?.HealthEvents?.Where(s => s.HealthInformation.SourceId.Contains(observer.ObserverName)); - var healthReporter = new ObserverHealthReporter(Logger); - healthReporter.ReportHealthToServiceFabric(healthReport); - } - catch (FabricException) + if (fabricObserverAppHealthEvents != null && fabricObserverAppHealthEvents.Any()) + { + foreach (var evt in fabricObserverAppHealthEvents) { - + try + { + healthReport.AppName = appName; + healthReport.EntityType = EntityType.Application; + healthReport.Property = evt.HealthInformation.Property; + healthReport.SourceId = evt.HealthInformation.SourceId; + + var healthReporter = new ObserverHealthReporter(Logger); + healthReporter.ReportHealthToServiceFabric(healthReport); + } + catch (FabricException) + { + + } } } } - } - else // Service Health reports. - { - Uri serviceName = new(service); - ServiceHealth serviceHealth = await FabricClientInstance.HealthManager.GetServiceHealthAsync(serviceName); - IEnumerable fabricObserverServiceHealthEvents = - serviceHealth.HealthEvents?.Where(s => s.HealthInformation.SourceId.Contains(obs.ObserverName)); - - if (fabricObserverServiceHealthEvents != null && fabricObserverServiceHealthEvents.Any()) + else // Service Health reports. { - foreach (var evt in fabricObserverServiceHealthEvents) - { - try - { - healthReport.ServiceName = serviceName; - healthReport.EntityType = EntityType.Service; - healthReport.Property = evt.HealthInformation.Property; - healthReport.SourceId = evt.HealthInformation.SourceId; + Uri serviceName = new(service); + ServiceHealth serviceHealth = await FabricClientInstance.HealthManager.GetServiceHealthAsync(serviceName); + IEnumerable fabricObserverServiceHealthEvents = + serviceHealth.HealthEvents?.Where(s => s.HealthInformation.SourceId.Contains(observer.ObserverName)); - var healthReporter = new ObserverHealthReporter(Logger); - healthReporter.ReportHealthToServiceFabric(healthReport); - } - catch (FabricException) + if (fabricObserverServiceHealthEvents != null && fabricObserverServiceHealthEvents.Any()) + { + foreach (var evt in fabricObserverServiceHealthEvents) { - + try + { + healthReport.ServiceName = serviceName; + healthReport.EntityType = EntityType.Service; + healthReport.Property = evt.HealthInformation.Property; + healthReport.SourceId = evt.HealthInformation.SourceId; + + var healthReporter = new ObserverHealthReporter(Logger); + healthReporter.ReportHealthToServiceFabric(healthReport); + } + catch (FabricException) + { + + } } } } } - } - catch (Exception e) when (e is FabricException or TimeoutException) - { + catch (Exception e) when (e is FabricException or TimeoutException) + { + } } } } - } - - // FSO Health Reports. - if (obs.ObserverName == ObserverConstants.FabricSystemObserverName) - { - try + // System reports (fabric:/System). + else if (observer.ObserverName == ObserverConstants.FabricSystemObserverName) { - // System app reports. - var sysAppHealth = - await FabricClientInstance.HealthManager.GetApplicationHealthAsync(new Uri(ObserverConstants.SystemAppName)); - var sysAppHealthEvents = sysAppHealth?.HealthEvents?.Where(s => s.HealthInformation.SourceId.Contains(obs.ObserverName)); - - if (sysAppHealthEvents != null && sysAppHealthEvents.Any()) + try { - foreach (var evt in sysAppHealthEvents) + var sysAppHealth = + await FabricClientInstance.HealthManager.GetApplicationHealthAsync(new Uri(ObserverConstants.SystemAppName)); + var sysAppHealthEvents = sysAppHealth?.HealthEvents?.Where(s => s.HealthInformation.SourceId.Contains(observer.ObserverName)); + + if (sysAppHealthEvents != null && sysAppHealthEvents.Any()) { - try + foreach (var evt in sysAppHealthEvents) { - healthReport.AppName = new Uri(ObserverConstants.SystemAppName); - healthReport.Property = evt.HealthInformation.Property; - healthReport.SourceId = evt.HealthInformation.SourceId; - healthReport.EntityType = EntityType.Application; + try + { + healthReport.AppName = new Uri(ObserverConstants.SystemAppName); + healthReport.Property = evt.HealthInformation.Property; + healthReport.SourceId = evt.HealthInformation.SourceId; + healthReport.EntityType = EntityType.Application; - var healthReporter = new ObserverHealthReporter(Logger); - healthReporter.ReportHealthToServiceFabric(healthReport); - } - catch (FabricException) - { + var healthReporter = new ObserverHealthReporter(Logger); + healthReporter.ReportHealthToServiceFabric(healthReport); + } + catch (FabricException) + { + } } } } - } - catch (Exception e) when (e is FabricException or TimeoutException) - { + catch (Exception e) when (e is FabricException or TimeoutException) + { + } } - } - try - { - if (obs.ObserverName == ObserverConstants.CertificateObserverName || - obs.ObserverName == ObserverConstants.DiskObserverName || - obs.ObserverName == ObserverConstants.FabricSystemObserverName || - obs.ObserverName == ObserverConstants.NodeObserverName || - obs.ObserverName == ObserverConstants.OSObserverName) + // Node reports. + if (observer.ObserverName == ObserverConstants.CertificateObserverName || + observer.ObserverName == ObserverConstants.DiskObserverName || + observer.ObserverName == ObserverConstants.FabricSystemObserverName || + observer.ObserverName == ObserverConstants.NodeObserverName || + observer.ObserverName == ObserverConstants.OSObserverName) { - // Node reports. - var nodeHealth = await FabricClientInstance.HealthManager.GetNodeHealthAsync(obs.NodeName); - var fabricObserverNodeHealthEvents = nodeHealth.HealthEvents?.Where(s => s.HealthInformation.SourceId.Contains(obs.ObserverName)); + var nodeHealth = await FabricClientInstance.HealthManager.GetNodeHealthAsync(observer.NodeName); + var fabricObserverNodeHealthEvents = nodeHealth.HealthEvents?.Where(s => s.HealthInformation.SourceId.Contains(observer.ObserverName)); if (fabricObserverNodeHealthEvents != null && fabricObserverNodeHealthEvents.Any()) { @@ -563,13 +588,14 @@ private async Task ClearHealthReportsAsync(string configUpdateLinux) } } } + + // Reset warning/error states. + observer.HasActiveFabricErrorOrWarning = false; } - catch (Exception e) when (e is FabricException or TimeoutException) + catch (Exception e) when (e is not OutOfMemoryException) { } - - obs.HasActiveFabricErrorOrWarning = false; } } @@ -1387,8 +1413,13 @@ private bool IsLVIDPerfCounterEnabled(ConfigurationSettings settings = null) // DEBUG Logger.LogInfo("IsLVIDPerfCounterEnabled: Running check since a supported observer is enabled for LVID monitoring."); - const string categoryName = "Windows Fabric Database"; - const string counterName = "Long-Value Maximum LID"; + string categoryName = "Windows Fabric Database"; + + + if (sfVersion.StartsWith("1")) + { + categoryName = "MSExchange Database"; + } // If there is corrupted state on the machine with respect to performance counters, an AV can occur (in native code, then wrapped in AccessViolationException) // when calling PerformanceCounterCategory.Exists below. This is actually a symptom of a problem that extends beyond just this counter category.. @@ -1397,7 +1428,7 @@ private bool IsLVIDPerfCounterEnabled(ConfigurationSettings settings = null) // cause issues (not FO crashes necessarily, but inaccurate data related to the metrics they represent (like, you will always see 0 or -1 measurement values)). try { - return PerformanceCounterCategory.CounterExists(counterName, categoryName); + return PerformanceCounterCategory.CounterExists(LVIDCounterName, categoryName); } catch (Exception e) when (e is ArgumentException or InvalidOperationException or UnauthorizedAccessException or Win32Exception) { diff --git a/FabricObserver/PackageRoot/Data/Plugins/Readme.txt b/FabricObserver/PackageRoot/Data/Plugins/Readme.txt index 42c8bfef..ea5ce63c 100644 --- a/FabricObserver/PackageRoot/Data/Plugins/Readme.txt +++ b/FabricObserver/PackageRoot/Data/Plugins/Readme.txt @@ -7,8 +7,8 @@ Note that the observer API lives in its own library, FabricObserver.Extensibilit 1. Create a new .NET 6 Library project. 2. Install the same version of the Microsoft.ServiceFabricApps.FabricObserver.Extensibility nupkg from https://www.nuget.org/profiles/ServiceFabricApps as the version of FabricObserver you are deploying. - E.g., 3.2.11 if you are going to deploy FO 3.2.11. - NOTE: You can also consume the entire FabricObserver 3.2.11 nupkg to build your plugin. Please see the SampleObserverPlugin project's csproj file for more information. + E.g., 3.2.12 if you are going to deploy FO 3.2.12. + NOTE: You can also consume the entire FabricObserver 3.2.12 nupkg to build your plugin. Please see the SampleObserverPlugin project's csproj file for more information. 3. Write an observer! @@ -68,5 +68,5 @@ cd C:\Users\me\source\repos\service-fabric-observer ./Build-FabricObserver ./Build-NugetPackages -The output from the above commands contains FabricObserver platform-specific nupkgs and a package you have to use for plugin authoring named Microsoft.ServiceFabricApps.FabricObserver.Extensibility.3.2.11.nupkg. Nupkg files from above command would be located in +The output from the above commands contains FabricObserver platform-specific nupkgs and a package you have to use for plugin authoring named Microsoft.ServiceFabricApps.FabricObserver.Extensibility.3.2.12.nupkg. Nupkg files from above command would be located in C:\Users\me\source\repos\service-fabric-observer\bin\release\FabricObserver\Nugets. \ No newline at end of file diff --git a/FabricObserver/PackageRoot/ServiceManifest.xml b/FabricObserver/PackageRoot/ServiceManifest.xml index 2356f394..09e87d61 100644 --- a/FabricObserver/PackageRoot/ServiceManifest.xml +++ b/FabricObserver/PackageRoot/ServiceManifest.xml @@ -1,6 +1,6 @@  @@ -9,7 +9,7 @@ This name must match the string used in RegisterServiceType call in Program.cs. --> - + install_lvid_perfcounter.bat @@ -25,10 +25,10 @@ - + - + \ No newline at end of file diff --git a/FabricObserver/PackageRoot/ServiceManifest_linux.xml b/FabricObserver/PackageRoot/ServiceManifest_linux.xml index d252968e..65b54348 100644 --- a/FabricObserver/PackageRoot/ServiceManifest_linux.xml +++ b/FabricObserver/PackageRoot/ServiceManifest_linux.xml @@ -1,6 +1,6 @@  @@ -11,7 +11,7 @@ - + setcaps.sh @@ -27,10 +27,10 @@ - + - + \ No newline at end of file diff --git a/FabricObserver/setcaps.sh b/FabricObserver/setcaps.sh index e2bb7b96..d89920e9 100644 --- a/FabricObserver/setcaps.sh +++ b/FabricObserver/setcaps.sh @@ -1,4 +1,6 @@ #!/bin/bash sudo setcap CAP_DAC_READ_SEARCH,CAP_SYS_PTRACE+p ./elevated_netstat sudo setcap CAP_DAC_READ_SEARCH,CAP_SYS_PTRACE+p ./elevated_proc_fd -sudo setcap CAP_DAC_READ_SEARCH,CAP_DAC_OVERRIDE+p ./elevated_docker_stats \ No newline at end of file +sudo setcap CAP_DAC_READ_SEARCH,CAP_DAC_OVERRIDE+p ./elevated_docker_stats + +sudo apt install net-tools \ No newline at end of file diff --git a/FabricObserverApp/ApplicationPackageRoot/ApplicationManifest.xml b/FabricObserverApp/ApplicationPackageRoot/ApplicationManifest.xml index ea47e0a5..96048f7f 100644 --- a/FabricObserverApp/ApplicationPackageRoot/ApplicationManifest.xml +++ b/FabricObserverApp/ApplicationPackageRoot/ApplicationManifest.xml @@ -1,6 +1,6 @@  - + @@ -236,7 +236,7 @@ should match the Name and Version attributes of the ServiceManifest element defined in the ServiceManifest.xml file. --> - + diff --git a/FabricObserverApp/StartupServices.xml b/FabricObserverApp/StartupServices.xml index ee13e966..b03bf8d0 100644 --- a/FabricObserverApp/StartupServices.xml +++ b/FabricObserverApp/StartupServices.xml @@ -1,7 +1,7 @@  - + diff --git a/FabricObserverTests/FabricObserverTests.csproj b/FabricObserverTests/FabricObserverTests.csproj index 337f4f75..b7d3eeaf 100644 --- a/FabricObserverTests/FabricObserverTests.csproj +++ b/FabricObserverTests/FabricObserverTests.csproj @@ -20,7 +20,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/FabricObserverTests/ObserverTests.cs b/FabricObserverTests/ObserverTests.cs index 305b683f..d751b829 100644 --- a/FabricObserverTests/ObserverTests.cs +++ b/FabricObserverTests/ObserverTests.cs @@ -102,6 +102,11 @@ public static async Task TestClassStartUp(TestContext testContext) long.MaxValue); // Install required SF test applications. + await DeployTestAppsAppsAsync(); + } + + private static async Task DeployTestAppsAppsAsync() + { await DeployHealthMetricsAppAsync(); await DeployTestApp42Async(); await DeployVotingAppAsync(); @@ -215,7 +220,6 @@ await FabricClientSingleton.QueryManager.GetDeployedApplicationListAsync( { return; } - string appType = "HealthMetricsType"; string appVersion = "1.0.0.0"; diff --git a/README.md b/README.md index cbef1d96..09a481d5 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -## FabricObserver 3.2.11 +## FabricObserver 3.2.12 [![Deploy to Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2Fmicrosoft%2Fservice-fabric-observer%2Fmain%2FDocumentation%2FDeployment%2Fservice-fabric-observer.json) @@ -87,7 +87,7 @@ see [FOAzurePipeline.yaml](/FOAzurePipeline.yaml) for msazure devops build tasks .net6 installed (if you deploy VM images from Azure gallery, then they will not have .net6 installed), then you must deploy the SelfContained package. ### Deploy FabricObserver -**Note: You must deploy this version (3.2.11) to clusters that are running SF 9.0 and above. This version also requires .NET 6.** +**Note: You must deploy this version (3.2.12) to clusters that are running SF 9.0 and above. This version also requires .NET 6.** You can deploy FabricObserver (and ClusterObserver) using Visual Studio (if you build the sources yourself), PowerShell or ARM. Please note that this version of FabricObserver no longer supports the DefaultServices node in ApplicationManifest.xml. This means that should you deploy using PowerShell, you must create an instance of the service as the last command in your script. This was done to support ARM deployment, specifically. The StartupServices.xml file you see in the FabricHealerApp project now contains the service information once held in ApplicationManifest's DefaultServices node. Note that this information is primarily useful for deploying from Visual Studio. @@ -135,7 +135,7 @@ Register-ServiceFabricApplicationType -ApplicationPathInImageStore FO3211 #Create FO application (if not already deployed at lesser version): -New-ServiceFabricApplication -ApplicationName fabric:/FabricObserver -ApplicationTypeName FabricObserverType -ApplicationTypeVersion 3.2.11 +New-ServiceFabricApplication -ApplicationName fabric:/FabricObserver -ApplicationTypeName FabricObserverType -ApplicationTypeVersion 3.2.12 #Create the Service instances (-1 means all nodes, which is what is required for FO): @@ -143,7 +143,7 @@ New-ServiceFabricService -Stateless -PartitionSchemeSingleton -ApplicationName f #OR if updating existing version: -Start-ServiceFabricApplicationUpgrade -ApplicationName fabric:/FabricObserver -ApplicationTypeVersion 3.2.11 -Monitored -FailureAction rollback +Start-ServiceFabricApplicationUpgrade -ApplicationName fabric:/FabricObserver -ApplicationTypeVersion 3.2.12 -Monitored -FailureAction rollback ``` ## Observer Model diff --git a/SampleObserverPlugin/SampleObserverPlugin.csproj b/SampleObserverPlugin/SampleObserverPlugin.csproj index 6ea3828d..9b87c8af 100644 --- a/SampleObserverPlugin/SampleObserverPlugin.csproj +++ b/SampleObserverPlugin/SampleObserverPlugin.csproj @@ -13,13 +13,13 @@ - - + + - - + - + \ No newline at end of file diff --git a/XmlDiffPatchSF/Program.cs b/XmlDiffPatchSF/Program.cs index 870469ba..07cc0b59 100644 --- a/XmlDiffPatchSF/Program.cs +++ b/XmlDiffPatchSF/Program.cs @@ -28,7 +28,7 @@ private static void Main(string[] args) "preceding the file extension.\n\n" + "**Note, if you have observer plugins, then you must supply true for [mergeExistingNodes] as the last argument to pull over your plugin settings as part of the merge.**.\n\n" + "Example:\n\n" + - "DiffPatchXml \"C:\\repos\\FO\\3.1.26\\configs\\ApplicationManifest.xml\" \"C:\\repos\\FO\\3.2.11\\configs\\ApplicationManifest.xml\"\n"); + "DiffPatchXml \"C:\\repos\\FO\\3.1.26\\configs\\ApplicationManifest.xml\" \"C:\\repos\\FO\\3.2.12\\configs\\ApplicationManifest.xml\"\n"); return; } diff --git a/conuget.md b/conuget.md index ac09fa9a..39a7bdda 100644 --- a/conuget.md +++ b/conuget.md @@ -1,4 +1,4 @@ -### ClusterObserver 2.2.6 +### ClusterObserver 2.2.7 #### This version requires SF Runtime >= 9.0 and targets .NET 6. .NET Core 3.1 is no longer supported. [ClusterObserver (CO)](https://github.com/microsoft/service-fabric-observer/tree/main/ClusterObserver) is a stateless singleton Service Fabric .NET 6 service that runs on one node in a cluster. CO observes cluster health (aggregated) diff --git a/foextlib.md b/foextlib.md index f139fa47..43585505 100644 --- a/foextlib.md +++ b/foextlib.md @@ -1,4 +1,4 @@ -## FabricObserver Extensibility Library 3.2.11 +## FabricObserver Extensibility Library 3.2.12 FabricObserver.Extensibility is a .NET 6 library for building custom observers that extend FabricObserver's capabilities to match your needs. A custom observer is managed just like a built-in observer. diff --git a/fonuget.md b/fonuget.md index 24a548ea..177e6620 100644 --- a/fonuget.md +++ b/fonuget.md @@ -1,4 +1,4 @@ -## FabricObserver 3.2.11 +## FabricObserver 3.2.12 [**FabricObserver (FO)**](https://github.com/microsoft/service-fabric-observer) is a production-ready watchdog service with an easy-to-use extensibility model, written as a stateless, singleton Service Fabric **.NET 6** application that by default