From 930b7ab54d9c70a913b4e5e5bc5c7e46ad1a7d86 Mon Sep 17 00:00:00 2001 From: Samik Roy Date: Tue, 24 Mar 2026 10:45:14 +0530 Subject: [PATCH 1/9] Add Cribl Workbook JSON configuration --- Solutions/Cribl/Workbooks/CriblWorkbook.json | 565 +++++++++++++++++++ 1 file changed, 565 insertions(+) create mode 100644 Solutions/Cribl/Workbooks/CriblWorkbook.json diff --git a/Solutions/Cribl/Workbooks/CriblWorkbook.json b/Solutions/Cribl/Workbooks/CriblWorkbook.json new file mode 100644 index 00000000000..7c0d9bfc681 --- /dev/null +++ b/Solutions/Cribl/Workbooks/CriblWorkbook.json @@ -0,0 +1,565 @@ +{ + "version": "Notebook/1.0", + "items": [ + { + "type": 1, + "content": { + "json": "# Cribl Workbook\r\n\r\nThis Workbook contains summary of \r\n\r\n\r\n| Access Logs | Audit Logs | Internal Logs | UI Access Logs|\r\n| -------------- | --------------- | -------------- |-------------- |\r\n|||||" + }, + "customWidth": "50", + "name": "text - 19" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "parameters": [ + { + "id": "007ea1ee-99dd-4c59-bc0f-7eb8b1e05c71", + "version": "KqlParameterItem/1.0", + "name": "TimeGenerated", + "type": 4, + "typeSettings": { + "selectableValues": [ + { + "durationMs": 300000 + }, + { + "durationMs": 900000 + }, + { + "durationMs": 1800000 + }, + { + "durationMs": 3600000 + }, + { + "durationMs": 14400000 + }, + { + "durationMs": 43200000 + }, + { + "durationMs": 86400000 + }, + { + "durationMs": 172800000 + }, + { + "durationMs": 259200000 + }, + { + "durationMs": 604800000 + }, + { + "durationMs": 1209600000 + }, + { + "durationMs": 2419200000 + }, + { + "durationMs": 2592000000 + }, + { + "durationMs": 5184000000 + }, + { + "durationMs": 7776000000 + } + ], + "allowCustom": true + }, + "timeContext": { + "durationMs": 86400000 + }, + "value": { + "durationMs": 86400000 + } + } + ], + "style": "pills", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "customWidth": "50", + "name": "parameters - 21" + }, + { + "type": 1, + "content": { + "json": "# Access Logs\n---\n", + "style": "info" + }, + "name": "text - 2" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "CriblAccess\n| summarize Count = count() by tostring(status)", + "size": 1, + "title": "Summary of HTTP Status Code", + "timeContextFromParameter": "TimeGenerated", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "piechart", + "chartSettings": { + "showMetrics": false, + "showLegend": true + } + }, + "customWidth": "33", + "name": "HTTP Status Code Overview" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "CriblAccess\n| summarize count() by method\n", + "size": 1, + "title": "Summary of HTTP Methods", + "timeContextFromParameter": "TimeGenerated", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "piechart", + "chartSettings": { + "showMetrics": false, + "showLegend": true + } + }, + "customWidth": "33", + "name": "HTTP Status Code Overview - Copy" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "CriblAccess\n| summarize Count = count() by src", + "size": 1, + "title": "Summary of Source", + "timeContextFromParameter": "TimeGenerated", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "table", + "gridSettings": { + "formatters": [ + { + "columnMatch": "Count", + "formatter": 8, + "formatOptions": { + "palette": "blue" + } + } + ] + } + }, + "customWidth": "33", + "name": "HTTP Status Code Overview - Copy - Copy - Copy" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "CriblAccess\n| summarize Hits = count() by url\n| top 10 by Hits\n", + "size": 0, + "title": "Top Accessed API Endpoints", + "timeContextFromParameter": "TimeGenerated", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "categoricalbar" + }, + "name": "Top Accessed API Endpoints" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "CriblAccess\n| where status >= 400\n| summarize ErrorCount = count() by tostring(status)\n| sort by ErrorCount desc\n", + "size": 0, + "title": "HTTP Error Code Summary", + "timeContextFromParameter": "TimeGenerated", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "barchart" + }, + "name": "HTTP Error Code Summary" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "CriblAccess\n| summarize AvgResponseTime = avg(response_time) by url\n| top 10 by AvgResponseTime\n\n", + "size": 0, + "title": "API Response Time Analysis", + "timeContextFromParameter": "TimeGenerated", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "unstackedbar" + }, + "name": "API Response Time Analysis" + }, + { + "type": 1, + "content": { + "json": "# Audit Logs\n---\n", + "style": "info" + }, + "name": "text - 2 - Copy" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "CriblAudit\n| summarize Count = count() by service\n", + "size": 1, + "title": "Summary of Servies", + "timeContextFromParameter": "TimeGenerated", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "gridSettings": { + "formatters": [ + { + "columnMatch": "Count", + "formatter": 8, + "formatOptions": { + "palette": "blue" + } + } + ] + } + }, + "customWidth": "50", + "name": "HTTP Status Code Overview - Copy - Copy" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "CriblAudit\n| summarize Count = count() by user\n| top 5 by Count\n", + "size": 1, + "title": "Top 5 Users by Audit Events", + "timeContextFromParameter": "TimeGenerated", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "piechart", + "chartSettings": { + "showMetrics": false, + "showLegend": true + } + }, + "customWidth": "50", + "name": "Top 5 Users by Audit Events" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "CriblAudit\n| summarize Count = count() by bin(event_time, {TimeGenerated:grain})\n", + "size": 0, + "title": "Requests Over Time", + "timeContextFromParameter": "TimeGenerated", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "timechart" + }, + "name": "Requests Over Time" + } + ] + }, + "name": "group - 32" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "CriblAudit\n| summarize Count = count() by action\n| order by Count desc\n", + "size": 0, + "title": "Most Performed Audit Actions", + "timeContextFromParameter": "TimeGenerated", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "unstackedbar" + }, + "name": "Most Performed Audit Actions" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "CriblAudit\n| summarize UniqueUsers = dcount(user) by action\n| order by UniqueUsers desc\n", + "size": 0, + "title": "User Participation by Action Type", + "timeContextFromParameter": "TimeGenerated", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "categoricalbar" + }, + "name": "User Participation by Action Type" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "CriblAudit\n| summarize Count = count() by bin(event_time, 5m)\n| order by event_time asc\n", + "size": 0, + "title": "Audit Event Activity Over Time", + "timeContextFromParameter": "TimeGenerated", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "timechart" + }, + "name": "Audit Event Activity Over Time" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "CriblAudit\n| summarize Count = count() by service, action\n| order by service asc\n", + "size": 0, + "title": "Actions by Cribl Service Module", + "timeContextFromParameter": "TimeGenerated", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "barchart" + }, + "name": "Actions by Cribl Service Module" + }, + { + "type": 1, + "content": { + "json": "# Internal Logs\n---\n", + "style": "info" + }, + "name": "text - 2 - Copy - Copy" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "CriblInternal\n| summarize avg(cpuPerc) by service\n| order by avg_cpuPerc desc\n", + "size": 0, + "title": "Average CPU Usage per Cribl Component", + "timeContextFromParameter": "TimeGenerated", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "unstackedbar" + }, + "name": "Average CPU Usage per Cribl Component" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "CriblInternal\n| summarize avg(mem_rss) by service\n| order by avg_mem_rss desc\n", + "size": 0, + "title": "Average Memory (RSS) Usage by Component", + "timeContextFromParameter": "TimeGenerated", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "categoricalbar" + }, + "name": "Average Memory (RSS) Usage by Component" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "CriblInternal\n| summarize avg(cpuPerc) , avg(eluPerc) by bin(event_time, 1m)\n| order by event_time asc\n", + "size": 0, + "title": "CPU vs ELU Over Time", + "timeContextFromParameter": "TimeGenerated", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "linechart" + }, + "name": "CPU vs ELU Over Time" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "CriblInternal\n| summarize avg(mem_heap), avg(mem_heapTotal) by bin(event_time, 1m)\n", + "size": 0, + "title": "Heap vs Total Heap Memory Over Time", + "timeContextFromParameter": "TimeGenerated", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "areachart" + }, + "name": "Heap vs Total Heap Memory Over Time" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "CriblInternal\n| summarize avg(mem_rss) by instance\n| top 5 by avg_mem_rss\n", + "size": 0, + "title": "Top 5 Hosts by RSS Memory Usage", + "timeContextFromParameter": "TimeGenerated", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "barchart" + }, + "name": "Top 5 Hosts by RSS Memory Usage" + }, + { + "type": 1, + "content": { + "json": "# UI Access Logs\n---\n", + "style": "info" + }, + "name": "text - 2 - Copy - Copy - Copy" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "CriblUIAccess\n| summarize Count = count() by user\n| top 5 by Count\n", + "size": 1, + "title": "Top 5 Users Accessing Cribl UI", + "timeContextFromParameter": "TimeGenerated", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "piechart", + "chartSettings": { + "showMetrics": false, + "showLegend": true + } + }, + "customWidth": "50", + "name": "Top 5 Users Accessing Cribl UI" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "CriblUIAccess\n| summarize Count = count() by tenantId\n| top 5 by Count\n", + "size": 1, + "title": "Top 5 Tenants Accessing Cribl UI", + "timeContextFromParameter": "TimeGenerated", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "piechart", + "chartSettings": { + "showMetrics": false, + "showLegend": true + } + }, + "customWidth": "50", + "name": "Top 5 Tenants Accessing Cribl UI" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "CriblUIAccess\n| summarize Count = count() by url\n| order by Count desc\n", + "size": 0, + "title": "Most Accessed UI Pages", + "timeContextFromParameter": "TimeGenerated", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "unstackedbar" + }, + "name": "Most Accessed UI Pages" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "CriblUIAccess\n| summarize AccessCount = count() by bin(event_time, 1m)\n| order by event_time asc\n", + "size": 0, + "title": "Cribl UI Access Trend", + "timeContextFromParameter": "TimeGenerated", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "timechart" + }, + "name": "Cribl UI Access Trend" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "CriblUIAccess\n| summarize AccessCount = count() by src\n| top 10 by AccessCount\n", + "size": 0, + "title": "Top Source IPs Accessing UI", + "timeContextFromParameter": "TimeGenerated", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "barchart" + }, + "name": "Top Source IPs Accessing UI" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "CriblUIAccess\n| summarize Count = count() by http_user_agent\n| top 5 by Count\n", + "size": 0, + "title": "Most Common Browsers & Tools", + "timeContextFromParameter": "TimeGenerated", + "showRefreshButton": true, + "showExportToExcel": true, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "categoricalbar" + }, + "name": "Most Common Browsers & Tools" + } + ], + "fallbackResourceIds": [], + "fromTemplateId": "sentinel-CriblWorkbook", + "$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json" +} From 3fde9cf4ddb0b0ddd7a12647c6801c2e944c0d92 Mon Sep 17 00:00:00 2001 From: Samik Roy Date: Mon, 30 Mar 2026 10:56:48 +0530 Subject: [PATCH 2/9] Update Solution_Cribl.json --- Solutions/Cribl/Data/Solution_Cribl.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Solutions/Cribl/Data/Solution_Cribl.json b/Solutions/Cribl/Data/Solution_Cribl.json index 1355622f2ec..fc025ef767c 100644 --- a/Solutions/Cribl/Data/Solution_Cribl.json +++ b/Solutions/Cribl/Data/Solution_Cribl.json @@ -3,6 +3,7 @@ "Author": "Cribl - tap@cribl.io", "Logo": "", "Description": "Cribl is a vendor neutral, purpose-built processing engine for data security and IT operations focused on centralized parsing and processing of event data.", + "WorkbookBladeDescription": "Monitor Cribl Logs across Access, Audit, INternal & UI Access.", "Data Connectors": [ "Data Connectors/Connector_Cribl.json" ], @@ -12,9 +13,12 @@ "Parsers/CriblInternal.yaml", "Parsers/CriblUIAccess.yaml" ], + "Workbooks": [ + "Solutions/Cribl/Workbooks/CriblWorkbook.json" + ], "BasePath": "C:\\GitHub\\Azure-Sentinel\\Solutions\\Cribl", "Version": "3.0.0", "Metadata": "SolutionMetadata.json", "TemplateSpec": true, "Is1Pconnector": false - } \ No newline at end of file + } From f8045a1a034d60fd8245bf50a8f4a1e6150a9642 Mon Sep 17 00:00:00 2001 From: samikroy Date: Thu, 16 Apr 2026 17:39:04 +0530 Subject: [PATCH 3/9] Fixed packaging structure and removed unintended solution changes --- Solutions/Cribl/Package/3.0.1.zip | Bin 7003 -> 9575 bytes .../Cribl/Package/createUiDefinition.json | 44 +++++- Solutions/Cribl/Package/mainTemplate.json | 138 ++++++++++++++++-- Solutions/Cribl/Package/testParameters.json | 8 + Solutions/Cribl/Workbooks/CriblWorkbook.json | 1 - 5 files changed, 180 insertions(+), 11 deletions(-) diff --git a/Solutions/Cribl/Package/3.0.1.zip b/Solutions/Cribl/Package/3.0.1.zip index 706a0d08af21fb044c81c1305c42ac0538b17cad..5dd21256f2e6f7f6192065e0e5ff31e64756010d 100644 GIT binary patch literal 9575 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 BT5$jX literal 7003 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 diff --git a/Solutions/Cribl/Package/createUiDefinition.json b/Solutions/Cribl/Package/createUiDefinition.json index b6b9c4358b7..32f2b3e22cd 100644 --- a/Solutions/Cribl/Package/createUiDefinition.json +++ b/Solutions/Cribl/Package/createUiDefinition.json @@ -6,7 +6,7 @@ "config": { "isWizard": false, "basics": { - "description": "\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/Cribl/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nCribl is a vendor neutral, purpose-built processing engine for data security and IT operations focused on centralized parsing and processing of event data.\n\n**Data Connectors:** 1, **Parsers:** 4\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)", + "description": "\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/Cribl/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nCribl is a vendor neutral, purpose-built processing engine for data security and IT operations focused on centralized parsing and processing of event data.\n\n**Data Connectors:** 1, **Parsers:** 4, **Workbooks:** 1\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)", "subscription": { "resourceProviders": [ "Microsoft.OperationsManagement/solutions", @@ -81,6 +81,48 @@ } } ] + }, + { + "name": "workbooks", + "label": "Workbooks", + "subLabel": { + "preValidation": "Configure the workbooks", + "postValidation": "Done" + }, + "bladeTitle": "Workbooks", + "elements": [ + { + "name": "workbooks-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "Monitor Cribl Logs across Access, Audit, INternal & UI Access." + } + }, + { + "name": "workbooks-link", + "type": "Microsoft.Common.TextBlock", + "options": { + "link": { + "label": "Learn more", + "uri": "https://docs.microsoft.com/azure/sentinel/tutorial-monitor-your-data" + } + } + }, + { + "name": "workbook1", + "type": "Microsoft.Common.Section", + "label": "Cribl Workbook", + "elements": [ + { + "name": "workbook1-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "This workbook provides insights into Cribl." + } + } + ] + } + ] } ], "outputs": { diff --git a/Solutions/Cribl/Package/mainTemplate.json b/Solutions/Cribl/Package/mainTemplate.json index a29c63d01d1..6728a6f8b3c 100644 --- a/Solutions/Cribl/Package/mainTemplate.json +++ b/Solutions/Cribl/Package/mainTemplate.json @@ -27,6 +27,14 @@ "metadata": { "description": "Workspace name for Log Analytics where Microsoft Sentinel is setup" } + }, + "workbook1-name": { + "type": "string", + "defaultValue": "Cribl Workbook", + "minLength": 1, + "metadata": { + "description": "Name for the workbook" + } } }, "variables": { @@ -73,6 +81,13 @@ "parserVersion4": "1.0.1", "parserContentId4": "CriblUIAccess-Parser" }, + "workbookVersion1": "1.0.0", + "workbookContentId1": "Cribl", + "workbookId1": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId1'))]", + "workbookTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId1'))))]", + "_workbookContentId1": "[variables('workbookContentId1')]", + "workspaceResourceId": "[resourceId('microsoft.OperationalInsights/Workspaces', parameters('workspace'))]", + "_workbookcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','wb','-', uniqueString(concat(variables('_solutionId'),'-','Workbook','-',variables('_workbookContentId1'),'-', variables('workbookVersion1'))))]", "_solutioncontentProductId": "[concat(take(variables('_solutionId'),50),'-','sl','-', uniqueString(concat(variables('_solutionId'),'-','Solution','-',variables('_solutionId'),'-', variables('_solutionVersion'))))]" }, "resources": [ @@ -401,7 +416,7 @@ "resources": [ { "name": "[variables('parserObject1')._parserName1]", - "apiVersion": "2022-10-01", + "apiVersion": "2025-07-01", "type": "Microsoft.OperationalInsights/workspaces/savedSearches", "location": "[parameters('workspace-location')]", "properties": { @@ -466,7 +481,7 @@ }, { "type": "Microsoft.OperationalInsights/workspaces/savedSearches", - "apiVersion": "2022-10-01", + "apiVersion": "2025-07-01", "name": "[variables('parserObject1')._parserName1]", "location": "[parameters('workspace-location')]", "properties": { @@ -533,7 +548,7 @@ "resources": [ { "name": "[variables('parserObject2')._parserName2]", - "apiVersion": "2022-10-01", + "apiVersion": "2025-07-01", "type": "Microsoft.OperationalInsights/workspaces/savedSearches", "location": "[parameters('workspace-location')]", "properties": { @@ -598,7 +613,7 @@ }, { "type": "Microsoft.OperationalInsights/workspaces/savedSearches", - "apiVersion": "2022-10-01", + "apiVersion": "2025-07-01", "name": "[variables('parserObject2')._parserName2]", "location": "[parameters('workspace-location')]", "properties": { @@ -665,7 +680,7 @@ "resources": [ { "name": "[variables('parserObject3')._parserName3]", - "apiVersion": "2022-10-01", + "apiVersion": "2025-07-01", "type": "Microsoft.OperationalInsights/workspaces/savedSearches", "location": "[parameters('workspace-location')]", "properties": { @@ -730,7 +745,7 @@ }, { "type": "Microsoft.OperationalInsights/workspaces/savedSearches", - "apiVersion": "2022-10-01", + "apiVersion": "2025-07-01", "name": "[variables('parserObject3')._parserName3]", "location": "[parameters('workspace-location')]", "properties": { @@ -797,7 +812,7 @@ "resources": [ { "name": "[variables('parserObject4')._parserName4]", - "apiVersion": "2022-10-01", + "apiVersion": "2025-07-01", "type": "Microsoft.OperationalInsights/workspaces/savedSearches", "location": "[parameters('workspace-location')]", "properties": { @@ -862,7 +877,7 @@ }, { "type": "Microsoft.OperationalInsights/workspaces/savedSearches", - "apiVersion": "2022-10-01", + "apiVersion": "2025-07-01", "name": "[variables('parserObject4')._parserName4]", "location": "[parameters('workspace-location')]", "properties": { @@ -911,6 +926,106 @@ } } }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('workbookTemplateSpecName1')]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "CriblWorkbook Workbook with template version 3.0.1", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('workbookVersion1')]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "type": "Microsoft.Insights/workbooks", + "name": "[variables('workbookContentId1')]", + "location": "[parameters('workspace-location')]", + "kind": "shared", + "apiVersion": "2021-08-01", + "metadata": { + "description": "This workbook provides insights into Cribl." + }, + "properties": { + "displayName": "[parameters('workbook1-name')]", + "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":1,\"content\":{\"json\":\"# Cribl Workbook\\r\\n\\r\\nThis Workbook contains summary of \\r\\n\\r\\n\\r\\n| Access Logs | Audit Logs | Internal Logs | UI Access Logs|\\r\\n| -------------- | --------------- | -------------- |-------------- |\\r\\n|||||\"},\"customWidth\":\"50\",\"name\":\"text - 19\"},{\"type\":9,\"content\":{\"version\":\"KqlParameterItem/1.0\",\"parameters\":[{\"id\":\"007ea1ee-99dd-4c59-bc0f-7eb8b1e05c71\",\"version\":\"KqlParameterItem/1.0\",\"name\":\"TimeGenerated\",\"type\":4,\"typeSettings\":{\"selectableValues\":[{\"durationMs\":300000},{\"durationMs\":900000},{\"durationMs\":1800000},{\"durationMs\":3600000},{\"durationMs\":14400000},{\"durationMs\":43200000},{\"durationMs\":86400000},{\"durationMs\":172800000},{\"durationMs\":259200000},{\"durationMs\":604800000},{\"durationMs\":1209600000},{\"durationMs\":2419200000},{\"durationMs\":2592000000},{\"durationMs\":5184000000},{\"durationMs\":7776000000}],\"allowCustom\":true},\"timeContext\":{\"durationMs\":86400000},\"value\":{\"durationMs\":86400000}}],\"style\":\"pills\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"50\",\"name\":\"parameters - 21\"},{\"type\":1,\"content\":{\"json\":\"# Access Logs\\n---\\n\",\"style\":\"info\"},\"name\":\"text - 2\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CriblAccess\\n| summarize Count = count() by tostring(status)\",\"size\":1,\"title\":\"Summary of HTTP Status Code\",\"timeContextFromParameter\":\"TimeGenerated\",\"showRefreshButton\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"chartSettings\":{\"showMetrics\":false,\"showLegend\":true}},\"customWidth\":\"33\",\"name\":\"HTTP Status Code Overview\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CriblAccess\\n| summarize count() by method\\n\",\"size\":1,\"title\":\"Summary of HTTP Methods\",\"timeContextFromParameter\":\"TimeGenerated\",\"showRefreshButton\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"chartSettings\":{\"showMetrics\":false,\"showLegend\":true}},\"customWidth\":\"33\",\"name\":\"HTTP Status Code Overview - Copy\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CriblAccess\\n| summarize Count = count() by src\",\"size\":1,\"title\":\"Summary of Source\",\"timeContextFromParameter\":\"TimeGenerated\",\"showRefreshButton\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"table\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Count\",\"formatter\":8,\"formatOptions\":{\"palette\":\"blue\"}}]}},\"customWidth\":\"33\",\"name\":\"HTTP Status Code Overview - Copy - Copy - Copy\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CriblAccess\\n| summarize Hits = count() by url\\n| top 10 by Hits\\n\",\"size\":0,\"title\":\"Top Accessed API Endpoints\",\"timeContextFromParameter\":\"TimeGenerated\",\"showRefreshButton\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"categoricalbar\"},\"name\":\"Top Accessed API Endpoints\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CriblAccess\\n| where status >= 400\\n| summarize ErrorCount = count() by tostring(status)\\n| sort by ErrorCount desc\\n\",\"size\":0,\"title\":\"HTTP Error Code Summary\",\"timeContextFromParameter\":\"TimeGenerated\",\"showRefreshButton\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"barchart\"},\"name\":\"HTTP Error Code Summary\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CriblAccess\\n| summarize AvgResponseTime = avg(response_time) by url\\n| top 10 by AvgResponseTime\\n\\n\",\"size\":0,\"title\":\"API Response Time Analysis\",\"timeContextFromParameter\":\"TimeGenerated\",\"showRefreshButton\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"unstackedbar\"},\"name\":\"API Response Time Analysis\"},{\"type\":1,\"content\":{\"json\":\"# Audit Logs\\n---\\n\",\"style\":\"info\"},\"name\":\"text - 2 - Copy\"},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CriblAudit\\n| summarize Count = count() by service\\n\",\"size\":1,\"title\":\"Summary of Servies\",\"timeContextFromParameter\":\"TimeGenerated\",\"showRefreshButton\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"formatters\":[{\"columnMatch\":\"Count\",\"formatter\":8,\"formatOptions\":{\"palette\":\"blue\"}}]}},\"customWidth\":\"50\",\"name\":\"HTTP Status Code Overview - Copy - Copy\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CriblAudit\\n| summarize Count = count() by user\\n| top 5 by Count\\n\",\"size\":1,\"title\":\"Top 5 Users by Audit Events\",\"timeContextFromParameter\":\"TimeGenerated\",\"showRefreshButton\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"chartSettings\":{\"showMetrics\":false,\"showLegend\":true}},\"customWidth\":\"50\",\"name\":\"Top 5 Users by Audit Events\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CriblAudit\\n| summarize Count = count() by bin(event_time, {TimeGenerated:grain})\\n\",\"size\":0,\"title\":\"Requests Over Time\",\"timeContextFromParameter\":\"TimeGenerated\",\"showRefreshButton\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"timechart\"},\"name\":\"Requests Over Time\"}]},\"name\":\"group - 32\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CriblAudit\\n| summarize Count = count() by action\\n| order by Count desc\\n\",\"size\":0,\"title\":\"Most Performed Audit Actions\",\"timeContextFromParameter\":\"TimeGenerated\",\"showRefreshButton\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"unstackedbar\"},\"name\":\"Most Performed Audit Actions\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CriblAudit\\n| summarize UniqueUsers = dcount(user) by action\\n| order by UniqueUsers desc\\n\",\"size\":0,\"title\":\"User Participation by Action Type\",\"timeContextFromParameter\":\"TimeGenerated\",\"showRefreshButton\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"categoricalbar\"},\"name\":\"User Participation by Action Type\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CriblAudit\\n| summarize Count = count() by bin(event_time, 5m)\\n| order by event_time asc\\n\",\"size\":0,\"title\":\"Audit Event Activity Over Time\",\"timeContextFromParameter\":\"TimeGenerated\",\"showRefreshButton\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"timechart\"},\"name\":\"Audit Event Activity Over Time\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CriblAudit\\n| summarize Count = count() by service, action\\n| order by service asc\\n\",\"size\":0,\"title\":\"Actions by Cribl Service Module\",\"timeContextFromParameter\":\"TimeGenerated\",\"showRefreshButton\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"barchart\"},\"name\":\"Actions by Cribl Service Module\"},{\"type\":1,\"content\":{\"json\":\"# Internal Logs\\n---\\n\",\"style\":\"info\"},\"name\":\"text - 2 - Copy - Copy\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CriblInternal\\n| summarize avg(cpuPerc) by service\\n| order by avg_cpuPerc desc\\n\",\"size\":0,\"title\":\"Average CPU Usage per Cribl Component\",\"timeContextFromParameter\":\"TimeGenerated\",\"showRefreshButton\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"unstackedbar\"},\"name\":\"Average CPU Usage per Cribl Component\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CriblInternal\\n| summarize avg(mem_rss) by service\\n| order by avg_mem_rss desc\\n\",\"size\":0,\"title\":\"Average Memory (RSS) Usage by Component\",\"timeContextFromParameter\":\"TimeGenerated\",\"showRefreshButton\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"categoricalbar\"},\"name\":\"Average Memory (RSS) Usage by Component\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CriblInternal\\n| summarize avg(cpuPerc) , avg(eluPerc) by bin(event_time, 1m)\\n| order by event_time asc\\n\",\"size\":0,\"title\":\"CPU vs ELU Over Time\",\"timeContextFromParameter\":\"TimeGenerated\",\"showRefreshButton\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"linechart\"},\"name\":\"CPU vs ELU Over Time\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CriblInternal\\n| summarize avg(mem_heap), avg(mem_heapTotal) by bin(event_time, 1m)\\n\",\"size\":0,\"title\":\"Heap vs Total Heap Memory Over Time\",\"timeContextFromParameter\":\"TimeGenerated\",\"showRefreshButton\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"areachart\"},\"name\":\"Heap vs Total Heap Memory Over Time\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CriblInternal\\n| summarize avg(mem_rss) by instance\\n| top 5 by avg_mem_rss\\n\",\"size\":0,\"title\":\"Top 5 Hosts by RSS Memory Usage\",\"timeContextFromParameter\":\"TimeGenerated\",\"showRefreshButton\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"barchart\"},\"name\":\"Top 5 Hosts by RSS Memory Usage\"},{\"type\":1,\"content\":{\"json\":\"# UI Access Logs\\n---\\n\",\"style\":\"info\"},\"name\":\"text - 2 - Copy - Copy - Copy\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CriblUIAccess\\n| summarize Count = count() by user\\n| top 5 by Count\\n\",\"size\":1,\"title\":\"Top 5 Users Accessing Cribl UI\",\"timeContextFromParameter\":\"TimeGenerated\",\"showRefreshButton\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"chartSettings\":{\"showMetrics\":false,\"showLegend\":true}},\"customWidth\":\"50\",\"name\":\"Top 5 Users Accessing Cribl UI\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CriblUIAccess\\n| summarize Count = count() by tenantId\\n| top 5 by Count\\n\",\"size\":1,\"title\":\"Top 5 Tenants Accessing Cribl UI\",\"timeContextFromParameter\":\"TimeGenerated\",\"showRefreshButton\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"piechart\",\"chartSettings\":{\"showMetrics\":false,\"showLegend\":true}},\"customWidth\":\"50\",\"name\":\"Top 5 Tenants Accessing Cribl UI\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CriblUIAccess\\n| summarize Count = count() by url\\n| order by Count desc\\n\",\"size\":0,\"title\":\"Most Accessed UI Pages\",\"timeContextFromParameter\":\"TimeGenerated\",\"showRefreshButton\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"unstackedbar\"},\"name\":\"Most Accessed UI Pages\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CriblUIAccess\\n| summarize AccessCount = count() by bin(event_time, 1m)\\n| order by event_time asc\\n\",\"size\":0,\"title\":\"Cribl UI Access Trend\",\"timeContextFromParameter\":\"TimeGenerated\",\"showRefreshButton\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"timechart\"},\"name\":\"Cribl UI Access Trend\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CriblUIAccess\\n| summarize AccessCount = count() by src\\n| top 10 by AccessCount\\n\",\"size\":0,\"title\":\"Top Source IPs Accessing UI\",\"timeContextFromParameter\":\"TimeGenerated\",\"showRefreshButton\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"barchart\"},\"name\":\"Top Source IPs Accessing UI\"},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CriblUIAccess\\n| summarize Count = count() by http_user_agent\\n| top 5 by Count\\n\",\"size\":0,\"title\":\"Most Common Browsers & Tools\",\"timeContextFromParameter\":\"TimeGenerated\",\"showRefreshButton\":true,\"showExportToExcel\":true,\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"categoricalbar\"},\"name\":\"Most Common Browsers & Tools\"}],\"fromTemplateId\":\"sentinel-CriblWorkbook\",\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\r\n", + "version": "1.0", + "sourceId": "[variables('workspaceResourceId')]", + "category": "sentinel" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Workbook-', last(split(variables('workbookId1'),'/'))))]", + "properties": { + "description": "@{workbookKey=Cribl; logoFileName=Azure_Sentinel.svg; description=This workbook provides insights into Cribl.; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=1.0.0; title=Cribl Workbook; templateRelativePath=CriblWorkbook.json; subtitle=; provider=Microsoft Sentinel Community; support=; author=}.description", + "parentId": "[variables('workbookId1')]", + "contentId": "[variables('_workbookContentId1')]", + "kind": "Workbook", + "version": "[variables('workbookVersion1')]", + "source": { + "kind": "Solution", + "name": "Cribl", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Cribl", + "email": "[variables('_email')]" + }, + "support": { + "tier": "Partner", + "name": "Cribl", + "email": "support@cribl.io", + "link": "https://www.cribl.io/support/" + }, + "dependencies": { + "operator": "AND", + "criteria": [ + { + "contentId": "CriblAccess_CL", + "kind": "DataType" + }, + { + "contentId": "CriblAudit_CL", + "kind": "DataType" + }, + { + "contentId": "CriblInternal_CL", + "kind": "DataType" + }, + { + "contentId": "CriblUIAccess_CL", + "kind": "DataType" + }, + { + "contentId": "Cribl", + "kind": "DataConnector" + } + ] + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_workbookContentId1')]", + "contentKind": "Workbook", + "displayName": "[parameters('workbook1-name')]", + "contentProductId": "[variables('_workbookcontentProductId1')]", + "id": "[variables('_workbookcontentProductId1')]", + "version": "[variables('workbookVersion1')]" + } + }, { "type": "Microsoft.OperationalInsights/workspaces/providers/contentPackages", "apiVersion": "2023-04-01-preview", @@ -921,7 +1036,7 @@ "contentSchemaVersion": "3.0.0", "displayName": "Cribl", "publisherDisplayName": "Cribl", - "descriptionHtml": "

Note: Please refer to the following before installing the solution:

\n

• Review the solution Release Notes

\n

• There may be known issues pertaining to this Solution, please refer to them before installing.

\n

Cribl is a vendor neutral, purpose-built processing engine for data security and IT operations focused on centralized parsing and processing of event data.

\n

Data Connectors: 1, Parsers: 4

\n

Learn more about Microsoft Sentinel | Learn more about Solutions

\n", + "descriptionHtml": "

Note: Please refer to the following before installing the solution:

\n

• Review the solution Release Notes

\n

• There may be known issues pertaining to this Solution, please refer to them before installing.

\n

Cribl is a vendor neutral, purpose-built processing engine for data security and IT operations focused on centralized parsing and processing of event data.

\n

Data Connectors: 1, Parsers: 4, Workbooks: 1

\n

Learn more about Microsoft Sentinel | Learn more about Solutions

\n", "contentKind": "Solution", "contentProductId": "[variables('_solutioncontentProductId')]", "id": "[variables('_solutioncontentProductId')]", @@ -970,6 +1085,11 @@ "kind": "Parser", "contentId": "[variables('parserObject4').parserContentId4]", "version": "[variables('parserObject4').parserVersion4]" + }, + { + "kind": "Workbook", + "contentId": "[variables('_workbookContentId1')]", + "version": "[variables('workbookVersion1')]" } ] }, diff --git a/Solutions/Cribl/Package/testParameters.json b/Solutions/Cribl/Package/testParameters.json index e55ec41a9ac..8f80225defc 100644 --- a/Solutions/Cribl/Package/testParameters.json +++ b/Solutions/Cribl/Package/testParameters.json @@ -20,5 +20,13 @@ "metadata": { "description": "Workspace name for Log Analytics where Microsoft Sentinel is setup" } + }, + "workbook1-name": { + "type": "string", + "defaultValue": "Cribl Workbook", + "minLength": 1, + "metadata": { + "description": "Name for the workbook" + } } } diff --git a/Solutions/Cribl/Workbooks/CriblWorkbook.json b/Solutions/Cribl/Workbooks/CriblWorkbook.json index 7c0d9bfc681..63aa63604fe 100644 --- a/Solutions/Cribl/Workbooks/CriblWorkbook.json +++ b/Solutions/Cribl/Workbooks/CriblWorkbook.json @@ -559,7 +559,6 @@ "name": "Most Common Browsers & Tools" } ], - "fallbackResourceIds": [], "fromTemplateId": "sentinel-CriblWorkbook", "$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json" } From ac6e8a681710f1bab677c1c13b7e250c47ba8e62 Mon Sep 17 00:00:00 2001 From: Samik Roy Date: Mon, 20 Apr 2026 18:37:49 +0530 Subject: [PATCH 4/9] Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- Solutions/Cribl/Data/Solution_Cribl.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Solutions/Cribl/Data/Solution_Cribl.json b/Solutions/Cribl/Data/Solution_Cribl.json index fc025ef767c..abfb03d86b9 100644 --- a/Solutions/Cribl/Data/Solution_Cribl.json +++ b/Solutions/Cribl/Data/Solution_Cribl.json @@ -3,7 +3,7 @@ "Author": "Cribl - tap@cribl.io", "Logo": "", "Description": "Cribl is a vendor neutral, purpose-built processing engine for data security and IT operations focused on centralized parsing and processing of event data.", - "WorkbookBladeDescription": "Monitor Cribl Logs across Access, Audit, INternal & UI Access.", + "WorkbookBladeDescription": "Monitor Cribl Logs across Access, Audit, Internal & UI Access.", "Data Connectors": [ "Data Connectors/Connector_Cribl.json" ], From 3d87a0c36b6f6118818f7e9da42bd1a274b2cf02 Mon Sep 17 00:00:00 2001 From: Samik Roy Date: Mon, 20 Apr 2026 18:41:08 +0530 Subject: [PATCH 5/9] Update Cribl Workbook JSON content formatting --- Solutions/Cribl/Workbooks/CriblWorkbook.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Solutions/Cribl/Workbooks/CriblWorkbook.json b/Solutions/Cribl/Workbooks/CriblWorkbook.json index 63aa63604fe..bbf2dec036e 100644 --- a/Solutions/Cribl/Workbooks/CriblWorkbook.json +++ b/Solutions/Cribl/Workbooks/CriblWorkbook.json @@ -4,7 +4,7 @@ { "type": 1, "content": { - "json": "# Cribl Workbook\r\n\r\nThis Workbook contains summary of \r\n\r\n\r\n| Access Logs | Audit Logs | Internal Logs | UI Access Logs|\r\n| -------------- | --------------- | -------------- |-------------- |\r\n|||||" + "json": "# Cribl Workbook\r\n\r\nThis Workbook contains summary of \r\n\r\n\r\n| Access Logs | Audit Logs | Internal Logs | UI Access Logs|\r\n| -------------- | --------------- | -------------- |-------------- |\r\n| Included | Included | Included | Included |" }, "customWidth": "50", "name": "text - 19" From 752b6b8f05673f4345e9de7bc9818a7c23de6233 Mon Sep 17 00:00:00 2001 From: Samik Roy Date: Mon, 20 Apr 2026 19:28:55 +0530 Subject: [PATCH 6/9] Refactor Cribl Workbook JSON for clarity and accuracy Updated queries and names in Cribl Workbook JSON. --- Solutions/Cribl/Workbooks/CriblWorkbook.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Solutions/Cribl/Workbooks/CriblWorkbook.json b/Solutions/Cribl/Workbooks/CriblWorkbook.json index bbf2dec036e..1fed4670e82 100644 --- a/Solutions/Cribl/Workbooks/CriblWorkbook.json +++ b/Solutions/Cribl/Workbooks/CriblWorkbook.json @@ -4,7 +4,7 @@ { "type": 1, "content": { - "json": "# Cribl Workbook\r\n\r\nThis Workbook contains summary of \r\n\r\n\r\n| Access Logs | Audit Logs | Internal Logs | UI Access Logs|\r\n| -------------- | --------------- | -------------- |-------------- |\r\n| Included | Included | Included | Included |" + "json": "# Cribl Workbook\r\n\r\nThis Workbook contains summary of \r\n\r\n\r\n| Access Logs | Audit Logs | Internal Logs | UI Access Logs|\r\n| -------------- | --------------- | -------------- | -------------- |\r\n| Included | Included | Included | Included |" }, "customWidth": "50", "name": "text - 19" @@ -132,7 +132,7 @@ } }, "customWidth": "33", - "name": "HTTP Status Code Overview - Copy" + "name": "httpStatusCodeSummary" }, { "type": 3, @@ -160,7 +160,7 @@ } }, "customWidth": "33", - "name": "HTTP Status Code Overview - Copy - Copy - Copy" + "name": "httpMethodsSummary" }, { "type": 3, @@ -182,7 +182,7 @@ "type": 3, "content": { "version": "KqlItem/1.0", - "query": "CriblAccess\n| where status >= 400\n| summarize ErrorCount = count() by tostring(status)\n| sort by ErrorCount desc\n", + "query": "CriblAccess\n| extend statusCode = toint(status)\n| where statusCode >= 400\n| summarize ErrorCount = count() by tostring(statusCode)\n| sort by ErrorCount desc\n", "size": 0, "title": "HTTP Error Code Summary", "timeContextFromParameter": "TimeGenerated", @@ -249,7 +249,7 @@ } }, "customWidth": "50", - "name": "HTTP Status Code Overview - Copy - Copy" + "name": "auditServiceSummaryTable" }, { "type": 3, @@ -276,7 +276,7 @@ "type": 3, "content": { "version": "KqlItem/1.0", - "query": "CriblAudit\n| summarize Count = count() by bin(event_time, {TimeGenerated:grain})\n", + "query": "CriblAudit\n| where event_time between ({TimeGenerated:start} .. {TimeGenerated:end})\n| summarize Count = count() by bin(event_time, {TimeGenerated:grain})\n", "size": 0, "title": "Requests Over Time", "timeContextFromParameter": "TimeGenerated", @@ -400,7 +400,7 @@ "type": 3, "content": { "version": "KqlItem/1.0", - "query": "CriblInternal\n| summarize avg(cpuPerc) , avg(eluPerc) by bin(event_time, 1m)\n| order by event_time asc\n", + "query": "CriblInternal\n| where event_time between ({TimeGenerated:start} .. {TimeGenerated:end})\n| summarize avg(cpuPerc), avg(eluPerc) by bin(event_time, {TimeGenerated:grain})\n", "size": 0, "title": "CPU vs ELU Over Time", "timeContextFromParameter": "TimeGenerated", @@ -514,7 +514,7 @@ "type": 3, "content": { "version": "KqlItem/1.0", - "query": "CriblUIAccess\n| summarize AccessCount = count() by bin(event_time, 1m)\n| order by event_time asc\n", + "query": "CriblUIAccess\n| where event_time between (datetime({TimeGenerated:start}) .. datetime({TimeGenerated:end}))\n| summarize AccessCount = count() by bin(event_time, 1m)\n| order by event_time asc\n", "size": 0, "title": "Cribl UI Access Trend", "timeContextFromParameter": "TimeGenerated", From 5133d2bd1e70e1c8c7546b2fdcaaca950dfb3c03 Mon Sep 17 00:00:00 2001 From: Samik Roy Date: Wed, 29 Apr 2026 16:51:45 +0530 Subject: [PATCH 7/9] Fix typo in title from 'Servies' to 'Services' --- Solutions/Cribl/Workbooks/CriblWorkbook.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Solutions/Cribl/Workbooks/CriblWorkbook.json b/Solutions/Cribl/Workbooks/CriblWorkbook.json index 1fed4670e82..9f210bcef6d 100644 --- a/Solutions/Cribl/Workbooks/CriblWorkbook.json +++ b/Solutions/Cribl/Workbooks/CriblWorkbook.json @@ -230,7 +230,7 @@ "version": "KqlItem/1.0", "query": "CriblAudit\n| summarize Count = count() by service\n", "size": 1, - "title": "Summary of Servies", + "title": "Summary of Services", "timeContextFromParameter": "TimeGenerated", "showRefreshButton": true, "showExportToExcel": true, From c706769d96edf77a30aefa6e7ad8b99c357faf3f Mon Sep 17 00:00:00 2001 From: Samik Roy Date: Wed, 29 Apr 2026 17:04:25 +0530 Subject: [PATCH 8/9] Rename summary fields and update query for audit logs --- Solutions/Cribl/Workbooks/CriblWorkbook.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Solutions/Cribl/Workbooks/CriblWorkbook.json b/Solutions/Cribl/Workbooks/CriblWorkbook.json index 9f210bcef6d..3ff6cf3335f 100644 --- a/Solutions/Cribl/Workbooks/CriblWorkbook.json +++ b/Solutions/Cribl/Workbooks/CriblWorkbook.json @@ -132,7 +132,7 @@ } }, "customWidth": "33", - "name": "httpStatusCodeSummary" + "name": "httpMethodSummary" }, { "type": 3, @@ -290,7 +290,7 @@ } ] }, - "name": "group - 32" + "name": "auditLogsRequestsOverTimeGroup" }, { "type": 3, @@ -328,7 +328,7 @@ "type": 3, "content": { "version": "KqlItem/1.0", - "query": "CriblAudit\n| summarize Count = count() by bin(event_time, 5m)\n| order by event_time asc\n", + "query": "CriblAudit\n| where event_time between (datetime({TimeGenerated:start}) .. datetime({TimeGenerated:end}))\n| summarize Count = count() by bin(event_time, 5m)\n| order by event_time asc\n", "size": 0, "title": "Audit Event Activity Over Time", "timeContextFromParameter": "TimeGenerated", From 2a2f9e807dff1ccf7ef7788a22539919276b0048 Mon Sep 17 00:00:00 2001 From: Samik Roy Date: Wed, 29 Apr 2026 17:06:40 +0530 Subject: [PATCH 9/9] Update workbook path in Solution_Cribl.json --- Solutions/Cribl/Data/Solution_Cribl.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Solutions/Cribl/Data/Solution_Cribl.json b/Solutions/Cribl/Data/Solution_Cribl.json index abfb03d86b9..a425b46494d 100644 --- a/Solutions/Cribl/Data/Solution_Cribl.json +++ b/Solutions/Cribl/Data/Solution_Cribl.json @@ -14,7 +14,7 @@ "Parsers/CriblUIAccess.yaml" ], "Workbooks": [ - "Solutions/Cribl/Workbooks/CriblWorkbook.json" + "Workbooks/CriblWorkbook.json" ], "BasePath": "C:\\GitHub\\Azure-Sentinel\\Solutions\\Cribl", "Version": "3.0.0",