Merge pull request #5 from SandyWalsh/attempt
Capture latest staging changes
This commit is contained in:
commit
804ed80e62
@ -20,6 +20,8 @@ from django.db import models
|
|||||||
class Tenant(models.Model):
|
class Tenant(models.Model):
|
||||||
email = models.CharField(max_length=50)
|
email = models.CharField(max_length=50)
|
||||||
project_name = models.CharField(max_length=50)
|
project_name = models.CharField(max_length=50)
|
||||||
|
nova_stats_template = models.CharField(max_length=200)
|
||||||
|
loggly_template = models.CharField(max_length=200)
|
||||||
tenant_id = models.AutoField(primary_key=True, unique=True)
|
tenant_id = models.AutoField(primary_key=True, unique=True)
|
||||||
|
|
||||||
|
|
||||||
@ -35,19 +37,31 @@ class RawData(models.Model):
|
|||||||
blank=True, db_index=True)
|
blank=True, db_index=True)
|
||||||
when = models.DateTimeField(db_index=True)
|
when = models.DateTimeField(db_index=True)
|
||||||
microseconds = models.IntegerField(default=0)
|
microseconds = models.IntegerField(default=0)
|
||||||
publisher = models.CharField(max_length=50, null=True,
|
publisher = models.CharField(max_length=100, null=True,
|
||||||
blank=True, db_index=True)
|
blank=True, db_index=True)
|
||||||
event = models.CharField(max_length=50, null=True,
|
event = models.CharField(max_length=50, null=True,
|
||||||
blank=True, db_index=True)
|
blank=True, db_index=True)
|
||||||
service = models.CharField(max_length=50, null=True,
|
service = models.CharField(max_length=50, null=True,
|
||||||
blank=True, db_index=True)
|
blank=True, db_index=True)
|
||||||
host = models.CharField(max_length=50, null=True,
|
host = models.CharField(max_length=100, null=True,
|
||||||
blank=True, db_index=True)
|
blank=True, db_index=True)
|
||||||
instance = models.CharField(max_length=50, null=True,
|
instance = models.CharField(max_length=50, null=True,
|
||||||
blank=True, db_index=True)
|
blank=True, db_index=True)
|
||||||
|
value = models.FloatField(null=True, blank=True, db_index=True)
|
||||||
|
units = models.CharField(max_length=10, null=True,
|
||||||
|
blank=True, db_index=True)
|
||||||
|
# Grouping ID is a number assigned and meant to fence-post
|
||||||
|
# a block of time. <set group id = 1> <do stuff> <set group id = 2> ...
|
||||||
|
# Later there will be REST call for setting this.
|
||||||
|
grouping_id = models.IntegerField(default=0, db_index=True)
|
||||||
|
|
||||||
|
# Nested calls can be grouped by a common transaction ID if you like.
|
||||||
|
# A calls B calls C calls D. These can all be linked with a common
|
||||||
|
# transaction ID if you like.
|
||||||
|
transaction_id = models.IntegerField(default=0, db_index=True)
|
||||||
|
|
||||||
|
|
||||||
class TenantForm(forms.ModelForm):
|
class TenantForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Tenant
|
model = Tenant
|
||||||
fields = ('email', 'project_name')
|
fields = ('email', 'project_name', 'nova_stats_template', 'loggly_template')
|
||||||
|
@ -9,6 +9,8 @@ urlpatterns = patterns('',
|
|||||||
name='data'),
|
name='data'),
|
||||||
url(r'^(?P<tenant_id>\d+)/details/(?P<column>\w+)/(?P<row_id>\d+)/$',
|
url(r'^(?P<tenant_id>\d+)/details/(?P<column>\w+)/(?P<row_id>\d+)/$',
|
||||||
'stacktach.views.details', name='details'),
|
'stacktach.views.details', name='details'),
|
||||||
|
url(r'^(?P<tenant_id>\d+)/search/$',
|
||||||
|
'stacktach.views.search', name='search'),
|
||||||
url(r'^(?P<tenant_id>\d+)/expand/(?P<row_id>\d+)/$',
|
url(r'^(?P<tenant_id>\d+)/expand/(?P<row_id>\d+)/$',
|
||||||
'stacktach.views.expand', name='expand'),
|
'stacktach.views.expand', name='expand'),
|
||||||
url(r'^(?P<tenant_id>\d+)/host_status/$',
|
url(r'^(?P<tenant_id>\d+)/host_status/$',
|
||||||
|
@ -36,8 +36,8 @@ def _monitor_message(routing_key, body):
|
|||||||
host = parts[1]
|
host = parts[1]
|
||||||
payload = body['payload']
|
payload = body['payload']
|
||||||
request_spec = payload.get('request_spec', None)
|
request_spec = payload.get('request_spec', None)
|
||||||
instance = None
|
instance = payload.get('instance_id', None)
|
||||||
instance = payload.get('instance_id', instance)
|
instance = payload.get('instance_uuid', instance)
|
||||||
nova_tenant = body.get('_context_project_id', None)
|
nova_tenant = body.get('_context_project_id', None)
|
||||||
nova_tenant = payload.get('tenant_id', nova_tenant)
|
nova_tenant = payload.get('tenant_id', nova_tenant)
|
||||||
return dict(host=host, instance=instance, publisher=publisher,
|
return dict(host=host, instance=instance, publisher=publisher,
|
||||||
@ -56,9 +56,18 @@ def _compute_update_message(routing_key, body):
|
|||||||
service=service, event=event, nova_tenant=nova_tenant)
|
service=service, event=event, nova_tenant=nova_tenant)
|
||||||
|
|
||||||
|
|
||||||
|
def _tach_message(routing_key, body):
|
||||||
|
event = body['event_type']
|
||||||
|
value = body['value']
|
||||||
|
units = body['units']
|
||||||
|
transaction_id = body['transaction_id']
|
||||||
|
return dict(event=event, value=value, units=units, transaction_id=transaction_id)
|
||||||
|
|
||||||
|
|
||||||
# routing_key : handler
|
# routing_key : handler
|
||||||
HANDLERS = {'monitor.info':_monitor_message,
|
HANDLERS = {'monitor.info':_monitor_message,
|
||||||
'monitor.error':_monitor_message,
|
'monitor.error':_monitor_message,
|
||||||
|
'tach':_tach_message,
|
||||||
'':_compute_update_message}
|
'':_compute_update_message}
|
||||||
|
|
||||||
|
|
||||||
@ -72,9 +81,12 @@ def _parse(tenant, args, json_args):
|
|||||||
|
|
||||||
values['tenant'] = tenant
|
values['tenant'] = tenant
|
||||||
when = body['_context_timestamp']
|
when = body['_context_timestamp']
|
||||||
when = datetime.datetime.strptime(when, "%Y-%m-%dT%H:%M:%S.%f")
|
try:
|
||||||
|
when = datetime.datetime.strptime(when, "%Y-%m-%dT%H:%M:%S.%f")
|
||||||
|
values['microseconds'] = when.microsecond
|
||||||
|
except Exception, e:
|
||||||
|
pass
|
||||||
values['when'] = when
|
values['when'] = when
|
||||||
values['microseconds'] = when.microsecond
|
|
||||||
values['routing_key'] = routing_key
|
values['routing_key'] = routing_key
|
||||||
values['json'] = json_args
|
values['json'] = json_args
|
||||||
record = models.RawData(**values)
|
record = models.RawData(**values)
|
||||||
@ -83,13 +95,22 @@ def _parse(tenant, args, json_args):
|
|||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
|
||||||
def _post_process_raw_data(rows, highlight=None):
|
def _post_process_raw_data(rows, state, highlight=None):
|
||||||
for row in rows:
|
for row in rows:
|
||||||
if "error" in row.routing_key:
|
if "error" in row.routing_key:
|
||||||
row.is_error = True
|
row.is_error = True
|
||||||
if highlight and row.id == int(highlight):
|
if highlight and row.id == int(highlight):
|
||||||
row.highlight = True
|
row.highlight = True
|
||||||
row.when += datetime.timedelta(microseconds=row.microseconds)
|
row.when += datetime.timedelta(microseconds=row.microseconds)
|
||||||
|
novastats = state.tenant.nova_stats_template
|
||||||
|
if novastats and row.instance:
|
||||||
|
novastats = novastats.replace("[instance]", row.instance)
|
||||||
|
row.novastats = novastats
|
||||||
|
loggly = state.tenant.loggly_template
|
||||||
|
if loggly and row.instance:
|
||||||
|
loggly = loggly.replace("[instance]", row.instance)
|
||||||
|
row.loggly = loggly
|
||||||
|
|
||||||
|
|
||||||
class State(object):
|
class State(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -102,6 +123,7 @@ class State(object):
|
|||||||
tenant = "'%s' - %s (%d)" % (self.tenant.project_name,
|
tenant = "'%s' - %s (%d)" % (self.tenant.project_name,
|
||||||
self.tenant.email, self.tenant.id)
|
self.tenant.email, self.tenant.id)
|
||||||
return "[Version %s, Tenant %s]" % (self.version, tenant)
|
return "[Version %s, Tenant %s]" % (self.version, tenant)
|
||||||
|
return "[Version %s, Tenant %s]" % (self.version, tenant)
|
||||||
|
|
||||||
|
|
||||||
def _reset_state(request):
|
def _reset_state(request):
|
||||||
@ -203,12 +225,13 @@ def details(request, tenant_id, column, row_id):
|
|||||||
if column != 'when':
|
if column != 'when':
|
||||||
rows = rows.filter(**{column:value})
|
rows = rows.filter(**{column:value})
|
||||||
else:
|
else:
|
||||||
|
value += datetime.timedelta(microseconds=row.microseconds)
|
||||||
from_time = value - datetime.timedelta(minutes=1)
|
from_time = value - datetime.timedelta(minutes=1)
|
||||||
to_time = value + datetime.timedelta(minutes=1)
|
to_time = value + datetime.timedelta(minutes=1)
|
||||||
rows = rows.filter(when__range=(from_time, to_time))
|
rows = rows.filter(when__range=(from_time, to_time))
|
||||||
|
|
||||||
rows = rows.order_by('-when', '-microseconds')[:200]
|
rows = rows.order_by('-when', '-microseconds')[:200]
|
||||||
_post_process_raw_data(rows, highlight=row_id)
|
_post_process_raw_data(rows, state, highlight=row_id)
|
||||||
c['rows'] = rows
|
c['rows'] = rows
|
||||||
c['allow_expansion'] = True
|
c['allow_expansion'] = True
|
||||||
c['show_absolute_time'] = True
|
c['show_absolute_time'] = True
|
||||||
@ -231,21 +254,25 @@ def host_status(request, tenant_id):
|
|||||||
state = _get_state(request, tenant_id)
|
state = _get_state(request, tenant_id)
|
||||||
c = _default_context(state)
|
c = _default_context(state)
|
||||||
hosts = models.RawData.objects.filter(tenant=tenant_id).\
|
hosts = models.RawData.objects.filter(tenant=tenant_id).\
|
||||||
filter(host__gt='').\
|
|
||||||
order_by('-when', '-microseconds')[:20]
|
order_by('-when', '-microseconds')[:20]
|
||||||
_post_process_raw_data(hosts)
|
_post_process_raw_data(hosts, state)
|
||||||
c['rows'] = hosts
|
c['rows'] = hosts
|
||||||
return render_to_response('host_status.html', c)
|
return render_to_response('host_status.html', c)
|
||||||
|
|
||||||
|
|
||||||
@tenant_check
|
@tenant_check
|
||||||
def instance_status(request, tenant_id):
|
def search(request, tenant_id):
|
||||||
state = _get_state(request, tenant_id)
|
state = _get_state(request, tenant_id)
|
||||||
c = _default_context(state)
|
c = _default_context(state)
|
||||||
instances = models.RawData.objects.filter(tenant=tenant_id).\
|
column = request.POST.get('field', None)
|
||||||
exclude(instance='n/a').\
|
value = request.POST.get('value', None)
|
||||||
exclude(instance__isnull=True).\
|
rows = None
|
||||||
order_by('-when', '-microseconds')[:20]
|
if column != None and value != None:
|
||||||
_post_process_raw_data(instances)
|
rows = models.RawData.objects.filter(tenant=tenant_id).\
|
||||||
c['rows'] = instances
|
filter(**{column:value}).\
|
||||||
return render_to_response('instance_status.html', c)
|
order_by('-when', '-microseconds')
|
||||||
|
_post_process_raw_data(rows, state)
|
||||||
|
c['rows'] = rows
|
||||||
|
c['allow_expansion'] = True
|
||||||
|
c['show_absolute_time'] = True
|
||||||
|
return render_to_response('rows.html', c)
|
||||||
|
@ -28,8 +28,8 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<div style='float:right;'>{{state.tenant.email}} (TID:{{state.tenant.tenant_id}}) - {{state.tenant.project_name}} <a href='/logout'>logout</a></div>
|
<div style='float:right;'><a href='/logout'>logout</a></div>
|
||||||
<div class='status-title'>Recent Activity</div>
|
<div class='status-title'>Recent Activity - {{state.tenant.project_name}} (TID:{{state.tenant.tenant_id}})</div>
|
||||||
<div id='host-box' class='status std-height'>
|
<div id='host-box' class='status std-height'>
|
||||||
<div id='host_activity' class='status-inner'>
|
<div id='host_activity' class='status-inner'>
|
||||||
{% include "host_status.html" %}
|
{% include "host_status.html" %}
|
||||||
|
@ -34,11 +34,13 @@
|
|||||||
<td class='cell-border'><a href='#' onclick='details({{state.tenant.tenant_id}}, "host", {{row.id}});'>{{row.host}}</a></td>
|
<td class='cell-border'><a href='#' onclick='details({{state.tenant.tenant_id}}, "host", {{row.id}});'>{{row.host}}</a></td>
|
||||||
<td class='cell-border'><b><a href='#' onclick='details({{state.tenant.tenant_id}}, "event", {{row.id}});'>{{row.event}}</a></b></td>
|
<td class='cell-border'><b><a href='#' onclick='details({{state.tenant.tenant_id}}, "event", {{row.id}});'>{{row.event}}</a></b></td>
|
||||||
<td class='cell-border'>
|
<td class='cell-border'>
|
||||||
<a href='#' onclick='details({{state.tenant.tenant_id}}, "instance", {{row.id}});'>
|
|
||||||
{% if row.instance %}
|
{% if row.instance %}
|
||||||
|
<a href='{{row.loggly}}' target="_blank">(L)</a>
|
||||||
|
<a href='{{row.novastats}}' target="_blank">(S)</a>
|
||||||
|
<a href='#' onclick='details({{state.tenant.tenant_id}}, "instance", {{row.id}});'>
|
||||||
{{row.instance}}
|
{{row.instance}}
|
||||||
{% endif %}
|
|
||||||
</a>
|
</a>
|
||||||
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td class='cell-border'><a href='#' onclick='details({{state.tenant.tenant_id}}, "when", {{row.id}});'>{% if show_absolute_time %}{{row.when}} (+{{row.when.microsecond}}){%else%}{{row.when|timesince:utc}} ago{%endif%}</a></td>
|
<td class='cell-border'><a href='#' onclick='details({{state.tenant.tenant_id}}, "when", {{row.id}});'>{% if show_absolute_time %}{{row.when}} (+{{row.when.microsecond}}){%else%}{{row.when|timesince:utc}} ago{%endif%}</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
21
urls.py
21
urls.py
@ -1,20 +1,9 @@
|
|||||||
from django.conf.urls.defaults import patterns, include, url
|
from django.conf.urls.defaults import patterns, include, url
|
||||||
|
|
||||||
|
# Uncomment the next two lines to enable the admin:
|
||||||
|
# from django.contrib import admin
|
||||||
|
# admin.autodiscover()
|
||||||
|
|
||||||
urlpatterns = patterns('',
|
urlpatterns = patterns('',
|
||||||
url(r'^$', 'stacktach.views.welcome', name='welcome'),
|
url(r'^', include('stacktach.url')),
|
||||||
url(r'new_tenant', 'stacktach.views.new_tenant', name='new_tenant'),
|
|
||||||
url(r'logout', 'stacktach.views.logout', name='logout'),
|
|
||||||
url(r'^(?P<tenant_id>\d+)/$', 'stacktach.views.home', name='home'),
|
|
||||||
url(r'^(?P<tenant_id>\d+)/data/$', 'stacktach.views.data',
|
|
||||||
name='data'),
|
|
||||||
url(r'^(?P<tenant_id>\d+)/details/(?P<column>\w+)/(?P<row_id>\d+)/$',
|
|
||||||
'stacktach.views.details', name='details'),
|
|
||||||
url(r'^(?P<tenant_id>\d+)/search/$',
|
|
||||||
'stacktach.views.search', name='search'),
|
|
||||||
url(r'^(?P<tenant_id>\d+)/expand/(?P<row_id>\d+)/$',
|
|
||||||
'stacktach.views.expand', name='expand'),
|
|
||||||
url(r'^(?P<tenant_id>\d+)/host_status/$',
|
|
||||||
'stacktach.views.host_status', name='host_status'),
|
|
||||||
url(r'^(?P<tenant_id>\d+)/instance_status/$',
|
|
||||||
'stacktach.views.instance_status', name='instance_status'),
|
|
||||||
)
|
)
|
||||||
|
82
worker.py
82
worker.py
@ -22,10 +22,20 @@ import kombu
|
|||||||
import kombu.connection
|
import kombu.connection
|
||||||
import kombu.entity
|
import kombu.entity
|
||||||
import kombu.mixins
|
import kombu.mixins
|
||||||
|
import logging
|
||||||
import threading
|
import threading
|
||||||
|
import time
|
||||||
import urllib
|
import urllib
|
||||||
import urllib2
|
import urllib2
|
||||||
|
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
LOG.setLevel(logging.DEBUG)
|
||||||
|
handler = logging.handlers.TimedRotatingFileHandler('worker.log',
|
||||||
|
when='h', interval=6, backupCount=4)
|
||||||
|
LOG.addHandler(handler)
|
||||||
|
|
||||||
|
|
||||||
# CHANGE THESE FOR YOUR INSTALLATION ...
|
# CHANGE THESE FOR YOUR INSTALLATION ...
|
||||||
DEPLOYMENTS = [
|
DEPLOYMENTS = [
|
||||||
dict(
|
dict(
|
||||||
@ -43,37 +53,39 @@ try:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# For now we'll just grab all the fanout messages from compute to scheduler ...
|
|
||||||
scheduler_exchange = kombu.entity.Exchange("scheduler_fanout", type="fanout",
|
|
||||||
durable=False, auto_delete=True,
|
|
||||||
exclusive=True)
|
|
||||||
|
|
||||||
scheduler_queues = [
|
# For now we'll just grab all the fanout messages from compute to scheduler ...
|
||||||
|
#scheduler_exchange = kombu.entity.Exchange("scheduler_fanout", type="fanout",
|
||||||
|
# durable=False, auto_delete=True,
|
||||||
|
# exclusive=True)
|
||||||
|
#
|
||||||
|
#scheduler_queues = [
|
||||||
# The Queue name has to be unique or we we'll end up with Round Robin
|
# The Queue name has to be unique or we we'll end up with Round Robin
|
||||||
# behavior from Rabbit, even though it's a Fanout queue. In Nova the
|
# behavior from Rabbit, even though it's a Fanout queue. In Nova the
|
||||||
# queues have UUID's tacked on the end.
|
# queues have UUID's tacked on the end.
|
||||||
kombu.Queue("scheduler.xxx", scheduler_exchange, durable=False,
|
# kombu.Queue("scheduler.xxx", scheduler_exchange, durable=False,
|
||||||
auto_delete=False),
|
# auto_delete=True),
|
||||||
]
|
# ]
|
||||||
|
|
||||||
nova_exchange = kombu.entity.Exchange("nova", type="topic",
|
nova_exchange = kombu.entity.Exchange("nova", type="topic", exclusive=False,
|
||||||
durable=True, auto_delete=False,
|
durable=True, auto_delete=False)
|
||||||
exclusive=False)
|
|
||||||
|
|
||||||
nova_queues = [
|
nova_queues = [
|
||||||
kombu.Queue("monitor", nova_exchange, durable=False, auto_delete=False,
|
kombu.Queue("monitor.info", nova_exchange, durable=True, auto_delete=False,
|
||||||
exclusive=False, routing_key='monitor.*'),
|
exclusive=False, routing_key='monitor.info'),
|
||||||
|
kombu.Queue("monitor.error", nova_exchange, durable=True, auto_delete=False,
|
||||||
|
exclusive=False, routing_key='monitor.error'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class SchedulerFanoutConsumer(kombu.mixins.ConsumerMixin):
|
class NovaConsumer(kombu.mixins.ConsumerMixin):
|
||||||
def __init__(self, connection, url):
|
def __init__(self, connection, url):
|
||||||
self.connection = connection
|
self.connection = connection
|
||||||
self.url = url
|
self.url = url
|
||||||
|
|
||||||
def get_consumers(self, Consumer, channel):
|
def get_consumers(self, Consumer, channel):
|
||||||
return [Consumer(queues=scheduler_queues,
|
return [#Consumer(queues=scheduler_queues,
|
||||||
callbacks=[self.on_scheduler]),
|
# callbacks=[self.on_scheduler]),
|
||||||
Consumer(queues=nova_queues, callbacks=[self.on_nova])]
|
Consumer(queues=nova_queues, callbacks=[self.on_nova])]
|
||||||
|
|
||||||
def _process(self, body, message):
|
def _process(self, body, message):
|
||||||
@ -86,20 +98,22 @@ class SchedulerFanoutConsumer(kombu.mixins.ConsumerMixin):
|
|||||||
cooked_data = urllib.urlencode(raw_data)
|
cooked_data = urllib.urlencode(raw_data)
|
||||||
req = urllib2.Request(self.url, cooked_data)
|
req = urllib2.Request(self.url, cooked_data)
|
||||||
response = urllib2.urlopen(req)
|
response = urllib2.urlopen(req)
|
||||||
page = response.read()
|
LOG.debug("Sent %s to %s", routing_key, self.url)
|
||||||
print page
|
#page = response.read()
|
||||||
|
#print page
|
||||||
except urllib2.HTTPError, e:
|
except urllib2.HTTPError, e:
|
||||||
if e.code == 401:
|
if e.code == 401:
|
||||||
print "Unauthorized. Correct URL?", self.url
|
LOG.debug("Unauthorized. Correct URL? %s" % self.url)
|
||||||
print e
|
LOG.exception(e)
|
||||||
page = e.read()
|
page = e.read()
|
||||||
print page
|
LOG.debug(page)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def on_scheduler(self, body, message):
|
def on_scheduler(self, body, message):
|
||||||
# Uncomment if you want periodic compute node status updates.
|
# Uncomment if you want periodic compute node status updates.
|
||||||
#self._process(body, message)
|
#self._process(body, message)
|
||||||
message.ack()
|
message.ack()
|
||||||
|
LOG.debug("SCHEDULER ACKED")
|
||||||
|
|
||||||
def on_nova(self, body, message):
|
def on_nova(self, body, message):
|
||||||
self._process(body, message)
|
self._process(body, message)
|
||||||
@ -121,8 +135,9 @@ class Monitor(threading.Thread):
|
|||||||
password = self.deployment.get('rabbit_password', 'rabbit')
|
password = self.deployment.get('rabbit_password', 'rabbit')
|
||||||
virtual_host = self.deployment.get('rabbit_virtual_host', '/')
|
virtual_host = self.deployment.get('rabbit_virtual_host', '/')
|
||||||
|
|
||||||
print "StackTach", url
|
LOG.info("StackTach %s" % url)
|
||||||
print "Rabbit:", host, port, user_id, virtual_host
|
LOG.info("Rabbit: %s %s %s %s" %
|
||||||
|
(host, port, user_id, virtual_host))
|
||||||
|
|
||||||
params = dict(hostname=host,
|
params = dict(hostname=host,
|
||||||
port=port,
|
port=port,
|
||||||
@ -130,17 +145,28 @@ class Monitor(threading.Thread):
|
|||||||
password=password,
|
password=password,
|
||||||
virtual_host=virtual_host)
|
virtual_host=virtual_host)
|
||||||
|
|
||||||
with kombu.connection.BrokerConnection(**params) as conn:
|
while True:
|
||||||
consumer = SchedulerFanoutConsumer(conn, url)
|
with kombu.connection.BrokerConnection(**params) as conn:
|
||||||
consumer.run()
|
try:
|
||||||
|
consumer = NovaConsumer(conn, url)
|
||||||
|
consumer.run()
|
||||||
|
except Exception as e:
|
||||||
|
LOG.exception("url=%s, exception=%s. Reconnecting in 5s" % (url, e))
|
||||||
|
time.sleep(5)
|
||||||
|
|
||||||
|
|
||||||
with daemon.DaemonContext():
|
with daemon.DaemonContext(files_preserve=[handler.stream]):
|
||||||
workers = []
|
workers = []
|
||||||
for deployment in DEPLOYMENTS:
|
for deployment in DEPLOYMENTS:
|
||||||
|
LOG.info("Starting deployment: %s", deployment)
|
||||||
monitor = Monitor(deployment)
|
monitor = Monitor(deployment)
|
||||||
workers.append(monitor)
|
workers.append(monitor)
|
||||||
monitor.start()
|
try:
|
||||||
|
monitor.start()
|
||||||
|
except Exception as e:
|
||||||
|
LOG.exception("Deployment: %s, Exception: %s" % (deployment, e))
|
||||||
|
|
||||||
for worker in workers:
|
for worker in workers:
|
||||||
|
LOG.info("Attempting to join to %s" % worker.deployment)
|
||||||
worker.join()
|
worker.join()
|
||||||
|
LOG.info("Joined to %s" % worker.deployment)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user