diff --git a/public/app/plugins/datasource/cloudwatch/components/LogsCheatSheet.tsx b/public/app/plugins/datasource/cloudwatch/components/LogsCheatSheet.tsx index d3ed3266695..5ed4c8d2e62 100644 --- a/public/app/plugins/datasource/cloudwatch/components/LogsCheatSheet.tsx +++ b/public/app/plugins/datasource/cloudwatch/components/LogsCheatSheet.tsx @@ -4,81 +4,189 @@ import { ExploreStartPageProps, DataQuery, ExploreMode } from '@grafana/data'; import Prism from 'prismjs'; import tokenizer from '../syntax'; import { flattenTokens } from '@grafana/ui/src/slate-plugins/slate-prism'; +import { css, cx } from 'emotion'; -const CLIQ_EXAMPLES = [ +interface QueryExample { + category: string; + examples: Array<{ + title: string; + expr: string; + }>; +} + +const CLIQ_EXAMPLES: QueryExample[] = [ { - 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`, - }, - { - 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`, - }, - { - title: 'Number of log entries by service, event type, and region', - expr: 'stats count(*) by eventSource, eventName, awsRegion', + 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`, + }, + ], }, { - 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`, + 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: 'Regions, usernames, and ARNs of newly created IAM users', - expr: stripIndents`filter eventName="CreateUser" | - fields awsRegion, requestParameters.userName, responseElements.user.arn`, + { + 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`, + }, + ], }, { - title: '25 most recently added log events', - expr: stripIndents`fields @timestamp, @message | - sort @timestamp desc | - limit 25`, + 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/', + }, + ], }, { - title: 'Number of exceptions logged every 5 minutes', - expr: stripIndents`filter @message like /Exception/ | - stats count(*) as exceptionCount by bin(5m) | - sort exceptionCount desc`, + 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', + }, + ], }, { - title: 'List of log events that are not exceptions', - expr: 'fields @message | filter @message not like /Exception/', + 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`, + }, + ], }, ]; @@ -101,6 +209,10 @@ function renderHighlightedMarkup(code: string, keyPrefix: string) { return
{spans}
; } +const exampleCategory = css` + margin-top: 5px; +`; + export default class LogsCheatSheet extends PureComponent { renderExpression(expr: string, keyPrefix: string) { const { onClickExample } = this.props; @@ -120,10 +232,15 @@ export default class LogsCheatSheet extends PureComponent

CloudWatch Logs Cheat Sheet

- {CLIQ_EXAMPLES.map((item, i) => ( -
-
{item.title}
- {this.renderExpression(item.expr, `item-${i}`)} + {CLIQ_EXAMPLES.map(cat => ( +
+
{cat.category}
+ {cat.examples.map((item, i) => ( +
+

{item.title}

+ {this.renderExpression(item.expr, `item-${i}`)} +
+ ))}
))}
diff --git a/public/app/plugins/datasource/cloudwatch/syntax.ts b/public/app/plugins/datasource/cloudwatch/syntax.ts index 109b52e1a50..73bcee4d0e0 100644 --- a/public/app/plugins/datasource/cloudwatch/syntax.ts +++ b/public/app/plugins/datasource/cloudwatch/syntax.ts @@ -339,7 +339,7 @@ const tokenizer: Grammar = { alias: 'function', }, function: { - pattern: new RegExp(`\\b(?:${FUNCTIONS.map(f => f.label).join('|')})`, 'i'), + pattern: new RegExp(`\\b(?:${FUNCTIONS.map(f => f.label).join('|')})\\b`, 'i'), }, keyword: { pattern: new RegExp(`(\\s+)(${KEYWORDS.join('|')})(?=\\s+)`, 'i'),