Commit 6213a8f3 by Bach Dániel

vm: remove calvin

parent 8e95b11f
......@@ -435,3 +435,10 @@ COMPANY_NAME = "BME IK 2014"
SOUTH_MIGRATION_MODULES = {
'taggit': 'taggit.south_migrations',
}
graphite_host = get_env_variable("GRAPHITE_HOST")
graphite_port = get_env_variable("GRAPHITE_PORT")
if graphite_host and graphite_port:
GRAPHITE_URL = 'http://%s:%s/render/' % (graphite_host, graphite_port)
else:
GRAPHITE_URL = None
......@@ -262,7 +262,7 @@ class VmDetailView(CheckedDetailView):
instance = context['instance']
ops = get_operations(instance, self.request.user)
context.update({
'graphite_enabled': VmGraphView.get_graphite_url() is not None,
'graphite_enabled': settings.GRAPHITE_URL is not None,
'vnc_url': reverse_lazy("dashboard.views.detail-vnc",
kwargs={'pk': self.object.pk}),
'ops': ops,
......@@ -691,7 +691,7 @@ class NodeDetailView(LoginRequiredMixin, SuperuserRequiredMixin, DetailView):
context['activities'] = na
context['trait_form'] = form
context['graphite_enabled'] = (
NodeGraphView.get_graphite_url() is not None)
settings.GRAPHITE_URL is not None)
return context
def post(self, request, *args, **kwargs):
......@@ -2407,19 +2407,8 @@ class TransferOwnershipConfirmView(LoginRequiredMixin, View):
class GraphViewBase(LoginRequiredMixin, View):
@staticmethod
def get_graphite_url():
graphite_host = getenv("GRAPHITE_HOST", None)
graphite_port = getenv("GRAPHITE_PORT", None)
if (graphite_host in ['', None] or graphite_port in ['', None]):
logger.debug('GRAPHITE_HOST is empty.')
return None
return 'http://%s:%s' % (graphite_host, graphite_port)
def get(self, request, pk, metric, time, *args, **kwargs):
graphite_url = GraphViewBase.get_graphite_url()
graphite_url = settings.GRAPHITE_URL
if graphite_url is None:
raise Http404()
......
# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
import requests
import os
class GraphiteHandler:
def __init__(self):
if os.getenv("GRAPHITE_HOST") in ['', None]:
raise RuntimeError
self.__server_name = os.getenv("GRAPHITE_HOST")
if os.getenv("GRAPHITE_PORT") in ['', None]:
raise RuntimeError
self.__server_port = os.getenv("GRAPHITE_PORT")
self.__queries = []
self.__responses = []
def put(self, query):
self.__queries.append(query)
def clean_up_queries(self):
self.__queries = []
def clean_up_responses(self):
self.__responses = []
def is_empty(self):
return len(self.__queries) is 0
def generate_all(self):
"""
Regenerate the queries before sending.
"""
for query in self.__queries:
query.generate()
def send(self):
"""
Generates the corrent query for the Graphite webAPI and flush all the
queries in the fifo.
Important: After sending queries to the server the fifo will lost its
content.
"""
url_base = "http://%s:%s/render?" % (self.__server_name,
self.__server_port)
for query in self.__queries:
response = requests.get(url_base + query.get_generated())
if query.get_format() == "json":
self.__responses.append(response.json()) # DICT
else:
self.__responses.append(response)
self.clean_up_queries()
def pop(self):
"""
Pop the first query has got from the server.
"""
try:
return self.__responses.pop(0) # Transform to dictionary
except:
raise RuntimeError
class Query:
def __init__(self):
"""
Query initializaion:
default format is json dictionary
keys: ("target <string>","datapoints <list>")
"""
self.__target = ""
self.__metric = ""
self.__start = ""
self.__end = ""
self.__function = ""
self.__response_format = "json"
self.__generated = ""
def set_target(self, target):
"""
Hostname of the target we should get the information from.
After the hostname you should use the domain the target is in.
Example: "foo.foodomain.domain.com.DOMAIN" where DOMAIN is
the root of the graphite server.
"""
self.__target = '.'.join(target.split('.')[::-1])
def get_target(self):
return self.__target
def set_metric(self, metric):
self.__metric = metric
def get_metric(self):
return self.__metric
def set_absolute_start(self, year, month, day, hour, minute):
"""
Function for setting the time you want to get the reports from.
"""
if (len(year) > 4 or len(year) < 2):
raise
self.__start = hour + ":" + minute + "_" + year + month + day
def set_relative_start(self, value, scale):
"""
Function for setting the time you want to get the reports from.
"""
if (scale not in ["years",
"months", "days", "hours", "minutes", "seconds"]):
raise
self.__start = "-" + str(value) + scale
def get_start(self):
return self.__start
def set_absolute_end(self, year, month, day, hour, minute):
"""
Function for setting the time until you want to get the reports from.
"""
if (len(year) > 4 or len(year) < 2):
raise
self.__end = hour + ":" + minute + "_" + year + month + day
def set_relative_end(self, value, scale):
"""
Function for setting the time until you want to get the reports from.
"""
if (scale not in ["years",
"months", "days", "hours", "minutes", "seconds"]):
raise
self.__end = "-" + str(value) + scale
def get_end(self):
return self.__end
def set_format(self, fmat):
"""
Function for setting the format of the response from the server.
Valid values: ["csv", "raw", "json"]
"""
valid_formats = ["csv", "raw", "json"]
if fmat not in valid_formats:
raise
self.__response_format = fmat
def get_format(self):
return self.__response_format
def generate(self):
"""
You must always call this function before sending the metric to the
server for it generates the valid format that the graphite API can
parse.
"""
tmp = "target=" + self.__target + "." + self.__metric
if len(self.__start) is not 0:
tmp = tmp + "&from=" + self.__start
if len(self.__end) is not 0:
tmp = tmp + "&until=" + self.__end
tmp = tmp + "&format=" + self.__response_format
self.__generated = tmp
return self.__generated
def get_generated(self):
"""
Returns the generated query string.
Throws exception if it haven't been done yet.
"""
if len(self.__generated) is 0:
raise
return self.__generated
# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from calvin import * # noqa
server_name = "0.0.0.0"
server_port = "8080"
query = Query()
query.setTarget("1889.foo.fook.fookie.com.DOMAIN")
query.setMetric("cpu.usage")
query.setFormat("json") # Not neccesary, default is json
query.setRelativeStart(1, "minutes") # Current cpu usage
query.generate()
# print(query.getGenerated())
print(query.getStart())
# query.setAbsoluteStart("1889", "04", "20", "00", "00")
# query.setRelativeEnd(...)
# query.setAbsoluteEnd(...)
handler = GraphiteHandler(server_name, server_port)
handler.put(query)
handler.send()
response = handler.pop()
print(response["target"])
print(response["datapoints"])
# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from calvin import * # noqa
import datetime
query = Query()
query.setTarget("2008.vm.ik.bme.hu.circle")
query.setMetric("cpu.usage")
query.setAbsoluteStart("2013", "10", "23", "00", "00")
query.generate()
handler = GraphiteHandler("10.9.1.209")
times = int(input(
"How many requests do you intend to send? [postive integer] "))
global_start = datetime.datetime.now()
for i in range(1, times):
local_start = datetime.datetime.now()
handler.put(query)
handler.send()
local_end = datetime.datetime.now()
print((local_end - local_start).microseconds)
global_end = datetime.datetime.now()
print("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*")
print("Summary:")
print(global_end - global_start)
print("AVG:")
print((global_end - global_start) / times)
print("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*")
......@@ -18,7 +18,9 @@
from __future__ import absolute_import, unicode_literals
from logging import getLogger
from warnings import warn
import requests
from django.conf import settings
from django.db.models import (
CharField, IntegerField, ForeignKey, BooleanField, ManyToManyField,
FloatField, permalink,
......@@ -33,8 +35,6 @@ from taggit.managers import TaggableManager
from common.models import method_cache, WorkerNotFound, HumanSortField
from common.operations import OperatedMixin
from firewall.models import Host
from monitor.calvin.calvin import Query
from monitor.calvin.calvin import GraphiteHandler
from ..tasks import vm_tasks
from .activity import node_activity, NodeActivity
from .common import Trait
......@@ -245,48 +245,50 @@ class Node(OperatedMixin, TimeStampedModel):
else:
return default
@property
@node_available
@method_cache(10)
def get_monitor_info(self):
def monitor_info(self):
metrics = ('cpu.usage', 'memory.usage')
prefix = 'circle.%s.' % self.name
params = [('target', '%s%s' % (prefix, metric))
for metric in metrics]
params.append(('from', '-5min'))
params.append(('format', 'json'))
try:
handler = GraphiteHandler()
except RuntimeError:
logger.info('%s %s', settings.GRAPHITE_URL, params)
response = requests.get(settings.GRAPHITE_URL, params=params)
retval = {}
for target in response.json():
# Example:
# {"target": "circle.szianode.cpu.usage",
# "datapoints": [[0.6, 1403045700], [0.5, 1403045760]
try:
metric = target['target']
if metric.startswith(prefix):
metric = metric[len(prefix):]
value = target['datapoints'][-2][0]
retval[metric] = float(value)
except (KeyError, IndexError, ValueError):
continue
return retval
except:
logger.exception('Unhandled exception: ')
return self.remote_query(vm_tasks.get_node_metrics, timeout=30,
priority="fast")
query = Query()
query.set_target(self.host.hostname + ".circle")
query.set_format("json")
query.set_relative_start(5, "minutes")
metrics = ["cpu.usage", "memory.usage"]
for metric in metrics:
query.set_metric(metric)
query.generate()
handler.put(query)
handler.send()
collected = {}
for metric in metrics:
response = handler.pop()
try:
cache = response[0]["datapoints"][-2][0]
except (IndexError, KeyError):
cache = 0
if cache is None:
cache = 0
collected[metric] = cache
return collected
@property
@node_available
def cpu_usage(self):
return float(self.get_monitor_info()["cpu.usage"]) / 100
return self.monitor_info.get('cpu.usage') / 100
@property
@node_available
def ram_usage(self):
return float(self.get_monitor_info()["memory.usage"]) / 100
return self.monitor_info.get('memory.usage') / 100
@property
@node_available
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment