Traces and Metrics for Basic Actor Request-Response Scenario
On this page we will take a look at the most simple scenario: two local actors are sending messages to each other.
Code
Here is a code sample we will use:
var pong = Sys.ActorOf<PongActor>("pong");
var ping = Sys.ActorOf(Props.Create(() => new PingActor(pong, TestActor)), "ping");
for (var i = 0; i < 2; ++i)
ping.Tell(Request.Instance);
for (var i = 0; i < 2; ++i)
ExpectMsg<Response>();
class PingActor : ReceiveActor
{
public PingActor(IActorRef pongActor, IActorRef testActor)
{
Receive<Request>(m => pongActor.Tell(Request.Instance));
Receive<Response>(m => testActor.Tell(Response.Instance));
}
}
class PongActor : ReceiveActor
{
public PongActor() => Receive<Request>(m =>
{
// increment custom counter
Context.GetInstrumentation().Monitor.Counter.Increment(new CounterOptions()
{
Name = "requests.count",
Tags = new MetricTags("myTag", "myValue")
});
Context.Sender.Tell(Response.Instance);
});
}
public class Request { public static readonly Request Instance = new Request(); }
public class Response { public static readonly Response Instance = new Response(); }
What will Phobos collect for us in this case?
Metrics
Phobos will automatically collect some metrics available in this sample:
akka.actor.created
counter - how many actors of given type were created at that moment?akka.messages.recv
meters - how many messages of given type arrived into actor's mailboxes?
Also, there is a tone of ways to collect your own metrics - see App.Metrics for details.
Here we are just incrementing custom requests.count
counter.
Context: Akka.NET
Counters
Name | Tags | Value |
---|---|---|
akka.actor.created | actortype: Phobos.Actor.End2End.Tests.Standalone.RequestResponseSpec+PingActor | 1 |
akka.actor.created | actortype: Phobos.Actor.End2End.Tests.Standalone.RequestResponseSpec+PongActor | 1 |
Meters
Name | Tags | Value |
---|---|---|
akka.messages.recv | actortype: Phobos.Actor.End2End.Tests.Standalone.RequestResponseSpec+PingActor messagetype: Phobos.Actor.End2End.Tests.Standalone.RequestResponseSpec+Request |
2 |
akka.messages.recv | actortype: Phobos.Actor.End2End.Tests.Standalone.RequestResponseSpec+PingActor messagetype: Phobos.Actor.End2End.Tests.Standalone.RequestResponseSpec+Response |
2 |
akka.messages.recv | actortype: Phobos.Actor.End2End.Tests.Standalone.RequestResponseSpec+PongActor messagetype: Phobos.Actor.End2End.Tests.Standalone.RequestResponseSpec+Request |
2 |
Context: Test
Counters
Name | Tags | Value |
---|---|---|
requests.count | myTag: myValue | 2 |
Traces
Phobos will also keep track of actor's communication, using Open Tracing to represent message flow.
Here is how one of two collected traces will look like:
sequenceDiagram
sys/.../testActor->>/user/ping: akka.msg.recv Request
Note over sys/.../testActor,/user/ping: SpanIndex: 0
ParentIndex: none
Tags:
akka.actor.recv.msgType:
Phobos.Actor.End2End.Tests.Standalone.RequestResponseSpec+Request
Logs:
message:
Phobos.Actor.End2End.Tests.Standalone.RequestResponseSpec+Request
/user/ping->>/user/pong: akka.msg.recv Request Note over /user/ping,/user/pong: SpanIndex: 1
ParentIndex: 0
Tags:
akka.actor.recv.msgType:
Phobos.Actor.End2End.Tests.Standalone.RequestResponseSpec+Request
References:
child_of: SpanIndex=0
Logs:
message:
Phobos.Actor.End2End.Tests.Standalone.RequestResponseSpec+Request
/user/pong->>/user/ping: akka.msg.recv Response Note over /user/pong,/user/ping: SpanIndex: 2
ParentIndex: 1
Tags:
akka.actor.recv.msgType:
Phobos.Actor.End2End.Tests.Standalone.RequestResponseSpec+Response
References:
child_of: SpanIndex=1
Logs:
message:
Phobos.Actor.End2End.Tests.Standalone.RequestResponseSpec+Response
ParentIndex: none
Tags:
akka.actor.recv.msgType:
Phobos.Actor.End2End.Tests.Standalone.RequestResponseSpec+Request
Logs:
message:
Phobos.Actor.End2End.Tests.Standalone.RequestResponseSpec+Request
/user/ping->>/user/pong: akka.msg.recv Request Note over /user/ping,/user/pong: SpanIndex: 1
ParentIndex: 0
Tags:
akka.actor.recv.msgType:
Phobos.Actor.End2End.Tests.Standalone.RequestResponseSpec+Request
References:
child_of: SpanIndex=0
Logs:
message:
Phobos.Actor.End2End.Tests.Standalone.RequestResponseSpec+Request
/user/pong->>/user/ping: akka.msg.recv Response Note over /user/pong,/user/ping: SpanIndex: 2
ParentIndex: 1
Tags:
akka.actor.recv.msgType:
Phobos.Actor.End2End.Tests.Standalone.RequestResponseSpec+Response
References:
child_of: SpanIndex=1
Logs:
message:
Phobos.Actor.End2End.Tests.Standalone.RequestResponseSpec+Response
Here we can see that:
- Test actor is sending a message of type
Request
to ourPing
actor Ping
actor is sendingRequest
toPong
. Note that this two spans are connected (child_of
relation), which puts them into single tracePong
actor is replying back withResponse
message
We have all this exported into your favourite tracing / metrics collection system out of the box!