Commit 34f94315 by Nagy Gergő

Fixed formating errors and added scheduled reporting.

parent b621e93d
[Client] [Client]
Frequency = 0
Debug = True Debug = True
[Server]
Address = 10.7.0.96
Port = 5672
[AMQP]
Queue = monitor
User = cloud
Pass = password
Vhost = monitor
[Metrics] [Metrics]
cpuUsage = True cpuUsage = True
memoryUsage = True memoryUsage = True
......
#!/usr/bin/python #!/usr/bin/python
import platform, collections, time, socket, pika, struct # import platform
# import collections
import time
import socket
import pika
# import struct
import logging import logging
import os
logging.basicConfig() logging.basicConfig()
class Client: class Client:
def __init__(self, config): def __init__(self, config):
""" """
Constructor of the client requires a configuration provided by cnfparse Constructor of the client requires a configuration provided by cnfparse
modul. It is a dictionary: {server_address, server_port, frequency, modul. It is a dictionary: {debugMode}
debugMode, amqp_user, amqp_pass, amqp_queue}.
""" """
hostname = socket.gethostname().split('.') hostname = socket.gethostname().split('.')
hostname.reverse() hostname.reverse()
self.name = "circle." + ".".join(hostname) self.name = "circle." + ".".join(hostname)
self.server_address = str(config["server_address"]) self.server_address = str(os.getenv("GRAPHITE_SERVER_ADDRESS"))
self.server_port = int(config["server_port"]) self.server_port = int(os.getenv("GRAPHITE_SERVER_PORT"))
self.delay = int(config["frequency"])
self.debugMode = config["debugMode"] self.debugMode = config["debugMode"]
self.amqp_user = str(config["amqp_user"]) self.amqp_user = str(os.getenv("GRAPHITE_AMQP_USER"))
self.amqp_pass = str(config["amqp_pass"]) self.amqp_pass = str(os.getenv("GRAPHITE_AMQP_PASSWORD"))
self.amqp_queue = str(config["amqp_queue"]) self.amqp_queue = str(os.getenv("GRAPHITE_AMQP_QUEUE"))
self.amqp_virtual_host = str(config["amqp_virtual_host"]) self.amqp_vhost = str(os.getenv("GRAPHITE_AMQP_VHOST"))
self.beat = 1
def __connect(self): def __connect(self):
""" """
...@@ -31,13 +39,11 @@ class Client: ...@@ -31,13 +39,11 @@ class Client:
""" """
try: try:
credentials = pika.PlainCredentials(self.amqp_user, self.amqp_pass) credentials = pika.PlainCredentials(self.amqp_user, self.amqp_pass)
self.connection = pika.BlockingConnection(pika.ConnectionParameters( params = pika.ConnectionParameters(host=self.server_address,
host=self.server_address,
port=self.server_port, port=self.server_port,
virtual_host=self.amqp_virtual_host, virtual_host=self.amqp_vhost,
credentials=credentials credentials=credentials)
) self.connection = pika.BlockingConnection(params)
)
self.channel = self.connection.channel() self.channel = self.connection.channel()
return True return True
except: except:
...@@ -54,8 +60,8 @@ class Client: ...@@ -54,8 +60,8 @@ class Client:
""" """
Send the message given in the parameters. Send the message given in the parameters.
""" """
self.channel.basic_publish(exchange=self.amqp_queue, routing_key='', self.channel.basic_publish(exchange=self. amqp_queue,
body="\n".join(message)) routing_key='', body="\n".join(message))
def __collectFromNode(self, metricCollectors): def __collectFromNode(self, metricCollectors):
""" """
...@@ -64,35 +70,46 @@ class Client: ...@@ -64,35 +70,46 @@ class Client:
""" """
metrics = [] metrics = []
for collector in metricCollectors: for collector in metricCollectors:
stat = collector() if (self.beat % collector[1]) is 0:
metrics.append(( stat = collector[0]()
self.name + "." + stat.name + metrics.append((self.name + "." +
" %d" % (stat.value) + stat.name + " %d" % (stat.value)
" %d" % (time.time()) + " %d" % (time.time())
)) ))
return metrics return metrics
def startReporting(self, metricCollectors = [], debugMode = False): def getMaxFrequency(self, metricCollectors=[]):
max = metricCollectors[0][1]
for item in metricCollectors:
if max < item[1]:
max = item[1]
return max
def startReporting(self, metricCollectors=[], debugMode=False):
""" """
Call this method to start reporting to the server, it needs the Call this method to start reporting to the server, it needs the
metricCollectors parameter that should be provided by the collectables metricCollectors parameter that should be provided by the collectables
modul to work properly. modul to work properly.
""" """
if self.__connect() == False: if self.__connect() is False:
print ("An error has occured while connecting to the server on %s" % print("An error has occured while connecting to the server on %s"
(self.server_address + ":" + str(self.server_port))) % (self.server_address + ":" + str(self.server_port)))
else: else:
print("Connection established to %s on port %s. \ print("Connection established to %s on port %s. \
Report frequency is %d sec. Clientname: %s" % Report frequency is %d sec. Clientname: %s"
(self.server_address, self.server_port, self.delay, self.name) % (self.server_address, self.server_port,
) self.delay, self.name))
try: try:
maxFrequency = self.getMaxFrequency(metricCollectors)
while True: while True:
metrics = self.__collectFromNode(metricCollectors) metrics = self.__collectFromNode(metricCollectors)
if self.debugMode == "True": if self.debugMode == "True":
print(metrics) print(metrics)
self.__send(metrics) self.__send(metrics)
time.sleep(self.delay) time.sleep(1)
self.beat = self.beat + 1
if ((self.beat % (maxFrequency + 1)) is 0):
self.beat = 1
except KeyboardInterrupt: except KeyboardInterrupt:
print("Reporting has stopped by the user. Exiting...") print("Reporting has stopped by the user. Exiting...")
finally: finally:
......
import ConfigParser as configparser import ConfigParser as configparser
def importConf(path_to_file): def importConf(path_to_file):
config = configparser.RawConfigParser(allow_no_value = False) config = configparser.RawConfigParser(allow_no_value=False)
try: try:
config.read(path_to_file) config.read(path_to_file)
params = {} params = {}
metrics = {} metrics = {}
params["frequency"] = config.get("Client" , "Frequency") params["debugMode"] = config.get("Client", "Debug")
params["debugMode"] = config.get("Client" , "Debug") metrics["cpu.usage"] = int(config.get("Metrics", "cpuUsage"))
params["server_address"] = config.get("Server" , "Address") metrics["memory.usage"] = int(config.get("Metrics", "memoryUsage"))
params["server_port"] = config.get("Server" , "Port") metrics["user.count"] = int(config.get("Metrics", "userCount"))
params["amqp_queue"] = config.get("AMQP" , "Queue") metrics["swap.usage"] = int(config.get("Metrics", "swapUsage"))
params["amqp_user"] = config.get("AMQP" , "User") metrics["system.boot_time"] = int(config.get("Metrics",
params["amqp_pass"] = config.get("AMQP" , "Pass") "systemBootTime"))
params["amqp_virtual_host"] = config.get("AMQP" , "Vhost") metrics["network"] = int(config.get("Metrics", "dataTraffic"))
metrics["cpu.usage"] = config.get("Metrics", "cpuUsage")
metrics["memory.usage"] = config.get("Metrics", "memoryUsage")
metrics["user.count"] = config.get("Metrics", "userCount")
metrics["swap.usage"] = config.get("Metrics", "swapUsage")
metrics["system.boot_time"]= config.get("Metrics", "systemBootTime")
metrics["network"] = config.get("Metrics", "dataTraffic")
except configparser.NoSectionError: except configparser.NoSectionError:
print("Config file contains error! Reason: Missing section.") print("Config file contains error! Reason: Missing section.")
raise raise
...@@ -31,5 +26,3 @@ def importConf(path_to_file): ...@@ -31,5 +26,3 @@ def importConf(path_to_file):
raise raise
return params, metrics return params, metrics
from metrics import * from metrics import *
class collectables: class collectables:
__collectables = { __collectables = {
...@@ -12,10 +13,8 @@ class collectables: ...@@ -12,10 +13,8 @@ class collectables:
std.network.bytes_sent.name: [std.network.bytes_sent], std.network.bytes_sent.name: [std.network.bytes_sent],
std.network.bytes_received.name: [std.network.bytes_received], std.network.bytes_received.name: [std.network.bytes_received],
std.system.boot_time.name: [std.system.boot_time], std.system.boot_time.name: [std.system.boot_time],
"network": [std.network.bytes_sent, "network": [std.network.bytes_sent, std.network.bytes_received,
std.network.bytes_received, std.network.packages_sent, std.network.packages_received],
std.network.packages_sent,
std.network.packages_received],
} }
@staticmethod @staticmethod
...@@ -31,19 +30,18 @@ class collectables: ...@@ -31,19 +30,18 @@ class collectables:
return [x.name for x in collectables.__collectables[key]] return [x.name for x in collectables.__collectables[key]]
@staticmethod @staticmethod
def provide(requests = []): def provide(requests=[]):
valid_keys = collectables.listKeys() #valid_keys = collectables.listKeys()
reqs = [request for request, value in requests.items() if value=="True"] reqs = [request for request, value in requests.items()
if value > 0]
collectors = [] collectors = []
for request in reqs: for request in reqs:
for item in collectables.__collectables[request]: for item in collectables.__collectables[request]:
collectors.append(item.harvest) collectors.append([item.harvest, value])
seen = set() seen = set()
seen_add = seen.add seen_add = seen.add
return [ x for x in collectors if x not in seen and not seen_add(x)] return [x for x in collectors if x not in seen and not seen_add(x)]
@staticmethod @staticmethod
def provideAll(): def provideAll():
return collectables.provide(collectables.listKeys()) return collectables.provide(collectables.listKeys())
...@@ -3,9 +3,11 @@ ...@@ -3,9 +3,11 @@
import psutil as ps import psutil as ps
import collections import collections
####################################################################################
#############################################################################
Metrics = collections.namedtuple("Metrics", ["name", "value"]) Metrics = collections.namedtuple("Metrics", ["name", "value"])
class Collection (object): class Collection (object):
class Group (object): class Group (object):
class Metric (object): class Metric (object):
...@@ -20,14 +22,14 @@ class Collection (object): ...@@ -20,14 +22,14 @@ class Collection (object):
if ((isinstance(query, list)) or (isinstance(query, dict))): if ((isinstance(query, list)) or (isinstance(query, dict))):
return Metrics(cls.name, return Metrics(cls.name,
query[cls.collector_function_result_attr]) query[cls.collector_function_result_attr])
elif (isinstance(query,tuple)): elif (isinstance(query, tuple)):
return Metrics(cls.name, return Metrics(cls.name,
query.__getattribute__(cls.collector_function_result_attr)) query.__getattribute__(cls.collector_function_result_attr))
else: else:
return Metrics(cls.name, return Metrics(cls.name, query)
query)
##############################################################################
####################################################################################
class std (Collection): class std (Collection):
...@@ -58,6 +60,7 @@ class std (Collection): ...@@ -58,6 +60,7 @@ class std (Collection):
class count (Collection.Group.Metric): class count (Collection.Group.Metric):
name = "user.count" name = "user.count"
@classmethod @classmethod
def harvest(cls): def harvest(cls):
return Metrics(cls.name, len(ps.get_users())) return Metrics(cls.name, len(ps.get_users()))
......
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