def __sevenm_metrics(self, kind, instances, metrics): values = {} times = {} cmd = NaServer.NaElement("perf-object-get-instances-iter-start") cmd.child_add_string("objectname", kind) counters = NaServer.NaElement("counters") for metric in metrics: counters.child_add_string("counter", metric) cmd.child_add(counters) insts = NaServer.NaElement("instances") for inst in instances: insts.child_add_string("instance", inst) cmd.child_add(insts) res = self.server.invoke_elem(cmd) if res.results_errno(): reason = res.results_reason() msg = ("perf-object-get-instances-iter-start" " cannot collect '%s': %s") raise ValueError(msg % (kind, reason)) next_tag = res.child_get_string("tag") instance_time = float(res.child_get_string("timestamp")) counter = self.perf_max_records while counter == self.perf_max_records: cmd = NaServer.NaElement("perf-object-get-instances-iter-next") cmd.child_add_string("tag", next_tag) cmd.child_add_string("maximum", self.perf_max_records) res = self.server.invoke_elem(cmd) if res.results_errno(): reason = res.results_reason() msg = ("perf-object-get-instances-iter-next" " cannot collect '%s': %s") raise ValueError(msg % (kind, reason)) counter = res.child_get_string("records") partial_values, partial_times, partial_inst_t \ = self.__collect_instances(res) # Mix them with the previous records of the same instance # WARNING, BUG with same instance and time!!!!!!!!! for instance, values in values.iteritems(): if instance in partial_values: values.update(partial_values[instance]) del partial_values[instance] values.update(partial_values) times.update(partial_times) cmd = NaServer.NaElement("perf-object-instance-list-info-iter-end") cmd.child_add_string("tag", next_tag) res = self.server.invoke_elem(cmd) if res.results_errno(): reason = res.results_reason() msg = ("perf-object-instance-list-info-iter-end" " cannot collect '%s': %s") raise ValueError(msg % (kind, reason)) return values, times, instance_time
def __clusterm_instances(self, kind, filter=''): counter = self.perf_max_records next_tag = '' instances_list = [] while counter == self.perf_max_records: cmd = NaServer.NaElement("perf-object-instance-list-info-iter") cmd.child_add_string("objectname", kind) if filter: cmd.child_add_string("filter-data", filter) if next_tag: cmd.child_add_string("tag", next_tag) cmd.child_add_string("max-records", self.perf_max_records) res = self.server.invoke_elem(cmd) if res.results_errno(): reason = res.results_reason() msg = ("perf-object-instance-list-info-iter" " cannot collect '%s': %s") raise ValueError(msg % (kind, reason)) next_tag = res.child_get_string("next-tag") counter = res.child_get_string("num-records") attr_list = res.child_get("attributes-list") if attr_list: for inst in attr_list.children_get(): name = inst.child_get_string("uuid") instances_list.append(name) return instances_list
def get_info(self, kind): cmd = NaServer.NaElement("perf-object-counter-list-info") cmd.child_add_string("objectname", kind) res = self.server.invoke_elem(cmd) counters = {} if res.results_errno(): reason = res.results_reason() msg = "perf-object-counter-list-info cannot collect '%s': %s" raise ValueError(msg % (kind, reason)) for counter in res.child_get("counters").children_get(): name = counter.child_get_string("name") desc = counter.child_get_string("desc") unit = '' if counter.child_get_string("unit"): unit = counter.child_get_string("unit") properties = '' if counter.child_get_string("properties"): properties = counter.child_get_string("properties") base = '' if counter.child_get_string("base-counter"): base = counter.child_get_string("base-counter") priv = counter.child_get_string("privilege-level") labels = [] if counter.child_get("labels"): clabels = counter.child_get("labels") if clabels.child_get_string("label-info"): tlabels = clabels.child_get_string("label-info") labels = [l.strip() for l in tlabels.split(',')] counters[name] = (unit, properties, base, priv, desc, labels) return counters
def _get_version(self): cmd = NaServer.NaElement('system-get-version') res = self.server.invoke_elem(cmd) if res.results_errno(): raise ValueError("system-get-version error: %s" % res.results_reason()) else: self.clustered = False clustered = res.child_get_string("is-clustered") if clustered == "true": self.clustered = True version_tuple = res.child_get("version-tuple") if version_tuple: version_tuple = version_tuple.child_get("system-version-tuple") self.generation = version_tuple.child_get_string("generation") self.major = version_tuple.child_get_string("major") self.minor = version_tuple.child_get_string("minor") else: version = res.child_get_string("version") if version: version_tuple = re.search(r'(\d+)\.(\d+)\.(\d+)', version) self.generation = version_tuple.group(1) self.major = version_tuple.group(2) self.minor = version_tuple.group(3) return (self.generation, self.major, self.minor)
def __clusterm_metrics(self, kind, instances, metrics): cmd = NaServer.NaElement("perf-object-get-instances") inst = NaServer.NaElement("instance-uuids") for instance in instances: inst.child_add_string("instance-uuid", instance) cmd.child_add(inst) cmd.child_add_string("objectname", kind) counters = NaServer.NaElement("counters") for metric in metrics: counters.child_add_string("counter", metric) cmd.child_add(counters) res = self.server.invoke_elem(cmd) if res.results_errno(): reason = res.results_reason() msg = "perf-object-get-instances cannot collect '%s': %s" raise ValueError(msg % (kind, reason)) return self.__collect_instances(res)
def __sevenm_instances(self, kind, filter=''): instances_list = [] cmd = NaServer.NaElement("perf-object-instance-list-info-iter-start") cmd.child_add_string("objectname", kind) res = self.server.invoke_elem(cmd) if res.results_errno(): reason = res.results_reason() msg = ("perf-object-instance-list-info-iter-start" " cannot collect '%s': %s") raise ValueError(msg % (kind, reason)) next_tag = res.child_get_string("tag") counter = self.perf_max_records while counter == self.perf_max_records: cmd = NaServer.NaElement( "perf-object-instance-list-info-iter-next") cmd.child_add_string("tag", next_tag) cmd.child_add_string("maximum", self.perf_max_records) res = self.server.invoke_elem(cmd) if res.results_errno(): reason = res.results_reason() msg = ("perf-object-instance-list-info-iter-next" " cannot collect '%s': %s") raise ValueError(msg % (kind, reason)) counter = res.child_get_string("records") instances = res.child_get("instances") if instances: for inst in instances.children_get(): name = inst.child_get_string("name") instances_list.append(name) cmd = NaServer.NaElement("perf-object-instance-list-info-iter-end") cmd.child_add_string("tag", next_tag) res = self.server.invoke_elem(cmd) if res.results_errno(): reason = res.results_reason() msg = ("perf-object-instance-list-info-iter-end" " cannot collect '%s': %s") raise ValueError(msg % (kind, reason)) # filter return instances_list
def get_objects(self): cmd = NaServer.NaElement('perf-object-list-info') res = self.server.invoke_elem(cmd) objects = {} if res.results_errno(): raise ValueError("perf-object-list-info error: %s" % res.results_reason()) else: for inst in res.child_get("objects").children_get(): inst_name = inst.child_get_string("name") inst_desc = inst.child_get_string("description") inst_priv = inst.child_get_string("privilege-level") objects[inst_name] = (inst_desc, inst_priv) return objects
def collect(self, device, ip, user, password): """ This function collects the metrics for one filer. """ sys.path.append(self.config['netappsdkpath']) try: import NaServer except ImportError: self.log.error("Unable to load NetApp SDK from %s" % (self.config['netappsdkpath'])) return # Set up the parameters server = NaServer.NaServer(ip, 1, 3) server.set_transport_type('HTTPS') server.set_style('LOGIN') server.set_admin_user(user, password) # We're only able to query a single object at a time, # so we'll loop over the objects. for na_object in self.METRICS.keys(): # For easy reference later, generate a new dict for this object LOCALMETRICS = {} for metric in self.METRICS[na_object]: metricname, prettyname, multiplier = metric LOCALMETRICS[metricname] = {} LOCALMETRICS[metricname]["prettyname"] = prettyname LOCALMETRICS[metricname]["multiplier"] = multiplier # Keep track of how long has passed since we checked last CollectTime = time.time() time_delta = None if na_object in self.LastCollectTime.keys(): time_delta = CollectTime - self.LastCollectTime[na_object] self.LastCollectTime[na_object] = CollectTime self.log.debug("Collecting metric of object %s" % na_object) query = NaServer.NaElement("perf-object-get-instances-iter-start") query.child_add_string("objectname", na_object) counters = NaServer.NaElement("counters") for metric in LOCALMETRICS.keys(): counters.child_add_string("counter", metric) query.child_add(counters) res = server.invoke_elem(query) if (res.results_status() == "failed"): self.log.error("Connection to filer %s failed; %s" % (device, res.results_reason())) return iter_tag = res.child_get_string("tag") num_records = 1 max_records = 100 # For some metrics there are dependencies between metrics for # a single object, so we'll need to collect all, so we can do # calculations later. raw = {} while (num_records != 0): query = NaServer.NaElement( "perf-object-get-instances-iter-next") query.child_add_string("tag", iter_tag) query.child_add_string("maximum", max_records) res = server.invoke_elem(query) if (res.results_status() == "failed"): print "Connection to filer %s failed; %s" % ( device, res.results_reason()) return num_records = res.child_get_int("records") if (num_records > 0): instances_list = res.child_get("instances") instances = instances_list.children_get() for instance in instances: raw_name = unicodedata.normalize( 'NFKD', instance.child_get_string("name")).encode( 'ascii', 'ignore') # Shorten the name for disks as they are very long and # padded with zeroes, eg: # 5000C500:3A236B0B:00000000:00000000:00000000:... if na_object is "disk": non_zero_blocks = [ block for block in raw_name.split(":") if block != "00000000" ] raw_name = "".join(non_zero_blocks) instance_name = re.sub(r'\W', '_', raw_name) counters_list = instance.child_get("counters") counters = counters_list.children_get() for counter in counters: metricname = unicodedata.normalize( 'NFKD', counter.child_get_string("name")).encode( 'ascii', 'ignore') metricvalue = counter.child_get_string("value") # We'll need a long complete pathname to not # confuse self.derivative pathname = ".".join([ self.config["path_prefix"], device, na_object, instance_name, metricname ]) raw[pathname] = int(metricvalue) # Do the math self.log.debug("Processing %i metrics for object %s" % (len(raw), na_object)) # Since the derivative function both returns the derivative # and saves a new point, we'll need to store all derivatives # for local reference. derivative = {} for key in raw.keys(): derivative[key] = self.derivative(key, raw[key]) for key in raw.keys(): metricname = key.split(".")[-1] prettyname = LOCALMETRICS[metricname]["prettyname"] multiplier = LOCALMETRICS[metricname]["multiplier"] if metricname in self.DROPMETRICS: continue elif metricname in self.DIVIDERS.keys(): self._gen_delta_depend(key, derivative, multiplier, prettyname, device) else: self._gen_delta_per_sec(key, derivative[key], time_delta, multiplier, prettyname, device)