Skip to content
Dynamic Telemetry is a PROPOSAL : please provide feedback! :-)

Dynamic Telemetry is not an implementation, it's a request for collaboration, that will lead to an shared understanding, and hopefully one or more implementations.

Your feedback and suggestions on this document are highly encouraged!

Please:

  1. Join us, by providing comments or feedback, in our Discussions page

  2. Submit a PR with changes to this file ( docs/Architecture.Components.Processor.QueryLanguage.document.md)

Direct Sharing URL

http://microsoft.github.io/DynamicTelemetry/docs/Architecture.Components.Processor.QueryLanguage.document/

Processor : Query Language

The Query Language Processor is one of the most straightforward available. It presents minimal risk while still providing valuable capabilities for dynamic modeling and system understanding. The query language Processor can be likened to command line tools found on all operating systems, which manipulate standard IO subsystems.

Introduction to Query Language Processor

The query language Processor integrates into the logging stream, monitoring events by applying straightforward query language filtering and aggregate functions. Unlike other Processors within dynamic telemetry, the query language Processor is designed solely for filtering and aggregating data. It does not enable the invocation of actions, which significantly reduces its associated risks in the risk taxonomy.

Simple Code Example; hashing files

public string HashFile(string imageName)
{
    try
    {
        // 1. Log the start of the hashing process
        LogStartingFileHash(m_logger, imageName);

        // 2. Open the file and hash it
        using (FileStream fileStream = File.OpenRead(imageName))
        {
            string hashValue = Convert.ToBase64String(m_SHA256.ComputeHash(fileStream));

            // 3. Log the end of the hashing process
            LogEndFileHash(m_logger, imageName, hashValue);
            return hashValue;
        }
    }
    catch (Exception e)
    {
        // Log any exceptions that occur
        ErrorHashing(m_logger, imageName, e);
        throw;
    }
}

[LoggerMessage(Level = LogLevel.Information, Message = "Starting FileHash {fileName}.")]
static partial void LogStartingFileHash(ILogger logger, string fileName);

[LoggerMessage(Level = LogLevel.Information, Message = "Ending FileHash {fileName}, hash={hashValue}.")]
static partial void LogEndFileHash(ILogger logger, string fileName, string hashValue);

[LoggerMessage(Level = LogLevel.Warning, Message = "Unable to hash image {fileName}")]
static partial void ErrorHashing(ILogger logger, string fileName, Exception e);

Query Language Overview

In this example you'll notice that the example code

  1. Logs when we begin hashing
  2. Hashs the file; or otherwise perform business logic
  3. Logs when we've completed the hashing of the file

This workflow outlines a typical sequence of operations for a developer. Log messages may be disabled before entering production, used during diagnostics, or employed to indicate failure and success in traditional testing.

Modeling Live System Behavior, with a Query Language Processor

An example use of the query language Processor is to suppress highly chatty events. Suppose we find that we are hashing many files and want to keep track of the count without needing file names or statuses. This often happens after deployment when it's realized that such functionality costs more than anticipated.

To address this, a simple aggregate function can be sent to the Dynamic Telemetry Query Language Processor to filter these events or aggregate in-memory statistics if they are still needed.

Suppressing Unneeded / Chatty Events

Aggregating Chatty Events

Lets look at a few examples, as they likely will help tell the tale

Image a piece of code that looks something like this:

Syntax error in textmermaid version 10.4.0

Example Scenarios