DEV Community

Cover image for How to build Azure Log Analytics URL with KQL Query?
Venkatesan Rethinam
Venkatesan Rethinam

Posted on

2 1

How to build Azure Log Analytics URL with KQL Query?

This is a requirement I had for one of my projects where we retrieve app insights data from several azure web apps on their flow performances. I used App Insights API for posting the KQL query and the timespan to get the flow performances which are logged using custom dimensions in the specific insights' logs.

I also had a requirement where I had to give the users who are seeing the data, the ability to see the query and timespan I used for retrieving the data they are seeing. There is no direct way Azure gives you this ability. So, I researched the Log Analytics 'Share' functionality on how they are sharing the queries in the URLs.

Here is the format they are using,
https://portal.azure.com/#blade/Microsoft_Azure_Monitoring_Logs/LogsBlade/resourceId/%2Fsubscriptions%2F{subscriptionId}%2FresourceGroups%2F{rg}%2Fproviders%2Fmicrosoft.insights%2Fcomponents%2F{resourcename}/source/LogsBlade.AnalyticsShareLinkToQuery/query/{query}

The values you see inside {} are to be replaced with actuals. However, for {query}, it does not take the KQL directly.

I eventually found that they are converting the KQL into Base64 bytes and compressing them. They have this property by default set to true => isQueryBase64Compressed=true in the query string.

So, the URL would become like this,
https://portal.azure.com/#blade/Microsoft_Azure_Monitoring_Logs/LogsBlade/resourceId/%2Fsubscriptions%2F{subscriptionId}%2FresourceGroups%2F{rg}%2Fproviders%2Fmicrosoft.insights%2Fcomponents%2F{resourcename}/source/LogsBlade.AnalyticsShareLinkToQuery/query/{query}/isQueryBase64Compressed/true

OK, Here is the code for that KQL query conversion to fit into this URL.

var queryBytes = Encoding.UTF8.GetBytes(query);
var memoryStream = new MemoryStream();
var gZipStream = new GZipStream(memoryStream, CompressionMode.Compress);

gZipStream.Write(queryBytes, 0, queryBytes.Length);
gZipStream.Close();

var compressedData = memoryStream.ToArray();

var encodedText = Convert.ToBase64String(compressedData);
encodedText = encodedText.Replace("/", "%2F");
encodedText = encodedText.Replace("+", "%2B");
encodedText = encodedText.Replace("=", "%3D");

var portalUrl = "https://portal.azure.com/#@sample.onmicrosoft.com/resource/subscriptions/guid-guid-guid-guid-guid/resourceGroups/rg-name/providers/microsoft.insights/components/app-insights-name/overview";

var (subscriptionId, rg, resourcename) = GetAzureResourceDetailsFromLogUrl(portalUrl);

url = "https://portal.azure.com/#blade/" + $"Microsoft_Azure_Monitoring_Logs/LogsBlade/resourceId/%2Fsubscriptions%2F{subscriptionId}%2FresourceGroups%2F{rg}%2Fproviders%2Fmicrosoft.insights%2Fcomponents%2F{resourcename}/source/LogsBlade.AnalyticsShareLinkToQuery/query/{encodedText}/isQueryBase64Compressed/true";

Enter fullscreen mode Exit fullscreen mode

Additional Perks
Here is an additional perk for getting the Subscription Id, Resource Group Name, and the Resource Name from an Azure App Insights resource URL.


private static (string, string, string) GetAzureResourceDetailsFromLogUrl(string portalUrl)
{
  var uri = new Uri(portalUrl.Replace("#", ""));

  var subscriptionId = uri.Segments[uri.Segments.ToList().FindIndex(f => f.Equals(SubscriptionsUrlSegment, StringComparison.OrdinalIgnoreCase)) + 1].Replace("/", "");

  var rg = uri.Segments[uri.Segments.ToList().FindIndex(f => f.Equals(RGUrlSegment, StringComparison.OrdinalIgnoreCase)) + 1].Replace("/", "");

  var resourceName = uri.Segments[uri.Segments.ToList().FindIndex(f => f.Equals(ComponentUrlSegment, StringComparison.OrdinalIgnoreCase)) + 1].Replace("/", "");

  return (subscriptionId, rg, resourceName);
}

Enter fullscreen mode Exit fullscreen mode

Billboard image

Imagine monitoring that's actually built for developers

Join Vercel, CrowdStrike, and thousands of other teams that trust Checkly to streamline monitor creation and configuration with Monitoring as Code.

Start Monitoring

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Dive into an ocean of knowledge with this thought-provoking post, revered deeply within the supportive DEV Community. Developers of all levels are welcome to join and enhance our collective intelligence.

Saying a simple "thank you" can brighten someone's day. Share your gratitude in the comments below!

On DEV, sharing ideas eases our path and fortifies our community connections. Found this helpful? Sending a quick thanks to the author can be profoundly valued.

Okay