Skip to content

Commit

Permalink
Diagnostics bag (#1807)
Browse files Browse the repository at this point in the history
* Introduce diagnostics events

* add extensions to diagnostics

* Add configurations

* Add config logging
  • Loading branch information
rogeralsing committed Oct 15, 2022
1 parent 155221a commit 6e8f7fe
Show file tree
Hide file tree
Showing 14 changed files with 89 additions and 12 deletions.
7 changes: 7 additions & 0 deletions examples/AspNetGrains/Node2/Program.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using AspNetGrains.Messages;
using Proto;
using Proto.Cluster;
using Proto.Cluster.Seed;
using Proto.Remote;
Expand All @@ -18,4 +19,10 @@

var app = builder.Build();

app.MapGet("/diagnostics", (ActorSystem system) =>
{
var entries = system.Diagnostics.Get();
return entries;
});

app.Run();
2 changes: 2 additions & 0 deletions src/Proto.Actor/ActorSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ public ActorSystem(ActorSystemConfig config)

DeferredFuture =
new Lazy<FutureFactory>(() => new FutureFactory(this, config.SharedFutures, config.SharedFutureSize));

Diagnostics.RegisterObject("ActorSystem", "Config", config);

RunThreadPoolStats();
}
Expand Down
6 changes: 6 additions & 0 deletions src/Proto.Actor/Configuration/ActorSystemConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
using Microsoft.Extensions.Logging;
using Proto.Context;
using Proto.Extensions;
using System.Text.Json;
using System.Text.Json.Serialization;

// ReSharper disable once CheckNamespace
namespace Proto;
Expand Down Expand Up @@ -51,12 +53,14 @@ public record ActorSystemConfig
/// The result from this will be used as the default sender for all requests,
/// except requests overriding the sender context by parameter
/// </summary>
[JsonIgnore]
public Func<RootContext, IRootContext> ConfigureRootContext { get; init; } = context => context;

/// <summary>
/// Allows ActorSystem-wide augmentation of any Props
/// All props are translated via this function
/// </summary>
[JsonIgnore]
public Func<Props, Props> ConfigureProps { get; init; } = props => props;

/// <summary>
Expand All @@ -65,6 +69,7 @@ public record ActorSystemConfig
/// By default, DeadlineDecorator, LoggingContextDecorator are used. Additionally, the supervision strategy is set to
/// AlwaysRestart.
/// </summary>
[JsonIgnore]
public Func<string, Props, Props> ConfigureSystemProps { get; init; } = (_, props) =>
{
var logger = Log.CreateLogger("Proto.SystemActors");
Expand Down Expand Up @@ -103,6 +108,7 @@ public record ActorSystemConfig
/// Function used to serialize actor state to a diagnostics string
/// Can be used together with RemoteDiagnostics to view the state of remote actors
/// </summary>
[JsonIgnore]
public Func<IActor, string> DiagnosticsSerializer { get; set; } = Diagnostics.DiagnosticsSerializer.Serialize;

/// <summary>
Expand Down
32 changes: 30 additions & 2 deletions src/Proto.Actor/Diagnostics/DiagnosticsStore.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using System.Collections.Concurrent;

using System.Text.Json.Serialization;


namespace Proto.Diagnostics;

public class DiagnosticsStore
Expand All @@ -8,7 +11,13 @@ public class DiagnosticsStore

public void RegisterEvent(string module, string message)
{
var entry = new DiagnosticsEntry(module, message);
var entry = new DiagnosticsEntry(module, message, null);
_entries.Add(entry);
}

public void RegisterObject(string module, string key, object data)
{
var entry = new DiagnosticsEntry(module, key, data);
_entries.Add(entry);
}

Expand All @@ -18,4 +27,23 @@ public DiagnosticsEntry[] Get()
}
}

public record DiagnosticsEntry(string Module, string Message);
public record DiagnosticsEntry
{
// ReSharper disable once ConvertToPrimaryConstructor
public DiagnosticsEntry(string module, string? message, object? data)
{
Module = module;
Message = message;
Data = data;
}

public string Module { get; }


[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? Message { get; }


[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public object? Data { get; }
}
1 change: 1 addition & 0 deletions src/Proto.Actor/Proto.Actor.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
<PackageReference Include="System.Collections.Immutable" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.0" />
<PackageReference Include="System.Diagnostics.DiagnosticSource" Version="6.0.0" />
<PackageReference Include="System.Text.Json" Version="6.0.6" />
<PackageReference Include="System.Threading.Channels" Version="6.0.0" />
<PackageReference Update="Microsoft.SourceLink.GitHub" Version="1.1.1" />
<PackageReference Update="JetBrains.Annotations" Version="2022.1.0" />
Expand Down
1 change: 1 addition & 0 deletions src/Proto.Cluster/Cluster.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ private async Task BeginStartAsync(bool client)
InitIdentityProxy();
await this.PubSub().StartAsync();
InitPidCacheTimeouts();
System.Diagnostics.RegisterObject("Cluster","Config", Config);
}

private void InitPidCacheTimeouts()
Expand Down
13 changes: 5 additions & 8 deletions src/Proto.Cluster/ClusterConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System;
using System.Collections.Immutable;
using System.Linq;
using System.Text.Json.Serialization;
using System.Threading;
using JetBrains.Annotations;
using Proto.Cluster.Identity;
Expand Down Expand Up @@ -53,6 +54,7 @@ private ClusterConfig(string clusterName, IClusterProvider clusterProvider, IIde
/// A delegate that returns a <see cref="IMemberStrategy" /> for the given cluster kind.
/// By default, <see cref="SimpleMemberStrategy" /> is used for all cluster kinds.
/// </summary>
[JsonIgnore]
public Func<Cluster, string, IMemberStrategy> MemberStrategyBuilder { get; init; }

/// <summary>
Expand All @@ -69,6 +71,7 @@ private ClusterConfig(string clusterName, IClusterProvider clusterProvider, IIde
/// <summary>
/// <see cref="IClusterProvider" /> to use for the cluster.
/// </summary>
[JsonIgnore]
public IClusterProvider ClusterProvider { get; }

/// <summary>
Expand Down Expand Up @@ -131,6 +134,7 @@ private ClusterConfig(string clusterName, IClusterProvider clusterProvider, IIde
/// <summary>
/// The <see cref="IIdentityLookup" /> to use for the cluster
/// </summary>
[JsonIgnore]
public IIdentityLookup IdentityLookup { get; }

/// <summary>
Expand All @@ -154,6 +158,7 @@ private ClusterConfig(string clusterName, IClusterProvider clusterProvider, IIde
/// Creates the <see cref="IClusterContext" />. The default implementation creates an instance of
/// <see cref="DefaultClusterContext" />
/// </summary>
[JsonIgnore]
public Func<Cluster, IClusterContext> ClusterContextProducer { get; init; } = c => new DefaultClusterContext(c);

/// <summary>
Expand All @@ -168,14 +173,6 @@ private ClusterConfig(string clusterName, IClusterProvider clusterProvider, IIde
/// </summary>
public bool LegacyRequestTimeoutBehavior { get; init; }

/// <summary>
/// Timeout for spawning an actor in the Partition Identity Lookup. Default is 5s.
/// </summary>
/// <param name="timeout"></param>
/// <returns></returns>
[Obsolete("Use ActorActivationTimeout instead")]
public ClusterConfig WithTimeout(TimeSpan timeout) => WithActorActivationTimeout(timeout);

/// <summary>
/// Timeout for single retry of actor request. Default is 5s.
/// Overall timeout for the request is controlled by the cancellation token on
Expand Down
9 changes: 7 additions & 2 deletions src/Proto.Cluster/ClusterKind.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// -----------------------------------------------------------------------

using System;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;
Expand All @@ -27,15 +28,19 @@ public record ClusterKind(string Name, Props Props)
/// <summary>
/// <see cref="IMemberStrategy" /> to be used when placing the actor in the cluster
/// </summary>
public Func<Cluster, IMemberStrategy>? StrategyBuilder { get; init; }
[JsonIgnore] public Func<Cluster, IMemberStrategy>? StrategyBuilder { get; init; }

/// <summary>
/// Optional filter that can prevent spawning identities outside of a certain set of allowed identities.
/// Useful e.g. in cases where actors are spawned as part of REST API call where actor identity is provided by the API
/// user.
/// In this case the system could be protected from DoS attacks by preventing spawning random identities.
/// </summary>
public CanSpawnIdentity? CanSpawnIdentity { get; init; }
[JsonIgnore] public CanSpawnIdentity? CanSpawnIdentity { get; init; }


/// <summary>Props to spawn the virtual actor</summary>
[JsonIgnore] public Props Props { get; init; } = Props;

/// <summary>
/// Sets the <see cref="IMemberStrategy" /> to be used when placing the actor in the cluster
Expand Down
3 changes: 3 additions & 0 deletions src/Proto.Remote/GrpcNet/GrpcNetClientRemote.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ public GrpcNetClientRemote(ActorSystem system, GrpcNetRemoteConfig config)
_config = config;
System.Extensions.Register(this);
System.Extensions.Register(config.Serialization);
System.Diagnostics.RegisterObject("Remote", "Config", Config);
config.Serialization.Init(system);
var channelProvider = new GrpcNetChannelProvider(_config);
_endpointManager = new EndpointManager(System, Config, channelProvider);
}
Expand Down Expand Up @@ -81,6 +83,7 @@ public Task StartAsync()
_logger.LogInformation("Starting Proto.Actor client ({Address})", System.Id);
Started = true;
System.Diagnostics.RegisterEvent("Remote", "Started GrpcNetClient Successfully");
System.Diagnostics.RegisterObject("Cluster", "Config", Config);
return Task.CompletedTask;
}
}
2 changes: 2 additions & 0 deletions src/Proto.Remote/GrpcNet/GrpcNetRemote.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ public Task StartAsync()

Started = true;
System.Diagnostics.RegisterEvent("Remote", "Started GrpcNet Successfully");
System.Diagnostics.RegisterObject("Remote", "Config", Config);
Config.Serialization.Init(System);

return Task.CompletedTask;
}
Expand Down
4 changes: 4 additions & 0 deletions src/Proto.Remote/GrpcNet/GrpcNetRemoteConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json.Serialization;
using Grpc.Net.Client;
using JetBrains.Annotations;
using Microsoft.AspNetCore.Server.Kestrel.Core;
Expand All @@ -28,19 +29,22 @@ protected GrpcNetRemoteConfig(string host, int port) : base(host, port)
/// <summary>
/// Channel options for the gRPC channel
/// </summary>
[JsonIgnore]
public GrpcChannelOptions ChannelOptions { get; init; } = new();

/// <summary>
/// A delegate that performs additional configuration on Kestrel <see cref="ListenOptions" />.
/// If not supplied, the default implementation sets the protocol to HTTP2
/// </summary>
[JsonIgnore]
public Action<ListenOptions>? ConfigureKestrel { get; init; }

/// <summary>
/// A delegate that allows to choose the address for the <see cref="ActorSystem" /> from the list of addresses Kestrel
/// listens on.
/// By default, the first address is used.
/// </summary>
[JsonIgnore]
public Func<IEnumerable<Uri>?, Uri?> UriChooser { get; init; } = uris => uris?.FirstOrDefault();

/// <summary>
Expand Down
2 changes: 2 additions & 0 deletions src/Proto.Remote/GrpcNet/HostedGrpcNetRemote.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ public Task StartAsync()

Started = true;
System.Diagnostics.RegisterEvent("Remote", "Started HostedGrpcNet Successfully");
System.Diagnostics.RegisterObject("Remote", "Config" , Config);
Config.Serialization.Init(System);
return Task.CompletedTask;
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/Proto.Remote/RemoteConfigBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

using System;
using System.Collections.Immutable;
using System.Text.Json.Serialization;
using Grpc.Core;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging;
Expand Down Expand Up @@ -38,12 +39,14 @@ protected RemoteConfigBase(string host, int port)
/// <summary>
/// Known actor kinds that can be spawned remotely
/// </summary>
[JsonIgnore]
public ImmutableDictionary<string, Props> RemoteKinds { get; init; } =
ImmutableDictionary<string, Props>.Empty;

/// <summary>
/// Gets or sets the CallOptions for the gRPC channel.
/// </summary>
[JsonIgnore]
public CallOptions CallOptions { get; init; }

/// <summary>
Expand All @@ -70,11 +73,13 @@ protected RemoteConfigBase(string host, int port)
/// <summary>
/// Endpoint writer options
/// </summary>
[JsonIgnore]
public EndpointWriterOptions EndpointWriterOptions { get; init; } = new();

/// <summary>
/// Serializations system that manages serializers for remote messages.
/// </summary>
[JsonIgnore]
public Serialization Serialization { get; init; } = new();

/// <summary>
Expand Down
14 changes: 14 additions & 0 deletions src/Proto.Remote/Serialization/Serialization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -199,4 +199,18 @@ private struct TypeSerializerItem
public ISerializer Serializer;
public int SerializerId;
}

public void Init(ActorSystem system)
{
foreach (var tl in TypeLookup)
{
system.Diagnostics.RegisterEvent("Serialization", $"Registered Protobuf Type {tl.Key}");
}

foreach (var s in _serializers)
{
system.Diagnostics.RegisterEvent("Serialization",
$"Registered Serializer {s.SerializerId} {s.Serializer.GetType().Name}");
}
}
}

0 comments on commit 6e8f7fe

Please sign in to comment.