Skip to content

Commit 8f6fd89

Browse files
authored
Diagnostics provider interface (#1819)
* Introduce IDiagnosticsProvider.cs * Introduce IDiagnosticsProvider support to IdentityLookup and ClusterProvider
1 parent 3fc0c1f commit 8f6fd89

File tree

11 files changed

+69
-36
lines changed

11 files changed

+69
-36
lines changed

src/Proto.Actor/ActorSystem.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public ActorSystem(ActorSystemConfig config)
5252
new Lazy<FutureFactory>(() => new FutureFactory(this, config.SharedFutures, config.SharedFutureSize));
5353

5454
Diagnostics.RegisterObject("ActorSystem", "Config", config);
55-
55+
Diagnostics.RegisterObject("ActorSystem", "Id", Id);
5656
RunThreadPoolStats();
5757
}
5858

@@ -194,7 +194,7 @@ public Task ShutdownAsync(string reason = "")
194194
{
195195
_logger.LogInformation("Shutting down actor system {Id} - Reason {Reason}", Id, reason);
196196
Stopper.Stop(reason);
197-
Diagnostics.RegisterEvent("ActorSystem", $"Stopped: {reason}");
197+
Diagnostics.RegisterObject("ActorSystem", "Stopped", reason);
198198
}
199199
catch
200200
{
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using System.Text.Json.Serialization;
2+
using JetBrains.Annotations;
3+
4+
namespace Proto.Diagnostics;
5+
6+
[PublicAPI]
7+
public record DiagnosticsEntry
8+
{
9+
// ReSharper disable once ConvertToPrimaryConstructor
10+
public DiagnosticsEntry(string module, string? message, object? data)
11+
{
12+
Module = module;
13+
Message = message;
14+
Data = data;
15+
}
16+
17+
public string Module { get; }
18+
19+
20+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
21+
public string? Message { get; }
22+
23+
24+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
25+
public object? Data { get; }
26+
}

src/Proto.Actor/Diagnostics/DiagnosticsStore.cs

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4-
using System.Text.Json.Serialization;
54
using System.Threading;
65
using System.Threading.Tasks;
76
using Microsoft.Extensions.Logging;
@@ -81,25 +80,4 @@ public async Task<DiagnosticsEntry[]> GetDiagnostics()
8180

8281
return entries.ToArray();
8382
}
84-
}
85-
86-
public record DiagnosticsEntry
87-
{
88-
// ReSharper disable once ConvertToPrimaryConstructor
89-
public DiagnosticsEntry(string module, string? message, object? data)
90-
{
91-
Module = module;
92-
Message = message;
93-
Data = data;
94-
}
95-
96-
public string Module { get; }
97-
98-
99-
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
100-
public string? Message { get; }
101-
102-
103-
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
104-
public object? Data { get; }
105-
}
83+
}

src/Proto.Actor/Diagnostics/IActorDiagnostics.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
namespace Proto.Diagnostics;
88

99
/// <summary>
10-
/// Adds the ability to return a diagnostic string for an actor
10+
/// Adds the ability to return a diagnostic string for an actor instance
1111
/// </summary>
1212
public interface IActorDiagnostics
1313
{
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
using JetBrains.Annotations;
4+
5+
namespace Proto.Diagnostics;
6+
7+
[PublicAPI]
8+
public interface IDiagnosticsProvider
9+
{
10+
Task<DiagnosticsEntry[]> GetDiagnostics() => Task.FromResult(Array.Empty<DiagnosticsEntry>());
11+
}

src/Proto.Actor/Diagnostics/IDiagnosticsTypeName.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
namespace Proto.Diagnostics;
22

3+
/// <summary>
4+
/// This interface allows specific message types to override what typename is returned for tracing and metrics.
5+
/// e.g. MessageEnvelope can return the name of the inner message type instead of its own type name
6+
/// </summary>
37
public interface IDiagnosticsTypeName
48
{
59
string GetTypeName();

src/Proto.Actor/Extensions/IActorSystemExtension.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,11 @@ namespace Proto.Extensions;
1414
/// <summary>
1515
/// Marks a class as an actor system extension
1616
/// </summary>
17-
public interface IActorSystemExtension
17+
public interface IActorSystemExtension : IDiagnosticsProvider
1818
{
1919
private static int _nextId;
2020

2121
internal static int GetNextId() => Interlocked.Increment(ref _nextId);
22-
Task<DiagnosticsEntry[]> GetDiagnostics() => Task.FromResult(Array.Empty<DiagnosticsEntry>());
2322
}
2423

2524
/// <summary>

src/Proto.Cluster/Cluster.cs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,32 @@ public class Cluster : IActorSystemExtension<Cluster>
3838

3939
public async Task<DiagnosticsEntry[]> GetDiagnostics()
4040
{
41-
var now = new DiagnosticsEntry("Cluster", $"Local Time", DateTimeOffset.UtcNow);
42-
var blocked = new DiagnosticsEntry("Cluster", "Blocked", System.Remote().BlockList.BlockedMembers.ToArray());
41+
var res = new List<DiagnosticsEntry>();
4342

43+
var now = new DiagnosticsEntry("Cluster", "Local Time", DateTimeOffset.UtcNow);
44+
res.Add(now);
45+
46+
var blocked = new DiagnosticsEntry("Cluster", "Blocked", System.Remote().BlockList.BlockedMembers.ToArray());
47+
res.Add(blocked);
48+
4449
var t = await Gossip.GetState<ClusterTopology>(GossipKeys.Topology);
4550

4651
var topology = new DiagnosticsEntry("Cluster", "Topology", t);
52+
res.Add(topology);
4753

4854
var h = await Gossip.GetStateEntry(GossipKeys.Heartbeat);
4955
var heartbeats = h.Select(heartbeat => new DiagnosticsMemberHeartbeat(heartbeat.Key, heartbeat.Value.Value.Unpack<MemberHeartbeat>(), heartbeat.Value.LocalTimestamp)).ToArray();
5056

5157
var heartbeat = new DiagnosticsEntry("Cluster", "Heartbeat", heartbeats);
58+
res.Add(heartbeat);
59+
60+
var idlookup = await IdentityLookup.GetDiagnostics();
61+
res.AddRange(idlookup);
62+
63+
var provider = await Provider.GetDiagnostics();
64+
res.AddRange(provider);
5265

53-
return new[] { now, blocked, topology, heartbeat };
66+
return res.ToArray();
5467
}
5568

5669
public Cluster(ActorSystem system, ClusterConfig config)

src/Proto.Cluster/IClusterProvider.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
using System.Threading.Tasks;
88
using JetBrains.Annotations;
9+
using Proto.Diagnostics;
910

1011
namespace Proto.Cluster;
1112

@@ -14,7 +15,7 @@ namespace Proto.Cluster;
1415
/// The cluster provider updates the <see cref="MemberList" />
1516
/// </summary>
1617
[PublicAPI]
17-
public interface IClusterProvider
18+
public interface IClusterProvider : IDiagnosticsProvider
1819
{
1920
/// <summary>
2021
/// Starts the cluster provider

src/Proto.Cluster/Identity/IIdentityLookup.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@
66

77
using System.Threading;
88
using System.Threading.Tasks;
9+
using Proto.Diagnostics;
910

1011
namespace Proto.Cluster.Identity;
1112

1213
/// <summary>
1314
/// Identity lookup is used to activate and locate virtual actor activations in the cluster.
1415
/// See <a href="https://proto.actor/docs/cluster/identity-lookup-net/">Identity Lookup docs</a> for more details.
1516
/// </summary>
16-
public interface IIdentityLookup
17+
public interface IIdentityLookup : IDiagnosticsProvider
1718
{
1819
/// <summary>
1920
/// Activates or locates a virtual actor in the cluster.

0 commit comments

Comments
 (0)