Created
February 9, 2022 12:32
-
-
Save ivanthelad/798808474d6e2c8fbf824b1e2ec6cb7f to your computer and use it in GitHub Desktop.
Cost Analysis Dashboard: A dashboard to highlight which microservices cost the most in a aks log analytics based cluster
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", | |
"contentVersion": "1.0.0.0", | |
"parameters": { | |
"workspacesubscriptionid": { | |
"defaultValue": "Insert_Subscription_Id", | |
"type": "String", | |
"metadata": { | |
"description": "Subscription id of the log analytics workspace is deployed. Can be found under 'Log Analytics Workspace -> Overview' " | |
} | |
}, | |
"workspaceResourceGroup":{ | |
"defaultValue": "workspaceResourceGroup", | |
"type": "String", | |
"metadata": { | |
"description": "Resource Group of where the log analytics workspace is deployed. Can be found under 'Log Analytics Workspace -> Overview' " | |
} | |
}, | |
"workspacename":{ | |
"defaultValue": "WorkSpaceName", | |
"type": "String", | |
"metadata": { | |
"description": "Log analytics workspace Name. Can be found under 'Log Analytics Workspace -> Overview' " | |
} | |
}, | |
"dashboardname":{ | |
"defaultValue": "DashboardName", | |
"type": "String", | |
"metadata": { | |
"description": "The is the name of the Dashboard displayed in the Portal" | |
} | |
} | |
}, | |
"variables": { | |
}, | |
"resources": [ | |
{ | |
"properties": { | |
"lenses": { | |
"0": { | |
"order": 0, | |
"parts": { | |
"0": { | |
"position": { | |
"x": 0, | |
"y": 0, | |
"colSpan": 14, | |
"rowSpan": 5 | |
}, | |
"metadata": { | |
"inputs": [ | |
{ | |
"name": "ComponentId", | |
"value": { | |
"SubscriptionId": "[parameters('workspacesubscriptionid')]", | |
"ResourceGroup": "[parameters('workspaceResourceGroup')]", | |
"Name": "[parameters('workspacename')]", | |
"ResourceId": "[concat('/subscriptions/',parameters('workspacesubscriptionid'),'/resourcegroups/',parameters('workspaceResourceGroup'),'/providers/microsoft.operationalinsights/workspaces/',parameters('workspacename'))]" | |
} | |
}, | |
{ | |
"name": "Query", | |
"value": "let daystosearch = 31d;\r\nunion isfuzzy=true withsource = tableName *\r\n| where _IsBillable == True\r\n| where TimeGenerated between (startofday(ago(daystosearch)) .. startofday(now()))\r\n| where tableName in (\"ContainerLog\",\"KubeServices\",\"KubeNodeInventory\",\"KubeEvents\",\"KubePodInventory\",\"ContainerNodeInventory\",\"ContainerInventory\")\r\n| project Computer, _ResourceId, _BilledSize, tableName, ControllerName, TimeGenerated , ContainerName\r\n| parse _ResourceId with *\"/managedclusters/\" ClusterName \r\n| summarize \r\n VolumeInGB =round(sum(_BilledSize / (1024*1024*1024)),4),\r\n TotalMBytes=round(sum(_BilledSize / (1024*1024 )),2),\r\n Foundin =make_set(tableName)\r\n by bin(TimeGenerated, 24h), ClusterName, ControllerName, Nodes=Computer, ContainerName\r\n| sort by TimeGenerated desc\r\n| render barchart title = \"Volume in GB per day\"\r\n//| summarize sum(VolumeInGB)\r\n" | |
}, | |
{ | |
"name": "Dimensions", | |
"value": { | |
"xAxis": { | |
"name": "TimeGenerated", | |
"type": "datetime" | |
}, | |
"yAxis": [ | |
{ | |
"name": "VolumeInGB", | |
"type": "real" | |
} | |
], | |
"splitBy": [ | |
{ | |
"name": "ClusterName", | |
"type": "string" | |
} | |
], | |
"aggregation": "Sum" | |
} | |
}, | |
{ | |
"name": "Version", | |
"value": "1.0" | |
}, | |
{ | |
"name": "PartId", | |
"value": "d8fa7b91-397f-4331-ad12-5e04092f5d83" | |
}, | |
{ | |
"name": "PartTitle", | |
"value": "Volume in GB per day" | |
}, | |
{ | |
"name": "PartSubTitle", | |
"value": "loganalyticskube" | |
}, | |
{ | |
"name": "resourceTypeMode", | |
"value": "workspace" | |
}, | |
{ | |
"name": "ControlType", | |
"value": "AnalyticsChart" | |
}, | |
{ | |
"name": "SpecificChart", | |
"value": "Bar" | |
}, | |
{ | |
"name": "TimeRange", | |
"isOptional": true | |
}, | |
{ | |
"name": "DashboardId", | |
"isOptional": true | |
} | |
], | |
"type": "Extension/AppInsightsExtension/PartType/AnalyticsPart", | |
"settings": { | |
"content": { | |
"Query": "let daystosearch = 31d;\nContainerLog\n| where _IsBillable == True\n| where TimeGenerated > startofday(ago(daystosearch))\n| join kind= inner (\n KubePodInventory\n | where TimeGenerated > startofday(ago(daystosearch))\n | distinct ContainerID, ClusterName , ControllerName\n) on ContainerID\n| project _BilledSize, ControllerName, TimeGenerated, ClusterName\n| summarize \n VolumeInGB =round(sum(_BilledSize / (1024*1024*1024)),4),\n TotalMBytes=round(sum(_BilledSize / (1024*1024 )),2)\n by bin(TimeGenerated, 24h), ClusterName, ControllerName\n| sort by TimeGenerated desc\n| render barchart title = \"Volume in GB per day\"\n\n" | |
} | |
}, | |
"asset": { | |
"idInputName": "ComponentId", | |
"type": "ApplicationInsights" | |
} | |
} | |
}, | |
"1": { | |
"position": { | |
"x": 0, | |
"y": 5, | |
"colSpan": 8, | |
"rowSpan": 5 | |
}, | |
"metadata": { | |
"inputs": [ | |
{ | |
"name": "ComponentId", | |
"value": { | |
"SubscriptionId": "[parameters('workspacesubscriptionid')]", | |
"ResourceGroup": "[parameters('workspaceResourceGroup')]", | |
"Name": "[parameters('workspacename')]", | |
"ResourceId": "[concat('/subscriptions/',parameters('workspacesubscriptionid'),'/resourcegroups/',parameters('workspaceResourceGroup'),'/providers/microsoft.operationalinsights/workspaces/',parameters('workspacename'))]" | |
} | |
}, | |
{ | |
"name": "Query", | |
"value": "// show usage against time\r\nlet containerImageDictionary = (){\r\nContainerInventory\r\n| where TimeGenerated > startofday(ago(10d))\r\n| distinct ContainerID, Image\r\n};\r\n \r\nunion withsource = tableName *\r\n| where TimeGenerated > startofday(ago(10d))\r\n| where tableName in ((Usage\r\n| where Solution == \"ContainerInsights\" | distinct DataType))\r\n| where isnotempty (ContainerID)\r\n| where _IsBillable == true\r\n| join kind=leftouter (containerImageDictionary) on ContainerID\r\n\r\n| project TimeGenerated, _BilledSize, ContainerID \r\n| join kind= inner (\r\n KubePodInventory \r\n | project ControllerName , ContainerID, ClusterName \r\n) on ContainerID \r\n| summarize VolumeInGB =round((sum(_BilledSize) / (1024 * 1024 * 1024)),4), TotalMBytes= round(sum(_BilledSize / 1024 / 1024), 2)\r\n by bin(TimeGenerated, 1d), ClusterName, ControllerName | order by VolumeInGB | render barchart " | |
}, | |
{ | |
"name": "Dimensions", | |
"value": { | |
"xAxis": { | |
"name": "TimeGenerated", | |
"type": "DateTime" | |
}, | |
"yAxis": [ | |
{ | |
"name": "VolumeInGB", | |
"type": "Double" | |
} | |
], | |
"splitBy": [ | |
{ | |
"name": "ClusterName", | |
"type": "String" | |
} | |
], | |
"aggregation": "Sum" | |
} | |
}, | |
{ | |
"name": "Version", | |
"value": "1.0" | |
}, | |
{ | |
"name": "PartId", | |
"value": "96d484a5-6330-431f-abd5-0ed647fbae6c" | |
}, | |
{ | |
"name": "PartTitle", | |
"value": "Analytics" | |
}, | |
{ | |
"name": "PartSubTitle", | |
"value": "loganalyticskube" | |
}, | |
{ | |
"name": "resourceTypeMode", | |
"value": "workspace" | |
}, | |
{ | |
"name": "ControlType", | |
"value": "AnalyticsChart" | |
}, | |
{ | |
"name": "SpecificChart", | |
"value": "Bar" | |
}, | |
{ | |
"name": "TimeRange", | |
"isOptional": true | |
}, | |
{ | |
"name": "DashboardId", | |
"isOptional": true | |
} | |
], | |
"type": "Extension/AppInsightsExtension/PartType/AnalyticsPart", | |
"settings": { | |
"content": { | |
"PartTitle": "GB Ingested", | |
"PartSubTitle": "loganalyticskube", | |
"Query": "let daystosearch = 31d;\nContainerLog\n| where _IsBillable == True\n| where TimeGenerated > startofday(ago(daystosearch))\n| join kind= inner (\n KubePodInventory\n | where TimeGenerated > startofday(ago(daystosearch))\n | distinct ContainerID, ClusterName , ControllerName\n) on ContainerID\n| project _BilledSize, ControllerName, TimeGenerated, ClusterName\n| summarize VolumeInGB =round((sum(_BilledSize) / (1024 * 1024 * 1024)),4), TotalMBytes= round(sum(_BilledSize / 1024 / 1024), 2)\n by bin(TimeGenerated, 1h), ClusterName, ControllerName | order by VolumeInGB\n| render barchart title = \"Volume in GB per Hour\"" | |
} | |
}, | |
"asset": { | |
"idInputName": "ComponentId", | |
"type": "ApplicationInsights" | |
} | |
} | |
}, | |
"2": { | |
"position": { | |
"x": 8, | |
"y": 5, | |
"colSpan": 6, | |
"rowSpan": 5 | |
}, | |
"metadata": { | |
"inputs": [ | |
{ | |
"name": "ComponentId", | |
"value": { | |
"SubscriptionId": "[parameters('workspacesubscriptionid')]", | |
"ResourceGroup": "[parameters('workspaceResourceGroup')]", | |
"Name": "[parameters('workspacename')]", | |
"ResourceId": "[concat('/subscriptions/',parameters('workspacesubscriptionid'),'/resourcegroups/',parameters('workspaceResourceGroup'),'/providers/microsoft.operationalinsights/workspaces/',parameters('workspacename'))]" | |
} | |
}, | |
{ | |
"name": "Query", | |
"value": " // Cost example \r\nlet pricingPerGig = 2.522; //Add Azure Pricing ($ Euro) the example is the cost per GIG in Europe. source: https://azure.microsoft.com/en-us/pricing/details/monitor/\r\n\r\nlet daystosearch = 60d;\r\nContainerLog\r\n| where _IsBillable == True\r\n| where TimeGenerated > startofday(ago(daystosearch))\r\n| join kind= inner (\r\n KubePodInventory\r\n | where TimeGenerated > startofday(ago(daystosearch))\r\n | distinct ContainerID, ClusterName , ControllerName\r\n) on ContainerID\r\n| project _BilledSize, ControllerName, TimeGenerated, ClusterName\r\n| summarize CurrentCostEuro = round(pricingPerGig* sum(_BilledSize/(1024*1024*1024)),2) by ClusterName, ControllerName\r\n| order by CurrentCostEuro desc | limit 10 | order by CurrentCostEuro, ControllerName\r\n| render piechart\r\n title=\"Cost esitmate per Cluster\" \r\n" | |
}, | |
{ | |
"name": "Dimensions", | |
"value": { | |
"xAxis": { | |
"name": "ClusterName", | |
"type": "string" | |
}, | |
"yAxis": [ | |
{ | |
"name": "CurrentCostEuro", | |
"type": "real" | |
} | |
], | |
"splitBy": [], | |
"aggregation": "Sum" | |
} | |
}, | |
{ | |
"name": "Version", | |
"value": "1.0" | |
}, | |
{ | |
"name": "PartId", | |
"value": "bff743a2-1f77-421f-9597-1891103376f8" | |
}, | |
{ | |
"name": "PartTitle", | |
"value": "Cost esitmate per Cluster" | |
}, | |
{ | |
"name": "PartSubTitle", | |
"value": "loganalyticskube" | |
}, | |
{ | |
"name": "resourceTypeMode", | |
"value": "workspace" | |
}, | |
{ | |
"name": "ControlType", | |
"value": "AnalyticsDonut" | |
}, | |
{ | |
"name": "TimeRange", | |
"isOptional": true | |
}, | |
{ | |
"name": "DashboardId", | |
"isOptional": true | |
}, | |
{ | |
"name": "SpecificChart", | |
"isOptional": true | |
} | |
], | |
"type": "Extension/AppInsightsExtension/PartType/AnalyticsPart", | |
"settings": {}, | |
"asset": { | |
"idInputName": "ComponentId", | |
"type": "ApplicationInsights" | |
} | |
} | |
}, | |
"3": { | |
"position": { | |
"x": 0, | |
"y": 10, | |
"colSpan": 8, | |
"rowSpan": 5 | |
}, | |
"metadata": { | |
"inputs": [ | |
{ | |
"name": "ComponentId", | |
"value": { | |
"SubscriptionId": "[parameters('workspacesubscriptionid')]", | |
"ResourceGroup": "[parameters('workspaceResourceGroup')]", | |
"Name": "[parameters('workspacename')]", | |
"ResourceId": "[concat('/subscriptions/',parameters('workspacesubscriptionid'),'/resourcegroups/',parameters('workspaceResourceGroup'),'/providers/microsoft.operationalinsights/workspaces/',parameters('workspacename'))]" | |
} | |
}, | |
{ | |
"name": "Query", | |
"value": "let containerImageDictionary = (){\r\nContainerInventory\r\n| where TimeGenerated > startofday(ago(31d))\r\n| distinct ContainerID, Image\r\n};\r\n \r\nunion withsource = tableName *\r\n| where TimeGenerated > startofday(ago(31d))\r\n| where tableName in ((Usage\r\n| where Solution == \"ContainerInsights\" | distinct DataType))\r\n| where isnotempty (ContainerID)\r\n| where _IsBillable == true\r\n| join kind=leftouter (containerImageDictionary) on ContainerID\r\n\r\n| project TimeGenerated, _BilledSize, ContainerID \r\n| join kind= inner (\r\n KubePodInventory \r\n | project ControllerName , ContainerID, ClusterName \r\n) on ContainerID \r\n| summarize RecordCount=count()\r\n by bin(TimeGenerated, 12h), ClusterName, ControllerName | render barchart \r\n\r\n" | |
}, | |
{ | |
"name": "Dimensions", | |
"value": { | |
"xAxis": { | |
"name": "TimeGenerated", | |
"type": "DateTime" | |
}, | |
"yAxis": [ | |
{ | |
"name": "RecordCount", | |
"type": "Int64" | |
} | |
], | |
"splitBy": [ | |
{ | |
"name": "ClusterName", | |
"type": "String" | |
} | |
], | |
"aggregation": "Sum" | |
} | |
}, | |
{ | |
"name": "Version", | |
"value": "1.0" | |
}, | |
{ | |
"name": "PartId", | |
"value": "96fb594e-78e5-4ed9-aa3e-ab7467922f52" | |
}, | |
{ | |
"name": "PartTitle", | |
"value": "Analytics" | |
}, | |
{ | |
"name": "PartSubTitle", | |
"value": "loganalyticskube" | |
}, | |
{ | |
"name": "resourceTypeMode", | |
"value": "workspace" | |
}, | |
{ | |
"name": "ControlType", | |
"value": "AnalyticsChart" | |
}, | |
{ | |
"name": "SpecificChart", | |
"value": "Bar" | |
}, | |
{ | |
"name": "TimeRange", | |
"isOptional": true | |
}, | |
{ | |
"name": "DashboardId", | |
"isOptional": true | |
} | |
], | |
"type": "Extension/AppInsightsExtension/PartType/AnalyticsPart", | |
"settings": { | |
"content": { | |
"PartTitle": "Count of Log entries ", | |
"PartSubTitle": "loganalyticskube", | |
"Query": "let containerImageDictionary = (){\nContainerInventory\n| where TimeGenerated > startofday(ago(31d))\n| distinct ContainerID, Image\n};\n \nlet daystosearch = 90d;\nContainerLog\n| where _IsBillable == True\n| where TimeGenerated > startofday(ago(daystosearch))\n| join kind= inner (\n KubePodInventory\n | where TimeGenerated > startofday(ago(daystosearch))\n | distinct ContainerID, ClusterName , ControllerName\n) on ContainerID\n| project _BilledSize, ControllerName, TimeGenerated, ClusterName\n| summarize RecordCount=count()\n by bin(TimeGenerated, 24h), ClusterName, ControllerName | render barchart title = \"Count of logs per day\"\n\n" | |
} | |
}, | |
"asset": { | |
"idInputName": "ComponentId", | |
"type": "ApplicationInsights" | |
} | |
} | |
}, | |
"4": { | |
"position": { | |
"x": 8, | |
"y": 10, | |
"colSpan": 6, | |
"rowSpan": 5 | |
}, | |
"metadata": { | |
"inputs": [ | |
{ | |
"name": "ComponentId", | |
"value": { | |
"SubscriptionId": "[parameters('workspacesubscriptionid')]", | |
"ResourceGroup": "[parameters('workspaceResourceGroup')]", | |
"Name": "[parameters('workspacename')]", | |
"ResourceId": "[concat('/subscriptions/',parameters('workspacesubscriptionid'),'/resourcegroups/',parameters('workspaceResourceGroup'),'/providers/microsoft.operationalinsights/workspaces/',parameters('workspacename'))]" | |
} | |
}, | |
{ | |
"name": "Query", | |
"value": "// Cost example\nlet pricingPerGig = 2.522;\n//Add Azure Pricing ($ Euro) the example is the cost per GIG in Europe. source: https://azure.microsoft.com/en-us/pricing/details/monitor/\n\nlet daystosearch = 31d;\nContainerLog\n| where _IsBillable == True\n| where TimeGenerated > startofday(ago(daystosearch))\n| join kind= inner\n(\n KubePodInventory\n | where TimeGenerated > startofday(ago(daystosearch))\n | distinct ContainerID, ClusterName , ControllerName\n)\non ContainerID\n| project _BilledSize, ControllerName, TimeGenerated, ClusterName\n| summarize CurrentCostEuro = round(pricingPerGig* sum(_BilledSize/(1024*1024*1024)),2) by ClusterName, ControllerName\n| order by CurrentCostEuro, ClusterName, ControllerName\n| render barchart title=\"Cost Distribution per cluster/microservice\" \n//| render table title=\"Cost esitmate per Controller\"" | |
}, | |
{ | |
"name": "Dimensions", | |
"value": { | |
"xAxis": { | |
"name": "ClusterName", | |
"type": "string" | |
}, | |
"yAxis": [ | |
{ | |
"name": "CurrentCostEuro", | |
"type": "real" | |
} | |
], | |
"splitBy": [ | |
{ | |
"name": "ControllerName", | |
"type": "string" | |
} | |
], | |
"aggregation": "Sum" | |
} | |
}, | |
{ | |
"name": "Version", | |
"value": "1.0" | |
}, | |
{ | |
"name": "PartId", | |
"value": "f973952d-72ff-48d8-9b30-936247e8834c" | |
}, | |
{ | |
"name": "PartTitle", | |
"value": "Cost Distribution per cluster/microservice" | |
}, | |
{ | |
"name": "PartSubTitle", | |
"value": "loganalyticskube" | |
}, | |
{ | |
"name": "resourceTypeMode", | |
"value": "workspace" | |
}, | |
{ | |
"name": "ControlType", | |
"value": "AnalyticsChart" | |
}, | |
{ | |
"name": "SpecificChart", | |
"value": "Bar" | |
}, | |
{ | |
"name": "TimeRange", | |
"isOptional": true | |
}, | |
{ | |
"name": "DashboardId", | |
"isOptional": true | |
} | |
], | |
"type": "Extension/AppInsightsExtension/PartType/AnalyticsPart", | |
"settings": {}, | |
"asset": { | |
"idInputName": "ComponentId", | |
"type": "ApplicationInsights" | |
} | |
} | |
}, | |
"5": { | |
"position": { | |
"x": 0, | |
"y": 15, | |
"colSpan": 14, | |
"rowSpan": 5 | |
}, | |
"metadata": { | |
"inputs": [ | |
{ | |
"name": "ComponentId", | |
"value": { | |
"SubscriptionId": "[parameters('workspacesubscriptionid')]", | |
"ResourceGroup": "[parameters('workspaceResourceGroup')]", | |
"Name": "[parameters('workspacename')]", | |
"ResourceId": "[concat('/subscriptions/',parameters('workspacesubscriptionid'),'/resourcegroups/',parameters('workspaceResourceGroup'),'/providers/microsoft.operationalinsights/workspaces/',parameters('workspacename'))]" | |
} | |
}, | |
{ | |
"name": "Query", | |
"value": "let pricingPerGig = 2.522; let containerImageDictionary = (){\r\nContainerInventory\r\n| where TimeGenerated > startofday(ago(2d))\r\n| distinct ContainerID, Image\r\n};\r\n \r\nunion withsource = tableName *\r\n| where TimeGenerated > startofday(ago(2d))\r\n| where tableName in ((Usage\r\n| where Solution == \"ContainerInsights\" | distinct DataType))\r\n| where isnotempty (ContainerID)\r\n| where _IsBillable == true\r\n| join kind=leftouter (containerImageDictionary) on ContainerID\r\n\r\n| project TimeGenerated, _BilledSize, ContainerID \r\n| join kind= inner (\r\n KubePodInventory \r\n | project ControllerName , ContainerID, ClusterName \r\n) on ContainerID \r\n| summarize RecordCount=count(), sum(_BilledSize), TotalGB=round( sum(_BilledSize/1024/1024/1024),2), TotalMBytes= round(sum(_BilledSize / 1024 / 1024), 2), CurrentCostEuro = round(pricingPerGig* sum(_BilledSize/(1024*1024*1024)),2) by ClusterName, ControllerName | order by RecordCount, ClusterName, ControllerName\r\n\r\n" | |
}, | |
{ | |
"name": "Version", | |
"value": "1.0" | |
}, | |
{ | |
"name": "PartId", | |
"value": "50824805-0d13-429a-a665-25da4b85b546" | |
}, | |
{ | |
"name": "PartTitle", | |
"value": "Analytics" | |
}, | |
{ | |
"name": "PartSubTitle", | |
"value": "loganalyticskube" | |
}, | |
{ | |
"name": "resourceTypeMode", | |
"value": "workspace" | |
}, | |
{ | |
"name": "ControlType", | |
"value": "AnalyticsGrid" | |
}, | |
{ | |
"name": "Dimensions", | |
"isOptional": true | |
}, | |
{ | |
"name": "TimeRange", | |
"isOptional": true | |
}, | |
{ | |
"name": "DashboardId", | |
"isOptional": true | |
}, | |
{ | |
"name": "SpecificChart", | |
"isOptional": true | |
} | |
], | |
"type": "Extension/AppInsightsExtension/PartType/AnalyticsPart", | |
"settings": { | |
"content": { | |
"PartTitle": "Cost estimate ", | |
"PartSubTitle": "loganalyticskube", | |
"Query": "// Cost example \nlet pricingPerGig = 2.522; //Add Azure Pricing ($ Euro) the example is the cost per GIG in Europe. source: https://azure.microsoft.com/en-us/pricing/details/monitor/\n\nlet daystosearch = 31d;\nContainerLog\n| where _IsBillable == True\n| where TimeGenerated > startofday(ago(daystosearch))\n| join kind= inner (\n KubePodInventory\n | where TimeGenerated > startofday(ago(daystosearch))\n | extend Application=extract(\"(\\\\S+)-[A-Fa-f0-9]+$\", 1, ControllerName)\n | distinct ContainerID, ClusterName , Application\n) on ContainerID\n| project _BilledSize, Application, TimeGenerated, ClusterName\n| summarize RecordCount=count(), sum(_BilledSize), TotalGB=round( sum(_BilledSize/1024/1024/1024),2), TotalMBytes= round(sum(_BilledSize / 1024 / 1024), 2), CurrentCostEuro = round(pricingPerGig* sum(_BilledSize/(1024*1024*1024)),2) by ClusterName, Application | order by CurrentCostEuro, RecordCount, ClusterName, Application \n| render table title=\"Cost esitmate per Controller\"\n" | |
} | |
}, | |
"asset": { | |
"idInputName": "ComponentId", | |
"type": "ApplicationInsights" | |
} | |
} | |
}, | |
"6": { | |
"position": { | |
"x": 0, | |
"y": 22, | |
"colSpan": 14, | |
"rowSpan": 4 | |
}, | |
"metadata": { | |
"inputs": [ | |
{ | |
"name": "ComponentId", | |
"value": { | |
"SubscriptionId": "[parameters('workspacesubscriptionid')]", | |
"ResourceGroup": "[parameters('workspaceResourceGroup')]", | |
"Name": "[parameters('workspacename')]", | |
"ResourceId": "[concat('/subscriptions/',parameters('workspacesubscriptionid'),'/resourcegroups/',parameters('workspaceResourceGroup'),'/providers/microsoft.operationalinsights/workspaces/',parameters('workspacename'))]" | |
} | |
}, | |
{ | |
"name": "Query", | |
"value": "\r\n\r\n// Show as table \r\n\r\nlet containerImageDictionary = (){\r\nContainerInventory\r\n| where TimeGenerated > startofday(ago(31d))\r\n| distinct ContainerID, Image\r\n};\r\n \r\nunion withsource = tableName *\r\n| where TimeGenerated > startofday(ago(31d))\r\n| where tableName in ((Usage\r\n| where Solution == \"ContainerInsights\" | distinct DataType))\r\n| where isnotempty (ContainerID)\r\n| where _IsBillable == true\r\n| join kind=leftouter (containerImageDictionary) on ContainerID\r\n\r\n| project TimeGenerated, _BilledSize, ContainerID \r\n| join kind= inner (\r\n KubePodInventory \r\n | project ControllerName , ContainerID, ClusterName \r\n) on ContainerID \r\n| summarize RecordCount=count(), TotalMBytes= round(sum(_BilledSize / 1024 / 1024), 2) by ClusterName, ControllerName | order by RecordCount, ClusterName, ControllerName\r\n " | |
}, | |
{ | |
"name": "Version", | |
"value": "1.0" | |
}, | |
{ | |
"name": "PartId", | |
"value": "42e6e09b-940c-4727-b0a7-6e2b11b245c1" | |
}, | |
{ | |
"name": "PartTitle", | |
"value": "Analytics" | |
}, | |
{ | |
"name": "PartSubTitle", | |
"value": "loganalyticskube" | |
}, | |
{ | |
"name": "resourceTypeMode", | |
"value": "workspace" | |
}, | |
{ | |
"name": "ControlType", | |
"value": "AnalyticsGrid" | |
}, | |
{ | |
"name": "Dimensions", | |
"isOptional": true | |
}, | |
{ | |
"name": "TimeRange", | |
"isOptional": true | |
}, | |
{ | |
"name": "DashboardId", | |
"isOptional": true | |
}, | |
{ | |
"name": "SpecificChart", | |
"isOptional": true | |
} | |
], | |
"type": "Extension/AppInsightsExtension/PartType/AnalyticsPart", | |
"settings": { | |
"content": { | |
"PartTitle": "Log Entries per Controller ", | |
"PartSubTitle": "loganalyticskube", | |
"Query": "\n\nlet daystosearch = 31d;\nContainerLog\n| where _IsBillable == True\n| where TimeGenerated > startofday(ago(daystosearch))\n| join kind= inner (\n KubePodInventory\n | where TimeGenerated > startofday(ago(daystosearch))\n | extend Application=extract(\"(\\\\S+)-[A-Fa-f0-9]+$\", 1, ControllerName)\n\n | distinct ContainerID, ClusterName , Application\n) on ContainerID\n| project _BilledSize, Application, TimeGenerated, ClusterName\n| summarize RecordCount=count(), TotalMBytes= round(sum(_BilledSize / 1024 / 1024), 2) by ClusterName, Application | order by RecordCount, ClusterName, Application | render table title = \"Log Entries per controller\"\n " | |
} | |
}, | |
"asset": { | |
"idInputName": "ComponentId", | |
"type": "ApplicationInsights" | |
} | |
} | |
}, | |
"7": { | |
"position": { | |
"x": 0, | |
"y": 26, | |
"colSpan": 7, | |
"rowSpan": 3 | |
}, | |
"metadata": { | |
"inputs": [ | |
{ | |
"name": "ComponentId", | |
"value": { | |
"SubscriptionId": "[parameters('workspacesubscriptionid')]", | |
"ResourceGroup": "[parameters('workspaceResourceGroup')]", | |
"Name": "[parameters('workspacename')]", | |
"ResourceId": "[concat('/subscriptions/',parameters('workspacesubscriptionid'),'/resourcegroups/',parameters('workspaceResourceGroup'),'/providers/microsoft.operationalinsights/workspaces/',parameters('workspacename'))]" | |
} | |
}, | |
{ | |
"name": "Query", | |
"value": "KubeEvents | where Reason in (\"NodeHasSufficientPID\", \"NodeHasNoDiskPressure\", \"NodeAllocatableEnforced\", \"NodeHasSufficientMemory\", \"FailedScheduling\", \"Killing\", \"FailedMount\") \r\n| where ObjectKind == \"Pod\"| summarize count(Reason) by bin(TimeGenerated, 30s),Reason | render barchart \r\n" | |
}, | |
{ | |
"name": "TimeRange", | |
"value": "PT1H" | |
}, | |
{ | |
"name": "Dimensions", | |
"value": { | |
"xAxis": { | |
"name": "TimeGenerated", | |
"type": "datetime" | |
}, | |
"yAxis": [ | |
{ | |
"name": "count_Reason", | |
"type": "long" | |
} | |
], | |
"splitBy": [ | |
{ | |
"name": "Reason", | |
"type": "string" | |
} | |
], | |
"aggregation": "Sum" | |
} | |
}, | |
{ | |
"name": "Version", | |
"value": "1.0" | |
}, | |
{ | |
"name": "PartId", | |
"value": "cf88c10c-36ee-42eb-b0d3-86769b2df3ed" | |
}, | |
{ | |
"name": "PartTitle", | |
"value": "Analytics" | |
}, | |
{ | |
"name": "PartSubTitle", | |
"value": "loganalyticskube" | |
}, | |
{ | |
"name": "resourceTypeMode", | |
"value": "workspace" | |
}, | |
{ | |
"name": "ControlType", | |
"value": "AnalyticsChart" | |
}, | |
{ | |
"name": "SpecificChart", | |
"value": "Bar" | |
}, | |
{ | |
"name": "DashboardId", | |
"isOptional": true | |
} | |
], | |
"type": "Extension/AppInsightsExtension/PartType/AnalyticsPart", | |
"settings": { | |
"content": { | |
"PartTitle": "Recent Pod Events ", | |
"PartSubTitle": "last 3 Hours", | |
"Query": "KubeEvents | where TimeGenerated > ago(1d) | where Reason in (\"NodeHasSufficientPID\", \"NodeHasNoDiskPressure\", \"NodeAllocatableEnforced\", \"NodeHasSufficientMemory\", \"FailedScheduling\", \"Killing\", \"FailedMount\") \n| where ObjectKind == \"Pod\"| summarize count(Reason) by bin(TimeGenerated, 30s),Reason | render barchart \n" | |
} | |
}, | |
"asset": { | |
"idInputName": "ComponentId", | |
"type": "ApplicationInsights" | |
} | |
} | |
}, | |
"8": { | |
"position": { | |
"x": 7, | |
"y": 26, | |
"colSpan": 7, | |
"rowSpan": 3 | |
}, | |
"metadata": { | |
"inputs": [ | |
{ | |
"name": "ComponentId", | |
"value": { | |
"SubscriptionId": "[parameters('workspacesubscriptionid')]", | |
"ResourceGroup": "[parameters('workspaceResourceGroup')]", | |
"Name": "[parameters('workspacename')]", | |
"ResourceId": "[concat('/subscriptions/',parameters('workspacesubscriptionid'),'/resourcegroups/',parameters('workspaceResourceGroup'),'/providers/microsoft.operationalinsights/workspaces/',parameters('workspacename'))]" | |
} | |
}, | |
{ | |
"name": "Query", | |
"value": "KubeEvents | where Reason in (\"NodeNotReady\", \"Rebooted\", \"NodeReady\") \r\n| where ObjectKind == \"Node\"| summarize count(Reason) by bin(TimeGenerated, 30s),Reason | render barchart \r\n\r\n" | |
}, | |
{ | |
"name": "TimeRange", | |
"value": "PT1H" | |
}, | |
{ | |
"name": "Dimensions", | |
"value": { | |
"xAxis": { | |
"name": "TimeGenerated", | |
"type": "datetime" | |
}, | |
"yAxis": [ | |
{ | |
"name": "count_Reason", | |
"type": "long" | |
} | |
], | |
"splitBy": [ | |
{ | |
"name": "Reason", | |
"type": "string" | |
} | |
], | |
"aggregation": "Sum" | |
} | |
}, | |
{ | |
"name": "Version", | |
"value": "1.0" | |
}, | |
{ | |
"name": "PartId", | |
"value": "a9c6d6fc-a86c-4c45-adb8-7505c878f6ed" | |
}, | |
{ | |
"name": "PartTitle", | |
"value": "Analytics" | |
}, | |
{ | |
"name": "PartSubTitle", | |
"value": "loganalyticskube" | |
}, | |
{ | |
"name": "resourceTypeMode", | |
"value": "workspace" | |
}, | |
{ | |
"name": "ControlType", | |
"value": "AnalyticsChart" | |
}, | |
{ | |
"name": "SpecificChart", | |
"value": "Bar" | |
}, | |
{ | |
"name": "DashboardId", | |
"isOptional": true | |
} | |
], | |
"type": "Extension/AppInsightsExtension/PartType/AnalyticsPart", | |
"settings": { | |
"content": { | |
"PartTitle": "Noticeable Node Events", | |
"PartSubTitle": "Last 3 hours ", | |
"Query": "KubeEvents | where TimeGenerated > ago(1d) | where Reason in (\"NodeNotReady\", \"Rebooted\", \"NodeReady\") \n| where ObjectKind == \"Node\"| summarize count(Reason) by bin(TimeGenerated, 30s),Reason | render barchart \n\n" | |
} | |
}, | |
"asset": { | |
"idInputName": "ComponentId", | |
"type": "ApplicationInsights" | |
} | |
} | |
}, | |
"9": { | |
"position": { | |
"x": 14, | |
"y": 0, | |
"colSpan": 6, | |
"rowSpan": 4 | |
}, | |
"metadata": { | |
"inputs": [ | |
{ | |
"name": "ComponentId", | |
"value": { | |
"SubscriptionId": "[parameters('workspacesubscriptionid')]", | |
"ResourceGroup": "[parameters('workspaceResourceGroup')]", | |
"Name": "[parameters('workspacename')]", | |
"ResourceId": "[concat('/subscriptions/',parameters('workspacesubscriptionid'),'/resourcegroups/',parameters('workspaceResourceGroup'),'/providers/microsoft.operationalinsights/workspaces/',parameters('workspacename'))]" | |
} | |
}, | |
{ | |
"name": "Query", | |
"value": "// Cost Distribution per cluster/microservice\r\n\r\n// Cost example\r\nlet pricingPerGig = 2.522;\r\n//Add Azure Pricing ($ Euro) the example is the cost per GIG in Europe. source: https://azure.microsoft.com/en-us/pricing/details/monitor/\r\n\r\nlet daystosearch = 31d;\r\nContainerLog\r\n| where _IsBillable == True\r\n| where TimeGenerated > startofday(ago(daystosearch))\r\n| join kind= inner\r\n(\r\n KubePodInventory\r\n | where TimeGenerated > startofday(ago(daystosearch))\r\n | extend Application=extract(\"(\\\\S+)-[A-Fa-f0-9]+$\", 1, ControllerName)\r\n | distinct ContainerID, ClusterName , Application\r\n)\r\non ContainerID\r\n| project _BilledSize, Application, TimeGenerated, ClusterName\r\n| summarize CurrentCostEuro = round(pricingPerGig* sum(_BilledSize/(1024*1024*1024)),2) by ClusterName, Application\r\n| order by CurrentCostEuro, ClusterName, Application\r\n| render barchart title=\"Cost Distribution per cluster/microservice\" \r\n//| render table title=\"Cost esitmate per Controller\"" | |
}, | |
{ | |
"name": "Dimensions", | |
"value": { | |
"xAxis": { | |
"name": "ClusterName", | |
"type": "string" | |
}, | |
"yAxis": [ | |
{ | |
"name": "CurrentCostEuro", | |
"type": "real" | |
} | |
], | |
"splitBy": [ | |
{ | |
"name": "Application", | |
"type": "string" | |
} | |
], | |
"aggregation": "Sum" | |
} | |
}, | |
{ | |
"name": "Version", | |
"value": "1.0" | |
}, | |
{ | |
"name": "PartId", | |
"value": "a60d03ec-c4dd-4996-a39a-3e0eecdc6ad9" | |
}, | |
{ | |
"name": "PartTitle", | |
"value": "Cost Distribution per cluster/microservice" | |
}, | |
{ | |
"name": "PartSubTitle", | |
"value": "loganalyticskube" | |
}, | |
{ | |
"name": "resourceTypeMode", | |
"value": "workspace" | |
}, | |
{ | |
"name": "ControlType", | |
"value": "AnalyticsChart" | |
}, | |
{ | |
"name": "SpecificChart", | |
"value": "Bar" | |
} | |
], | |
"type": "Extension/AppInsightsExtension/PartType/AnalyticsPart", | |
"asset": { | |
"idInputName": "ComponentId", | |
"type": "ApplicationInsights" | |
} | |
} | |
} | |
} | |
} | |
}, | |
"metadata": { | |
"model": { | |
"timeRange": { | |
"value": { | |
"relative": { | |
"duration": 24, | |
"timeUnit": 1 | |
} | |
}, | |
"type": "MsPortalFx.Composition.Configuration.ValueTypes.TimeRange" | |
}, | |
"filterLocale": { | |
"value": "en-us" | |
}, | |
"filters": { | |
"value": { | |
"MsPortalFx_TimeRange": { | |
"model": { | |
"format": "local", | |
"granularity": "30m", | |
"relative": "30d" | |
}, | |
"displayCache": { | |
"name": "Local Time", | |
"value": "Past 30 days" | |
}, | |
"filteredPartIds": [ | |
"StartboardPart-AnalyticsPart-c399d004-c9e8-471a-86f8-5c82429dc0ac", | |
"StartboardPart-AnalyticsPart-c399d004-c9e8-471a-86f8-5c82429dc0ae", | |
"StartboardPart-AnalyticsPart-c399d004-c9e8-471a-86f8-5c82429dc0b0", | |
"StartboardPart-AnalyticsPart-c399d004-c9e8-471a-86f8-5c82429dc0b2", | |
"StartboardPart-AnalyticsPart-c399d004-c9e8-471a-86f8-5c82429dc0b4", | |
"StartboardPart-AnalyticsPart-c399d004-c9e8-471a-86f8-5c82429dc0b6", | |
"StartboardPart-AnalyticsPart-c399d004-c9e8-471a-86f8-5c82429dc0b8", | |
"StartboardPart-AnalyticsPart-c399d004-c9e8-471a-86f8-5c82429dc0ba", | |
"StartboardPart-AnalyticsPart-c399d004-c9e8-471a-86f8-5c82429dc0bc" | |
] | |
} | |
} | |
} | |
} | |
} | |
}, | |
"name": "[parameters('dashboardname')]", | |
"type": "Microsoft.Portal/dashboards", | |
"location": "[resourceGroup().location]", | |
"tags": { | |
"hidden-title": "[parameters('dashboardname')]" | |
}, | |
"apiVersion": "2015-08-01-preview" | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment