Skip to content

Commit

Permalink
[Fixes #4911] On Monitoring plugin the uptime is not correctly comput…
Browse files Browse the repository at this point in the history
…ed (#4912)

*  - Average response time tentative fix

* - Average response time tentative fix

* - Average response time tentative fix

* - Average response time tentative fix

*  - IT translations

*  - Average geonode response time UI fix

*  - Improve settings for Monitoring plugin

* - IT translations

*  - Fix monitoring gui issues

* [Fixes #4911] On Monitoring plugin the uptime is not correctly computed
  • Loading branch information
Alessio Fabiani committed Sep 18, 2019
1 parent bc20458 commit 80c8de7
Show file tree
Hide file tree
Showing 14 changed files with 91 additions and 74 deletions.
Binary file modified geonode/locale/it/LC_MESSAGES/django.mo
Binary file not shown.
2 changes: 1 addition & 1 deletion geonode/locale/it/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ msgstr ""
"Project-Id-Version: GeoNode\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-09-17 16:19+0000\n"
"PO-Revision-Date: 2019-09-17 18:34+0200\n"
"PO-Revision-Date: 2019-09-18 14:24+0200\n"
"Last-Translator: Julien Collaer <julien.collaer@opengeode.be>\n"
"Language-Team: Italian (http://www.transifex.com/geonode/geonode/language/"
"it/)\n"
Expand Down
Binary file modified geonode/locale/it/LC_MESSAGES/djangojs.mo
Binary file not shown.
6 changes: 3 additions & 3 deletions geonode/locale/it/LC_MESSAGES/djangojs.po
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ msgstr ""
"Project-Id-Version: GeoNode\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-09-17 16:19+0000\n"
"PO-Revision-Date: 2019-09-17 18:36+0200\n"
"PO-Revision-Date: 2019-09-18 11:15+0200\n"
"Last-Translator: Julien Collaer <julien.collaer@opengeode.be>\n"
"Language-Team: Italian (http://www.transifex.com/geonode/geonode/language/"
"it/)\n"
Expand Down Expand Up @@ -207,7 +207,7 @@ msgstr "Vostro "

#: geonode/static/geonode/js/upload/LayerInfo.js:422
msgid "Performing Final GeoServer Config Step"
msgstr "Esecuzione finale GeoServer Config Passo"
msgstr "Esecuzione step finale configurazione GeoServer"

#: geonode/static/geonode/js/upload/LayerInfo.js:439
#: geonode/static/geonode/js/upload/LayerInfo.js:483
Expand All @@ -226,7 +226,7 @@ msgstr "Una dimensione temporale può essere aggiunta a questo livello."

#: geonode/static/geonode/js/upload/LayerInfo.js:521
msgid "Performing GeoServer Config Step"
msgstr "Esecuzione GeoServer Config Passo"
msgstr "Configurazione di GeoServer"

#: geonode/static/geonode/js/upload/LayerInfo.js:610
msgid ""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ class ResponseTable extends React.Component {
}

render() {
const average = this.props.average ? `${this.props.average} ms` : 'N/A';
const max = this.props.max ? `${this.props.max} ms` : 'N/A';
const requests = this.props.requests || 0;
const average = this.props.average != undefined ? `${this.props.average} ms` : 'N/A';
const max = this.props.max != undefined ? `${this.props.max} ms` : 'N/A';
const requests = this.props.requests != undefined ? this.props.requests : 0;
return (
<div style={styles.content}>
<h4>Average Response Time {average}</h4>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,27 @@ class ResponseTime extends React.Component {
}

render() {
let avgResponse = 0;
let minResponse = 0;
let maxResponse = 0;
let latestResponse = 0;
for (let i = this.props.data.length - 1; i >= 0; --i) {
const response = this.props.data[i].time;
if (response !== 0) {
latestResponse = response;
break;
minResponse = minResponse == 0 || response < minResponse ? response : minResponse;
maxResponse = response > maxResponse ? response : maxResponse;
if (latestResponse == 0) {
latestResponse = response;
}
}
}
avgResponse = (minResponse + maxResponse) / 2;
return (
<div style={styles.content}>
<h4>Response Time</h4>
Last Response Time: {latestResponse} ms<br />
Max Response Time: {this.props.max} ms<br />
Average Response Time: {this.props.average} ms<br />
Max Response Time: {maxResponse} ms<br />
Average Response Time: {avgResponse} ms<br />
<LineChart
width={500}
height={300}
Expand All @@ -65,5 +72,4 @@ class ResponseTime extends React.Component {
}
}


export default ResponseTime;
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class Uptime extends React.Component {
if (data.length > 0) {
if (data[0].data.length > 0) {
const metric = data[0].data[0];
uptime = Math.floor(Number(metric.val) / 60 / 60 / 24);
uptime = Math.floor(Number(metric.max) / (60 * 60 * 24));
}
}
}
Expand Down
22 changes: 14 additions & 8 deletions geonode/monitoring/frontend/monitoring/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,14 @@ export const sequenceInterval = (interval) => {


export const getResponseData = (response) => {
let averageResponseTime;
let maxResponseTime;
let totalRequests;
let averageResponseTime = 0;
let maxResponseTime = 0;
let totalRequests = 0;

if (!response) {
return [0, 0, 0];
return ["N/A", "N/A", "N/A"];
}

const rawData = response.data.data;
const rawDataLength = rawData.length;
if (rawDataLength > 0) {
Expand All @@ -125,15 +127,19 @@ export const getResponseData = (response) => {
const dataLength = data.data.length;
if (dataLength > 0) {
const metric = data.data[dataLength - 1];
maxResponseTime = Number(metric.max) > 1
maxResponseTime = Number(metric.max) >= 0
? Math.floor(metric.max)
: Number(metric.max.slice(0, 4));
averageResponseTime = Number(metric.val) > 1
: Number(metric.max);
averageResponseTime = Number(metric.val) >= 0
? Math.floor(metric.val)
: Number(metric.val.slice(0, 4));
: Number(metric.val);
totalRequests = metric.samples_count;
}
}

averageResponseTime = averageResponseTime > 0 ? averageResponseTime : "N/A";
maxResponseTime = maxResponseTime > 0 ? maxResponseTime : "N/A";
totalRequests = totalRequests > 0 ? totalRequests : "N/A";
return [averageResponseTime, maxResponseTime, totalRequests];
};

Expand Down
11 changes: 6 additions & 5 deletions geonode/monitoring/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,6 @@

from django.db.models import Sum, F, Case, When, Max

from geonode.utils import parse_datetime


log = logging.getLogger(__name__)

GEOIP_DB = None
Expand Down Expand Up @@ -639,6 +636,8 @@ def _get_user_data_gs(cls, request):

@classmethod
def from_geonode(cls, service, request, response):
from geonode.utils import parse_datetime

received = datetime.utcnow().replace(tzinfo=pytz.utc)
rqmeta = getattr(request, '_monitoring', {})
created = rqmeta.get('started', received)
Expand Down Expand Up @@ -718,6 +717,9 @@ def from_geoserver(cls, service, request_data, received=None):
"""
Writes RequestEvent for data from audit log in GS
"""
from dateutil.tz import tzlocal
from geonode.utils import parse_datetime

rd = request_data.get('org.geoserver.monitor.RequestData')
if not rd:
log.warning("No request data payload in %s", request_data)
Expand Down Expand Up @@ -752,7 +754,6 @@ def from_geoserver(cls, service, request_data, received=None):
# region = client_loc['region']
# city = client_loc['city']

from dateutil.tz import tzlocal
utc = pytz.utc
try:
local_tz = pytz.timezone(datetime.now(tzlocal()).tzname())
Expand Down Expand Up @@ -895,7 +896,7 @@ class MetricLabel(models.Model):
blank=True)

def __str__(self):
return 'Metric Label: {}'.format(self.name)
return 'Metric Label: {}'.format(self.name.encode('ascii', 'ignore'))


class MetricValue(models.Model):
Expand Down
32 changes: 16 additions & 16 deletions geonode/monitoring/static/monitoring/bundle.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion geonode/monitoring/templates/monitoring/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
{% load i18n %}
{% load static from staticfiles %}

{% block title %} {% trans "Monitoring" %} - {{ block.super }} {% endblock %}
{% block title %} {% trans "Monitoring & Analytics" %} - {{ block.super }} {% endblock %}

{% block header %}
{{ block.super }}
Expand Down
2 changes: 1 addition & 1 deletion geonode/monitoring/templates/monitoring/non_superuser.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{% extends "geonode_base.html" %}
{% load i18n %}

{% block title %} {% trans "Monitoring" %} - {{ block.super }} {% endblock %}
{% block title %} {% trans "Monitoring & Analytics" %} - {{ block.super }} {% endblock %}

{% block body_class %}monitoring{% endblock %}

Expand Down
10 changes: 8 additions & 2 deletions geonode/monitoring/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,12 @@
from urllib import urlencode
from urlparse import urlsplit
from bs4 import BeautifulSoup as bs
from requests.auth import HTTPBasicAuth
from datetime import datetime, timedelta
from defusedxml import lxml as dlxml

from django.conf import settings
from django.db.models.fields.related import RelatedField

from geonode.monitoring.models import RequestEvent, ExceptionEvent
from geonode.settings import DATETIME_INPUT_FORMATS


Expand All @@ -54,6 +52,8 @@ def __init__(self, service, *args, **kwargs):
self.service = service

def emit(self, record):
from geonode.monitoring.models import RequestEvent, ExceptionEvent

exc_info = record.exc_info
req = record.request
resp = record.response
Expand Down Expand Up @@ -82,6 +82,8 @@ def add(self, req, resp):
RequestToMonitoringThread.q.put(item)

def run(self):
from geonode.monitoring.models import RequestEvent

q = RequestToMonitoringThread.q
while True:
if not q.empty():
Expand Down Expand Up @@ -114,6 +116,8 @@ def get_requests(self, format=None, since=None, until=None):
"""
Returns list of requests from monitoring
"""
from requests.auth import HTTPBasicAuth

rest_url = '{}rest/monitor/requests.html'.format(self.base_url)
qargs = {}
if since:
Expand Down Expand Up @@ -144,6 +148,8 @@ def get_requests(self, format=None, since=None, until=None):
log.warning("Skipping payload for {}".format(href))

def get_request(self, href, format=format):
from requests.auth import HTTPBasicAuth

username = settings.OGC_SERVER['default']['USER']
password = settings.OGC_SERVER['default']['PASSWORD']
log.debug(" href: %s " % href)
Expand Down
54 changes: 26 additions & 28 deletions geonode/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -1176,7 +1176,7 @@

MONITORING_CONFIG = os.getenv("MONITORING_CONFIG", None)
MONITORING_HOST_NAME = os.getenv("MONITORING_HOST_NAME", HOSTNAME)
MONITORING_SERVICE_NAME = os.getenv("MONITORING_SERVICE_NAME", 'local-geonode')
MONITORING_SERVICE_NAME = os.getenv("MONITORING_SERVICE_NAME", 'geonode')

# how long monitoring data should be stored
MONITORING_DATA_TTL = timedelta(days=int(os.getenv("MONITORING_DATA_TTL", 7)))
Expand All @@ -1192,6 +1192,31 @@
MIDDLEWARE_CLASSES += \
('geonode.monitoring.middleware.MonitoringMiddleware',)

# skip certain paths to not to mud stats too much
MONITORING_SKIP_PATHS = ('/api/o/',
'/monitoring/',
'/admin',
'/lang.js',
'/jsi18n',
STATIC_URL,
MEDIA_URL,
re.compile('^/[a-z]{2}/admin/'),
)

# configure aggregation of past data to control data resolution
# list of data age, aggregation, in reverse order
# for current data, 1 minute resolution
# for data older than 1 day, 1-hour resolution
# for data older than 2 weeks, 1 day resolution
MONITORING_DATA_AGGREGATION = (
(timedelta(seconds=0), timedelta(minutes=1),),
(timedelta(days=1), timedelta(minutes=60),),
(timedelta(days=14), timedelta(days=1),),
)
USER_ANALYTICS_ENABLED = ast.literal_eval(os.getenv('USER_ANALYTICS_ENABLED', 'True'))
GEOIP_PATH = os.getenv('GEOIP_PATH', os.path.join(PROJECT_ROOT, 'GeoIPCities.dat'))
# -- END Settings for MONITORING plugin

CACHES = {
# DUMMY CACHE FOR DEVELOPMENT
'default': {
Expand Down Expand Up @@ -1754,33 +1779,6 @@ def get_geonode_catalogue_service():
# Each uploaded Layer must be approved by an Admin before becoming visible
ADMIN_MODERATE_UPLOADS = ast.literal_eval(os.environ.get('ADMIN_MODERATE_UPLOADS', 'False'))

GEOIP_PATH = os.getenv('GEOIP_PATH', os.path.join(PROJECT_ROOT, 'GeoIPCities.dat'))

# skip certain paths to not to mud stats too much
MONITORING_SKIP_PATHS = ('/api/o/',
'/monitoring/',
'/admin',
'/lang.js',
'/jsi18n',
STATIC_URL,
MEDIA_URL,
re.compile('^/[a-z]{2}/admin/'),
)

# configure aggregation of past data to control data resolution
# list of data age, aggregation, in reverse order
# for current data, 1 minute resolution
# for data older than 1 day, 1-hour resolution
# for data older than 2 weeks, 1 day resolution
MONITORING_DATA_AGGREGATION = (
(timedelta(seconds=0), timedelta(minutes=1),),
(timedelta(days=1), timedelta(minutes=60),),
(timedelta(days=14), timedelta(days=1),),
)

# privacy settings
USER_ANALYTICS_ENABLED = ast.literal_eval(os.getenv('USER_ANALYTICS_ENABLED', 'False'))

# If this option is enabled, Resources belonging to a Group won't be
# visible by others
GROUP_PRIVATE_RESOURCES = ast.literal_eval(os.environ.get('GROUP_PRIVATE_RESOURCES', 'False'))
Expand Down

0 comments on commit 80c8de7

Please sign in to comment.