Skip to content

Instantly share code, notes, and snippets.

@markilott
Created October 30, 2022 09:44
Show Gist options
  • Save markilott/df1a29a3a2042069bc5e68186f0b41c5 to your computer and use it in GitHub Desktop.
Save markilott/df1a29a3a2042069bc5e68186f0b41c5 to your computer and use it in GitHub Desktop.
// Full project available here: https://github.com/markilott/aws-cdk-lambda-powertools
import { Stack } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { QueryDefinition, QueryString } from 'aws-cdk-lib/aws-logs';
import {
Color, Dashboard, GraphWidget, GraphWidgetView, LegendPosition, Metric, Row, TextWidget,
} from 'aws-cdk-lib/aws-cloudwatch';
import { CfnGroup } from 'aws-cdk-lib/aws-xray';
// ... import local types
interface DashboardStackProps extends DemoStackProps {
/** Demo API inc Dashboard widgets */
demoApi: CustomApi;
/** Custom Functions */
functions: CustomFunction[];
/** Custom Table */
colourTable: CustomDynamoTable;
}
/**
* Creates the metrics and CloudWatch Dashboard for the application.
*/
export class DashboardStack extends Stack {
/**
* @param {Construct} scope
* @param {string} id
* @param {DashboardStackProps} props
*/
constructor(scope: Construct, id: string, props: DashboardStackProps) {
super(scope, id, props);
const {
svcName = 'ToolsDemo',
functions, colourTable, demoApi,
} = props;
// CloudWatch Log Insights =============================================
// These appear as saved queries in Log Insights
// All of the function log groups
const logGroups = functions.map((fnc) => fnc.logGroup);
// WARN query
new QueryDefinition(this, 'WarnLevel', {
queryDefinitionName: `${svcName}_WarnLevel`,
queryString: new QueryString({
fields: ['@timestamp', '@message'],
sort: '@timestamp desc',
limit: 20,
filter: 'level = "WARN"',
}),
logGroups,
});
// ... ERROR query
// WARN query with correlationId filter
new QueryDefinition(this, 'WarnLevelCorrelationId', {
queryDefinitionName: `${svcName}_WarnLevel_CorrelationId`,
queryString: new QueryString({
fields: ['@timestamp', '@message'],
sort: '@timestamp desc',
limit: 20,
filter: 'level = "WARN" and correlationId = "enter_id"',
}),
logGroups,
});
// ... ERROR query with correlationId filter
// X-Ray Group ===========================================================
// Filter the Service Map and Traces in X-Ray
new CfnGroup(this, 'ServiceGroup', {
filterExpression: `annotation.Service = "${svcName.toUpperCase()}"`,
groupName: svcName,
insightsConfiguration: {
insightsEnabled: true,
notificationsEnabled: false,
},
});
// CloudWatch Dashboard ==================================================
const metricsSvcName = svcName.toUpperCase();
const dashboard = new Dashboard(this, 'DemoDashboard', {
dashboardName: `${svcName}_Dashboard`,
});
// Service Stats from custom metrics
const header = new TextWidget({
markdown: `## ${svcName} Results`,
width: 24,
height: 1,
});
const colourWidget = new GraphWidget({
title: 'Colour Selections',
width: 12,
height: 6,
view: GraphWidgetView.BAR,
stacked: true,
setPeriodToTimeRange: true,
legendPosition: LegendPosition.HIDDEN,
left: [
new Metric({
metricName: 'RED',
namespace: 'DemoNamespace',
label: 'Red',
dimensionsMap: {
service: metricsSvcName,
feature: 'colourPicker',
},
statistic: 'sum',
color: Color.RED,
}),
new Metric({
metricName: 'BLUE',
namespace: 'DemoNamespace',
label: 'Blue',
dimensionsMap: {
service: metricsSvcName,
feature: 'colourPicker',
},
statistic: 'sum',
color: Color.BLUE,
}),
new Metric({
metricName: 'PURPLE',
namespace: 'DemoNamespace',
label: 'Purple',
dimensionsMap: {
service: metricsSvcName,
feature: 'colourPicker',
},
statistic: 'sum',
color: Color.PURPLE,
}),
new Metric({
metricName: 'BLACK',
namespace: 'DemoNamespace',
label: 'Black',
dimensionsMap: {
service: metricsSvcName,
feature: 'colourPicker',
},
statistic: 'sum',
color: '#000000',
}),
],
});
dashboard.addWidgets(new Row(header, colourWidget));
// DynamoDb Table Widgets from CustomTable construct
dashboard.addWidgets(new Row(...colourTable.dashboardWidgets));
// API Gateway Widgets from CustomApi construct
dashboard.addWidgets(new Row(...demoApi.dashboardWidgets));
// Function Stats from CustomFunction construct
const rows = functions.map((fnc) => new Row(...fnc.dashboardWidgets));
rows.forEach((row) => {
dashboard.addWidgets(row);
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment