Show / Hide Table of Contents

    Trace Filtering

    One of the best practices for working with Phobos in high throughput Akka.NET systems is to use Phobos.Tracing's filtering capabilities to help reduce noise collected inside the tracing system. This article explains how to use those filtering capabilities.

    A quick introducing to trace filtering by way of example:

    
        var config = @"
        akka.actor.provider = ""Phobos.Actor.PhobosActorRefProvider,Phobos.Actor""
        
        phobos.tracing{
            provider-type = test
            filter{
                mode = blacklist
                message-types = [
                    ""Phobos.Docs.Samples.Tests.Tracing.IFilteredMessage, Phobos.Docs.Samples.Tests""
                ]
            }
        }
    ";
    
        sys = ActorSystem.Create("PhobosTest", config);
        var tracer = (MockTracer) ActorTracing.For(sys).Tracer;
        var actor = sys.ActorOf(Props.Create(() => new EchoActor()), "echo");
    
        // send a message that WON'T be filtered out by blacklist
        actor.Ask<NormalMessage>(new NormalMessage("hi"), TimeSpan.FromMilliseconds(100)).Wait();
        AwaitAssert(() => tracer.FinishedSpans().Count.Should().Be(1)); // no trace recorded
        tracer.Reset(); // reset the MockTracer 
    
        // send a message that WILL be filtered out by blacklist
        actor.Ask<FilteredMessage>(new FilteredMessage("bye"), TimeSpan.FromMilliseconds(100)).Wait();
        Task.Delay(100).Wait(); // wait for activity in other threads to stop
        tracer.FinishedSpans().Count.Should().Be(0);
    
    

    In the sample above, Phobos uses a blacklist filter by default to exclude all messages that implement the interface Phobos.Docs.Samples.Tests.Tracing.IFilteredMessage from any new or ongoing traces inside Phobos. The assertions included in the code sample validate that messages which do not implement this interface, such as a System.String, will be received by the actor and a trace will be recorded.

    This is the gist of how trace filtering works: trace the interesting messages and don't bother tracing the rest.

    If you need to learn more about how to configure Phobos.Tracing and the filter system, please see the Phobos.Actor configuration settings.

    Filtering Modes

    Phobos.Tracing exposes two different methods for filtering data inside your Akka.NET applications:

    • Blacklist filtering - this means that the tracing system excludes any messages which appear on this list. Any messages that don't appear on the blacklist are included in the trace.
    • Whitelist filtering - this means that the tracing system ONLY STARTS NEW TRACES when a message type that appears on this list is received. From that point onward, any other messages downstream in the trace will also be included in the trace, but only the message types that appear on this list can cause a new trace to start.

    Matching Message Types

    An important note about how the message-types setting works in Phobos: in addition to matching message types exactly the filter will also include or exclude types that are assignable from the specified types on this list.

    For instance, if you include IEnumerable<string> in the message-types list for a whitelist filter then any messages of type List<string> or HashSet<string> would also be included in the whitelist. This design is intentional and it's intended to make it easier for developers to target broad categories of messages that implement specific interfaces or base classes.

    Whitelist Filtering

    Whitelist filtering is primarily used for noise reduction inside busy Akka.NET applications, designed ensure that only specific message types can start a trace. Once a trace is started with whitelist filtering, however, all subsequent messages originating from the initially traced message will be included in the trace going forward.

    
                    var config = @"
    akka.actor.provider = ""Phobos.Actor.PhobosActorRefProvider,Phobos.Actor""
    akka.actor.deployment {
        /echo1 {
            phobos{
                # all children of echo1 will use the same filtering settings
                propagate-settings-to-children = on
                tracing.filter{
                    mode = whitelist
                    message-types = [
                        ""System.String""
                    ]
                }
            }
        }
    }                
    
    phobos.tracing{
        provider-type = test
    }";
    
                    sys = ActorSystem.Create("PhobosTest", config);
                    var tracer = (MockTracer) ActorTracing.For(sys).Tracer;
                    var actorWithFiltering = sys.ActorOf(Props.Create(() => new EchoActor()), "echo1");
                    var actorWithoutFiltering = sys.ActorOf(Props.Create(() => new EchoActor()), "echo2");
    
    // send a message that will be filtered out by whitelist for echo1
                    actorWithFiltering.Ask<NormalMessage>(new NormalMessage("hi"), TimeSpan.FromMilliseconds(100)).Wait();
                    Task.Delay(100).Wait(); // wait for activity in other threads to stop
                    tracer.FinishedSpans().Count.Should().Be(0); // no trace recorded
    
    // send the same message to echo2
                    actorWithoutFiltering.Ask<NormalMessage>(new NormalMessage("hi"), TimeSpan.FromMilliseconds(100))
                        .Wait();
                    AwaitAssert(() => tracer.FinishedSpans().Count.Should().Be(1)); // trace gets recorded
    
                    tracer.Reset(); // reset the MockTracer
    
    // send a message to echo1 that won't be filtered out by whitelist
                    actorWithFiltering.Ask<string>("bye", TimeSpan.FromMilliseconds(100)).Wait();
                    AwaitAssert(() => tracer.FinishedSpans().Count.Should().Be(1));
    
    

    In the example above, the /user/echo1 actor is able to use its own whitelist filter to only trigger new traces whenever it receives a message of type System.String. The rest of the ActorSystem will continue to use whatever the global filtering settings are, if any, but this actor and all of its children will use this custom whitelist since /user/echo1 was deployed with the phobos.propagate-settings-to-children option enabled.

    Blacklist Filtering

    Blacklist filtering is primarily used for breaking up large traces into smaller ones, by treating specific types of messages as "terminating" events for the trace. Phobos uses this, internally, to break apart large Akka.Streams graph-processing into a series of smaller streams that are easier to digest.

    
                    var config = @"
    akka.actor.provider = ""Phobos.Actor.PhobosActorRefProvider,Phobos.Actor""
    akka.actor.deployment {
        /echo1 {
            phobos{
                # all children of echo1 will use the same filtering settings
                propagate-settings-to-children = on
                tracing.filter{
                    mode = blacklist
                    message-types = [
                        ""System.String""
                    ]
                }
            }
        }
    }                
    
    phobos.tracing{
        provider-type = test
    }";
    
                    sys = ActorSystem.Create("PhobosTest", config);
                    var tracer = (MockTracer) ActorTracing.For(sys).Tracer;
                    var actorWithFiltering = sys.ActorOf(Props.Create(() => new EchoActor()), "echo1");
                    var actorWithoutFiltering = sys.ActorOf(Props.Create(() => new EchoActor()), "echo2");
    
    // send a message that will be filtered out by blacklist for echo1
                    actorWithFiltering.Ask<string>("hi", TimeSpan.FromMilliseconds(100)).Wait();
                    Task.Delay(100).Wait(); // wait for activity in other threads to stop
                    tracer.FinishedSpans().Count.Should().Be(0); // no trace recorded
    
    // send the same message to echo2
                    actorWithoutFiltering.Ask<string>("hi", TimeSpan.FromMilliseconds(100)).Wait();
                    AwaitAssert(() => tracer.FinishedSpans().Count.Should().Be(1)); // trace gets recorded
    
                    tracer.Reset(); // reset the MockTracer
    
    // send a message to echo1 that won't be filtered out by blacklist
                    actorWithFiltering.Ask<NormalMessage>(new NormalMessage("bye"), TimeSpan.FromMilliseconds(100)).Wait();
                    AwaitAssert(() => tracer.FinishedSpans().Count.Should().Be(1));
    
    

    In the example above, the /user/echo1 actor is able to use its own blacklist filter to exclude any messages of type System.String from all traces, whether they're ongoing or not. The rest of the ActorSystem will continue to use whatever the global filtering settings are, if any, but this actor and all of its children will use this custom blacklist since /user/echo1 was deployed with the phobos.propagate-settings-to-children option enabled.

    Back to top Copyright © 2015-2018 Petabridge®