//Metrics returns metrics for a given object
Metrics returns metrics for a given object
// Metrics returns metrics for a given object
func (c *Client) Metrics(mor types.ManagedObjectReference, pr *prtgData, str []string, interval int32) (err error) {
	ctx := context.Background()
	ctx, _ = context.WithTimeout(ctx, 30*time.Second)
	perfManager := performance.NewManager(c.c)
	counters, err := perfManager.CounterInfoByName(ctx)
	if err != nil {
		return fmt.Errorf("perfmanager %v", err)
	}
	var names []string
	for name := range counters {
		names = append(names, name)
	}
	spec := types.PerfQuerySpec{
		MaxSample:  1,
		MetricId:   []types.PerfMetricId{},
		IntervalId: interval,
	}
	maxQuery, err := c.getMaxQueryMetrics(ctx)
	if err != nil {
		return fmt.Errorf("getMaxQueryMetrics %v", err)
	}
	psum, err := perfManager.ProviderSummary(ctx, mor)
	if err != nil {
		return fmt.Errorf("object not found %v", mor)
	}
	if !psum.CurrentSupported {
		fmt.Printf("%v performance metrics not available\n", mor)
		return
	}
	sample, err := perfManager.SampleByName(ctx, spec, names, []types.ManagedObjectReference{mor})
	if (err != nil) || len(sample) == 0 {
		return fmt.Errorf("could not find sample data for %v, err: %v", mor, err)
	}
	if len(sample) > maxQuery {
		return fmt.Errorf("query metrics level too low, needed %v  max setting %v", len(sample), maxQuery)
	}
	result, err := perfManager.ToMetricSeries(ctx, sample)
	if err != nil {
		return fmt.Errorf("metrics %v", err)
	}
	res := result[0]
	sort.Slice(res.Value, func(i, j int) bool {
		return res.Value[i].Name < res.Value[j].Name
	})
	for _, v := range res.Value {
		if (len(v.Value) == 0) || v.Value[0] == -1 {
			continue
		}
		var hide bool
		counter := counters[v.Name]
		instance := v.Instance
		if inStringSlice(v.Name, str) {
			if instance != "" {
				switch mor.Type {
				case "VmwareDistributedVirtualSwitch":
					v.Name = v.Name[15:]
					fields := strings.Fields(instance)
					switch len(fields) {
					case 1:
						v.Name = fmt.Sprintf("%v.%v", v.Name, fields[0])
					case 2:
						hide = true
						v.Name = fmt.Sprintf("%v Port %v %v", fields[0], fields[1], v.Name)
					default:
						v.Name = fmt.Sprintf("%v %v", fields, v.Name)
					}
				default:
					continue
				}
			}
			units := counter.UnitInfo.GetElementDescription().Label
			fixedPointFloat := float64(v.Value[0]) / 100
			if strings.Contains(v.Name, "power") || strings.Contains(v.Name, "sys.uptime") {
				fixedPointFloat = float64(v.Value[0])
			}
			u, s, cu := metType(units, counter.GroupInfo.GetElementDescription().Key)
			if !hide {
				_ = pr.add(fixedPointFloat, ps.SensorChannel{Channel: v.Name, Unit: u, VolumeSize: s, CustomUnit: cu}) 
			} else {
				_ = pr.add(fixedPointFloat, ps.SensorChannel{Channel: v.Name, Unit: u, VolumeSize: s, CustomUnit: cu, ShowChart: "0", ShowTable: "0"})
			}
		}
	}
	return
}
func ( c * Client ) Metrics ( mor types . ManagedObjectReference , pr * prtgData , str [ ] string , interval int32 ) ( err error ) { ctx := context . Background ( ) ctx , _ = context . WithTimeout ( ctx , 30 * time . Second ) perfManager := performance . NewManager ( c . c ) counters , err := perfManager . CounterInfoByName ( ctx ) if err != nil { return fmt . Errorf ( " " , err ) } var names [ ] string for name := range counters { names = append ( names , name ) } spec := types . PerfQuerySpec { MaxSample : 1 , MetricId : [ ] types . PerfMetricId { } , IntervalId : interval , } maxQuery , err := c . getMaxQueryMetrics ( ctx ) if err != nil { return fmt . Errorf ( " " , err ) } psum , err := perfManager . ProviderSummary ( ctx , mor ) if err != nil { return fmt . Errorf ( " " , mor ) } if ! psum . CurrentSupported { fmt . Printf ( " \n " , mor ) return } sample , err := perfManager . SampleByName ( ctx , spec , names , [ ] types . ManagedObjectReference { mor } ) if ( err != nil ) || len ( sample ) == 0 { return fmt . Errorf ( " " , mor , err ) } if len ( sample ) > maxQuery { return fmt . Errorf ( " " , len ( sample ) , maxQuery ) } result , err := perfManager . ToMetricSeries ( ctx , sample ) if err != nil { return fmt . Errorf ( " " , err ) } res := result [ 0 ] sort . Slice ( res . Value , func ( i , j int ) bool { return res . Value [ i ] . Name < res . Value [ j ] . Name } ) for _ , v := range res . Value { if ( len ( v . Value ) == 0 ) || v . Value [ 0 ] == - 1 { continue } var hide bool counter := counters [ v . Name ] instance := v . Instance if inStringSlice ( v . Name , str ) { if instance != " " { switch mor . Type { case " " : v . Name = v . Name [ 15 : ] fields := strings . Fields ( instance ) switch len ( fields ) { case 1 : v . Name = fmt . Sprintf ( " " , v . Name , fields [ 0 ] ) case 2 : hide = true v . Name = fmt . Sprintf ( " " , fields [ 0 ] , fields [ 1 ] , v . Name ) default : v . Name = fmt . Sprintf ( " " , fields , v . Name ) } default : continue } } units := counter . UnitInfo . GetElementDescription ( ) . Label fixedPointFloat := float64 ( v . Value [ 0 ] ) / 100 if strings . Contains ( v . Name , " " ) || strings . Contains ( v . Name , " " ) { fixedPointFloat = float64 ( v . Value [ 0 ] ) } u , s , cu := metType ( units , counter . GroupInfo . GetElementDescription ( ) . Key ) if ! hide { _ = pr . add ( fixedPointFloat , ps . SensorChannel { Channel : v . Name , Unit : u , VolumeSize : s , CustomUnit : cu } ) } else { _ = pr . add ( fixedPointFloat , ps . SensorChannel { Channel : v . Name , Unit : u , VolumeSize : s , CustomUnit : cu , ShowChart : " " , ShowTable : " " } ) } } } return }
Metrics returns metrics for a given object
Metrics returns metrics for a given object
// Retrieve counters // Check PerfQuerySpec // Query metrics // dont run query if it will exceed current limit //Read result // special handling of metric names using instance data // drop net.throughput prefix //if instance == "" { //	instance = "-" //} // special handling for int's // get PRTG version of vmware metric, eg type % == Percent // allow hiding of verbose channels //, DecimalMode: decMode})