fuel-plugin-lma-collector/deployment_scripts/puppet/modules/lma_collector/files/collectd/openstack_neutron.py

166 lines
5.9 KiB
Python

#!/usr/bin/python
# Copyright 2015 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Collectd plugin for getting resource statistics from Neutron
import collectd
from collections import Counter
from collections import defaultdict
import re
import collectd_openstack as openstack
PLUGIN_NAME = 'neutron'
INTERVAL = openstack.INTERVAL
class NeutronStatsPlugin(openstack.CollectdPlugin):
""" Class to report the statistics on Neutron service.
state of agents
number of networks broken down by status
number of subnets
number of ports broken down by owner and status
number of routers broken down by status
number of floating IP addresses broken down by free/associated
"""
neutron_re = re.compile('^neutron-')
agent_re = re.compile('-agent$')
states = {'up': 0, 'down': 1, 'disabled': 2}
def collect(self):
def groupby_network(x):
return "networks.%s" % x.get('status', 'unknown').lower()
def groupby_router(x):
return "routers.%s" % x.get('status', 'unknown').lower()
def groupby_port(x):
owner = x.get('device_owner', 'none')
if owner.startswith('network:'):
owner = owner.replace('network:', '')
elif owner.startswith('compute:'):
# The part after 'compute:' is the name of the Nova AZ
owner = 'compute'
else:
owner = 'none'
status = x.get('status', 'unknown').lower()
return "ports.%s.%s" % (owner, status)
def groupby_floating(x):
if x.get('port_id', None):
status = 'associated'
else:
status = 'free'
return "floatingips.%s" % status
# Get information of the state per agent
# State can be up or down
aggregated_agents = defaultdict(Counter)
for agent in self.iter_workers('neutron'):
host = agent['host'].split('.')[0]
service = self.agent_re.sub(
'', self.neutron_re.sub('', agent['service']))
state = agent['state']
aggregated_agents[service][state] += 1
self.dispatch_value('neutron_agent',
self.states[state],
{'host': host,
'service': service,
'state': state})
for service in aggregated_agents:
totala = sum(aggregated_agents[service].values())
for state in self.states:
prct = (100.0 * aggregated_agents[service][state]) / totala
self.dispatch_value('neutron_agents_percent',
prct,
{'service': service, 'state': state})
self.dispatch_value('neutron_agents',
aggregated_agents[service][state],
{'service': service, 'state': state})
# Networks
networks = self.get_objects('neutron', 'networks', api_version='v2.0')
status = self.count_objects_group_by(networks,
group_by_func=groupby_network)
for s, nb in status.iteritems():
self.dispatch_value(s, nb)
self.dispatch_value('networks', len(networks))
# Subnets
subnets = self.get_objects('neutron', 'subnets', api_version='v2.0')
self.dispatch_value('subnets', len(subnets))
# Ports
ports = self.get_objects('neutron', 'ports', api_version='v2.0')
status = self.count_objects_group_by(ports,
group_by_func=groupby_port)
for s, nb in status.iteritems():
self.dispatch_value(s, nb)
self.dispatch_value('ports', len(ports))
# Routers
routers = self.get_objects('neutron', 'routers', api_version='v2.0')
status = self.count_objects_group_by(routers,
group_by_func=groupby_router)
for s, nb in status.iteritems():
self.dispatch_value(s, nb)
self.dispatch_value('routers', len(routers))
# Floating IP addresses
floatingips = self.get_objects('neutron', 'floatingips',
api_version='v2.0')
status = self.count_objects_group_by(floatingips,
group_by_func=groupby_floating)
for s, nb in status.iteritems():
self.dispatch_value(s, nb)
self.dispatch_value('floatingips', len(floatingips))
def dispatch_value(self, name, value, meta=None):
v = collectd.Values(
plugin=PLUGIN_NAME, # metric source
type='gauge',
type_instance=name,
interval=INTERVAL,
# w/a for https://github.com/collectd/collectd/issues/716
meta=meta or {'0': True},
values=[value]
)
v.dispatch()
plugin = NeutronStatsPlugin(collectd, PLUGIN_NAME)
def config_callback(conf):
plugin.config_callback(conf)
def notification_callback(notification):
plugin.notification_callback(notification)
def read_callback():
plugin.conditional_read_callback()
collectd.register_config(config_callback)
collectd.register_notification(notification_callback)
collectd.register_read(read_callback, INTERVAL)