123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285 |
- import { css, cx } from '@emotion/css';
- import { stripIndent, stripIndents } from 'common-tags';
- import Prism from 'prismjs';
- import React, { PureComponent } from 'react';
- import { QueryEditorHelpProps } from '@grafana/data';
- import { flattenTokens } from '@grafana/ui/src/slate-plugins/slate-prism';
- import tokenizer from '../syntax';
- import { CloudWatchQuery } from '../types';
- interface QueryExample {
- category: string;
- examples: Array<{
- title: string;
- expr: string;
- }>;
- }
- const CLIQ_EXAMPLES: QueryExample[] = [
- {
- category: 'Lambda',
- examples: [
- {
- title: 'View latency statistics for 5-minute intervals',
- expr: stripIndents`filter @type = "REPORT" |
- stats avg(@duration), max(@duration), min(@duration) by bin(5m)`,
- },
- {
- title: 'Determine the amount of overprovisioned memory',
- expr: stripIndent`
- filter @type = "REPORT" |
- stats max(@memorySize / 1024 / 1024) as provisonedMemoryMB,
- min(@maxMemoryUsed / 1024 / 1024) as smallestMemoryRequestMB,
- avg(@maxMemoryUsed / 1024 / 1024) as avgMemoryUsedMB,
- max(@maxMemoryUsed / 1024 / 1024) as maxMemoryUsedMB,
- provisonedMemoryMB - maxMemoryUsedMB as overProvisionedMB`,
- },
- {
- title: 'Find the most expensive requests',
- expr: stripIndents`filter @type = "REPORT" |
- fields @requestId, @billedDuration |
- sort by @billedDuration desc`,
- },
- ],
- },
- {
- category: 'VPC Flow Logs',
- examples: [
- {
- title: 'Average, min, and max byte transfers by source and destination IP addresses',
- expr: `stats avg(bytes), min(bytes), max(bytes) by srcAddr, dstAddr`,
- },
- {
- title: 'IP addresses using UDP transfer protocol',
- expr: 'filter protocol=17 | stats count(*) by srcAddr',
- },
- {
- title: 'Top 10 byte transfers by source and destination IP addresses',
- expr: stripIndents`stats sum(bytes) as bytesTransferred by srcAddr, dstAddr |
- sort bytesTransferred desc |
- limit 10`,
- },
- {
- title: 'Top 20 source IP addresses with highest number of rejected requests',
- expr: stripIndents`filter action="REJECT" |
- stats count(*) as numRejections by srcAddr |
- sort numRejections desc |
- limit 20`,
- },
- ],
- },
- {
- category: 'CloudTrail',
- examples: [
- {
- title: 'Number of log entries by service, event type, and region',
- expr: 'stats count(*) by eventSource, eventName, awsRegion',
- },
- {
- title: 'Number of log entries by region and EC2 event type',
- expr: stripIndents`filter eventSource="ec2.amazonaws.com" |
- stats count(*) as eventCount by eventName, awsRegion |
- sort eventCount desc`,
- },
- {
- title: 'Regions, usernames, and ARNs of newly created IAM users',
- expr: stripIndents`filter eventName="CreateUser" |
- fields awsRegion, requestParameters.userName, responseElements.user.arn`,
- },
- ],
- },
- {
- category: 'Common Queries',
- examples: [
- {
- title: '25 most recently added log events',
- expr: stripIndents`fields @timestamp, @message |
- sort @timestamp desc |
- limit 25`,
- },
- {
- title: 'Number of exceptions logged every 5 minutes',
- expr: stripIndents`filter @message like /Exception/ |
- stats count(*) as exceptionCount by bin(5m) |
- sort exceptionCount desc`,
- },
- {
- title: 'List of log events that are not exceptions',
- expr: 'fields @message | filter @message not like /Exception/',
- },
- ],
- },
- {
- category: 'Route 53',
- examples: [
- {
- title: 'Number of requests received every 10 minutes by edge location',
- expr: 'stats count(*) by queryType, bin(10m)',
- },
- {
- title: 'Number of unsuccessful requests by domain',
- expr: 'filter responseCode="SERVFAIL" | stats count(*) by queryName',
- },
- {
- title: 'Number of requests received every 10 minutes by edge location',
- expr: 'stats count(*) as numRequests by resolverIp | sort numRequests desc | limit 10',
- },
- ],
- },
- {
- category: 'AWS AppSync',
- examples: [
- {
- title: 'Number of unique HTTP status codes',
- expr: stripIndents`fields ispresent(graphQLAPIId) as isApi |
- filter isApi |
- filter logType = "RequestSummary" |
- stats count() as statusCount by statusCode |
- sort statusCount desc`,
- },
- {
- title: 'Top 10 resolvers with maximum latency',
- expr: stripIndents`fields resolverArn, duration |
- filter logType = "Tracing" |
- sort duration desc |
- limit 10`,
- },
- {
- title: 'Most frequently invoked resolvers',
- expr: stripIndents`fields ispresent(resolverArn) as isRes |
- stats count() as invocationCount by resolverArn |
- filter isRes |
- filter logType = "Tracing" |
- sort invocationCount desc |
- limit 10`,
- },
- {
- title: 'Resolvers with most errors in mapping templates',
- expr: stripIndents`fields ispresent(resolverArn) as isRes |
- stats count() as errorCount by resolverArn, logType |
- filter isRes and (logType = "RequestMapping" or logType = "ResponseMapping") and fieldInError |
- sort errorCount desc |
- limit 10`,
- },
- {
- title: 'Field latency statistics',
- expr: stripIndents`fields requestId, latency |
- filter logType = "RequestSummary" |
- sort latency desc |
- limit 10`,
- },
- {
- title: 'Resolver latency statistics',
- expr: stripIndents`fields ispresent(resolverArn) as isRes |
- filter isRes |
- filter logType = "Tracing" |
- stats min(duration), max(duration), avg(duration) as avgDur by resolverArn |
- sort avgDur desc |
- limit 10`,
- },
- {
- title: 'Top 10 requests with maximum latency',
- expr: stripIndents`fields requestId, latency |
- filter logType = "RequestSummary" |
- sort latency desc |
- limit 10`,
- },
- ],
- },
- ];
- function renderHighlightedMarkup(code: string, keyPrefix: string) {
- const grammar = tokenizer;
- const tokens = flattenTokens(Prism.tokenize(code, grammar));
- const spans = tokens
- .filter((token) => typeof token !== 'string')
- .map((token, i) => {
- return (
- <span
- className={`prism-token token ${token.types.join(' ')} ${token.aliases.join(' ')}`}
- key={`${keyPrefix}-token-${i}`}
- >
- {token.content}
- </span>
- );
- });
- return <div className="slate-query-field">{spans}</div>;
- }
- const exampleCategory = css`
- margin-top: 5px;
- `;
- export default class LogsCheatSheet extends PureComponent<
- QueryEditorHelpProps<CloudWatchQuery>,
- { userExamples: string[] }
- > {
- onClickExample(query: CloudWatchQuery) {
- this.props.onClickExample(query);
- }
- renderExpression(expr: string, keyPrefix: string) {
- return (
- <div
- className="cheat-sheet-item__example"
- key={expr}
- onClick={() =>
- this.onClickExample({
- refId: this.props.query.refId ?? 'A',
- expression: expr,
- queryMode: 'Logs',
- region: this.props.query.region,
- id: this.props.query.refId ?? 'A',
- logGroupNames: 'logGroupNames' in this.props.query ? this.props.query.logGroupNames : [],
- })
- }
- >
- <pre>{renderHighlightedMarkup(expr, keyPrefix)}</pre>
- </div>
- );
- }
- renderLogsCheatSheet() {
- return (
- <div>
- <h2>CloudWatch Logs Cheat Sheet</h2>
- {CLIQ_EXAMPLES.map((cat, i) => (
- <div key={`${cat.category}-${i}`}>
- <div className={`cheat-sheet-item__title ${cx(exampleCategory)}`}>{cat.category}</div>
- {cat.examples.map((item, j) => (
- <div className="cheat-sheet-item" key={`item-${j}`}>
- <h4>{item.title}</h4>
- {this.renderExpression(item.expr, `item-${j}`)}
- </div>
- ))}
- </div>
- ))}
- </div>
- );
- }
- render() {
- return (
- <div>
- <h3>CloudWatch Logs cheat sheet</h3>
- {CLIQ_EXAMPLES.map((cat, i) => (
- <div key={`cat-${i}`}>
- <div className={`cheat-sheet-item__title ${cx(exampleCategory)}`}>{cat.category}</div>
- {cat.examples.map((item, j) => (
- <div className="cheat-sheet-item" key={`item-${j}`}>
- <h4>{item.title}</h4>
- {this.renderExpression(item.expr, `item-${j}`)}
- </div>
- ))}
- </div>
- ))}
- </div>
- );
- }
- }
|