Integrating DevOps Guru Insights with CloudWatch Dashboard

Many customers use Amazon CloudWatch dashboards to monitor applications and often ask how they can integrate Amazon DevOps Guru Insights in order to have a unified dashboard for monitoring.  This blog post showcases integrating DevOps Guru proactive and reactive insights to a CloudWatch dashboard by using Custom Widgets. It can help you to correlate trends over time and spot issues more efficiently by displaying related data from different sources side by side and to have a single pane of glass visualization in the CloudWatch dashboard.

Amazon DevOps Guru is a machine learning (ML) powered service that helps developers and operators automatically detect anomalies and improve application availability. DevOps Guru’s anomaly detectors can proactively detect anomalous behavior even before it occurs, helping you address issues before they happen; detailed insights provide recommendations to mitigate that behavior.

Amazon CloudWatch dashboard is a customizable home page in the CloudWatch console that monitors multiple resources in a single view. You can use CloudWatch dashboards to create customized views of the metrics and alarms for your AWS resources.

Solution overview

This post will help you to create a Custom Widget for Amazon CloudWatch dashboard that displays DevOps Guru Insights. A custom widget is part of your CloudWatch dashboard that calls an AWS Lambda function containing your custom code. The Lambda function accepts custom parameters, generates your dataset or visualization, and then returns HTML to the CloudWatch dashboard. The CloudWatch dashboard will display this HTML as a widget. In this post, we are providing sample code for the Lambda function that will call DevOps Guru APIs to retrieve the insights information and displays as a widget in the CloudWatch dashboard. The architecture diagram of the solution is below.

Figure 1: Reference architecture diagram

Prerequisites and Assumptions

An AWS account. To sign up:

Create an AWS account. For instructions, see Sign Up For AWS.

DevOps Guru should be enabled in the account. For enabling DevOps guru, see DevOps Guru Setup

Follow this Workshop to deploy a sample application in your AWS Account which can help generate some DevOps Guru insights.

Solution Deployment

We are providing two options to deploy the solution – using the AWS console and AWS CloudFormation. The first section has instructions to deploy using the AWS console followed by instructions for using CloudFormation. The key difference is that we will create one Widget while using the Console, but three Widgets are created when we use AWS CloudFormation.

Using the AWS Console:

We will first create a Lambda function that will retrieve the DevOps Guru insights. We will then modify the default IAM role associated with the Lambda function to add DevOps Guru permissions. Finally we will create a CloudWatch dashboard and add a custom widget to display the DevOps Guru insights.

Navigate to the Lambda Console after logging to your AWS Account and click on Create function.

Figure 2a: Create Lambda Function

Choose Author from Scratch and use the runtime Node.js 16.x. Leave the rest of the settings at default and create the function.

Figure 2b: Create Lambda Function

After a few seconds, the Lambda function will be created and you will see a code source box. Copy the code from the text box below and replace the code present in code source as shown in screen print below. // SPDX-License-Identifier: MIT-0
// CloudWatch Custom Widget sample: displays count of Amazon DevOps Guru Insights
const aws = require(‘aws-sdk’);

const DOCS = `## DevOps Guru Insights Count
Displays the total counts of Proactive and Reactive Insights in DevOps Guru.

async function getProactiveInsightsCount(DevOpsGuru, StartTime, EndTime) {
let NextToken = null;
let proactivecount=0;

do {
const args = { StatusFilter: { Any : { StartTimeRange: { FromTime: StartTime, ToTime: EndTime }, Type: ‘PROACTIVE’ }}}
const result = await DevOpsGuru.listInsights(args).promise();
NextToken = result.NextToken;
result.ProactiveInsights.forEach(res => {
} while (NextToken);
return proactivecount;

async function getReactiveInsightsCount(DevOpsGuru, StartTime, EndTime) {
let NextToken = null;
let reactivecount=0;

do {
const args = { StatusFilter: { Any : { StartTimeRange: { FromTime: StartTime, ToTime: EndTime }, Type: ‘REACTIVE’ }}}
const result = await DevOpsGuru.listInsights(args).promise();
NextToken = result.NextToken;
result.ReactiveInsights.forEach(res => {
} while (NextToken);
return reactivecount;

function getHtmlOutput(proactivecount, reactivecount, region, event, context) {

return `DevOps Guru Proactive Insights<br><font size=”+10″ color=”#FF9900″>${proactivecount}</font>
<p>DevOps Guru Reactive Insights</p><font size=”+10″ color=”#FF9900″>${reactivecount}`;

exports.handler = async (event, context) => {
if (event.describe) {
return DOCS;
const widgetContext = event.widgetContext;
const timeRange = widgetContext.timeRange.zoom || widgetContext.timeRange;
const StartTime = new Date(timeRange.start);
const EndTime = new Date(timeRange.end);
const region = event.region || process.env.AWS_REGION;
const DevOpsGuru = new aws.DevOpsGuru({ region });

const proactivecount = await getProactiveInsightsCount(DevOpsGuru, StartTime, EndTime);
const reactivecount = await getReactiveInsightsCount(DevOpsGuru, StartTime, EndTime);

return getHtmlOutput(proactivecount, reactivecount, region, event, context);


Figure 3: Lambda Function Source Code

Click on Deploy to save the function code
Since we used the default settings while creating the function, a default Execution role is created and associated with the function. We will need to modify the IAM role to grant DevOps Guru permissions to retrieve Proactive and Reactive insights.
Click on the Configuration tab and select Permissions from the left side option list. You can see the IAM execution role associated with the function as shown in figure 4.

Figure 4: Lambda function execution role

Click on the IAM role name to open the role in the IAM console. Click on Add Permissions and select Attach policies.

Figure 5: IAM Role Update

Search for DevOps and select the AmazonDevOpsGuruReadOnlyAccess. Click on Add permissions to update the IAM role.

Figure 6: IAM Role Policy Update

Now that we have created the Lambda function for our custom widget and assigned appropriate permissions, we can navigate to CloudWatch to create a Dashboard.
Navigate to CloudWatch and click on dashboards from the left side list. You can choose to create a new dashboard or add the widget in an existing dashboard.
We will choose to create a new dashboard

Figure 7: Create New CloudWatch dashboard

Choose Custom Widget in the Add widget page

Figure 8: Add widget

Click Next in the custom widge page without choosing a sample

Figure 9: Custom Widget Selection

Choose the region where devops guru is enabled. Select the Lambda function that we created earlier. In the preview pane, click on preview to view DevOps Guru metrics. Once the preview is successful, create the Widget.

Figure 10: Create Custom Widget

Congratulations, you have now successfully created a CloudWatch dashboard with a custom widget to get insights from DevOps Guru. The sample code that we provided can be customized to suit your needs.

Using AWS CloudFormation

You may skip this step and move to future scope section if you have already created the resources using AWS Console.

In this step we will show you how to  deploy the solution using AWS CloudFormation. AWS CloudFormation lets you model, provision, and manage AWS and third-party resources by treating infrastructure as code. Customers define an initial template and then revise it as their requirements change. For more information on CloudFormation stack creation refer to  this blog post.

The following resources are created.

Three Lambda functions that will support CloudWatch Dashboard custom widgets
An AWS Identity and Access Management (IAM) role to that allows the Lambda function to access DevOps Guru Insights and to publish logs to CloudWatch
Three Log Groups under CloudWatch
A CloudWatch dashboard with widgets to pull data from the Lambda Functions

To deploy the solution by using the CloudFormation template

You can use this downloadable template  to set up the resources. To launch directly through the console, choose Launch Stack button, which creates the stack in the us-east-1 AWS Region.
Choose Next to go to the Specify stack details page.
(Optional) On the Configure Stack Options page, enter any tags, and then choose Next.
On the Review page, select I acknowledge that AWS CloudFormation might create IAM resources.
Choose Create stack.

It takes approximately 2-3 minutes for the provisioning to complete. After the status is “Complete”, proceed to validate the resources as listed below.

Validate the resources

Now that the stack creation has completed successfully, you should validate the resources that were created.

On AWS Console, head to CloudWatch, under Dashboards – there will be a dashboard created with name <StackName-Region>.
On AWS Console, head to CloudWatch, under LogGroups there will be 3 new log-groups created with the name as:


On AWS Console, head to Lambda, there will be lambda function(s) under the name:


On AWS Console, head to IAM, under Roles there will be a new role created with name “lambdaIAMRole”

To View Results/Outcome

With the appropriate time-range setup on CloudWatch Dashboard, you will be able to navigate through the insights that have been generated from DevOps Guru on the CloudWatch Dashboard.

Figure 11: DevOpsGuru Insights in Cloudwatch Dashboard


For cost optimization, after you complete and test this solution, clean up the resources. You can delete them manually if you used the AWS Console or by deleting the AWS CloudFormation stack called devopsguru-cloudwatch-dashboard if you used AWS CloudFormation.

For more information on deleting the stacks, see Deleting a stack on the AWS CloudFormation console.


This blog post outlined how you can integrate DevOps Guru insights into a CloudWatch Dashboard. As a customer, you can start leveraging CloudWatch Custom Widgets to include DevOps Guru Insights in an existing Operational dashboard.

AWS Customers are now using Amazon DevOps Guru to monitor and improve application performance. You can start monitoring your applications by following the instructions in the product documentation. Head over to the Amazon DevOps Guru console to get started today.

To learn more about AIOps for Serverless using Amazon DevOps Guru check out this video.

Suresh Babu

Suresh Babu is a DevOps Consultant at Amazon Web Services (AWS) with 21 years of experience in designing and implementing software solutions from various industries. He helps customers in Application Modernization and DevOps adoption. Suresh is a passionate public speaker and often speaks about DevOps and Artificial Intelligence (AI)

Venkat Devarajan

Venkat Devarajan is a Senior Solutions Architect at Amazon Webservices (AWS) supporting enterprise automotive customers. He has over 18 years of industry experience in helping customers design, build, implement and operate enterprise applications.

Ashwin Bhargava

Ashwin is a DevOps Consultant at AWS working in Professional Services Canada. He is a DevOps expert and a security enthusiast with more than 15 years of development and consulting experience.

Murty Chappidi

Murty is an APJ Partner Solutions Architecture Lead at Amazon Web Services with a focus on helping customers with accelerated and seamless journey to AWS by providing solutions through our GSI partners. He has more than 25 years’ experience in software and technology and has worked in multiple industry verticals. He is the APJ SME for AI for DevOps Focus Area. In his free time, he enjoys gardening and cooking.

372: Trends

This week Marie and Chris get together to chat about what’s been hot hot hot on CodePen lately. We’ve discovered there is a really taking to the creamy cardstock look, for one thing. Typography is always great, but we’re seeing more typographic trickery often including variable fonts. While not new, there are still loads of really wonderfully creative Pens using Three.js and p5.js. Neon-on-dark is a fresh look. We get into those and more, a bit sneakily as we can take an internal look at what the Top 100 might look like this year, but we can’t share those details too early!

Time Jumps

00:24 Trending episode

01:34 The web3 aesthetic

03:33 Pen and ink on cardstock

06:44 Variable fonts

10:18 Ask the database what’s popping?

11:42 Celebrating follower number

12:49 ThreeJS and P5 processing

20:08 Public documentation on what it takes to get picked

26:33 CodePen Challenges

The post 372: Trends appeared first on CodePen Blog.Flatlogic Admin Templates banner

350: 2021’s Most Hearted

It’s back! We counted up all the hearts given to every Pen created in 2021 and created a list of the top 100. Marie and Chris chat about this year’s list. Who’s on it, what’s on it, and digging into the numbers where we can.

Remember that people can heart pens up to 3 times each, so if it looks like a Pen lower down the list has more hearts than one higher up the list, it’s because of the density of hearts. The number you see on the card only reflects the number of people that have hearted not the true number of hearts.

Lots of folks hitting multiple times. George Francis hit 6(!) times (7, 28, 59, 75, 80, 82), an impressive feat for a member who only joined in late 2020. Four people with four placements: Aysenur Turk (3, 11, 14… and 1), Yoav Kadosh (17, 33, 72, 95), Dilum Sanjaya (22, 24, 64, 65), and Aybüke Ceylan (38, 46, 63, 91), and a couple of 2-position people. Woot!

“Full page” layouts were quite a trend on the Top 100 this year. That is, Pens that look like complete websites with widgets and cards and navigation and sidebars and the whole nine yards. That’s opposed to some past years where more minimal small-yet-surprising Pens were more dominant in the Top 100.

Advice for those shooting for the top? Talk about your work. Almost nobody on the list creates work and then never shares it. Share it on social media, blog about it, make a video, re-promote it multiple times. Be part of the community by liking other people’s work. Remember, your hearts come from other CodePen members. Also, feel free to update and revise your Pens. Many of the Top 100 are updated and improved even after their initial wave of popularity.

Time Jumps

01:43 Multiple hearting a Pen

03:26 Where to find the list for 2021

04:11 #1 on the list

07:31 George Francis on the list 6 times

10:13 Sponsor: Netlify

11:55 Getting pens in front of the community

14:52 It’s just gotta have something special

15:15 Doing the CodePen Challenges

15:32 Posting in January vs December

17:56 High fives to Yoav Kadosh

18:34 Carousel carousels

20:18 New faces and old faces on the list

21:47 Personal favorite pens

26:33 Full page UI

28:29 Bigger than smaller for 2021

31:05 If you’re new to CodePen…

Sponsor: Netlify

Did you Netlify offers auth? They call it Netlify Identity. Why would you need auth on a static site? Well, a static site can also by quite dynamic, that’s the nature of Jamstack. Say you’re building a TODO app. No problem! You can have users sign up and log in. You can store their data in a cloud database. You can pull the data for that user from the database based on information about the logged-in user because of Netlify Identity.

The post 350: 2021’s Most Hearted appeared first on CodePen Blog.

New .NET 6 APIs driven by the developer community

.NET 6 is on the way, and I wanted to share some of my favorite new APIs in .NET and ASP.NET Core that you are going to love. Why are you going to love them? Well because they were directly driven by our fantastic .NET developer community! Let’s get started!

Reading & Writing Files

In .NET 6, there’s a new low-level API to enable reading/writing of files without using a FileStream. It also supports scatter/gather IO (multiple buffers) and overlapping reads and writes at a given file offset.

using Microsoft.Win32.SafeHandles;
using SafeFileHandle handle = File.OpenHandle(“ConsoleApp128.exe”);
long length = RandomAccess.GetLength(handle);


Process Path & Id

There are a couple of new ways to access a process path and process id without allocating a new process object:

int pid = Environment.ProcessId;
string path = Environment.ProcessPath;


CSPNG (Cryptographically Secure Pseudorandom Number Generator)

Generating random numbers from a CSPNG (Cryptographically Secure Pseudorandom Number Generator) is a easier than ever:

// Give me 200 random bytes
byte[] bytes = RandomNumberGenerator.GetBytes(200);


We finally added Parallel.ForEachAsync, a way to schedule asynchronous work that allows you to control the degree of parallelism:

var urlsToDownload = new []

var client = new HttpClient();

await Parallel.ForEachAsync(urlsToDownload, async (url, token) =>
var targetPath = Path.Combine(Path.GetTempPath(), “http_cache”, url);

HttpResponseMessage response = await client.GetAsync(url);

if (response.IsSuccessStatusCode)
using FileStream target = File.OpenWrite(targetPath);

await response.Content.CopyToAsync(target);

Configuration Helpers

We added a helper to make it easier to throw if a required section of configuration is missing:

var configuration = new ConfigurationManager();
var options = new MyOptions();

// This will throw if the section isn’t configured

class MyOptions
public string? SettingValue { get; set;}


There’s a ton of new LINQ methods as well. It got lots of love in this release. Here’s a new helper to chunk any IEnumerable into batches:

int chunkNumber = 1;
foreach (int[] chunk in Enumerable.Range(0, 9).Chunk(3))
Console.WriteLine($”Chunk {chunkNumber++}”);
foreach (var item in chunk)

Even More LINQ!

More LINQ! There are now MaxBy and MinBy methods:

var people = GetPeople();

var oldest = people.MaxBy(p => p.Age);
var youngest = people.MinBy(p => p.Age);

Console.WriteLine($”The oldest person is {oldest.Age}”);
Console.WriteLine($”The youngest person is {youngest.Age}”);

public record Person(string Name, int Age);

Power of 2

Don’t keep bit math in your head? Me neither. Here are some new helpers for working with powers of 2:

using System.Numerics;

uint bufferSize = 235;
if (!BitOperations.IsPow2(bufferSize))
bufferSize = BitOperations.RoundUpToPowerOf2(bufferSize);


WaitAsync Improvements

There’s now a much easier (and properly implemented) way to wait for task to complete asynchronously. The following code will yield the await if it hasn’t completed in 10 seconds. The operation might still be running! This is for un-cancellable operations!

Task operationTask = SomeLongRunningOperationAsync();

await operationTask.WaitAsync(TimeSpan.FromSeconds(10));


No more having to check for null in every method before you throw an exception. It is now just one line of code.

void DoSomethingUseful(object obj)

Working with NativeMemory

If you want to use C APIs to allocate memory because you’re a l33t hacker or need to allocate native memory, then look no further. Don’t forget to free!

using System.Runtime.InteropServices;

byte* buffer = (byte*)NativeMemory.Alloc(100);


Posix Signal Handling

Native support for Posix signal handling is here and we also emulate a couple of signals on Windows.

using System.Runtime.InteropServices;

var tcs = new TaskCompletionSource();

PosixSignalRegistration.Create(PosixSignal.SIGTERM, context =>
Console.WriteLine($”{context.Signal} fired”);

await tcs.Task;

New Metrics API

We added an entirely new metrics API based on @opentelemetry in .NET 6. It supports dimensions, is super efficient and will have exporters for popular metric sinks.

using System.Diagnostics.Metrics;

// This is how you produce metrics

var meter = new Meter(“Microsoft.AspNetCore”, “v1.0”);
Counter<int> counter = meter.CreateCounter<int>(“Requests”);

var app = WebApplication.Create(args);

app.Use((context, next) =>
counter.Add(1, KeyValuePair.Create<string, object?>(“path”, context.Request.Path.ToString()));
return next(context);

app.MapGet(“/”, () => “Hello World”);

You can even listen in and meter:

var listener = new MeterListener();
listener.InstrumentPublished = (instrument, meterListener) =>
if(instrument.Name == “Requests” && instrument.Meter.Name == “Microsoft.AspNetCore”)
meterListener.EnableMeasurementEvents(instrument, null);

listener.SetMeasurementEventCallback<int>((instrument, measurement, tags, state) =>
Console.WriteLine($”Instrument: {instrument.Name} has recorded the measurement: {measurement}”);


Modern Timer API

Last but not least, a modern timer API (I think this is the 5th timer API in .NET now). It’s fully async and isn’t plagued by the types of gotchas the other timers are plagued with like object lifetime issues, no asynchronous callbacks etc.

var timer = new PeriodicTimer(TimeSpan.FromSeconds(1));

while (await timer.WaitForNextTickAsync())


This is just a sampling of the new APIs coming in .NET 6. For more information look at the .NET 6 release notes API diffs. Also, Stephen just wrote a spectacular blog on performance improvements in .NET6 so be sure to give that a read. Finally, don’t forget to download the .NET 6 Preview and try out the new APIs today.

The post New .NET 6 APIs driven by the developer community appeared first on .NET Blog.