Skip to content
This repository has been archived by the owner on Sep 26, 2018. It is now read-only.

Subscriber status and activation report #64

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions cloud/endagaweb/stats_app/stats_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,3 +369,61 @@ def timeseries(self, key=None, **kwargs):
if 'aggregation' not in kwargs:
kwargs['aggregation'] = 'average_value'
return self.aggregate_timeseries(key, **kwargs)

class SubscriberStatsClient(StatsClientBase):
"""Gathers data on SubscriberStats instance at tower and network level"""

def __init__(self, *args, **kwargs):
super(SubscriberStatsClient, self).__init__(*args, **kwargs)

def timeseries(self, key=None, **kwargs):
if 'aggregation' not in kwargs:
kwargs['aggregation'] = 'average_value'
return self.aggregate_timeseries(key, **kwargs)

class BTSStatsClient(StatsClientBase):
"""Gathers data on BTSStats instances at a tower and network level"""

def __init__(self, *args, **kwargs):
super(BTSStatsClient, self).__init__(*args, **kwargs)

def timeseries(self, kind=None, **kwargs):
results, usage, bts_values = ([] for i in range(3))

start_time = datetime.fromtimestamp(kwargs['start_time_epoch'],
pytz.utc)

# Limit end time to 7 days.
kwargs['end_time'] = start_time + timedelta(days=7)

try:
previous_state = models.SystemEvent.objects.filter(
bts_id=self.level_id, date__lt=start_time).order_by('-date')[0]
previous_state = previous_state.type
except IndexError:
previous_state = 'bts up'

for call_kind in BTS_KINDS:
# bts up
usage = self.aggregate_timeseries(call_kind, **kwargs)
values = [u[1] for u in usage]
results.append(values)
dates = [u[0] for u in usage]
# Get last state
last_val = None
bts_status = [sum(v) for v in zip(*results)]
for value in bts_status:
if last_val is None:
if previous_state == 'bts up':
last_val = 1
elif previous_state == 'bts up':
last_val = 0
# last_val = value
if value > 0:
last_val = 1
elif value < 0:
last_val = 0
bts_values.append(last_val)
return zip(dates, bts_values)


83 changes: 83 additions & 0 deletions cloud/endagaweb/templates/dashboard/report/health.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
{% extends "dashboard/layout.html" %}
{% comment %}
Copyright (c) 2016-present, Facebook, Inc.
All rights reserved.

This source code is licensed under the BSD-style license found in the
LICENSE file in the root directory of this source tree. An additional grant
of patent rights can be found in the PATENTS file in the same directory.
{% endcomment %}
{% load apptags %}

{% block title %}
{% tmpl_const "SITENAME" %} | towers
{% endblock %}

{% block pagestyle %}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.1.13-beta/nv.d3.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.14.30/css/bootstrap-datetimepicker.min.css">
{% endblock %}

{% block content %}
{% include "dashboard/report/header.html" with header='Health' %}

<div class='row'>
{% include "dashboard/report/nav.html" with active_tab='health_reports' %}
<div class='content col-xs-12 col-sm-10 col-md-10'>
{% include "dashboard/report/health-filter-action.html" with action_url='/dashboard/reports/health' %}
{% if network_has_activity %}
<div class="row">
<div id='health-chart'></div>
</div>
{% include 'dashboard/timezone-notice.html' %}
{% else %}
<p>There is no network activity to display.</p>
{% endif %}
</div> <!-- /.col-md-4 -->
</div>

{% endblock %}
{% block js %}
<script>
$(function() {
setTimeout(function() {
$('.timezone-notice').fadeIn(500);
}, 800);
});
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.12.2/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.12.2/JSXTransformer.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.1.5/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.1.13-beta/nv.d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.9.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.14.30/js/bootstrap-datetimepicker.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.7.0/moment.min.js" type="text/javascript"></script>
<script src="https://cdn.datatables.net/1.10.15/js/jquery.dataTables.min.js"></script>
<script src="/static/js/dashboard/saveSvgAsPng.js"></script>
<script type="text/jsx" src="/static/js/dashboard/report-chart-components.js"></script>
<script type="text/jsx">
var currentTimeEpoch = {{ current_time_epoch }};
var timezoneOffset = {{ timezone_offset }};
React.render(
<TimeseriesChartWithButtonsAndDatePickers
title='BTS Status'
chartID='call-chart'
statTypes='health_state'
level='tower'
levelID='{{ level_id }}'
defaultButtonText='day'
aggregation='bts_status'
buttons={['day','week']}
yAxisLabel='STATE'
currentTimeEpoch={currentTimeEpoch}
timezoneOffset={timezoneOffset}
tooltipUnits=''
chartType='line-chart'
info='This report shows BTS health status in terms of BTS uptime and downtime for each BTS for selected time window.'
/>,
document.getElementById('health-chart')
);
</script>


{% endblock %}
100 changes: 100 additions & 0 deletions cloud/endagaweb/templates/dashboard/report/subscriber.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
{% extends "dashboard/layout.html" %}
{% comment %}
Copyright (c) 2016-present, Facebook, Inc.
All rights reserved.

This source code is licensed under the BSD-style license found in the
LICENSE file in the root directory of this source tree. An additional grant
of patent rights can be found in the PATENTS file in the same directory.
{% endcomment %}
{% load apptags %}

{% block title %}
{% tmpl_const "SITENAME" %} | towers
{% endblock %}

{% block pagestyle %}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.1.13-beta/nv.d3.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.14.30/css/bootstrap-datetimepicker.min.css">
<link rel="stylesheet" href="https://cdn.datatables.net/1.10.15/css/jquery.dataTables.min.css" type="text/css"/>
{% endblock %}

{% block content %}
{% include "dashboard/report/header.html" with header='Subscriber' %}

<div class='row'>
{% include "dashboard/report/nav.html" with active_tab='subscriber_reports' %}
<div class='content col-xs-12 col-sm-10 col-md-10'>
{% include "dashboard/report/filter.html" with action_url='/dashboard/reports/subscriber' %}
{% if network_has_activity %}
<div class="row">
<div id='subscriber-chart'></div>
<div id='subscriber-status'></div>
</div>
{% include 'dashboard/timezone-notice.html' %}
{% else %}
<p>There is no network activity to display.</p>
{% endif %}
</div> <!-- /.col-md-4 -->
</div>

{% endblock %}
{% block js %}
<script>
$(function() {
setTimeout(function() {
$('.timezone-notice').fadeIn(500);
}, 800);
});
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.12.2/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.12.2/JSXTransformer.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.1.5/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.1.13-beta/nv.d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.9.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.14.30/js/bootstrap-datetimepicker.min.js"></script>
<script src="https://cdn.datatables.net/1.10.15/js/jquery.dataTables.min.js"></script>

<script type="text/jsx" src="/static/js/dashboard/report-chart-components.js"></script>
<script type="text/jsx">
var currentTimeEpoch = {{ current_time_epoch }};
var timezoneOffset = {{ timezone_offset }};
{% if 'Subscriber Activity' in reports %}
React.render(
<TimeseriesChartWithButtonsAndDatePickers
title='Subscriber Activity'
chartID='call-chart'
statTypes='Provisioned,deactivate_number,zero_balance_subscriber'
level='{{ level }}'
levelID='{{ level_id }}'
aggregation='count'
yAxisLabel='numbers'
currentTimeEpoch={currentTimeEpoch}
timezoneOffset={timezoneOffset}
tooltipUnits='s of'
chartType='bar-chart'
/>,
document.getElementById('subscriber-chart')
);
{% endif %}
{% if 'Subscriber Status' in reports %}
React.render(
<TimeseriesChartWithButtonsAndDatePickers
title='Subscriber Status'
chartID='status-chart'
statTypes='expired,first_expired,blocked'
level='{{ level }}'
levelID='{{ level_id }}'
aggregation='count'
yAxisLabel='numbers'
currentTimeEpoch={currentTimeEpoch}
timezoneOffset={timezoneOffset}
tooltipUnits='s of'
chartType='bar-chart'
/>,
document.getElementById('subscriber-status')
);
{% endif %}
</script>

{% endblock %}
1 change: 1 addition & 0 deletions cloud/endagaweb/views/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@
import debug
import internalapi
import file_upload
import reports
38 changes: 38 additions & 0 deletions cloud/endagaweb/views/reports.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@


class SubscriberReportView(BaseReport):
"""View Subscriber reports on basis of Network or tower level."""

def __init__(self, **kwargs):
template = "dashboard/report/subscriber.html"
url_namespace = "subscriber-report"
reports = {'Subscriber': ['Subscriber Activity',
'Subscriber Status']}
super(SubscriberReportView, self).__init__(reports, template,
url_namespace, **kwargs)

def get(self, request):
return self.handle_request(request)

def post(self, request):
return self.handle_request(request)


class HealthReportView(BaseReport):
"""View System health reports."""

def __init__(self, **kwargs):
template = "dashboard/report/health.html"
url_namespace = "health-report"
reports = {'Health': ['BTS Health']}
super(HealthReportView, self).__init__(reports, template,
url_namespace, **kwargs)

def get(self, request):
return self.handle_request(request)

def post(self, request):
return self.handle_request(request)