Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | 1x 1x 169x 169x 90x 558x 558x 558x 169x 1x 1x 90x 113x 113x 113x 169x 169x 169x 169x 558x 558x 52x 506x 169x 506x 506x 558x 558x 558x 556x 558x | import { loadCannedMetricsFile, MetricTemplate } from './canned-metrics/canned-metrics-schema';
export type NonEmptyArray<T> = [T, ...T[]];
/**
* A single canned service metric
*
* These are kindly provided to us by the good people of CloudWatch Explorer.
*/
export interface CannedMetric {
/**
* Metric namespace
*/
readonly namespace: string;
/**
* Metric name
*/
readonly metricName: string;
/**
* List of all possible dimension permutations for this metric
*
* Most metrics will have a single list of strings as their one set of
* allowed dimensions, but some metrics are emitted under multiple
* combinations of dimensions.
*/
readonly dimensions: NonEmptyArray<string[]>;
/**
* Suggested default aggregration statistic
*
* Not always the most appropriate one to use! These defaults have
* been classified by people and they generally just pick "Average"
* as the default, even if it doesn't make sense.
*
* For example: for event-based metrics that only ever emit `1`
* (and never `0`) the better statistic would be `Sum`.
*
* Use your judgement based on the type of metric this is.
*/
readonly defaultStat: string;
}
/**
* Return the list of canned metrics for the given service
*/
export function cannedMetricsForService(cloudFormationNamespace: string): CannedMetric[] {
// One metricTemplate has a single set of dimensions, but the same metric NAME
// may occur in multiple metricTemplates (if it has multiple sets of dimensions)
const metricTemplates = cannedMetricsIndex()[cloudFormationNamespace] ?? [];
// First construct almost what we need, but with a single dimension per metric
const metricsWithDuplicates = flatMap(metricTemplates, metricSet => {
const dimensions = metricSet.dimensions.map(d => d.dimensionName);
return metricSet.metrics.map(metric => ({
namespace: metricSet.namespace,
dimensions,
metricName: metric.name,
defaultStat: metric.defaultStat,
}));
});
// Then combine the dimensions for the same metrics into a single list
return groupBy(metricsWithDuplicates, m => `${m.namespace}/${m.metricName}`).map(metrics => ({
namespace: metrics[0].namespace,
metricName: metrics[0].metricName,
defaultStat: metrics[0].defaultStat,
dimensions: Array.from(dedupeStringLists(metrics.map(m => m.dimensions))) as any,
}));
}
type CannedMetricsIndex = Record<string, MetricTemplate[]>;
let cannedMetricsCache: CannedMetricsIndex | undefined;
/**
* Load the canned metrics file and process it into an index, grouped by service namespace
*/
function cannedMetricsIndex() {
if (cannedMetricsCache === undefined) {
cannedMetricsCache = {};
for (const group of loadCannedMetricsFile()) {
for (const metricTemplate of group.metricTemplates) {
const [aws, service] = metricTemplate.resourceType.split('::');
const serviceKey = [aws, service].join('::');
(cannedMetricsCache[serviceKey] ?? (cannedMetricsCache[serviceKey] = [])).push(metricTemplate);
}
}
}
return cannedMetricsCache;
}
function flatMap<A, B>(xs: A[], fn: (x: A) => B[]): B[] {
return Array.prototype.concat.apply([], xs.map(fn));
}
function groupBy<A>(xs: A[], keyFn: (x: A) => string): Array<NonEmptyArray<A>> {
const obj: Record<string, NonEmptyArray<A>> = {};
for (const x of xs) {
const key = keyFn(x);
if (key in obj) {
obj[key].push(x);
} else {
obj[key] = [x];
}
}
return Object.values(obj);
}
function* dedupeStringLists(xs: string[][]): IterableIterator<string[]> {
const seen = new Set<string>();
for (const x of xs) {
x.sort();
const key = `${x.join(',')}`;
if (!seen.has(key)) {
yield x;
}
seen.add(key);
}
} |