#===============================================================#
#                                                               #
# ID                                                            #
#                                                               #
# perf_aggr_latency.py                                          #
#                                                               #
# Copyright (c) 2011 NetApp, Inc. All rights reserved.          #
# Specifications subject to change without notice.              #
#                                                               #
# We do not have API to get read_latency, write_latency, and    #
# average_latency at aggregate level. This sample code          #
# demonstrates a method to get this data by reading the         #
# required latency of all volumes for the given aggregate.      #
# Use this information to generate latency at aggregate level.  #
#                                                               #
# This Sample code is supported from DataFabric Manager 3.7.1   #
# onwards.                                                      #
# However few of the functionalities of the sample code may     #
# work on older versions of DataFabric Manager.                 #
#===============================================================#

import sys
import time
sys.path.append("../../../../../../../lib/python/NetApp")
from NaServer import *

def print_help() :
	print ("\nCommand:\n")
	print ("perf_aggr_latency.py <dfm> <user> <password> <aggr-name>\n")
	print ("<dfm>       -- DFM Server name\n")
	print ("<user>      -- User name\n")
	print ("<password>  -- Password\n")
	print ("<aggr-name> -- Name of the aggregate in format storage:aggrName\n")
	print ("-" * 80 + "\n")

	print ("This sample code provides information on read latency, write latency\n")
	print ("and average latency of an aggregate \n")
	print ("This data can be used to charts to represent data in graphical format.\n")
	print ("To generate the graph, redirect output of this sample code to\n")
	print ("an Excel sheet.\n")
	sys.exit (1)
			

def print_output() : 
	i = 0
	samples = len(time1) 
	print ("Time\t\t\t\tRead Latency\tWrite Latency\tAverage Latency\n")

	if (samples > 0) :
	
		for i in range(samples) :
			print("%s\t%.5f\t\t%.5f\t\t%.5f" %(time.asctime(time1[i]), (read_latency[i]/samples), (write_latency[i]/samples), (avg_latency[i]/samples)))


def invoke_perf_zapi() :
	# Initialize server context
	server_ctx = NaServer (dfm, 1, 0)
	server_ctx.set_transport_type("HTTP")
	server_ctx.set_style("LOGIN")
	server_ctx.set_admin_user(user, pw)
	server_ctx.set_server_type("DFM")
	server_ctx.set_port(8088)

	# Create API request
	perf_in = NaElement("perf-get-counter-data")
	perf_in.child_add_string("duration", 6000)
	perf_in.child_add_string("number-samples", 50)
	perf_in.child_add_string("time-consolidation-method", "average")

	instance_info = NaElement("instance-counter-info")
	instance_info.child_add_string("object-name-or-id", aggr_name)

	counter_info = NaElement("counter-info")
	perf_obj_ctr1 = NaElement("perf-object-counter")
	perf_obj_ctr1.child_add_string("object-type", "volume")
	perf_obj_ctr1.child_add_string("counter-name", "read_latency")

	perf_obj_ctr2 = NaElement("perf-object-counter")
	perf_obj_ctr2.child_add_string("object-type", "volume")
	perf_obj_ctr2.child_add_string("counter-name", "write_latency")

	perf_obj_ctr3 = NaElement("perf-object-counter")
	perf_obj_ctr3.child_add_string("object-type", "volume")
	perf_obj_ctr3.child_add_string("counter-name", "avg_latency")

	counter_info.child_add(perf_obj_ctr1)
	counter_info.child_add(perf_obj_ctr2)
	counter_info.child_add(perf_obj_ctr3)
	instance_info.child_add(counter_info)
	perf_in.child_add(instance_info)

	perf_out = server_ctx.invoke_elem(perf_in)
	
	if(perf_out.results_status() == "failed") :
		print(perf_out.results_reason() + "\n")
		sys.exit(2)
	
	return perf_out


def extract_perf_counter_data(perf_out) :
	gen_time_arr = 1
	time_i = 0
	read_i = 0
	write_i = 0
	avg_i = 0
	instance = perf_out.child_get("perf-instances")
	instances = instance.children_get()
	
	if(instances == None):
	        instances = []

	for rec in instances :
		vol_name = rec.child_get_string("instance-name")
		counters = rec.child_get("counters")
		perf_cnt_data = counters.children_get()
		
		for rec1 in perf_cnt_data :
			read_i = 0
			write_i = 0
			avg_i = 0
			counter_name = rec1.child_get_string("counter-name")
			counter_str = rec1.child_get_string("counter-data")
			counter_arr = counter_str.split (',')
		
			if(counter_name == "read_latency") :
				
				for time_val in counter_arr :
					time_val_arr = [float(s) for s in time_val.split(':')]
	
					if(gen_time_arr) :
						time1.append(time.localtime(time_val_arr[0]))
					
					read_latency.append(time_val_arr[1])	
				
				gen_time_arr = 0
			
			elif(counter_name == "write_latency") :
				
				for time_val in counter_arr :
					time_val_arr = [float(s) for s in time_val.split(':')]
	
					if(gen_time_arr) :
						time1.append(time.localtime(time_val_arr[0]))
					
					write_latency.append(time_val_arr[1])	
				
				gen_time_arr = 0
			
			elif(counter_name == "avg_latency") :
				
				for time_val in counter_arr :
					time_val_arr = time_val.split(':')
					time_val_arr = [float(s) for s in time_val.split(':')]
	
					if(gen_time_arr) :
						time1.append(time.localtime(time_val_arr[0]))					
					avg_latency.append(time_val_arr[1])	
				
				gen_time_arr = 0


def main() :
	perf_out = invoke_perf_zapi()
	extract_perf_counter_data(perf_out)
	print_output()
	sys.exit (1)

	
# Command line arguments
args = len(sys.argv) - 1

if(args < 4):
    print_help()

dfm = sys.argv[1]
user = sys.argv[2]
pw  = sys.argv[3]
aggr_name = sys.argv[4]

time1 = []
read_latency = []
write_latency = []
avg_latency = []

#Invoke routine
main()

#=========================== POD ============================#

'''=head1 NAME

  perf_aggr_latency.py - This sample code provides information on read latency,
  write latency and average latency of an aggregate.

=head1 SYNOPSIS

  perf_aggr_latency.py <dfm> <user> <password> <aggr-name>

=head1 ARGUMENTS

  <dfm>
  DFM Server name.

  <user>
  User name.

  <password>
  Password.

  <aggr-name>
  Name of the aggregate in format storage:aggrName.

=head1 SEE ALSO

  NaElement.py, NaServer.py

=head1 COPYRIGHT

 Copyright (c) 2009 NetApp, Inc. All rights reserved.
 Specifications subject to change without notice.

=cut'''


