all Technical posts

Announcing Arcus Observability

Empower your applications with a variety of observability essentials to run operable platforms.

While building applications it’s important that you ensure the applications give enough insight on what is going on and provide enough information to make diagnoses if any issues arise. As we all know, this is not a trivial thing to do.

Over the past couple of years, we’ve seen more and more focus on that front and decided to bring some of that experience to Arcus as we believe everybody benefits from it!

We are happy to announce that we are introducing Arcus Observability. This allows you to empower your applications with a variety of essential features to run operable platforms.

  • Go beyond traces, use most suited telemetry types.
  • Correlate your telemetry out-of-the-box.
  • Empower your telemetry with automatic enrichment and contextual information.
  • Support for structured logging.

Extend instead of reinvent

There are a variety of libraries out in the wild which try to fix one or more of the goals we have but we’ve decided not to go that route, and instead decided to heavily invest in extending what is already in the community.

That’s why we have:

  • Make Microsoft logging functionality more powerful by extending ILogger
  • Build on top of Serilog, a powerful framework that allows you to write telemetry once and flow it to a variety of sinks

While we mainly use application insights and plain logs (containers 👋) on our projects, we want to be open for any platform and that’s why we believe Serilog is the best fit.

We took it a step further by not only building on top of Serilog but also extending Serilogs Application Insight sink to support all telemetry types.

Once our library is more stable we will collaborate with the owners to see if we can contribute some of it more upstream.

Take a look at what it has to offer.

Writing different types of telemetry

Our Arcus.Observability.Telemetry.Core package provides a whole bunch of extensions on the ILogger type that makes it a piece of cake to write a variety of telemetry types that fit your needs.

By using Arcus Observability; you can write custom events, requests, dependencies, and (multi-dimensional) metrics in your applications and we’ll nicely output them with structured logging!

You can very easily write a custom/business event as following:

For more examples about the other types, have a look at our documentation.

Making it easier to provide contextual information

Providing context around your telemetry is super powerful. You not only provide information about what happened but also give more information about the why.

Let’s use an example – when measuring a metric you get an understanding of the count, in our case the number of orders received:

If we output this to Azure Application Insights as a metric similar to our example:

However, you can very easily provide additional context, allowing you to get an understanding of the number of orders received and annotate it with the vendor information.

The outputted telemetry will contain that information and depending on the sink that you are using it’s even going to be more powerful.

For example, when using Azure Application Insights your metric will evolve from a single-dimensional metric to multi-dimensional metrics allowing you to get the total number of orders, get the number of orders per vendor or filter the metric to one specific vendor.

Here we are using our multi-dimensional metric and splitting it per customer to get more detailed insights:

Making it easier to measure dependencies

For dependency telemetry, we provide an easy way to measure the duration of actions by using DependencyMeasurement.

You can simply start a new measurement and pass that information to our extension:

By measuring your dependencies you will gain insights on what is going on and be able to pinpoint issues over time. Depending on the telemetry sink that you are using this will even become more powerful.

When using Azure Application Insights, it will automatically start drawing your Application Map giving you insights of the general performance of all your components.

Every circle represents a “Component” and if you use our Application enricher we will use the name for them that you provide. (more on this later in the post)

Source: “Application Map: Triage Distributed Applications”

As you provide more dependency information for all your components you’ll start to build living documentation of your Azure landscape of how every piece works together:

Source: “Application Map: Triage Distributed Applications”

We’ve seen that, when done right, Application Map is super powerful and an essential tool in your operational tool belt to monitor but also more easily onboard new people as they’ll easily grasp how all components work together.

A conventional way to correlate

With our Arcus.Observability.Correlation package we provide a convenient way to correlate all telemetry in your applications.

It provides a minimal model called CorrelationInfo which uses correlation on two levels:

  • Transaction Id – ID that relates different requests together into a functional transaction.
  • Operation Id – Unique ID information for a single request.

Here is what it looks like in an example:

The correlation info can be accessed throughout the application via an ICorrelationInfoAccessor implementation. We are using this under the hood for our correlation Serilog enricher which automatically adds this information to your telemetry as well.

Laying the foundation for other components and apps

The purpose of our correlation is to provide a basic setup in the most general way but what it doesn’t include is how this correlation is initially retrieved because this is application-specific. It’s up to the consumer to call the ICorrelationInfoAccessor.SetCorrelation at the right moment.

For example, in Arcus Web API we use a HttpCorrelationInfoAccessor under the hood that uses the HTTP request features to access this correlation information for each incoming HTTP request. This will then be used to automatically correlate all telemetry in the application back to the individual request that was made.

While in Arcus Messaging we will even take it a step further and provide a 3rd level of correlation – Message Processing Cycle Id. This is a unique identifier that will be assigned to every attempt when processing an inbound message.

This allows you to scope the telemetry to just a given processing attempt, which helps you troubleshoot poison messages or transient issues.

For more information on how the correlation in this library can be configured and how customization can be done, see the docs.

Boosted serilog functionality

To improve writing telemetry information via Serilog, we have added some extra functionality.

Let’s have a closer look.

Enrichment

The Arcus.Observability.Telemetry.Serilog.Enrichers package provides several Serilog Enrichers to automatically add information to your telemetry:

  • Application enricher adds a ComponentName to the logs which can be used for dependency tracking in Application Insights.
  • Correlation enricher adds the correlation information based on ICorrelationInfoAccessor.
  • Kubernetes enricher adds machine information of the environment related to Kubernetes.
  • Version enricher adds the current runtime assembly version of the product.

By using these, you don’t have to specify them every time you write telemetry – we’ve got this.

For more information, see docs.

Sinking to Application Insights

As mentioned before, we decided to extend the official Azure Application Insights sink with a lot more functionality.

Our Serilog sink is available in Arcus.Observability.Telemetry.Serilog.Sinks.ApplicationInsights package and provides even better integration with Azure Application Insights on top of the official one:

  • When using our new ILogger extensions, we will report telemetry using Application Insights native telemetry types (events, metrics, requests, dependencies)
    • Traces were already supported out-of-the-box
  • Correlation information is automatically annotated on Application Insights telemetry to be fully optimized
  • Automatically provide cloud context by assigning role name & instance information to provide better integration with application map
    • For this to work properly, we highly suggest using our application enricher as this is based on ComponentName information

Following example shows how this sink can be configured in your Serilog setup:

For more information, see docs.

Filtering

When writing to a lot of telemetry, some telemetry types can be filtered-out using the available Serilog filter.

This allows you to use the different flavors of telemetry types according to your needs and use filters to reduce the information stream to your sinks based on configuration.

You can get started by using our Arcus.Observability.Telemetry.Serilog.Filters package.

The following example shows how telemetry events can be filtered out:

You can use this for all Serilog telemetry sinks, not just Azure Application Insights. For more information, see docs.

Roadmap

While we have introduced a lot of powerful features in this first release, we have a lot of ideas on making it even more powerful!

We want to:

  • Provide more dependency types out-of-the-box, making it easier for you to provide the data and we’ll make sure it’s optimized for systems such as Azure Application Insights (list of upcoming types)
  • Provide native support for cross-component correlation allowing you to have more powerful information and optimized Azure Application Insights App Map.
  • Integrating observability in all Arcus components such as Web API, Messaging, Templates, Background Jobs, etc.
  • Improve our documentation

What do you like to see in Arcus Observability? Let us know on GitHub!

Thanks for reading,

Stijn & Tom

Subscribe to our RSS feed