diff --git a/src/modules/real-time-metrics/chart/format-c3-graph-props.js b/src/modules/real-time-metrics/chart/format-c3-graph-props.js index a3d787a8f..7c552ba7f 100644 --- a/src/modules/real-time-metrics/chart/format-c3-graph-props.js +++ b/src/modules/real-time-metrics/chart/format-c3-graph-props.js @@ -275,6 +275,7 @@ function generateMeanLineValues(resultChart, mean) { * @returns {string} - The title case string */ export function camelToTitle(text) { + if (!text) return return text .replace(/([a-z])([A-Z0-9])/g, '$1 $2') .replace(/\s+/g, ' ') @@ -332,7 +333,7 @@ export function getSeriesInfos(resultChart, chartData, hasMeanLineSeries, hasMea seriesTotal /= series.length - 1 } const formattedSeriesTotal = formatYAxisLabels(seriesTotal, chartData) - const seriesName = camelToTitle(series[0]) + const seriesName = !chartData?.doNotConvertToCamelCase ? camelToTitle(series[0]) : series[0] const renamedSeries = `${seriesName} - ${formattedSeriesTotal}` seriesNames = { ...seriesNames, [series[0]]: renamedSeries } @@ -366,10 +367,10 @@ export function getSeriesInfos(resultChart, chartData, hasMeanLineSeries, hasMea * @param {Array} tooltipData - The tooltip data to reset * @returns {Array} - The tooltip data with the label reset */ -function resetTooltipLabel(tooltipData) { +function resetTooltipLabel(tooltipData, chartData) { return tooltipData.map((item) => ({ ...item, - name: camelToTitle(item.id) + name: !chartData?.doNotConvertToCamelCase ? camelToTitle(item.id) : item.id })) } @@ -535,7 +536,7 @@ export function FormatC3GraphProps({ if (chartData.type === 'ordered-bar') { const { index } = d[0] return this.getTooltipContent( - resetTooltipLabel(d), + resetTooltipLabel(d, chartData), defaultTitleFormat, defaultValueFormat, () => CHART_RULES.BASE_COLOR_PATTERNS[index] @@ -543,7 +544,7 @@ export function FormatC3GraphProps({ } return this.getTooltipContent( - resetTooltipLabel(d), + resetTooltipLabel(d, chartData), defaultTitleFormat, defaultValueFormat, color diff --git a/src/modules/real-time-metrics/constants/chart-rules.js b/src/modules/real-time-metrics/constants/chart-rules.js index 98cac291a..03f440bce 100644 --- a/src/modules/real-time-metrics/constants/chart-rules.js +++ b/src/modules/real-time-metrics/constants/chart-rules.js @@ -16,6 +16,13 @@ const SCREEN_XSMALL_BREAKPOINT = 540 const MEAN_LINE_LABEL = 'Mean Line' +const COLUMN_NAMES_FIELD = { + sum: 'Total', + geolocCountryName: 'Country', + geolocAsn: 'ASN', + geolocRegionName: 'Region' +} + const DATA_VOLUME = { tera: 1e12, giga: 1073741824, @@ -82,7 +89,8 @@ const CHART_RULES = { BOTTOM_LEGEND_PADDING, BASE_COLOR_PATTERNS, MEAN_LINE_PATTERN, - GAUGE_COLOR_SCHEMA + GAUGE_COLOR_SCHEMA, + COLUMN_NAMES_FIELD } export default CHART_RULES diff --git a/src/modules/real-time-metrics/constants/dashboards.js b/src/modules/real-time-metrics/constants/dashboards.js index 7c5f14d59..8f2533235 100644 --- a/src/modules/real-time-metrics/constants/dashboards.js +++ b/src/modules/real-time-metrics/constants/dashboards.js @@ -53,6 +53,12 @@ const PAGES_DASHBOARDS = { label: 'Bandwidth Saving', path: 'bandwidth-saving', dataset: 'httpMetrics' + }, + { + id: '357549179454620240', + label: 'Request Breakdown', + path: 'request-breakdown', + dataset: 'httpBreakdownMetrics' } ] }, @@ -147,6 +153,20 @@ const PAGES_DASHBOARDS = { dataset: 'botManagerBreakdownMetrics' } ] + }, + { + id: 10, + label: 'Threats Breakdown', + path: 'threats', + groupId: 2, + dashboards: [ + { + id: '357548675837198934', + label: 'Threats Breakdown', + path: 'breakdown', + dataset: 'httpBreakdownMetrics' + } + ] } ], observe: [ diff --git a/src/modules/real-time-metrics/constants/help-center-urls.js b/src/modules/real-time-metrics/constants/help-center-urls.js index c7ccb84ee..fbc2feb43 100644 --- a/src/modules/real-time-metrics/constants/help-center-urls.js +++ b/src/modules/real-time-metrics/constants/help-center-urls.js @@ -26,6 +26,8 @@ const HELP_CENTER_URLS = { '/real-time-metrics/edge-applications/requests/missed-requests-per-second', missedRequests: '/real-time-metrics/edge-applications/requests/missed-requests', requestsByMethod: '/real-time-metrics/edge-applications/requests/requests-by-method', + averageRequestTime: '/real-time-metrics/edge-applications/requests/average-request-time', + requestByScheme: '/real-time-metrics/edge-applications/requests/request-by-scheme', requestsOffloaded: '/real-time-metrics/edge-applications/requests/requests-offloaded', requestsPerSecondOffloaded: '/real-time-metrics/edge-applications/requests/requests-per-second-offloaded', @@ -40,7 +42,8 @@ const HELP_CENTER_URLS = { httpStatusCodes2xx: '/real-time-metrics/edge-applications/status-codes/http-status-codes-2xx', httpStatusCodes3xx: '/real-time-metrics/edge-applications/status-codes/http-status-codes-3xx', httpStatusCodes4xx: '/real-time-metrics/edge-applications/status-codes/http-status-codes-4xx', - httpStatusCodes5xx: '/real-time-metrics/edge-applications/status-codes/http-status-codes-5xx' + httpStatusCodes5xx: '/real-time-metrics/edge-applications/status-codes/http-status-codes-5xx', + statusUpstream: '/real-time-metrics/edge-applications/status-codes/status-upstream' } }, edgeFunctions: { @@ -84,6 +87,7 @@ const HELP_CENTER_URLS = { botHits: '/real-time-metrics/bot-manager-advanced/overview/bot-hits', transactions: '/real-time-metrics/bot-manager-advanced/overview/transactions', botTraffic: '/real-time-metrics/bot-manager-advanced/overview/bot-traffic', + topBotTraffic: '/real-time-metrics/bot-manager-advanced/overview/top-bot-traffic', topBotAction: '/real-time-metrics/bot-manager-advanced/overview/top-bot-action', botCaptchaLine: '/real-time-metrics/bot-manager-advanced/overview/bot-captcha-line-graph', topBotCaptchaPie: @@ -97,6 +101,9 @@ const HELP_CENTER_URLS = { topBadBotIps: '/real-time-metrics/bot-manager-advanced/breakdown/top-bad-bot-ips', topImpactedUrls: '/real-time-metrics/bot-manager-advanced/breakdown/top-impacted-urls' } + }, + threatsBreakdown: { + threatsRequestsByIps: '/real-time-metrics/threats/breakdown' } } diff --git a/src/modules/real-time-metrics/constants/reports-texts.js b/src/modules/real-time-metrics/constants/reports-texts.js index e4255afc7..12dcaea6a 100644 --- a/src/modules/real-time-metrics/constants/reports-texts.js +++ b/src/modules/real-time-metrics/constants/reports-texts.js @@ -85,11 +85,11 @@ const REPORTS_TEXTS = { statusCodes: { httpStatusCodes2xx: { description: - 'Indicates user requests that were received, understood, accepted, and processed by the server. Displays Requests Status Code 200, Requests Status Code 204, Requests Status Code 206, and Requests Status Code 2xx.' + 'Indicates successful responses to user requests. Displays Request Status Code 200 and other 2xx status codes.' }, httpStatusCodes3xx: { description: - 'Indicates user requests that were redirected and had to go through another stage to be delivered. Displays Requests Status Code 301, Requests Status Code 302, Requests Status Code 304, and Requests Status Code 3xx.' + 'Indicates redirections that have occurred with user requests. Displays Request Status Code 300 and other 3xx status codes.' }, httpStatusCodes4xx: { description: @@ -98,6 +98,15 @@ const REPORTS_TEXTS = { httpStatusCodes5xx: { description: 'Indicates the server failed to deliver an apparently valid request. Displays Requests Status Code 500, Requests Status Code 502, Requests Status Code 503, and Requests Status Code 5xx.' + }, + statusUpstream: { + description: 'Top 10 Status and Upstream Status that had the most requests.' + } + }, + requestBreakdown: { + iPAddressInformation: { + description: + 'Displays the distribution of requests by region, country, ASN, and individual IP address.' } }, waf: { @@ -125,7 +134,11 @@ const REPORTS_TEXTS = { httpMethods: { requestsByMethod: { description: - 'Total requests made to your domain divided by the HTTP method used. Displays methods Requests Http Method Get, Requests Http Method Post, Requests Http Method Head, and Requests Http Method Others.' + 'Sum of requests for each HTTP method during the selected period. Displays the overall request count for each method.' + }, + averageRequestTime: { + description: + 'Average request duration over time. Displays how long requests take on average, in seconds.' } }, bandwidthSaving: { diff --git a/src/modules/real-time-metrics/constants/reports.js b/src/modules/real-time-metrics/constants/reports.js index c680ab249..13c128f18 100644 --- a/src/modules/real-time-metrics/constants/reports.js +++ b/src/modules/real-time-metrics/constants/reports.js @@ -384,18 +384,73 @@ const REPORTS = [ rotated: false, dataset: 'httpMetrics', dataUnit: 'count', - limit: 5000, - fields: [ - 'requestsHttpMethodGet', - 'requestsHttpMethodPost', - 'requestsHttpMethodHead', - 'requestsHttpMethodOthers' + limit: 10000, + aggregations: [ + { + aggregation: 'sum', + variable: 'requests' + } ], - groupBy: [], + fields: [], + groupBy: ['ts', 'requestMethod'], orderDirection: 'ASC', dashboardId: '357548623571976783', helpCenterPath: HELP_CENTER_URLS.edgeApplications.requests.requestsByMethod }, + { + id: '357825388709151310', + chartOwner: 'azion', + label: 'Average Request Time', + description: REPORTS_TEXTS.edgeApplications.httpMethods.averageRequestTime.description, + aggregationType: 'avg', + columns: 6, + type: 'line', + xAxis: 'ts', + isTopX: false, + rotated: false, + dataset: 'httpMetrics', + dataUnit: 'perSecond', + limit: 10000, + fields: [], + groupBy: [], + aggregations: [ + { + aggregation: 'avg', + variable: 'requestTime' + } + ], + orderDirection: 'ASC', + variationType: 'inverse', + dashboardId: '357548623571976783', + helpCenterPath: HELP_CENTER_URLS.edgeApplications.requests.averageRequestTime + }, + { + id: '357825388709151312', + chartOwner: 'azion', + label: 'Requests by Scheme', + description: 'Sum of requests, categorized by scheme, over the selected period.', + aggregationType: 'sum', + columns: 6, + type: 'line', + xAxis: 'ts', + isTopX: false, + rotated: false, + dataset: 'httpMetrics', + dataUnit: 'count', + limit: 10000, + fields: [], + groupBy: ['ts', 'scheme'], + aggregations: [ + { + aggregation: 'sum', + variable: 'requests' + } + ], + orderDirection: 'ASC', + variationType: 'inverse', + dashboardId: '357548623571976783', + helpCenterPath: HELP_CENTER_URLS.edgeApplications.requests.requestByScheme + }, /** * BUILD * Edge Applications - Status Codes @@ -413,14 +468,21 @@ const REPORTS = [ rotated: false, dataset: 'httpMetrics', dataUnit: 'count', - limit: 5000, - fields: [ - 'requestsStatusCode200', - 'requestsStatusCode204', - 'requestsStatusCode206', - 'requestsStatusCode2xx' + limit: 10000, + aggregations: [ + { + aggregation: 'sum', + variable: 'requests' + } ], - groupBy: [], + filters: { + statusRange: { + begin: 200, + end: 299 + } + }, + fields: [], + groupBy: ['ts', 'status'], orderDirection: 'ASC', dashboardId: '357548642810200653', helpCenterPath: HELP_CENTER_URLS.edgeApplications.statusCodes.httpStatusCodes2xx @@ -438,14 +500,21 @@ const REPORTS = [ rotated: false, dataset: 'httpMetrics', dataUnit: 'count', - limit: 5000, - fields: [ - 'requestsStatusCode301', - 'requestsStatusCode302', - 'requestsStatusCode304', - 'requestsStatusCode3xx' + limit: 10000, + aggregations: [ + { + aggregation: 'sum', + variable: 'requests' + } ], - groupBy: [], + filters: { + statusRange: { + begin: 300, + end: 399 + } + }, + fields: [], + groupBy: ['ts', 'status'], orderDirection: 'ASC', dashboardId: '357548642810200653', helpCenterPath: HELP_CENTER_URLS.edgeApplications.statusCodes.httpStatusCodes3xx @@ -500,6 +569,34 @@ const REPORTS = [ dashboardId: '357548642810200653', helpCenterPath: HELP_CENTER_URLS.edgeApplications.statusCodes.httpStatusCodes5xx }, + { + id: '357825388709151322', + chartOwner: 'azion', + label: 'Requests by Status and Upstream Status ', + description: + 'Sum of processed requests, broken down by the top status and upstream status categories responsible for the most flagged requests.', + aggregationType: 'sum', + columns: 6, + type: 'list', + xAxis: 'cat', + isTopX: false, + rotated: false, + dataset: 'httpMetrics', + dataUnit: 'count', + limit: 10, + fields: ['status', 'upstreamStatus'], + groupBy: ['status', 'upstreamStatus'], + aggregations: [ + { + aggregation: 'sum', + variable: 'requests' + } + ], + orderDirection: 'DESC', + variationType: 'inverse', + dashboardId: '357548642810200653', + helpCenterPath: HELP_CENTER_URLS.edgeApplications.requests.averageRequestTime + }, /** * BUILD * Edge Applications - Bandwidth Saving @@ -525,6 +622,39 @@ const REPORTS = [ variationType: 'regular', helpCenterPath: HELP_CENTER_URLS.edgeApplications.bandwidthSaving.bandwidthSaving }, + + /** + * BUILD + * Resquest Breakdown + */ + { + id: '357825388709151326', + chartOwner: 'azion', + label: 'IP Address Information', + description: REPORTS_TEXTS.edgeApplications.requestBreakdown.iPAddressInformation.description, + aggregationType: 'sum', + columns: 12, + type: 'list', + xAxis: 'cat', + isTopX: false, + rotated: false, + dataset: 'httpBreakdownMetrics', + dataUnit: 'count', + limit: 10, + fields: ['remoteAddress', 'geolocAsn', 'geolocCountryName', 'geolocRegionName'], + groupBy: ['remoteAddress', 'geolocAsn', 'geolocCountryName', 'geolocRegionName'], + aggregations: [ + { + aggregation: 'sum', + variable: 'requests' + } + ], + orderDirection: 'DESC', + variationType: 'inverse', + dashboardId: '357549179454620240', + helpCenterPath: HELP_CENTER_URLS.edgeApplications.requests.averageRequestTime + }, + /** * BUILD * Tiered Cache - Caching Offload @@ -800,6 +930,136 @@ const REPORTS = [ variationType: 'inverse', helpCenterPath: HELP_CENTER_URLS.waf.threats.otherThreats }, + { + id: '357842851576414806', + chartOwner: 'azion', + label: 'Top WAF Threat Requests by Country', + description: + 'Sum of requests identified as threats by WAF, broken down by the top countries responsible for the most flagged requests. Displays the data in percentages.', + aggregationType: 'sum', + columns: 6, + type: 'pie', + xAxis: 'cat', + isTopX: true, + rotated: false, + dataset: 'httpMetrics', + dataUnit: 'count', + limit: 20, + aggregations: [ + { + aggregation: 'sum', + variable: 'requests' + } + ], + filters: { + wafBlock: '1', + wafLearning: '0' + }, + fields: [], + groupBy: ['geolocCountryName'], + orderDirection: 'DESC', + dashboardId: '357548675837198933', + variationType: 'regular', + helpCenterPath: '/real-time-metrics/waf/threats/top-threat-requests-by-country' + }, + { + id: '357842851576414807', + chartOwner: 'azion', + label: 'Top WAF Threat Requests by Country', + description: + 'Sum of requests identified as threats by WAF, broken down by the top countries responsible for the most flagged requests. Displays the total amount of detected threats.', + aggregationType: 'sum', + columns: 6, + type: 'ordered-bar', + xAxis: 'cat', + isTopX: true, + rotated: true, + dataset: 'httpMetrics', + dataUnit: 'count', + limit: 20, + aggregations: [ + { + aggregation: 'sum', + variable: 'requests' + } + ], + filters: { + wafBlock: '1', + wafLearning: '0' + }, + fields: [], + groupBy: ['geolocCountryName'], + orderDirection: 'DESC', + dashboardId: '357548675837198933', + variationType: 'regular', + helpCenterPath: '/real-time-metrics/waf/threats/top-threat-requests-by-country' + }, + { + id: '357842851576414808', + chartOwner: 'azion', + label: 'WAF Threat Requests by Family Attack', + description: + 'Sum of requests identified as threats by WAF, broken down by the top attack families responsible for the most flagged requests. Displays the total amount of detected threats.', + aggregationType: 'sum', + columns: 6, + type: 'ordered-bar', + xAxis: 'cat', + isTopX: true, + rotated: true, + dataset: 'httpMetrics', + dataUnit: 'count', + limit: 10, + aggregations: [ + { + aggregation: 'sum', + variable: 'requests' + } + ], + filters: { + wafBlock: '1', + wafLearning: '0' + }, + fields: [], + groupBy: ['wafAttackFamily'], + orderDirection: 'DESC', + dashboardId: '357548675837198933', + variationType: 'regular', + helpCenterPath: '/real-time-metrics/waf/threats/top-threat-requests-by-family-attack' + }, + { + id: '357842851576414809', + chartOwner: 'azion', + label: 'WAF Threat Requests by Host', + description: + 'Sum of requests identified as threats by WAF, broken down by the top hosts responsible for the most flagged requests. Displays the total amount of detected threats.', + aggregationType: 'sum', + columns: 12, + type: 'line', + xAxis: 'ts', + isTopX: false, + rotated: false, + dataset: 'httpMetrics', + dataUnit: 'count', + limit: 10000, + aggregations: [ + { + aggregation: 'sum', + variable: 'requests' + } + ], + filters: { + wafBlock: '1', + wafLearning: '0' + }, + fields: [], + groupBy: ['ts', 'host'], + orderDirection: 'ASC', + dashboardId: '357548675837198933', + variationType: 'inverse', + helpCenterPath: '/real-time-metrics/waf/threats/waf-threat-requests-by-host', + doNotConvertToCamelCase: true, + largeTooltip: true + }, /** * SECURE * Edge DNS - Standard Queries @@ -977,6 +1237,33 @@ const REPORTS = [ variationType: 'regular', helpCenterPath: HELP_CENTER_URLS.botManager.botManagerOverview.botTraffic }, + { + id: '329891149133127509', + chartOwner: 'azion', + label: 'Top Bot Traffic', + description: + 'Sum of requests grouped by identifying traffic as Legitimate, Bad Bot, Good Bot, and Under Evaluation.', + aggregationType: 'sum', + columns: 6, + type: 'pie', + xAxis: 'cat', + isTopX: true, + rotated: false, + dataUnit: 'count', + dataset: 'botManagerMetrics', + aggregations: [ + { + aggregation: 'sum', + variable: 'requests' + } + ], + limit: 10000, + groupBy: ['classified'], + orderDirection: 'ASC', + dashboardId: '371360344901061482', + variationType: 'regular', + helpCenterPath: HELP_CENTER_URLS.botManager.botManagerOverview.topBotTraffic + }, { id: '577704475532819772', chartOwner: 'azion', @@ -1102,7 +1389,7 @@ const REPORTS = [ label: 'Bot Activity Map', description: REPORTS_TEXTS.botManager.botManagerOverview.botActivityMap.description, aggregationType: 'sum', - columns: 6, + columns: 12, type: 'map', xAxis: 'cat', isTopX: true, @@ -1264,6 +1551,35 @@ const REPORTS = [ dashboardId: '352149476039721549', variationType: 'regular', helpCenterPath: HELP_CENTER_URLS.dataStream.requests.totalRequests + }, + { + id: '424388331488145487', + chartOwner: 'azion', + label: 'Top WAF Threat Requests by IP', + description: + 'Sum of requests identified as threats by WAF, broken down by the top IP addresses responsible for the most flagged requests.', + aggregationType: 'sum', + columns: 6, + type: 'ordered-bar', + xAxis: 'cat', + isTopX: true, + rotated: true, + dataUnit: 'count', + dataset: 'httpBreakdownMetrics', + aggregations: [ + { + aggregation: 'sum', + variable: 'wafThreatRequests' + } + ], + filters: {}, + limit: 10, + groupBy: ['remoteAddress'], + fields: ['remoteAddress'], + orderDirection: 'DESC', + dashboardId: '357548675837198934', + variationType: 'regular', + helpCenterPath: HELP_CENTER_URLS.threatsBreakdown.threatsRequestsByIps } ] diff --git a/src/modules/real-time-metrics/filters/filter-to-graphql-string.js b/src/modules/real-time-metrics/filters/filter-to-graphql-string.js index 1faadc149..9103e2c36 100644 --- a/src/modules/real-time-metrics/filters/filter-to-graphql-string.js +++ b/src/modules/real-time-metrics/filters/filter-to-graphql-string.js @@ -8,6 +8,15 @@ const shouldReplaceString = (value) => { return (value === '' || Number.isNaN(+value)) && value.charAt(0) !== '$' } +/** + * Check if the input is a string and does not start with '$' + * @param {any} value - The input to be checked + * @returns {boolean} - Returns true if the input is a string and does not start with '$', otherwise returns false + */ +function isValidString(value) { + return typeof value === 'string' && value.charAt(0) !== '$' +} + /** * Generates the GraphQL string for a filter. * @@ -37,6 +46,8 @@ export default function FiltersToGraphQLString(name, value) { // escape strings if (shouldReplaceString(value)) { queryValue = `"${value.replace(/^\\\$/, '$')}"` + } else if (isValidString(value)) { + queryValue = `"${value}"` } result += queryValue } diff --git a/src/modules/real-time-metrics/reports/convert-beholder-to-chart.js b/src/modules/real-time-metrics/reports/convert-beholder-to-chart.js index ce36c00d5..cf61d2b4a 100644 --- a/src/modules/real-time-metrics/reports/convert-beholder-to-chart.js +++ b/src/modules/real-time-metrics/reports/convert-beholder-to-chart.js @@ -2,7 +2,6 @@ import { CHART_RULES } from '@modules/real-time-metrics/constants' import { formatDataUnit } from '../chart/format-graph' -import countries from '../helpers/countries-code.json' import { formatYAxisLabels, @@ -416,6 +415,7 @@ const formatRotatedBarChartData = ({ report, data }) => { const values = [dataUnit] const TOP_IMPACTED_URLS_CHART = '1030427483148242' + const WAF_THREAT_REQUEST_BY_FAMILY_ATTACK_CHART = '357842851576414808' data[dataset].forEach((item) => { report.id !== TOP_IMPACTED_URLS_CHART @@ -424,6 +424,13 @@ const formatRotatedBarChartData = ({ report, data }) => { values.push(item[aggregation] || item[fieldName]) }) + if (report.id === WAF_THREAT_REQUEST_BY_FAMILY_ATTACK_CHART) { + const newSeries = series.map((value) => + typeof value === 'string' ? value.replaceAll('$', '') : value + ) + return [newSeries, values] + } + return [series, values] } @@ -466,37 +473,33 @@ const formatBigNumbers = ({ report, data }) => { * @param {Array} data - The data to be formatted. */ const formatListChart = ({ report, data }) => { - const dataset = Object.keys(data) - const fieldsRequest = Object.keys(data[dataset][0]) - const fieldNames = report.fields - const fieldCountryName = report.groupBy[0] - - const dataValue = data[dataset].map((obj) => { - const extractedObj = {} - fieldNames.forEach((key) => { - extractedObj[key] = formatYAxisLabels(obj[key], report) - extractedObj[fieldCountryName] = { - code: countries[obj[fieldCountryName]] || '-', - country: obj[fieldCountryName] - } - }) + const datasetKey = report.dataset + const dataset = data[datasetKey] || [] - return { ...obj, ...extractedObj } - }) + if (!dataset.length) return { data: [], columns: [] } + + const { fields, aggregations } = report + const fieldsHandle = [...new Set(fields)] + + const aggregationKey = aggregations[0]?.aggregation - const header = fieldsRequest.map((field) => camelToTitle(field)) + if (!aggregationKey) return { data: [], columns: [] } - const columns = fieldsRequest.map((field, index) => ({ - field: field, - header: header[index] + // Formata os valores da agregação para exibição + const formattedData = dataset.map((item) => ({ + ...item, + [aggregationKey]: formatDataUnit(item[aggregationKey], report)?.value })) - return [ - { - data: dataValue, - columns - } - ] + fieldsHandle.push(aggregationKey) + + // Define as colunas com os nomes corretos + const columns = fieldsHandle.map((field) => ({ + field, + header: CHART_RULES.COLUMN_NAMES_FIELD[field] || camelToTitle(field) + })) + + return [{ data: formattedData, columns }] } const formatMapChartData = ({ report, data }) => { diff --git a/src/templates/advanced-filter/dialog-filter.vue b/src/templates/advanced-filter/dialog-filter.vue index 2397fa2bd..b2a4a080e 100644 --- a/src/templates/advanced-filter/dialog-filter.vue +++ b/src/templates/advanced-filter/dialog-filter.vue @@ -171,6 +171,8 @@ const operatorType = filterSelected.operator[0].value.type if (['Boolean', 'StringObject'].includes(operatorType)) { data.value = selectedValue + } else if (['Like', 'Ilike'].includes(operatorSelected.value)) { + data.value = `%${selectedValue}%` } else { data.value = selectedValue ?? { begin, end } } diff --git a/src/templates/graphs-card-block/components/chart/line-chart.vue b/src/templates/graphs-card-block/components/chart/line-chart.vue index 902f545ae..a60d01543 100644 --- a/src/templates/graphs-card-block/components/chart/line-chart.vue +++ b/src/templates/graphs-card-block/components/chart/line-chart.vue @@ -1,6 +1,6 @@ + + diff --git a/src/templates/graphs-card-block/components/chart/list-chart.vue b/src/templates/graphs-card-block/components/chart/list-chart.vue index a40f13dc7..babb3278e 100644 --- a/src/templates/graphs-card-block/components/chart/list-chart.vue +++ b/src/templates/graphs-card-block/components/chart/list-chart.vue @@ -1,58 +1,23 @@ - + diff --git a/src/templates/graphs-card-block/components/chart/pie-chart.vue b/src/templates/graphs-card-block/components/chart/pie-chart.vue index d8026fdce..5fbdf19eb 100644 --- a/src/templates/graphs-card-block/components/chart/pie-chart.vue +++ b/src/templates/graphs-card-block/components/chart/pie-chart.vue @@ -15,7 +15,7 @@ const generateGraph = () => { const c3Props = FormatC3GraphProps({ chartData: props.chartData, - resultChart: props.resultChart + resultChart: filterEmptyValues(props.resultChart) }) c3.generate({ @@ -23,6 +23,10 @@ ...c3Props }) } + + const filterEmptyValues = (data) => { + return data.filter((item) => item[0] !== undefined && item[0] !== null) + } diff --git a/src/templates/list-table-block/graphic.vue b/src/templates/list-table-block/graphic.vue new file mode 100644 index 000000000..fe0bb94a6 --- /dev/null +++ b/src/templates/list-table-block/graphic.vue @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + {{ emptyListMessage }} + + + + + + + + + diff --git a/src/templates/list-table-block/index.vue b/src/templates/list-table-block/index.vue index 2e1bf3335..f5b2649b4 100644 --- a/src/templates/list-table-block/index.vue +++ b/src/templates/list-table-block/index.vue @@ -11,6 +11,7 @@ :pt="props.pt" @rowReorder="onRowReorder" scrollable + :scrollHeight="props.scrollHeight" removableSort :value="data" dataKey="id" @@ -354,6 +355,10 @@ required: true, type: Function }, + scrollHeight: { + type: String, + default: () => '' + }, enableEditClick: { type: Boolean, default: true diff --git a/src/tests/modules/real-time-metrics/constants/chart-rules.test.js b/src/tests/modules/real-time-metrics/constants/chart-rules.test.js index 524aeffd5..e226215b4 100644 --- a/src/tests/modules/real-time-metrics/constants/chart-rules.test.js +++ b/src/tests/modules/real-time-metrics/constants/chart-rules.test.js @@ -28,6 +28,12 @@ describe('RealTimeMetricsModule', () => { ts: 'timeseries', cat: 'category' }, + COLUMN_NAMES_FIELD: { + geolocAsn: 'ASN', + geolocCountryName: 'Country', + geolocRegionName: 'Region', + sum: 'Total' + }, LABEL: { width: 50, rotatedWidth: 80, diff --git a/src/tests/modules/real-time-metrics/constants/dashboards.test.js b/src/tests/modules/real-time-metrics/constants/dashboards.test.js index 11f78f40e..229f82e5b 100644 --- a/src/tests/modules/real-time-metrics/constants/dashboards.test.js +++ b/src/tests/modules/real-time-metrics/constants/dashboards.test.js @@ -43,6 +43,12 @@ describe('RealTimeMetricsModule', () => { label: 'Bandwidth Saving', path: 'bandwidth-saving', dataset: 'httpMetrics' + }, + { + dataset: 'httpBreakdownMetrics', + id: '357549179454620240', + label: 'Request Breakdown', + path: 'request-breakdown' } ] }, @@ -142,6 +148,20 @@ describe('RealTimeMetricsModule', () => { dataset: 'botManagerBreakdownMetrics' } ] + }, + { + id: 10, + label: 'Threats Breakdown', + path: 'threats', + groupId: 2, + dashboards: [ + { + id: '357548675837198934', + label: 'Threats Breakdown', + path: 'breakdown', + dataset: 'httpBreakdownMetrics' + } + ] } ] }, diff --git a/src/tests/modules/real-time-metrics/constants/reports.test.js b/src/tests/modules/real-time-metrics/constants/reports.test.js index 0003a1564..7e54d9546 100644 --- a/src/tests/modules/real-time-metrics/constants/reports.test.js +++ b/src/tests/modules/real-time-metrics/constants/reports.test.js @@ -375,19 +375,75 @@ describe('RealTimeMetricsModule', () => { dataUnit: 'count', dataset: 'httpMetrics', description: - 'Total requests made to your domain divided by the HTTP method used. Displays methods Requests Http Method Get, Requests Http Method Post, Requests Http Method Head, and Requests Http Method Others.', - fields: [ - 'requestsHttpMethodGet', - 'requestsHttpMethodPost', - 'requestsHttpMethodHead', - 'requestsHttpMethodOthers' + 'Sum of requests for each HTTP method during the selected period. Displays the overall request count for each method.', + fields: [], + groupBy: ['ts', 'requestMethod'], + aggregations: [ + { + aggregation: 'sum', + variable: 'requests' + } ], - groupBy: [], helpCenterPath: '/real-time-metrics/edge-applications/requests/requests-by-method', id: '357825388709151309', isTopX: false, label: 'Requests by Method', - limit: 5000, + limit: 10000, + orderDirection: 'ASC', + rotated: false, + type: 'line', + xAxis: 'ts' + }, + { + aggregationType: 'avg', + chartOwner: 'azion', + columns: 6, + dashboardId: '357548623571976783', + dataUnit: 'perSecond', + dataset: 'httpMetrics', + description: + 'Average request duration over time. Displays how long requests take on average, in seconds.', + fields: [], + groupBy: [], + aggregations: [ + { + aggregation: 'avg', + variable: 'requestTime' + } + ], + helpCenterPath: '/real-time-metrics/edge-applications/requests/average-request-time', + id: '357825388709151310', + variationType: 'inverse', + isTopX: false, + label: 'Average Request Time', + limit: 10000, + orderDirection: 'ASC', + rotated: false, + type: 'line', + xAxis: 'ts' + }, + { + aggregationType: 'sum', + chartOwner: 'azion', + columns: 6, + dashboardId: '357548623571976783', + dataUnit: 'count', + dataset: 'httpMetrics', + description: 'Sum of requests, categorized by scheme, over the selected period.', + fields: [], + groupBy: ['ts', 'scheme'], + aggregations: [ + { + aggregation: 'sum', + variable: 'requests' + } + ], + helpCenterPath: '/real-time-metrics/edge-applications/requests/request-by-scheme', + id: '357825388709151312', + variationType: 'inverse', + isTopX: false, + label: 'Requests by Scheme', + limit: 10000, orderDirection: 'ASC', rotated: false, type: 'line', @@ -401,19 +457,26 @@ describe('RealTimeMetricsModule', () => { dataUnit: 'count', dataset: 'httpMetrics', description: - 'Indicates user requests that were received, understood, accepted, and processed by the server. Displays Requests Status Code 200, Requests Status Code 204, Requests Status Code 206, and Requests Status Code 2xx.', - fields: [ - 'requestsStatusCode200', - 'requestsStatusCode204', - 'requestsStatusCode206', - 'requestsStatusCode2xx' - ], - groupBy: [], + 'Indicates successful responses to user requests. Displays Request Status Code 200 and other 2xx status codes.', + fields: [], + groupBy: ['ts', 'status'], helpCenterPath: '/real-time-metrics/edge-applications/status-codes/http-status-codes-2xx', id: '357824919768138325', isTopX: false, label: 'HTTP Status Codes 2XX', - limit: 5000, + limit: 10000, + aggregations: [ + { + aggregation: 'sum', + variable: 'requests' + } + ], + filters: { + statusRange: { + begin: 200, + end: 299 + } + }, orderDirection: 'ASC', rotated: false, type: 'line', @@ -427,19 +490,26 @@ describe('RealTimeMetricsModule', () => { dataUnit: 'count', dataset: 'httpMetrics', description: - 'Indicates user requests that were redirected and had to go through another stage to be delivered. Displays Requests Status Code 301, Requests Status Code 302, Requests Status Code 304, and Requests Status Code 3xx.', - fields: [ - 'requestsStatusCode301', - 'requestsStatusCode302', - 'requestsStatusCode304', - 'requestsStatusCode3xx' - ], - groupBy: [], + 'Indicates redirections that have occurred with user requests. Displays Request Status Code 300 and other 3xx status codes.', + fields: [], + groupBy: ['ts', 'status'], helpCenterPath: '/real-time-metrics/edge-applications/status-codes/http-status-codes-3xx', id: '357825000731837013', isTopX: false, label: 'HTTP Status Codes 3XX', - limit: 5000, + limit: 10000, + aggregations: [ + { + aggregation: 'sum', + variable: 'requests' + } + ], + filters: { + statusRange: { + begin: 300, + end: 399 + } + }, orderDirection: 'ASC', rotated: false, type: 'line', @@ -497,6 +567,34 @@ describe('RealTimeMetricsModule', () => { type: 'line', xAxis: 'ts' }, + { + aggregationType: 'sum', + aggregations: [ + { + aggregation: 'sum', + variable: 'requests' + } + ], + chartOwner: 'azion', + columns: 6, + dashboardId: '357548642810200653', + dataUnit: 'count', + dataset: 'httpMetrics', + description: + 'Sum of processed requests, broken down by the top status and upstream status categories responsible for the most flagged requests.', + fields: ['status', 'upstreamStatus'], + groupBy: ['status', 'upstreamStatus'], + helpCenterPath: '/real-time-metrics/edge-applications/requests/average-request-time', + id: '357825388709151322', + isTopX: false, + label: 'Requests by Status and Upstream Status ', + limit: 10, + orderDirection: 'DESC', + rotated: false, + type: 'list', + variationType: 'inverse', + xAxis: 'cat' + }, { aggregationType: 'sum', chartOwner: 'azion', @@ -519,6 +617,34 @@ describe('RealTimeMetricsModule', () => { variationType: 'regular', xAxis: 'ts' }, + { + aggregationType: 'sum', + aggregations: [ + { + aggregation: 'sum', + variable: 'requests' + } + ], + chartOwner: 'azion', + columns: 12, + dashboardId: '357549179454620240', + dataUnit: 'count', + dataset: 'httpBreakdownMetrics', + description: + 'Displays the distribution of requests by region, country, ASN, and individual IP address.', + fields: ['remoteAddress', 'geolocAsn', 'geolocCountryName', 'geolocRegionName'], + groupBy: ['remoteAddress', 'geolocAsn', 'geolocCountryName', 'geolocRegionName'], + helpCenterPath: '/real-time-metrics/edge-applications/requests/average-request-time', + id: '357825388709151326', + isTopX: false, + label: 'IP Address Information', + limit: 10, + orderDirection: 'DESC', + rotated: false, + type: 'list', + variationType: 'inverse', + xAxis: 'cat' + }, { aggregationType: 'sum', chartOwner: 'azion', @@ -784,6 +910,136 @@ describe('RealTimeMetricsModule', () => { variationType: 'inverse', xAxis: 'ts' }, + { + aggregationType: 'sum', + chartOwner: 'azion', + columns: 6, + dashboardId: '357548675837198933', + dataUnit: 'count', + dataset: 'httpMetrics', + description: + 'Sum of requests identified as threats by WAF, broken down by the top countries responsible for the most flagged requests. Displays the data in percentages.', + fields: [], + aggregations: [ + { + aggregation: 'sum', + variable: 'requests' + } + ], + filters: { + wafBlock: '1', + wafLearning: '0' + }, + groupBy: ['geolocCountryName'], + helpCenterPath: '/real-time-metrics/waf/threats/top-threat-requests-by-country', + id: '357842851576414806', + isTopX: true, + label: 'Top WAF Threat Requests by Country', + limit: 20, + orderDirection: 'DESC', + rotated: false, + type: 'pie', + variationType: 'regular', + xAxis: 'cat' + }, + { + aggregationType: 'sum', + chartOwner: 'azion', + columns: 6, + dashboardId: '357548675837198933', + dataUnit: 'count', + dataset: 'httpMetrics', + description: + 'Sum of requests identified as threats by WAF, broken down by the top countries responsible for the most flagged requests. Displays the total amount of detected threats.', + fields: [], + aggregations: [ + { + aggregation: 'sum', + variable: 'requests' + } + ], + filters: { + wafBlock: '1', + wafLearning: '0' + }, + groupBy: ['geolocCountryName'], + helpCenterPath: '/real-time-metrics/waf/threats/top-threat-requests-by-country', + id: '357842851576414807', + isTopX: true, + label: 'Top WAF Threat Requests by Country', + limit: 20, + orderDirection: 'DESC', + rotated: true, + type: 'ordered-bar', + variationType: 'regular', + xAxis: 'cat' + }, + { + aggregationType: 'sum', + chartOwner: 'azion', + columns: 6, + dashboardId: '357548675837198933', + dataUnit: 'count', + dataset: 'httpMetrics', + description: + 'Sum of requests identified as threats by WAF, broken down by the top attack families responsible for the most flagged requests. Displays the total amount of detected threats.', + fields: [], + aggregations: [ + { + aggregation: 'sum', + variable: 'requests' + } + ], + filters: { + wafBlock: '1', + wafLearning: '0' + }, + groupBy: ['wafAttackFamily'], + helpCenterPath: '/real-time-metrics/waf/threats/top-threat-requests-by-family-attack', + id: '357842851576414808', + isTopX: true, + label: 'WAF Threat Requests by Family Attack', + limit: 10, + orderDirection: 'DESC', + rotated: true, + type: 'ordered-bar', + variationType: 'regular', + xAxis: 'cat' + }, + { + aggregationType: 'sum', + chartOwner: 'azion', + columns: 12, + dashboardId: '357548675837198933', + dataUnit: 'count', + dataset: 'httpMetrics', + description: + 'Sum of requests identified as threats by WAF, broken down by the top hosts responsible for the most flagged requests. Displays the total amount of detected threats.', + fields: [], + aggregations: [ + { + aggregation: 'sum', + variable: 'requests' + } + ], + filters: { + wafBlock: '1', + wafLearning: '0' + }, + groupBy: ['ts', 'host'], + helpCenterPath: '/real-time-metrics/waf/threats/waf-threat-requests-by-host', + id: '357842851576414809', + isTopX: false, + label: 'WAF Threat Requests by Host', + limit: 10000, + orderDirection: 'ASC', + rotated: false, + type: 'line', + variationType: 'inverse', + xAxis: 'ts', + doNotConvertToCamelCase: true, + largeTooltip: true + }, { aggregationType: 'sum', aggregations: [ @@ -955,6 +1211,33 @@ describe('RealTimeMetricsModule', () => { variationType: 'regular', xAxis: 'ts' }, + { + aggregationType: 'sum', + aggregations: [ + { + aggregation: 'sum', + variable: 'requests' + } + ], + chartOwner: 'azion', + columns: 6, + dashboardId: '371360344901061482', + dataUnit: 'count', + dataset: 'botManagerMetrics', + description: + 'Sum of requests grouped by identifying traffic as Legitimate, Bad Bot, Good Bot, and Under Evaluation.', + groupBy: ['classified'], + helpCenterPath: '/real-time-metrics/bot-manager-advanced/overview/top-bot-traffic', + id: '329891149133127509', + isTopX: true, + label: 'Top Bot Traffic', + limit: 10000, + orderDirection: 'ASC', + rotated: false, + type: 'pie', + variationType: 'regular', + xAxis: 'cat' + }, { id: '577704475532819772', chartOwner: 'azion', @@ -1083,7 +1366,7 @@ describe('RealTimeMetricsModule', () => { label: 'Bot Activity Map', description: 'Sum of requests identified as bots, presented by the country of origin.', aggregationType: 'sum', - columns: 6, + columns: 12, type: 'map', xAxis: 'cat', isTopX: true, @@ -1240,6 +1523,35 @@ describe('RealTimeMetricsModule', () => { type: 'line', variationType: 'regular', xAxis: 'ts' + }, + { + id: '424388331488145487', + chartOwner: 'azion', + label: 'Top WAF Threat Requests by IP', + description: + 'Sum of requests identified as threats by WAF, broken down by the top IP addresses responsible for the most flagged requests.', + aggregationType: 'sum', + columns: 6, + type: 'ordered-bar', + xAxis: 'cat', + isTopX: true, + rotated: true, + dataUnit: 'count', + dataset: 'httpBreakdownMetrics', + aggregations: [ + { + aggregation: 'sum', + variable: 'wafThreatRequests' + } + ], + filters: {}, + limit: 10, + groupBy: ['remoteAddress'], + fields: ['remoteAddress'], + orderDirection: 'DESC', + dashboardId: '357548675837198934', + variationType: 'regular', + helpCenterPath: '/real-time-metrics/threats/breakdown' } ] diff --git a/src/tests/modules/real-time-metrics/reports/fixtures/gql-fixtures.js b/src/tests/modules/real-time-metrics/reports/fixtures/gql-fixtures.js index 270e839f5..bf3fe51f2 100644 --- a/src/tests/modules/real-time-metrics/reports/fixtures/gql-fixtures.js +++ b/src/tests/modules/real-time-metrics/reports/fixtures/gql-fixtures.js @@ -467,15 +467,77 @@ ts } } }, + { + id: '357825388709151310', + label: 'Average Request Time', + gqlQuery: { + query: `query ($tsRange_begin:DateTime!, $tsRange_end:DateTime!) { + httpMetrics ( + limit: 10000 + aggregate: {avg: requestTime +} + groupBy: [ts] + orderBy: [ts_ASC] + filter: { + tsRange: { +begin: $tsRange_begin +end: $tsRange_end + +} + + } + ) { + avg +ts + } + }`, + variables: { + tsRange_begin: '2024-01-01T12:00:00', + tsRange_end: '2024-12-01T12:00:00' + } + } + }, + { + id: '357825388709151312', + label: 'Requests by Scheme', + gqlQuery: { + query: `query ($tsRange_begin:DateTime!, $tsRange_end:DateTime!) { + httpMetrics ( + limit: 10000 + aggregate: {sum: requests +} + groupBy: [ts, scheme] + orderBy: [ts_ASC] + filter: { + tsRange: { +begin: $tsRange_begin +end: $tsRange_end + +} + + } + ) { + sum +ts +scheme + } + }`, + variables: { + tsRange_begin: '2024-01-01T12:00:00', + tsRange_end: '2024-12-01T12:00:00' + } + } + }, { id: '357825388709151309', label: 'Requests by Method', gqlQuery: { query: `query ($tsRange_begin:DateTime!, $tsRange_end:DateTime!) { httpMetrics ( - limit: 5000 - - groupBy: [ts] + limit: 10000 + aggregate: {sum: requests +} + groupBy: [ts, requestMethod] orderBy: [ts_ASC] filter: { tsRange: { @@ -486,11 +548,9 @@ end: $tsRange_end } ) { - requestsHttpMethodGet -requestsHttpMethodPost -requestsHttpMethodHead -requestsHttpMethodOthers + sum ts +requestMethod } }`, variables: { @@ -505,24 +565,28 @@ ts gqlQuery: { query: `query ($tsRange_begin:DateTime!, $tsRange_end:DateTime!) { httpMetrics ( - limit: 5000 - - groupBy: [ts] + limit: 10000 + aggregate: {sum: requests +} + groupBy: [ts, status] orderBy: [ts_ASC] filter: { tsRange: { begin: $tsRange_begin end: $tsRange_end +} +statusRange: { +begin: 200 +end: 299 + } } ) { - requestsStatusCode200 -requestsStatusCode204 -requestsStatusCode206 -requestsStatusCode2xx + sum ts +status } }`, variables: { @@ -537,24 +601,28 @@ ts gqlQuery: { query: `query ($tsRange_begin:DateTime!, $tsRange_end:DateTime!) { httpMetrics ( - limit: 5000 - - groupBy: [ts] + limit: 10000 + aggregate: {sum: requests +} + groupBy: [ts, status] orderBy: [ts_ASC] filter: { tsRange: { begin: $tsRange_begin end: $tsRange_end +} +statusRange: { +begin: 300 +end: 399 + } } ) { - requestsStatusCode301 -requestsStatusCode302 -requestsStatusCode304 -requestsStatusCode3xx + sum ts +status } }`, variables: { @@ -999,6 +1067,135 @@ ts } } }, + { + id: '357842851576414806', + label: 'Top WAF Threat Requests by Country', + gqlQuery: { + query: `query ($tsRange_begin:DateTime!, $tsRange_end:DateTime!) { + httpMetrics ( + limit: 20 + aggregate: {sum: requests +} + groupBy: [geolocCountryName] + orderBy: [sum_DESC] + filter: { + tsRange: { +begin: $tsRange_begin +end: $tsRange_end + +} +wafBlock: "1" +wafLearning: "0" + + } + ) { + sum +geolocCountryName + } + }`, + variables: { + tsRange_begin: '2024-01-01T12:00:00', + tsRange_end: '2024-12-01T12:00:00' + } + } + }, + { + id: '357842851576414807', + label: 'Top WAF Threat Requests by Country', + gqlQuery: { + query: `query ($tsRange_begin:DateTime!, $tsRange_end:DateTime!) { + httpMetrics ( + limit: 20 + aggregate: {sum: requests +} + groupBy: [geolocCountryName] + orderBy: [sum_DESC] + filter: { + tsRange: { +begin: $tsRange_begin +end: $tsRange_end + +} +wafBlock: "1" +wafLearning: "0" + + } + ) { + sum +geolocCountryName + } + }`, + variables: { + tsRange_begin: '2024-01-01T12:00:00', + tsRange_end: '2024-12-01T12:00:00' + } + } + }, + { + id: '357842851576414808', + label: 'WAF Threat Requests by Family Attack', + gqlQuery: { + query: `query ($tsRange_begin:DateTime!, $tsRange_end:DateTime!) { + httpMetrics ( + limit: 10 + aggregate: {sum: requests +} + groupBy: [wafAttackFamily] + orderBy: [sum_DESC] + filter: { + tsRange: { +begin: $tsRange_begin +end: $tsRange_end + +} +wafBlock: "1" +wafLearning: "0" + + } + ) { + sum +wafAttackFamily + } + }`, + variables: { + tsRange_begin: '2024-01-01T12:00:00', + tsRange_end: '2024-12-01T12:00:00' + } + } + }, + { + id: '357842851576414809', + label: 'WAF Threat Requests by Host', + gqlQuery: { + query: `query ($tsRange_begin:DateTime!, $tsRange_end:DateTime!) { + httpMetrics ( + limit: 10000 + aggregate: {sum: requests +} + groupBy: [ts, host] + orderBy: [ts_ASC] + filter: { + tsRange: { +begin: $tsRange_begin +end: $tsRange_end + +} +wafBlock: "1" +wafLearning: "0" + + } + ) { + sum +ts +host + } + }`, + variables: { + tsRange_begin: '2024-01-01T12:00:00', + tsRange_end: '2024-12-01T12:00:00' + } + } + }, { id: '357843490139298789', label: 'Total Queries', @@ -1174,6 +1371,36 @@ end: $tsRange_end ) { sum ts +classified + } + }`, + variables: { + tsRange_begin: '2024-01-01T12:00:00', + tsRange_end: '2024-12-01T12:00:00' + } + } + }, + { + id: '329891149133127509', + label: 'Top Bot Traffic', + gqlQuery: { + query: `query ($tsRange_begin:DateTime!, $tsRange_end:DateTime!) { + botManagerMetrics ( + limit: 10000 + aggregate: {sum: requests +} + groupBy: [classified] + orderBy: [sum_ASC] + filter: { + tsRange: { +begin: $tsRange_begin +end: $tsRange_end + +} + + } + ) { + sum classified } }`, @@ -1521,6 +1748,104 @@ ts tsRange_end: '2024-12-01T12:00:00' } } + }, + { + id: '424388331488145487', + label: 'Top WAF Threat Requests by IP', + description: 'Top 10 IPs that generated the most threats identified by the WAF', + gqlQuery: { + query: `query ($tsRange_begin:DateTime!, $tsRange_end:DateTime!) { + httpBreakdownMetrics ( + limit: 10 + aggregate: {sum: wafThreatRequests +} + groupBy: [remoteAddress] + orderBy: [sum_DESC] + filter: { + tsRange: { +begin: $tsRange_begin +end: $tsRange_end + +} + + } + ) { + remoteAddress +sum + } + }`, + variables: { + tsRange_begin: '2024-01-01T12:00:00', + tsRange_end: '2024-12-01T12:00:00' + } + } + }, + { + id: '357825388709151322', + label: 'Top WAF Threat Requests by IP', + description: 'Top 10 IPs that generated the most threats identified by the WAF', + gqlQuery: { + query: `query ($tsRange_begin:DateTime!, $tsRange_end:DateTime!) { + httpMetrics ( + limit: 10 + aggregate: {sum: requests +} + groupBy: [status, upstreamStatus] + orderBy: [sum_DESC] + filter: { + tsRange: { +begin: $tsRange_begin +end: $tsRange_end + +} + + } + ) { + status +upstreamStatus +sum + } + }`, + variables: { + tsRange_begin: '2024-01-01T12:00:00', + tsRange_end: '2024-12-01T12:00:00' + } + } + }, + { + id: '357825388709151326', + label: 'IP Address Information', + description: + 'Displays the distribution of requests by region, country, ASN, and individual IP address.', + gqlQuery: { + query: `query ($tsRange_begin:DateTime!, $tsRange_end:DateTime!) { + httpBreakdownMetrics ( + limit: 10 + aggregate: {sum: requests +} + groupBy: [remoteAddress, geolocAsn, geolocCountryName, geolocRegionName] + orderBy: [sum_DESC] + filter: { + tsRange: { +begin: $tsRange_begin +end: $tsRange_end + +} + + } + ) { + remoteAddress +geolocAsn +geolocCountryName +geolocRegionName +sum + } + }`, + variables: { + tsRange_begin: '2024-01-01T12:00:00', + tsRange_end: '2024-12-01T12:00:00' + } + } } ]
+ {{ emptyListMessage }} +