diff --git a/.drone.sh b/.drone.sh index 4163041..6b28c0c 100644 --- a/.drone.sh +++ b/.drone.sh @@ -3,7 +3,7 @@ export now=$(TZ=Australia/Sydney date '+%Y%m%d-%H%M%S') echo $now echo "build commences" -go build -ldflags "-X main.sha1ver=`git rev-parse HEAD` -X main.buildTime=$now" -o vm-metrics +go build -ldflags "-X main.sha1ver=`git rev-parse HEAD` -X main.buildTime=$now" -o drsscore echo "build complete" -sha256sum vm-metrics > vm-metrics_checksum.txt +sha256sum drsscore > drsscore_checksum.txt ls -lah \ No newline at end of file diff --git a/.drone.yml b/.drone.yml index cede9f9..4e81e9b 100644 --- a/.drone.yml +++ b/.drone.yml @@ -24,5 +24,5 @@ steps: PLUGIN_VERIFY: false PLUGIN_CHMOD: false #PLUGIN_DEBUG: false - PLUGIN_INCLUDE: ^vm-metrics$,^vm-metrics_checksum.txt$ + PLUGIN_INCLUDE: ^drsscore$,^drsscore_checksum.txt$ PLUGIN_EXCLUDE: ^\.git/$ \ No newline at end of file diff --git a/.gitignore b/.gitignore index 9656516..04fa594 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -vm-metrics +drsscore log.txt \ No newline at end of file diff --git a/go.mod b/go.mod index f2b19d9..4d100b8 100644 --- a/go.mod +++ b/go.mod @@ -1,5 +1,5 @@ -module nathan/vm-metrics/v2 +module nathan/drsscore/v2 go 1.21.0 -require github.com/vmware/govmomi v0.30.7 // indirect +require github.com/vmware/govmomi v0.30.7 diff --git a/go.sum b/go.sum index fd0638e..887c423 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,4 @@ +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/vmware/govmomi v0.30.7 h1:YO8CcDpLJzmq6PK5/CBQbXyV21iCMh8SbdXt+xNkXp8= github.com/vmware/govmomi v0.30.7/go.mod h1:epgoslm97rLECMV4D+08ORzUBEU7boFSepKjt7AYVGg= diff --git a/main.go b/main.go index 7e53d49..6cdb298 100644 --- a/main.go +++ b/main.go @@ -14,11 +14,8 @@ import ( _ "time/tzdata" "github.com/vmware/govmomi" - "github.com/vmware/govmomi/object" - "github.com/vmware/govmomi/performance" "github.com/vmware/govmomi/property" "github.com/vmware/govmomi/view" - "github.com/vmware/govmomi/vim25" "github.com/vmware/govmomi/vim25/mo" "github.com/vmware/govmomi/vim25/types" ) @@ -27,10 +24,10 @@ var ( c *govmomi.Client ctx context.Context cancel context.CancelFunc - location *time.Location sha1ver string // sha1 revision used to build the program buildTime string // when the executable was built results []DrsResults + location *time.Location ) type DrsResults struct { @@ -44,215 +41,6 @@ type DrsResults struct { NumVmsDrsBucket81To100 int32 } -/* - func findPerfCounter(perfManager *vim25.PerformanceManager, counterName string) (*vim25.PerfCounterInfo, error) { - perfCounters, err := perfManager.QueryPerfCounter(context.Background(), nil) - if err != nil { - return nil, err - } - - for _, counter := range perfCounters { - if counter.NameInfo.GetElement().Key == counterName { - return &counter, nil - } - } - - return nil, fmt.Errorf("Performance counter '%s' not found", counterName) - } -*/ -func findVMByName(ctx context.Context, client *vim25.Client, vmName string) ([]mo.VirtualMachine, error) { - m := view.NewManager(client) - - vms, err := m.CreateContainerView(ctx, client.ServiceContent.RootFolder, []string{"VirtualMachine"}, true) - if err != nil { - return nil, err - } - defer vms.Destroy(ctx) - - var matchingVMs []mo.VirtualMachine - - err = vms.Retrieve(ctx, []string{"VirtualMachine"}, []string{"name"}, &matchingVMs) - if err != nil { - return nil, err - } - - var result []mo.VirtualMachine - - for _, vm := range matchingVMs { - if vm.Name == vmName { - result = append(result, vm) - } - } - - return result, nil -} - -func findClusterByName(ctx context.Context, client *vim25.Client, name string) mo.ClusterComputeResource { - // Create a container view so that we can search vCenter - m := view.NewManager(client) - cv, _ := m.CreateContainerView(ctx, c.ServiceContent.RootFolder, []string{"ClusterComputeResource"}, true) - - var clusters []mo.ClusterComputeResource - log.Printf("Searching for Cluster '%s'\n", name) - err := cv.Retrieve(ctx, []string{"ClusterComputeResource"}, []string{"summary", "name"}, &clusters) - if err != nil { - log.Printf("Failed searching for Cluster %s : %s\n", name, err) - return mo.ClusterComputeResource{} - } else { - for _, cluster := range clusters { - if cluster.Name == name { - log.Printf("Found corresponding Cluster with MoRef '%s'\n", cluster.Reference()) - return cluster - } - } - } - - // If we reached here then we didn't find the Cluster - return mo.ClusterComputeResource{} -} - -func getMetricIds(counters []types.PerfCounterInfo) []types.PerfMetricId { - var metricIds []types.PerfMetricId - for _, counter := range counters { - var metricId types.PerfMetricId - metricId.CounterId = counter.Key - metricIds = append(metricIds, metricId) - } - fmt.Printf("metric IDs : '%v'\n", metricIds) - return metricIds -} - -func getSpecificVMMetrics(ctx context.Context, c *vim25.Client, vmName string) { - //perfManager := c.ServiceContent.PerfManager - perfManager := performance.NewManager(c) - var perfCounterInfos []types.PerfCounterInfo - startTime := time.Now().Add(-time.Hour) - timeNow := time.Now() - - // Find the performance counters for CPU Entitlement, CPU Consumed, and CPU Demand - counterNames := []string{"cpu.entitlement.latest", "cpu.usage.average", "cpu.demand.average", "cpu.readiness.average"} - //counterNames := []string{"cpu.entitlement.latest", "cpu.usage.average"} - - // Retrieve counters name list - counters, err := perfManager.CounterInfoByName(ctx) - if err != nil { - //return err - fmt.Printf("Error getting counter info : '%s'\n", err) - return - } - - fmt.Printf("Found '%d' counters\n", len(counters)) - - for _, counter := range counters { - for _, counterName := range counterNames { - if counter.Name() == counterName { - groupInfo := counter.GroupInfo.GetElementDescription() - nameInfo := counter.NameInfo.GetElementDescription() - - fmt.Printf("Found counter matching name '%s' : '%s';'%s'\n", counterName, groupInfo, nameInfo) - - perfCounterInfos = append(perfCounterInfos, *counter) - } else { - //fmt.Printf("Ignoring '%s' : '%s'\n", counter.StatsType, counter.Name()) - } - } - } - - fmt.Printf("Ended search with %d counter infos\n", len(perfCounterInfos)) - - // Find the VM by its name - vmMatches, err := findVMByName(ctx, c, vmName) - if err != nil { - fmt.Println("Error finding VM:", err) - return - } - - for _, vm := range vmMatches { - // Create PerfQuerySpec as per https://github.com/vmware/govmomi/blob/main/performance/example_test.go - spec := types.PerfQuerySpec{ - //MaxSample: 180, // In one hour there are 180 instances of 20 second intervals - MetricId: getMetricIds(perfCounterInfos), - IntervalId: 20, - StartTime: &startTime, // 1 hour ago - EndTime: &timeNow, - } - - // Query metrics - sample, err := perfManager.SampleByName(ctx, spec, counterNames, []types.ManagedObjectReference{vm.Reference()}) - if err != nil { - fmt.Printf("Error getting SampleByName : '%s'\n", err) - return - } - fmt.Printf("Sample result is %d\n", len(sample)) - - /* - for _, v := range sample { - fmt.Printf("%v\n", v.GetPerfEntityMetricBase().Entity) - } - */ - - result, err := perfManager.ToMetricSeries(ctx, sample) - if err != nil { - fmt.Printf("Error getting ToMetricSeries : '%s'\n", err) - return - } - - fmt.Printf("Retrieved %d metric series\n", len(result)) - - // Read result - for _, metric := range result { - vm := object.NewVirtualMachine(c, metric.Entity) - name, err := vm.ObjectName(ctx) - if err != nil { - fmt.Printf("Error getting vm name : '%s'\n", err) - return - } - - fmt.Printf("Vm %s has %d metric values : %v\n", name, len(metric.Value), metric) - - for i, v := range metric.Value { - fmt.Printf("Processing [%d] : '%v'\n", i, v) - - counter := counters[v.Name] - units := counter.UnitInfo.GetElementDescription().Label - - instance := v.Instance - if instance == "" { - instance = "-" - } - - if len(v.Value) != 0 { - //fmt.Printf("%s\t%s\t%s\t%s : %v\n", name, instance, v.Name, units, v.ValueCSV()) - fmt.Printf("%s\t%s\t%s\t%s : %v (%d)\n", name, instance, v.Name, units, v.Value, len(v.Value)) - } - } - } - - fmt.Printf("Finished receiving result.\n") - - /* - // Create a query specification - query := perfManager.QueryPerf(ctx, &vim25.QueryPerf{ - Entity: []vim25.ManagedObjectReference{vm.Reference()}, - MaxSample: 1, - MetricId: getMetricIds(perfCounterInfos), - IntervalId: 20, // 20-second interval - StartTime: time.Now().Add(-time.Hour), // 1 hour ago - EndTime: time.Now(), - }) - - // Process the query result - for _, perf := range query { - fmt.Println("VM:", vmName) - for i, value := range perf.Value { - counterInfo := perfCounterInfos[i] - fmt.Printf("%s: %v\n", counterInfo.NameInfo.GetElement().Key, value.Value[0]) - } - } - */ - } -} - // From https://stackoverflow.com/a/33769379 func Scan(d interface{}) { v := reflect.ValueOf(d) @@ -397,7 +185,6 @@ func main() { } defer c.Logout(ctx) - //getSpecificVMMetrics(ctx, c.Client, *vmName) err = getNumVmsPerDrsScoreBucket(c) if err != nil { log.Printf("Error retrieving NumVmsPerDrsScoreBucket: %s\n", err)