From 820c600a532118a03dd7336f4c89b9328d7aa362 Mon Sep 17 00:00:00 2001 From: MusikAnimal Date: Fri, 8 Dec 2017 14:06:10 -0500 Subject: [PATCH] Meta: add visualization of API usage stats --- app/Resources/views/base.html.twig | 1 + app/Resources/views/meta/result.html.twig | 179 ++++++++++++++++++-- src/AppBundle/Controller/MetaController.php | 93 +++++++++- web/static/css/meta.scss | 8 + 4 files changed, 257 insertions(+), 24 deletions(-) create mode 100644 web/static/css/meta.scss diff --git a/app/Resources/views/base.html.twig b/app/Resources/views/base.html.twig index 7a3fa1847..7338f1c41 100755 --- a/app/Resources/views/base.html.twig +++ b/app/Resources/views/base.html.twig @@ -38,6 +38,7 @@ 'static/css/autoedits.scss' 'static/css/editcounter.scss' 'static/css/pages.scss' + 'static/css/meta.scss' output='static/production/application.css' %} {% endstylesheets %} diff --git a/app/Resources/views/meta/result.html.twig b/app/Resources/views/meta/result.html.twig index 812af0d88..0e63f7e11 100644 --- a/app/Resources/views/meta/result.html.twig +++ b/app/Resources/views/meta/result.html.twig @@ -29,24 +29,24 @@
- +
{% set total = 0 %} - {% for tool, count in totals %} + {% for tool, count in toolUsage.totals %}
- {{ msg('tool') | capitalize_first }} + {{ msg('tool')|capitalize_first }} - {{ msg('count') | capitalize_first }} + {{ msg('count')|capitalize_first }}
@@ -64,21 +64,21 @@
- {{ totals | length }} - {{ msg('num-tools', [totals | length]) }} + {{ toolUsage.totals|length }} + {{ msg('num-tools', [toolUsage.totals|length]) }} - {{ grandSum|num_format }} + {{ toolUsage.grandSum|num_format }}
{% set totalChartData = [] %} - {% for tool, count in totals %} - {% set totalChartData = totalChartData | merge([{ + {% for tool, count in toolUsage.totals %} + {% set totalChartData = totalChartData|merge([{ label: msg('tool-'~tool), value: count, - percentage: (count / grandSum) * 100, + percentage: (count / toolUsage.grandSum) * 100, }]) %} {% endfor %} {{ chart.pie_chart('totals_chart', totalChartData, false, 'toggle-table--chart') }} @@ -90,13 +90,13 @@ {% endset %} - {{ layout.content_block('timeline', content) }} + {{ layout.content_block('Timeline', content, '', null, true) }} - {% set toolNames = totals | keys %} + {% set toolNames = toolUsage.totals|keys %} + + {######## FOR THE API STATS ########} + + {% set content %} +
+ + + + + + + + + +
{{ msg('start') }}{{ start }}
{{ msg('end') }}{{ end }}
+
+
+ + + + + + + {% set total = 0 %} + {% for endpoint, count in apiUsage.totals %} + + + + + {% endfor %} + + + + + + + +
+ + Endpoint + + + + + {{ msg('count')|capitalize_first }} + + +
+ + + + + {{ endpoint }} + + {{ count|num_format }} +
+ {{ apiUsage.totals|length }} endpoints + + {{ apiUsage.grandSum|num_format }} +
+ {% set apiTotalChartData = [] %} + {% for endpoint, count in apiUsage.totals %} + {% set apiTotalChartData = apiTotalChartData|merge([{ + label: endpoint, + value: count, + percentage: (count / apiUsage.grandSum) * 100, + }]) %} + {% endfor %} + {{ chart.pie_chart('api_totals_chart', apiTotalChartData, false, 'toggle-table--chart') }} + {% endset %} + {{ layout.content_block('API Summary', content, '', null, true) }} + + {% set content %} +
+ +
+ {% endset %} + {{ layout.content_block('API Timeline', content, '', null, true) }} + + {% set endpointNames = apiUsage.totals|keys %} + + {% endblock %} diff --git a/src/AppBundle/Controller/MetaController.php b/src/AppBundle/Controller/MetaController.php index b777e424e..c69402570 100644 --- a/src/AppBundle/Controller/MetaController.php +++ b/src/AppBundle/Controller/MetaController.php @@ -10,6 +10,7 @@ use Symfony\Component\HttpFoundation\Request; use DateTime; use Symfony\Component\HttpFoundation\Response; +use Doctrine\DBAL\Connection; /** * This controller serves everything for the Meta tool. @@ -53,14 +54,36 @@ public function resultAction($start, $end, $legacy = false) { $db = $legacy ? 'toolsdb' : 'default'; $table = $legacy ? 's51187__metadata.xtools_timeline' : 'usage_timeline'; - $client = $this->container ->get('doctrine') ->getManager($db) ->getConnection(); + $toolUsage = $this->getToolUsageStats($client, $table, $start, $end); + $apiUsage = $this->getApiUsageStats($client, $start, $end); + + return $this->render('meta/result.html.twig', [ + 'xtPage' => 'meta', + 'start' => $start, + 'end' => $end, + 'toolUsage' => $toolUsage, + 'apiUsage' => $apiUsage, + ]); + } + + /** + * Get usage statistics of the core tools. + * @param Connection $client + * @param string $table Table to query. + * @param string $start Start date. + * @param string $end End date. + * @return array + * @codeCoverageIgnore + */ + private function getToolUsageStats(Connection $client, $table, $start, $end) + { $query = $client->prepare("SELECT * FROM $table - WHERE date >= :start AND date <= :end"); + WHERE date >= :start AND date <= :end"); $query->bindParam('start', $start); $query->bindParam('end', $end); $query->execute(); @@ -99,16 +122,70 @@ public function resultAction($start, $end, $legacy = false) } arsort($totals); - return $this->render('meta/result.html.twig', [ - 'xtPage' => 'meta', - 'start' => $start, - 'end' => $end, - 'data' => $data, + return [ 'totals' => $totals, 'grandSum' => $grandSum, 'dateLabels' => $dateLabels, 'timeline' => $timeline, - ]); + ]; + } + + /** + * Get usage statistics of the API. + * @param Connection $client + * @param string $start Start date. + * @param string $end End date. + * @return array + * @codeCoverageIgnore + */ + private function getApiUsageStats(Connection $client, $start, $end) + { + $query = $client->prepare("SELECT * FROM usage_api_timeline + WHERE date >= :start AND date <= :end"); + $query->bindParam('start', $start); + $query->bindParam('end', $end); + $query->execute(); + + $data = $query->fetchAll(); + + // Create array of totals, along with formatted timeline data as needed by Chart.js + $totals = []; + $dateLabels = []; + $timeline = []; + $startObj = new DateTime($start); + $endObj = new DateTime($end); + $numDays = (int) $endObj->diff($startObj)->format("%a"); + $grandSum = 0; + + // Generate array of date labels + for ($dateObj = new DateTime($start); $dateObj <= $endObj; $dateObj->modify('+1 day')) { + $dateLabels[] = $dateObj->format('Y-m-d'); + } + + foreach ($data as $entry) { + if (!isset($totals[$entry['endpoint']])) { + $totals[$entry['endpoint']] = (int) $entry['count']; + + // Create arrays for each endpoint, filled with zeros for each date in the timeline + $timeline[$entry['endpoint']] = array_fill(0, $numDays, 0); + } else { + $totals[$entry['endpoint']] += (int) $entry['count']; + } + + $date = new DateTime($entry['date']); + $dateIndex = (int) $date->diff($startObj)->format("%a"); + $timeline[$entry['endpoint']][$dateIndex] = (int) $entry['count']; + + $grandSum += $entry['count']; + } + arsort($totals); + + return [ + 'totals' => $totals, + 'grandSum' => $grandSum, + 'dateLabels' => $dateLabels, + 'timeline' => $timeline, + ]; } /** diff --git a/web/static/css/meta.scss b/web/static/css/meta.scss new file mode 100644 index 000000000..54e894847 --- /dev/null +++ b/web/static/css/meta.scss @@ -0,0 +1,8 @@ +@import 'mixins.scss'; + +.meta { + #usage_chart, + #api_usage_chart { + max-width: 1000px; + } +}