import { css } from '@emotion/css';
import Prism from 'prismjs';
import { useState } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { Collapse, useStyles2, Text } from '@grafana/ui';
import { flattenTokens } from '@grafana/ui/src/slate-plugins/slate-prism';
import { trackSampleQuerySelection } from '../../tracking';
import { CloudWatchLogsQuery, CloudWatchQuery, LogsQueryLanguage } from '../../types';
import * as sampleQueries from './sampleQueries';
import { cwliTokenizer, pplTokenizer, sqlTokenizer } from './tokenizer';
interface QueryExample {
category: string;
examples: sampleQueries.SampleQuery[];
}
const QUERIES: QueryExample[] = [
{
category: 'General queries',
examples: sampleQueries.generalQueries,
},
{
category: 'Lambda',
examples: sampleQueries.lambdaSamples,
},
{
category: 'VPC Flow Logs',
examples: sampleQueries.vpcSamples,
},
{
category: 'CloudTrail Logs',
examples: sampleQueries.cloudtrailSamples,
},
{
category: 'NAT Gateway',
examples: sampleQueries.natSamples,
},
{
category: 'AWS App Sync',
examples: sampleQueries.appSyncSamples,
},
{
category: 'IOT queries',
examples: sampleQueries.iotSamples,
},
];
function renderHighlightedMarkup(
code: string,
keyPrefix: string,
queryLanugage: LogsQueryLanguage = LogsQueryLanguage.CWLI
) {
const grammar = getGrammarForLanguage(queryLanugage);
const tokens = flattenTokens(Prism.tokenize(code, grammar));
const spans = tokens
.filter((token) => typeof token !== 'string')
.map((token, i) => {
return (
{token.content}
);
});
return
{spans}
;
}
interface CollapseProps {
key?: string;
label: string;
children: React.ReactNode;
}
const CheatSheetCollapse = (props: CollapseProps) => {
const [isOpen, setIsOpen] = useState(false);
return (
{props.children}
);
};
type Props = {
onClickExample: (query: CloudWatchQuery) => void;
query: CloudWatchQuery;
};
const isLogsQuery = (query: CloudWatchQuery): query is CloudWatchLogsQuery => query.queryMode === 'Logs';
const LogsCheatSheet = (props: Props) => {
const styles = useStyles2(getStyles);
const queryLanguage: LogsQueryLanguage =
(isLogsQuery(props.query) && props.query.queryLanguage) || LogsQueryLanguage.CWLI;
const onClickExample = (query: sampleQueries.SampleQuery, queryCategory: string) => {
props.onClickExample({
...props.query,
refId: props.query.refId ?? 'A',
expression: query.expr[queryLanguage],
queryMode: 'Logs',
region: props.query.region,
id: props.query.refId ?? 'A',
logGroupNames: 'logGroupNames' in props.query ? props.query.logGroupNames : [],
logGroups: 'logGroups' in props.query ? props.query.logGroups : [],
});
trackSampleQuerySelection({ queryLanguage, queryCategory });
};
return (
CloudWatch Logs cheat sheet
{QUERIES.map((query, i) => (
{query.examples.map((item, j) => (
<>
{item.expr[queryLanguage] && (
<>
{item.title}
>
)}
>
))}
))}
);
};
export default LogsCheatSheet;
const getStyles = (theme: GrafanaTheme2) => ({
heading: css({
marginBottom: theme.spacing(2),
}),
link: css({
textDecoration: 'underline',
}),
cheatSheetExample: css({
margin: theme.spacing(0.5, 0),
// element is interactive, clear button styles
textAlign: 'left',
border: 'none',
background: 'transparent',
display: 'block',
}),
});
const getGrammarForLanguage = (queryLanugage: LogsQueryLanguage) => {
switch (queryLanugage) {
case LogsQueryLanguage.CWLI:
return cwliTokenizer;
case LogsQueryLanguage.PPL:
return pplTokenizer;
case LogsQueryLanguage.SQL:
return sqlTokenizer;
}
};