api/ui/debug/js/memory.js (122 lines of code) (raw):

// Copyright (c) 2017-2018 Uber Technologies, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. var pieChart = null; jQuery.fn.dataTable.ext.type.order['data-size-pre'] = function (data) { var matches = data.match(/^(\d+\.\d+)?\s*([a-z]+)/i); var multipliers = { b: 1, kb: 1024, mb: 1048576, gb: 1073741824 }; if (matches) { var multiplier = multipliers[matches[2].toLowerCase()]; return parseFloat(matches[1]) * multiplier; } else { return -1; } }; function initHostMemoryExplorer() { $.ajax({ url: "/dbg/host-memory", success: function (body) { initTableShardList(body); }, error: function (xhr) { alert(xhr.responseText) } } ) } var tableShardData = []; var rawData; function initTableShardList(data) { rawData = data; renderMemoryTable(); } function processRawData(data) { tableShardData = []; Object.keys(data).forEach(function(tableShardKey) { var index = tableShardKey.lastIndexOf("_"); var table = tableShardKey.substring(0, index); var shard = tableShardKey.substring(index+1); var preloadMemory = 0; var nonPreloadMemory = 0; var liveMemory = 0; var primaryKeyMemory = data[tableShardKey].pk; Object.keys(data[tableShardKey].cols).forEach(function(column) { preloadMemory += data[tableShardKey].cols[column].preloaded; nonPreloadMemory += data[tableShardKey].cols[column].nonPreloaded; liveMemory += data[tableShardKey].cols[column].live; }); var tableShardItem = { table: table, shard: shard, preloadMemory: preloadMemory, nonPreloadMemory: nonPreloadMemory, liveMemory: liveMemory, primaryKeyMemory: primaryKeyMemory, total: preloadMemory + nonPreloadMemory + liveMemory + primaryKeyMemory, columns: processColumnMemoryData(tableShardKey, data[tableShardKey].cols) }; tableShardData.push(tableShardItem); }); } function processColumnMemoryData(tableShardKey, columns) { var columnMemoryData = []; Object.keys(columns).forEach(function(column) { var preloadMemory = columns[column].preloaded; var nonPreloadMemory = columns[column].nonPreloaded; var liveMemory = columns[column].live; var total = preloadMemory + nonPreloadMemory + liveMemory; columnMemoryData.push({ column: column, preloadMemory: preloadMemory, nonPreloadMemory: nonPreloadMemory, liveMemory: liveMemory, total: total }); }); return columnMemoryData; } function drawPieChat(name, data, labels) { if (pieChart != null) { pieChart.destroy(); } var ctx = document.getElementById("chart").getContext('2d'); pieChart = new Chart(ctx, { type: 'pie', data: { datasets: [{ label: name, data: data, backgroundColor: palette('tol-rainbow', data.length).map(function(hex) { return '#' + hex; }) }], labels: labels, options: { tooltips: { callbacks: { label: function(tooltipItem, data) { var datasetLabel = ''; var label = data.labels[tooltipItem.index]; return data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index]; } } } } } }); $('#chart-container').show(); } function renderMemoryTable() { processRawData(rawData); function renderMem(data, type, row) { var gb = 1 << 30; var mb = 1 << 20; var kb = 1 << 10; if (data > gb) { return '' + (data / gb).toFixed(2) + ' GB'; } else if (data > mb) { return '' + (data / mb).toFixed(2) + ' MB'; } else if (data > kb) { return '' + (data / kb).toFixed(2) + ' KB'; } return '' + data.toFixed(2) + ' B'; } var tableShardsTable = $('#table-shards-table').DataTable({ paging: false, autoWidth: false, aoColumns: [ {title: "Table", data: "table"}, {title: "Shard", data: "shard"}, {title: "Preloaded", data: "preloadMemory", type: "data-size", render: renderMem}, {title: "NonPreloaded", data: "nonPreloadMemory", type: "data-size", render: renderMem}, {title: "Live", data: "liveMemory", type: "data-size", render: renderMem}, {title: "PrimaryKey", data: "primaryKeyMemory", type: "data-size", render: renderMem}, {title: "Total", data: "total", type: "data-size", render: renderMem} ], aaData: tableShardData }); var tableColumnsTable = $('#table-columns-table').DataTable({ paging: false, autoWidth: false, aoColumns: [ {title: "Column", data: "column"}, {title: "Preloaded", data: "preloadMemory", type: "data-size", render: renderMem}, {title: "NonPreloaded", data: "nonPreloadMemory", type: "data-size", render: renderMem}, {title: "Live", data: "liveMemory", type: "data-size", render: renderMem}, {title: "Total", data: "total", type: "data-size", render: renderMem} ], aaData: [] }); $('#table-columns-close').click(function(event){ $('#table-columns').addClass("collapse"); $("#table-shards").removeClass("col-md-6"); $("#table-shards").addClass("col-md-12"); }); $('#table-shards-table').on('click', 'tr', function(event) { var data = tableShardsTable.row(this).data(); var chartData = []; var chartLabels = []; if (!data) { return; } data.columns.forEach(function(col) { chartData.push(col.total); chartLabels.push(col.column); }); drawPieChat('Memory By Columns', chartData, chartLabels); tableColumnsTable.clear(); tableColumnsTable.rows.add(data.columns).draw(); $("#table-shards").removeClass("col-md-12"); $("#table-shards").addClass("col-md-6"); $('#table-columns').removeClass("collapse"); }); $('#table-columns-table').on('click', 'tr', function(event) { var data = tableColumnsTable.row(this).data(); if (!data) { return; } var chartData = [data.preloadMemory, data.nonPreloadMemory, data.liveMemory]; var chartLabels = ['preloaded', 'nonPreloaded', 'live']; drawPieChat('Column Memory Detail', chartData, chartLabels); }); $('#chart-container').hide(); }