Show / Hide Table of Contents

    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

    Here we can see that:

    1. Test actor is sending a message of type Request to our Ping actor
    2. Ping actor is sending Request to Pong. Note that this two spans are connected (child_of relation), which puts them into single trace
    3. Pong actor is replying back with Response message

    We have all this exported into your favourite tracing / metrics collection system out of the box!

    Back to top Generated by DocFX