parent
9158290982
commit
ad47dc3b49
|
@ -2,19 +2,134 @@ package gotoc
|
||||||
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/vmware/leap/util"
|
||||||
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
//#include "../../../../../Include/sigar.h"
|
//#include "../../../../../Include/sigar.h"
|
||||||
|
//#include "../../../../../Include/sigar_format.h"
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
|
var _prevCpuUsage C.sigar_cpu_t //usged for percentage calculation
|
||||||
|
var prevSampleTs int64
|
||||||
|
|
||||||
|
type CpuUsageInfo struct {
|
||||||
|
User uint64
|
||||||
|
Sys uint64
|
||||||
|
Nice uint64
|
||||||
|
Idle uint64
|
||||||
|
Wait uint64
|
||||||
|
Irq uint64
|
||||||
|
SoftIrq uint64
|
||||||
|
Stolen uint64
|
||||||
|
Total uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
type CpuPctUsageInfo struct {
|
||||||
|
User float64
|
||||||
|
Sys float64
|
||||||
|
Nice float64
|
||||||
|
Idle float64
|
||||||
|
Wait float64
|
||||||
|
Irq float64
|
||||||
|
SoftIrq float64
|
||||||
|
Stolen float64
|
||||||
|
Combined float64
|
||||||
|
}
|
||||||
|
func (this *CpuPctUsageInfo) String() string {
|
||||||
|
return "CPU states: "+
|
||||||
|
strconv.FormatFloat(this.User,'f', 1, 64)+"% user, "+
|
||||||
|
strconv.FormatFloat(this.Sys,'f', 1, 64)+"% system, "+
|
||||||
|
strconv.FormatFloat(this.Nice,'f', 1, 64)+"% nice, "+
|
||||||
|
strconv.FormatFloat(this.Wait,'f', 1, 64) +"% wait, "+
|
||||||
|
strconv.FormatFloat(this.Idle,'f', 1, 64)+"% idle"
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
// CpuPctUsageInfo (Float64) CpuPctUsageInfo (Float64) CpuPctUsageInfo (Float64) CpuPctUsageInfo (Float64) CpuPctUsageInfo (Float64)
|
||||||
|
//------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
func GetCpuPctUsageInfo() (result *CpuPctUsageInfo, err error) {
|
||||||
|
defer util.Panic2Error(&err)
|
||||||
|
|
||||||
|
sigar := GetSigarHandle()
|
||||||
|
cur_c_cpu_t, err := _getCpu(sigar)
|
||||||
|
if err != nil {
|
||||||
|
return nil,err
|
||||||
|
}
|
||||||
|
|
||||||
|
if prevSampleTs == 0 {
|
||||||
|
|
||||||
|
_prevCpuUsage = *cur_c_cpu_t
|
||||||
|
time.Sleep(500*time.Millisecond)
|
||||||
|
|
||||||
|
cur_c_cpu_t, err = _getCpu(sigar)
|
||||||
|
if err != nil {
|
||||||
|
return nil,err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var c_pct_cpu_t C.sigar_cpu_perc_t
|
||||||
|
C.sigar_cpu_perc_calculate(&_prevCpuUsage, cur_c_cpu_t, &c_pct_cpu_t)
|
||||||
|
_prevCpuUsage = *cur_c_cpu_t
|
||||||
|
prevSampleTs = util.NowEpoch()
|
||||||
|
|
||||||
|
return &CpuPctUsageInfo{
|
||||||
|
User : float64(c_pct_cpu_t.user),
|
||||||
|
Sys : float64(c_pct_cpu_t.sys),
|
||||||
|
Nice : float64(c_pct_cpu_t.nice),
|
||||||
|
Idle : float64(c_pct_cpu_t.idle),
|
||||||
|
Wait : float64(c_pct_cpu_t.wait),
|
||||||
|
Irq : float64(c_pct_cpu_t.irq),
|
||||||
|
SoftIrq : float64(c_pct_cpu_t.soft_irq),
|
||||||
|
Stolen : float64(c_pct_cpu_t.stolen),
|
||||||
|
Combined : float64(c_pct_cpu_t.combined),
|
||||||
|
},nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
//CpuUsageInfo (uint64) CpuUsageInfo (uint64) CpuUsageInfo (uint64) CpuUsageInfo (uint64) CpuUsageInfo (uint64) CpuUsageInfo (uint64)
|
||||||
|
//------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
func GetCpuUsageInfo() (result *CpuUsageInfo, err error) {
|
||||||
|
defer util.Panic2Error(&err)
|
||||||
|
|
||||||
|
c_cpu_t, err := _getCpu(GetSigarHandle())
|
||||||
|
if err != nil {
|
||||||
|
return nil,err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &CpuUsageInfo{
|
||||||
|
User : uint64(c_cpu_t.user),
|
||||||
|
Sys : uint64(c_cpu_t.sys),
|
||||||
|
Nice : uint64(c_cpu_t.nice),
|
||||||
|
Idle : uint64(c_cpu_t.idle),
|
||||||
|
Wait : uint64(c_cpu_t.wait),
|
||||||
|
Irq : uint64(c_cpu_t.irq),
|
||||||
|
SoftIrq : uint64(c_cpu_t.soft_irq),
|
||||||
|
Stolen : uint64(c_cpu_t.stolen),
|
||||||
|
Total : uint64(c_cpu_t.total),
|
||||||
|
},nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
//Helpers Helpers Helpers Helpers Helpers Helpers Helpers Helpers Helpers Helpers Helpers Helpers Helpers Helpers Helpers Helpers Helpers Helpers
|
||||||
|
//------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
func _getCpu(sigar *C.sigar_t) (*C.sigar_cpu_t, error) {
|
||||||
|
|
||||||
|
var c_cpu_t C.sigar_cpu_t
|
||||||
|
if status := int(C.sigar_cpu_get(sigar, &c_cpu_t)) ; status != SIGAR_OK {
|
||||||
|
return nil,fmt.Errorf("Failed to retrieve cpu usage info with error: %v", status)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &c_cpu_t,nil
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
//List List List List List List List List List List List List List List List List List List List List List List List List List List List List
|
||||||
|
//------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
func Cpu() (C.sigar_cpu_list_t,[]C.sigar_cpu_t){
|
func Cpu() (C.sigar_cpu_list_t,[]C.sigar_cpu_t){
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,9 @@ package gotoc
|
||||||
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
"strconv"
|
||||||
)
|
)
|
||||||
/*
|
/*
|
||||||
#include "../../../../../Include/sigar.h"
|
#include "../../../../../Include/sigar.h"
|
||||||
|
@ -15,30 +15,77 @@ import (
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
|
|
||||||
func FileInfo() []C.sigar_file_system_t{
|
const (
|
||||||
|
FSTYPE_UNKNOWN = iota
|
||||||
|
FSTYPE_NONE
|
||||||
|
FSTYPE_LOCAL_DISK
|
||||||
|
FSTYPE_NETWORK
|
||||||
|
FSTYPE_RAM_DISK
|
||||||
|
FSTYPE_CDROM
|
||||||
|
FSTYPE_SWAP
|
||||||
|
FSTYPE_MAX
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
type FsInfo struct {
|
||||||
|
DirName string
|
||||||
|
DevName string
|
||||||
|
TypeName string
|
||||||
|
SysTypeName string
|
||||||
|
Options string
|
||||||
|
Type int
|
||||||
|
Flags uint64
|
||||||
|
}
|
||||||
|
func (this *FsInfo) String() string {
|
||||||
|
return fmt.Sprintf("{Dirname: %v, DevName: %v, TypeName: %v, SysTypeName: %v, Options: %v, Type: %v, Flags:%v",
|
||||||
|
this.DirName,
|
||||||
|
this.DevName,
|
||||||
|
this.TypeName,
|
||||||
|
this.SysTypeName,
|
||||||
|
this.Options,
|
||||||
|
this.Type,
|
||||||
|
this.Flags,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetFsInfo() (result []*FsInfo, err error){
|
||||||
|
defer func() {
|
||||||
|
if r := recover() ; r != nil{
|
||||||
|
err = fmt.Errorf("Failed to discover file systems due to: " + err.Error())
|
||||||
|
}
|
||||||
|
}()
|
||||||
var sigar *C.sigar_t=GetSigarHandle()
|
var sigar *C.sigar_t=GetSigarHandle()
|
||||||
var fileSystemList C.sigar_file_system_list_t
|
var fileSystemList C.sigar_file_system_list_t
|
||||||
//C.fileInfo(sigar,&fileSystemList)
|
|
||||||
C.sigar_file_system_list_get(sigar, &fileSystemList);
|
C.sigar_file_system_list_get(sigar, &fileSystemList);
|
||||||
|
defer C.sigar_file_system_list_destroy(sigar, &fileSystemList);
|
||||||
|
|
||||||
var length int=int(fileSystemList.number)
|
var length int=int(fileSystemList.number)
|
||||||
|
|
||||||
|
|
||||||
cFs:=GetGoSlice(length, unsafe.Pointer(fileSystemList.data))
|
cFs:=GetGoSlice(length, unsafe.Pointer(fileSystemList.data))
|
||||||
|
|
||||||
var goFs []C.sigar_file_system_t
|
var goFs []C.sigar_file_system_t
|
||||||
goFs = *(*[]C.sigar_file_system_t)(unsafe.Pointer(&cFs))
|
goFs = *(*[]C.sigar_file_system_t)(unsafe.Pointer(&cFs))
|
||||||
|
|
||||||
//fmt.Printf("%v\n", C.GoString(&goFs[1].dir_name[0]))
|
|
||||||
C.sigar_file_system_list_destroy(sigar, &fileSystemList);
|
|
||||||
|
|
||||||
return goFs
|
result = make([]*FsInfo, length)
|
||||||
|
for i,fs := range goFs {
|
||||||
|
fsType,err := strconv.Atoi(fmt.Sprintf("%v", fs._type))
|
||||||
|
if err != nil {
|
||||||
|
fsType = FSTYPE_UNKNOWN
|
||||||
|
}
|
||||||
|
result[i] = &FsInfo{
|
||||||
|
DirName : C.GoString(&fs.dir_name[0]),
|
||||||
|
DevName : C.GoString(&fs.dev_name[0]),
|
||||||
|
TypeName : C.GoString(&fs.type_name[0]),
|
||||||
|
SysTypeName : C.GoString(&fs.sys_type_name[0]),
|
||||||
|
Options : C.GoString(&fs.options[0]),
|
||||||
|
Type : fsType,
|
||||||
|
Flags : uint64(fs.flags),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result,nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,122 @@
|
||||||
|
package gotoc
|
||||||
|
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
/*
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "../../../../../Include/sigar.h"
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
type sigar_file_system_usage_t struct {
|
||||||
|
UsedPct float64
|
||||||
|
Total int64
|
||||||
|
Free int64
|
||||||
|
Used int64
|
||||||
|
Avail int64
|
||||||
|
Files int64
|
||||||
|
FreeFiles int64
|
||||||
|
}
|
||||||
|
|
||||||
|
type FsUsage struct {
|
||||||
|
UsedPct float64
|
||||||
|
Total int64
|
||||||
|
Free int64
|
||||||
|
Used int64
|
||||||
|
Avail int64
|
||||||
|
Files int64
|
||||||
|
FreeFiles int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *FsUsage) String() string { return fmt.Sprintf("used: %v, total: %v, free: %v, used: %v, avail: %v, files: %v, freeFiles: %v", this.UsedPct, this.Total, this.Free, this.Used, this.Avail, this.Files, this.FreeFiles) }
|
||||||
|
|
||||||
|
type DiskUsage struct {
|
||||||
|
Reads int64
|
||||||
|
Writes int64
|
||||||
|
WriteBytes int64
|
||||||
|
ReadBytes int64
|
||||||
|
Rtime int64
|
||||||
|
Wtime int64
|
||||||
|
Qtime int64
|
||||||
|
Time int64
|
||||||
|
SnapTime int64
|
||||||
|
ServiceTime float64
|
||||||
|
Queue float64
|
||||||
|
}
|
||||||
|
|
||||||
|
type FsUsageInfo struct {
|
||||||
|
Fs *FsUsage
|
||||||
|
Disk *DiskUsage
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetFsUsageInfo(dirName string, diskName string)(fsUsageInfo *FsUsageInfo,err error){
|
||||||
|
|
||||||
|
var sigar *C.sigar_t=GetSigarHandle()
|
||||||
|
//TODO: noticed that sigar_file_system_usage_t contains a sigar_disk_usage_t member, should there be two invocations?
|
||||||
|
fsUsage, err := _getFsUsage(dirName, sigar)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
diskUsage, err := _getDiskUsage(diskName, sigar) ;
|
||||||
|
if err != nil {
|
||||||
|
return nil,err
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return &FsUsageInfo {fsUsage, diskUsage}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func GetFsUsage(dirName string) (*FsUsage, error) {
|
||||||
|
return _getFsUsage(dirName, GetSigarHandle())
|
||||||
|
}
|
||||||
|
|
||||||
|
func _getFsUsage(dirName string, sigar *C.sigar_t) (out *FsUsage, err error) {
|
||||||
|
var fsusage C.sigar_file_system_usage_t
|
||||||
|
|
||||||
|
dir:=C.CString(dirName)
|
||||||
|
|
||||||
|
C.free(unsafe.Pointer(dir))
|
||||||
|
|
||||||
|
C.sigar_file_system_usage_get(sigar , dir, &fsusage)
|
||||||
|
|
||||||
|
out = &FsUsage{
|
||||||
|
float64(fsusage.use_percent),
|
||||||
|
int64(fsusage.total),
|
||||||
|
int64(fsusage.free),
|
||||||
|
int64(fsusage.used),
|
||||||
|
int64(fsusage.avail),
|
||||||
|
int64(fsusage.files),
|
||||||
|
int64(fsusage.free_files),
|
||||||
|
}
|
||||||
|
|
||||||
|
return out,nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetDiskUsage(diskName string) (*DiskUsage, error) {
|
||||||
|
return _getDiskUsage(diskName, GetSigarHandle())
|
||||||
|
}
|
||||||
|
|
||||||
|
func _getDiskUsage(diskName string, sigar *C.sigar_t) (*DiskUsage, error) {
|
||||||
|
var diskusage C.sigar_disk_usage_t
|
||||||
|
disk:=C.CString(diskName)
|
||||||
|
defer C.free(unsafe.Pointer(disk))
|
||||||
|
C.sigar_disk_usage_get(sigar , disk, &diskusage)
|
||||||
|
return &DiskUsage {
|
||||||
|
int64(diskusage.reads),
|
||||||
|
int64(diskusage.writes),
|
||||||
|
int64(diskusage.write_bytes),
|
||||||
|
int64(diskusage.read_bytes),
|
||||||
|
int64(diskusage.rtime),
|
||||||
|
int64(diskusage.wtime),
|
||||||
|
int64(diskusage.qtime),
|
||||||
|
int64(diskusage.time),
|
||||||
|
int64(diskusage.snaptime),
|
||||||
|
float64(diskusage.service_time),
|
||||||
|
float64(diskusage.queue),
|
||||||
|
},nil
|
||||||
|
}
|
|
@ -48,11 +48,19 @@ func GetGoSlice(number int, pointer unsafe.Pointer ) reflect.SliceHeader{
|
||||||
Len: length,
|
Len: length,
|
||||||
Cap: length,
|
Cap: length,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return cObj
|
return cObj
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func CArr2SlicePtr(length int, cArray interface{}) unsafe.Pointer{
|
||||||
|
|
||||||
|
vl := reflect.ValueOf(cArray)
|
||||||
|
header := reflect.SliceHeader{
|
||||||
|
Data: uintptr(unsafe.Pointer(vl.Pointer())),
|
||||||
|
Len: length,
|
||||||
|
Cap: length,
|
||||||
|
}
|
||||||
|
|
||||||
|
return unsafe.Pointer(&header)
|
||||||
}
|
}
|
|
@ -1,11 +0,0 @@
|
||||||
package gotoc
|
|
||||||
|
|
||||||
import (
|
|
||||||
|
|
||||||
)
|
|
||||||
|
|
||||||
func main(){
|
|
||||||
|
|
||||||
|
|
||||||
NetInfo()
|
|
||||||
}
|
|
|
@ -2,9 +2,8 @@ package gotoc
|
||||||
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/vmware/leap/util"
|
||||||
|
|
||||||
)
|
)
|
||||||
/*
|
/*
|
||||||
|
|
||||||
|
@ -15,17 +14,49 @@ import (
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
type Info struct {
|
type Mem struct {
|
||||||
Free int64
|
Ram uint64
|
||||||
|
Total uint64
|
||||||
|
Used uint64
|
||||||
|
Free uint64
|
||||||
|
ActualUsed uint64
|
||||||
|
ActualFree uint64
|
||||||
|
UsedPerecent float64
|
||||||
|
FreePerecent float64
|
||||||
|
}
|
||||||
|
func (this *Mem) String() string {
|
||||||
|
return fmt.Sprintf("Mem: %vK av, %vK used, %vK free", (this.Total / 1024),(this.Used / 1024), (this.Free / 1024))
|
||||||
|
}
|
||||||
|
|
||||||
|
type Swap struct {
|
||||||
|
Total uint64
|
||||||
|
Used uint64
|
||||||
|
Free uint64
|
||||||
|
PageIn uint64
|
||||||
|
PageOut uint64
|
||||||
|
}
|
||||||
|
func (this *Swap) String() string {
|
||||||
|
return fmt.Sprintf("Swap: %vK av, %vK used, %vK free", (this.Total / 1024),(this.Used / 1024), (this.Free / 1024))
|
||||||
}
|
}
|
||||||
|
|
||||||
type MemInfo struct {
|
type MemInfo struct {
|
||||||
Mem *Info
|
Mem *Mem
|
||||||
Swap *Info
|
Swap *Swap
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetMemInfo() (*MemInfo, error){
|
func GetTotalMem() (total uint64,err error) {
|
||||||
|
defer util.Panic2Error(&err)
|
||||||
|
var sigar *C.sigar_t=GetSigarHandle()
|
||||||
|
var mem C.sigar_mem_t
|
||||||
|
status := int(C.sigar_mem_get(sigar, &mem))
|
||||||
|
if status != SIGAR_OK {
|
||||||
|
return 0,fmt.Errorf("Failed to rertieve sys mem info with error: %v", status)
|
||||||
|
}
|
||||||
|
return uint64(mem.total),nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetMemInfo() (result *MemInfo,err error){
|
||||||
|
defer util.Panic2Error(&err)
|
||||||
var sigar *C.sigar_t=GetSigarHandle()
|
var sigar *C.sigar_t=GetSigarHandle()
|
||||||
var mem C.sigar_mem_t
|
var mem C.sigar_mem_t
|
||||||
var swap C.sigar_swap_t
|
var swap C.sigar_swap_t
|
||||||
|
@ -34,11 +65,24 @@ func GetMemInfo() (*MemInfo, error){
|
||||||
C.sigar_swap_get(sigar, &swap);
|
C.sigar_swap_get(sigar, &swap);
|
||||||
|
|
||||||
return &MemInfo{
|
return &MemInfo{
|
||||||
Mem : &Info{ Free : int64(mem.free)},
|
Mem : &Mem{
|
||||||
Swap : &Info{ Free : int64(swap.free)},
|
Ram : uint64(mem.ram),
|
||||||
|
Total : uint64(mem.total),
|
||||||
|
Used : uint64(mem.used),
|
||||||
|
Free : uint64(mem.free),
|
||||||
|
ActualUsed : uint64(mem.actual_used),
|
||||||
|
ActualFree : uint64(mem.actual_free),
|
||||||
|
UsedPerecent : float64(mem.used_percent),
|
||||||
|
FreePerecent : float64(mem.free_percent),
|
||||||
|
},
|
||||||
|
Swap : &Swap{
|
||||||
|
Total : uint64(swap.total),
|
||||||
|
Used : uint64(swap.used),
|
||||||
|
Free : uint64(swap.free),
|
||||||
|
PageIn : uint64(swap.page_in),
|
||||||
|
PageOut : uint64(swap.page_out),
|
||||||
|
},
|
||||||
},nil
|
},nil
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,47 +2,168 @@ package gotoc
|
||||||
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
"github.com/vmware/leap/util"
|
||||||
|
|
||||||
)
|
)
|
||||||
/*
|
/*
|
||||||
|
|
||||||
#include "../../../../../Include/sigar.h"
|
#include "../../../../../Include/sigar.h"
|
||||||
#include<stdlib.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
typedef unsigned char byte;
|
typedef unsigned char byte;
|
||||||
void translateNetConfig(sigar_t *sigar){
|
void translateNetConfig(sigar_t *sigar){
|
||||||
|
|
||||||
|
sigar_net_interface_list_t net_iflist;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
sigar_net_interface_config_t config;
|
sigar_net_interface_list_get(sigar, &net_iflist);
|
||||||
|
printf("number: %lu\n", net_iflist.number) ;
|
||||||
|
for (i = 0; i < net_iflist.number; i++) {
|
||||||
|
char *ifname = net_iflist.data[i];
|
||||||
|
sigar_net_interface_stat_t ifstat;
|
||||||
sigar_net_interface_config_get(sigar, "eth10", &config);
|
sigar_net_interface_config_t config;
|
||||||
sigar_uint32_t a=config.address.addr.in;
|
|
||||||
|
int ret=sigar_net_interface_config_get(sigar, ifname, &(config));
|
||||||
|
if(ret!=SIGAR_OK){
|
||||||
char buf[180];
|
printf("error number: %d\n",ret);
|
||||||
unsigned char* ucp = (unsigned char *)&a;
|
return;
|
||||||
sprintf(buf, "%d.%d.%d.%d", ucp[0] & 0xff, ucp[1] & 0xff, ucp[2] & 0xff, ucp[3] & 0xff);
|
}
|
||||||
printf("%s\n",buf);
|
sigar_uint32_t a=config.address.addr.in;
|
||||||
|
char buf[180];
|
||||||
|
unsigned char* ucp = (unsigned char *)&a;
|
||||||
|
sprintf(buf, "%d.%d.%d.%d", ucp[0] & 0xff, ucp[1] & 0xff, ucp[2] & 0xff, ucp[3] & 0xff);
|
||||||
|
printf("%s: %s\n",ifname, buf);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
sigar_net_interface_config_t netconfPrimary;
|
||||||
|
sigar_net_interface_config_primary_get(sigar, &netconfPrimary);
|
||||||
|
sigar_uint32_t a=netconfPrimary.address.addr.in;
|
||||||
|
|
||||||
|
char buf[18];
|
||||||
|
unsigned char* ucp = (unsigned char *)&a;
|
||||||
|
sprintf(buf, "%d.%d.%d.%d", ucp[0] & 0xff, ucp[1] & 0xff, ucp[2] & 0xff, ucp[3] & 0xff);
|
||||||
|
printf("%s\n",buf);
|
||||||
|
|
||||||
|
sigar_net_interface_list_destroy(sigar, &net_iflist);
|
||||||
|
|
||||||
|
|
||||||
|
//char *name=netinfo->name;
|
||||||
|
//char *type=netinfo->type;
|
||||||
|
|
||||||
|
//sigar_uint32_t a=netinfo->address.addr.in;
|
||||||
|
//printf("%s broadcast:\n", netinfo->address.addr.mac[0]);
|
||||||
|
//printf("%d.%d.%d.%d", (byte)a>>24 & 0xFF, (byte)a>>16 & 0xFF, (byte)a>>8& 0xFF, (byte)a& 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
|
type NetConfig struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
type NetAddress struct{
|
||||||
|
Family string
|
||||||
|
In uint32
|
||||||
|
In6 uint32
|
||||||
|
Mac string
|
||||||
|
}
|
||||||
|
func (this *NetAddress) String() string { return fmt.Sprintf("{ Family: %v, In: %v, in6: %v, Mac: %v }", this.Family, this.In, this.In6, this.Mac) }
|
||||||
|
|
||||||
|
type InterfaceConfigInfo struct {
|
||||||
|
Name string
|
||||||
|
Type string
|
||||||
|
Description string
|
||||||
|
Hwaddr *NetAddress
|
||||||
|
Address *NetAddress
|
||||||
|
Destination *NetAddress
|
||||||
|
Broadcast *NetAddress
|
||||||
|
Netmask *NetAddress
|
||||||
|
Address6 *NetAddress
|
||||||
|
Prefix6Length int
|
||||||
|
Scope6 int
|
||||||
|
Flags uint64
|
||||||
|
Mtu uint64
|
||||||
|
Metric uint64
|
||||||
|
TxQueueLen int
|
||||||
|
}
|
||||||
|
func (this *InterfaceConfigInfo) String() string {
|
||||||
|
return fmt.Sprintf(`Name: %v, Type: %v, Description: %v, Hwaddr: %v, Address: %v, Destination: %v, Broadcast: %v, Netmask: %v, Address6: %v, Prefix6Length: %v, Scope6: %v, Flags: %v, Mtu: %v, Metric: %v, TxQueueLen: %v`,
|
||||||
|
this.Name,
|
||||||
|
this.Type,
|
||||||
|
this.Description,
|
||||||
|
this.Hwaddr,
|
||||||
|
this.Address,
|
||||||
|
this.Destination,
|
||||||
|
this.Broadcast,
|
||||||
|
this.Netmask,
|
||||||
|
this.Address6,
|
||||||
|
this.Prefix6Length,
|
||||||
|
this.Scope6,
|
||||||
|
this.Flags,
|
||||||
|
this.Mtu,
|
||||||
|
this.Metric,
|
||||||
|
this.TxQueueLen,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
type NetIfaceUsageInfo struct {
|
||||||
|
RxPackets uint64
|
||||||
|
RxBytes uint64
|
||||||
|
RxErrors uint64
|
||||||
|
RxDropped uint64
|
||||||
|
RxOverruns uint64
|
||||||
|
RxFrame uint64
|
||||||
|
/* transmitted */
|
||||||
|
TxPackets uint64
|
||||||
|
TxBytes uint64
|
||||||
|
TxErrors uint64
|
||||||
|
TxDropped uint64
|
||||||
|
TxOverruns uint64
|
||||||
|
TxCollisions uint64
|
||||||
|
TxCarrier uint64
|
||||||
|
Speed uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
//Top-Level Top-Level Top-Level Top-Level Top-Level Top-Level Top-Level Top-Level Top-Level
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
func GetNetInterfaceConfig() (result []*InterfaceConfigInfo, err error) {
|
||||||
|
return getNetInterfaceConfigWithSigar(GetSigarHandle()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetNetIfaceUsageInfo(netIfaceName string) (netifaceInfo *NetIfaceUsageInfo, err error) {
|
||||||
|
defer util.Panic2Error(&err)
|
||||||
|
|
||||||
|
c_netifaceName := C.CString(netIfaceName)
|
||||||
|
defer Free(c_netifaceName)
|
||||||
|
|
||||||
|
var c_sigar_net_interface_stat_t C.sigar_net_interface_stat_t
|
||||||
|
if status := int(C.sigar_net_interface_stat_get(GetSigarHandle(), c_netifaceName, &c_sigar_net_interface_stat_t)) ; status != SIGAR_OK {
|
||||||
|
return nil,fmt.Errorf("Failed to rertieve network interface status for: %v with error: %v", netIfaceName, status)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &NetIfaceUsageInfo{
|
||||||
|
RxPackets: uint64(c_sigar_net_interface_stat_t.rx_packets),
|
||||||
|
RxBytes: uint64(c_sigar_net_interface_stat_t.rx_bytes),
|
||||||
|
RxErrors: uint64(c_sigar_net_interface_stat_t.rx_errors),
|
||||||
|
RxDropped: uint64(c_sigar_net_interface_stat_t.rx_dropped),
|
||||||
|
RxOverruns: uint64(c_sigar_net_interface_stat_t.rx_overruns),
|
||||||
|
RxFrame: uint64(c_sigar_net_interface_stat_t.rx_frame),
|
||||||
|
TxPackets: uint64(c_sigar_net_interface_stat_t.tx_packets),
|
||||||
|
TxBytes: uint64(c_sigar_net_interface_stat_t.tx_bytes),
|
||||||
|
TxErrors: uint64(c_sigar_net_interface_stat_t.tx_errors),
|
||||||
|
TxDropped: uint64(c_sigar_net_interface_stat_t.tx_dropped),
|
||||||
|
TxOverruns: uint64(c_sigar_net_interface_stat_t.tx_overruns),
|
||||||
|
TxCollisions: uint64(c_sigar_net_interface_stat_t.tx_collisions),
|
||||||
|
TxCarrier: uint64(c_sigar_net_interface_stat_t.tx_carrier),
|
||||||
|
Speed: uint64(c_sigar_net_interface_stat_t.speed),
|
||||||
|
},nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func GetNetConfig()(C.sigar_net_interface_config_t,[]C.sigar_net_interface_config_t,[]C.sigar_net_interface_stat_t){
|
func GetNetConfig()(C.sigar_net_interface_config_t,[]C.sigar_net_interface_config_t,[]C.sigar_net_interface_stat_t){
|
||||||
|
|
||||||
|
@ -78,30 +199,103 @@ func GetNetConfig()(C.sigar_net_interface_config_t,[]C.sigar_net_interface_confi
|
||||||
return netconfPrimary, netconf, netstat
|
return netconfPrimary, netconf, netstat
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetNetInterfaceConfig(){
|
//----------------------------------------------------------------------------------------
|
||||||
|
//Helpers Helpers Helpers Helpers Helpers Helpers Helpers Helpers Helpers Helpers Helpers
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
//_,netconf,_:=GetNetConfig()
|
|
||||||
|
func getNetInterfaceConfigWithSigar(sigar *C.sigar_t) (result []*InterfaceConfigInfo) {
|
||||||
|
|
||||||
var sigar *C.sigar_t=GetSigarHandle()
|
|
||||||
C.translateNetConfig(sigar)
|
|
||||||
|
|
||||||
|
goInterfacesNames, length, closeable := getNetInterfaceNamesWithSigar(sigar)
|
||||||
|
defer closeable(sigar)
|
||||||
|
result = make([]*InterfaceConfigInfo, length)
|
||||||
|
|
||||||
|
var sigarNetInterfaceConfig C.sigar_net_interface_config_t
|
||||||
|
for i:=0;i<length;i++{
|
||||||
|
|
||||||
|
// fmt.Println("interface name: ", &goInterfacesNames[i])
|
||||||
|
C.sigar_net_interface_config_get(sigar, goInterfacesNames[i], &sigarNetInterfaceConfig)
|
||||||
|
|
||||||
|
result[i] = &InterfaceConfigInfo{
|
||||||
|
Name : C.GoString(&sigarNetInterfaceConfig.name[0]),
|
||||||
|
Type : C.GoString(&sigarNetInterfaceConfig._type[0]),
|
||||||
|
Description: C.GoString(&sigarNetInterfaceConfig.description[0]),
|
||||||
|
Hwaddr : GetNetAddress(sigar, sigarNetInterfaceConfig.hwaddr),
|
||||||
|
Address : GetNetAddress(sigar, sigarNetInterfaceConfig.address),
|
||||||
|
Destination : GetNetAddress(sigar, sigarNetInterfaceConfig.destination),
|
||||||
|
Broadcast : GetNetAddress(sigar, sigarNetInterfaceConfig.broadcast),
|
||||||
|
Netmask : GetNetAddress(sigar, sigarNetInterfaceConfig.netmask),
|
||||||
|
Address6 : GetNetAddress(sigar, sigarNetInterfaceConfig.address6),
|
||||||
|
Prefix6Length : int(sigarNetInterfaceConfig.prefix6_length),
|
||||||
|
Scope6 : int(sigarNetInterfaceConfig.scope6),
|
||||||
|
Flags : uint64(sigarNetInterfaceConfig.flags),
|
||||||
|
Mtu : uint64(sigarNetInterfaceConfig.mtu),
|
||||||
|
Metric : uint64(sigarNetInterfaceConfig.metric),
|
||||||
|
TxQueueLen : int(sigarNetInterfaceConfig.tx_queue_len),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
type NetworkService struct {
|
type byteSliceReader struct {
|
||||||
name string
|
remain []byte
|
||||||
RawIdentifier string
|
}
|
||||||
Id string
|
func (br *byteSliceReader) Read(p []byte) (int, error) {
|
||||||
Broadcast string
|
n := copy(p, br.remain)
|
||||||
Address string
|
br.remain = br.remain[n:]
|
||||||
NetMask string
|
return n, nil
|
||||||
Flags string
|
}
|
||||||
Mtu string
|
|
||||||
Mac string
|
func GetNetAddress(sigar *C.sigar_t, sigarNetAddress C.sigar_net_address_t) (result *NetAddress) {
|
||||||
|
|
||||||
|
//addstr := C.addr2string(sigar, &sigarNetAddress)
|
||||||
|
//fmt.Println("%v", C.GoString(&addstr[0]))
|
||||||
|
return &NetAddress{}
|
||||||
|
/*var addrStr *[46]*C.char
|
||||||
|
C.sigar_net_address_to_string(sigar, sigarNetAddress, &addrStr[0])
|
||||||
|
fmt.Println(C.GoString(&addrStr[0]))
|
||||||
|
|
||||||
|
result = &NetAddress{}
|
||||||
|
|
||||||
|
//Family : C.GoString(&sigarNetAddress[0]),
|
||||||
|
//addrPointer := (*int32)(unsafe.Pointer(&sigarNetAddress.addr[0]))
|
||||||
|
bsr := &byteSliceReader { sigarNetAddress.addr[:] }
|
||||||
|
var r io.Reader = bsr
|
||||||
|
var in, in6 C.uint
|
||||||
|
binary.Read(r, binary.BigEndian, &in)
|
||||||
|
//fmt.Println("remaining ", len(bsr.remain))
|
||||||
|
binary.Read(r, binary.BigEndian, &in6)
|
||||||
|
//fmt.Println("remaining ", len(bsr.remain))
|
||||||
|
|
||||||
|
result.In = uint32(in)
|
||||||
|
result.In6 = uint32(in6)
|
||||||
|
|
||||||
|
//mac := (*[]*C.uchar)(unsafe.Pointer(&bsr.remain[0]))
|
||||||
|
for i:=0; i < len(bsr.remain) ; i++ {
|
||||||
|
result.Mac = fmt.Sprintf("%v%v", result.Mac, rune(C.char(bsr.remain[i])))
|
||||||
|
}
|
||||||
|
//result.Mac = string(mac)
|
||||||
|
|
||||||
|
return result
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
func getNetInterfaceNamesWithSigar(sigar *C.sigar_t) (goInterfacesNames ([]*C.char), length int, closeable func(sigar *C.sigar_t)) {
|
||||||
|
var netlistconf C.sigar_net_interface_list_t
|
||||||
|
|
||||||
|
C.sigar_net_interface_list_get(sigar, &netlistconf)
|
||||||
|
|
||||||
|
length =int(netlistconf.number)
|
||||||
|
|
||||||
|
cinteraces := GetGoSlice(length, unsafe.Pointer(netlistconf.data))
|
||||||
|
goInterfacesNames = *((*[]*C.char)(unsafe.Pointer(&cinteraces)))
|
||||||
|
|
||||||
|
//goInterfacesNames = ((*[1 << 30]*C.char)(unsafe.Pointer(netlistconf.data)))[:length]
|
||||||
|
|
||||||
|
return goInterfacesNames,
|
||||||
|
length,
|
||||||
|
func(sigar *C.sigar_t) {
|
||||||
|
C.sigar_net_interface_list_destroy(sigar, &netlistconf)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,27 +2,54 @@ package gotoc
|
||||||
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/vmware/leap/util"
|
||||||
|
|
||||||
)
|
)
|
||||||
/*
|
/*
|
||||||
|
|
||||||
#include "../../../../../Include/sigar.h"
|
#include "../../../../../Include/sigar.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
func NetInfo() C.sigar_net_info_t{
|
type NetInfo struct {
|
||||||
|
DefaultGateway string
|
||||||
|
DefaultGatewayInterface string
|
||||||
|
HostName string
|
||||||
|
DomainName string
|
||||||
|
PrimaryDns string
|
||||||
|
SecondaryDns string
|
||||||
|
Fqdn string
|
||||||
|
}
|
||||||
|
func (this *NetInfo) String() string { return "{ DefaultGateway:" + this.DefaultGateway + ", " +
|
||||||
|
"DefaultGatewayInterface: " + this.DefaultGatewayInterface + ", " +
|
||||||
|
"HostName: " + this.HostName + ", " +
|
||||||
|
"DomainName: " + this.DomainName + ", " +
|
||||||
|
"PrimaryDns: " + this.PrimaryDns + ", " +
|
||||||
|
"SecondaryDns: " + this.SecondaryDns + ", " +
|
||||||
|
"Fqdn: " + this.Fqdn + "}"
|
||||||
|
}
|
||||||
|
|
||||||
var sigar *C.sigar_t=GetSigarHandle()
|
func GetNetInfo() (netInfo *NetInfo, err error){
|
||||||
var netInfo C.sigar_net_info_t
|
defer util.Panic2Error(&err)
|
||||||
C.sigar_net_info_get(sigar, &netInfo)
|
|
||||||
|
|
||||||
|
sigar := GetSigarHandle()
|
||||||
|
var c_netInfo C.sigar_net_info_t
|
||||||
|
C.sigar_net_info_get(sigar, &c_netInfo)
|
||||||
|
|
||||||
|
//[512]
|
||||||
return netInfo
|
var c_fqdn [C.SIGAR_FQDN_LEN]C.char
|
||||||
|
if status := C.sigar_fqdn_get(sigar, &c_fqdn[0], C.SIGAR_FQDN_LEN) ; status != SIGAR_OK {
|
||||||
|
return nil,fmt.Errorf("Failed to retrieve fqdn due to " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return &NetInfo{
|
||||||
|
DefaultGateway: C.GoString(&c_netInfo.default_gateway[0]),
|
||||||
|
DefaultGatewayInterface: C.GoString(&c_netInfo.default_gateway_interface[0]),
|
||||||
|
HostName: C.GoString(&c_netInfo.host_name[0]),
|
||||||
|
DomainName: C.GoString(&c_netInfo.domain_name[0]),
|
||||||
|
PrimaryDns: C.GoString(&c_netInfo.primary_dns[0]),
|
||||||
|
SecondaryDns: C.GoString(&c_netInfo.secondary_dns[0]),
|
||||||
|
Fqdn : C.GoString(&c_fqdn[0]),
|
||||||
|
},nil
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
package gotoc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/vmware/leap/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include "../../../../../Include/sigar.h"
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
|
||||||
|
type ProcStatInfo struct {
|
||||||
|
Total uint64
|
||||||
|
Sleeping uint64
|
||||||
|
Running uint64
|
||||||
|
Zombie uint64
|
||||||
|
Stopped uint64
|
||||||
|
Idle uint64
|
||||||
|
Threads uint64
|
||||||
|
}
|
||||||
|
func (this *ProcStatInfo) String() string {
|
||||||
|
return fmt.Sprintf("{Threads=%v, Sleeping=%v, Stopped=%v, Zombie=%v, Idle=%v, Total=%v, Running=%v}",
|
||||||
|
this.Threads,
|
||||||
|
this.Sleeping,
|
||||||
|
this.Stopped,
|
||||||
|
this.Zombie,
|
||||||
|
this.Idle,
|
||||||
|
this.Total,
|
||||||
|
this.Running,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetProcStatInfo() (procStatInfo *ProcStatInfo, err error) {
|
||||||
|
defer util.Panic2Error(&err)
|
||||||
|
var c_procStat C.sigar_proc_stat_t
|
||||||
|
|
||||||
|
sigar := GetSigarHandle()
|
||||||
|
if status := int(C.sigar_proc_stat_get(sigar, &c_procStat)) ; status != SIGAR_OK {
|
||||||
|
return nil,fmt.Errorf("Failed to retrieve system proc stat info with error: %v", status)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &ProcStatInfo{
|
||||||
|
Total : uint64(c_procStat.total),
|
||||||
|
Sleeping : uint64(c_procStat.sleeping),
|
||||||
|
Running : uint64(c_procStat.running),
|
||||||
|
Zombie : uint64(c_procStat.zombie),
|
||||||
|
Stopped : uint64(c_procStat.stopped),
|
||||||
|
Idle : uint64(c_procStat.idle),
|
||||||
|
Threads : uint64(c_procStat.threads),
|
||||||
|
},nil
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -2,19 +2,14 @@ package gotoc
|
||||||
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
||||||
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"github.com/vmware/leap/util"
|
||||||
|
log "github.com/jbrodriguez/mlog"
|
||||||
)
|
)
|
||||||
/*
|
/*
|
||||||
|
|
||||||
#include "../../../../../Include/sigar.h"
|
#include "../../../../../Include/sigar.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
|
@ -100,8 +95,314 @@ func Ps() ([]C.sigar_proc_state_t ,
|
||||||
pfd,
|
pfd,
|
||||||
pexe
|
pexe
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
//-------------------------------------------------------------------------------
|
||||||
|
//ProcessInfoList ProcessInfoList ProcessInfoList ProcessInfoList ProcessInfoList
|
||||||
|
//-------------------------------------------------------------------------------
|
||||||
|
func GetProcInfo(pid uint64, infoTypesMask ProcInfoType) (procInfo *ProcessInfo, err error) {
|
||||||
|
procInfo,_,err = _getProcInfo(pid, infoTypesMask, nil, GetSigarHandle())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetAllProcInfos(infoTypesMask ProcInfoType) (processes *ProcessInfoList, err error) {
|
||||||
|
|
||||||
|
var procList C.sigar_proc_list_t
|
||||||
|
defer util.Panic2Error(&err)
|
||||||
|
defer C.sigar_proc_list_destroy(sigar, &procList)
|
||||||
|
|
||||||
|
sigar:=GetSigarHandle()
|
||||||
|
|
||||||
|
C.sigar_proc_list_get(sigar, &procList)
|
||||||
|
|
||||||
|
return getProcInfos(&procList, infoTypesMask, sigar)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getProcInfos(procList *C.sigar_proc_list_t, infoTypesMask ProcInfoType, sigar *C.sigar_t) (processes *ProcessInfoList, err error) {
|
||||||
|
defer util.Panic2Error(&err)
|
||||||
|
|
||||||
|
noOfProcesses := int(procList.number)
|
||||||
|
pids := *(*[]C.sigar_pid_t) (CArr2SlicePtr(noOfProcesses, procList.data))
|
||||||
|
|
||||||
|
procInfos := make([]*ProcessInfo, noOfProcesses)
|
||||||
|
var errors, index int
|
||||||
|
var sysMemInfoOut *MemInfo
|
||||||
|
for _,pid := range pids {
|
||||||
|
|
||||||
|
procInfo,sysMemInfo, err := _getProcInfo(uint64(pid), infoTypesMask, sysMemInfoOut, sigar)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.ErrorS(err.Error())
|
||||||
|
errors = errors+1
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if sysMemInfoOut == nil {
|
||||||
|
sysMemInfoOut = sysMemInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
procInfos[index] = procInfo
|
||||||
|
index = index+1
|
||||||
|
}
|
||||||
|
|
||||||
|
if errors > 0 {
|
||||||
|
newSize := noOfProcesses-errors
|
||||||
|
procInfos = append(([]*ProcessInfo)(nil), procInfos[:newSize]...)
|
||||||
|
log.ErrorS("%v errors have occurred, prunning array size from %v to %v index is: %v, newSize: %v", errors, noOfProcesses, newSize, index, len(procInfos))
|
||||||
|
}
|
||||||
|
|
||||||
|
return &ProcessInfoList { procInfos, sysMemInfoOut },nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//ProcInfo ProcInfo ProcInfo ProcInfo ProcInfo ProcInfo ProcInfo ProcInfo
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type ProcInfoType uint64
|
||||||
|
const (
|
||||||
|
MEM ProcInfoType = 1 << iota
|
||||||
|
CPU
|
||||||
|
TIME
|
||||||
|
DISK
|
||||||
|
ARGS
|
||||||
|
STATE
|
||||||
|
CRED_NAME
|
||||||
|
)
|
||||||
|
|
||||||
|
type ProcessInfoList struct {
|
||||||
|
Processes []*ProcessInfo
|
||||||
|
SysMemInfo *MemInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type ProcessInfo struct {
|
||||||
|
Pid uint64
|
||||||
|
Args []string
|
||||||
|
State *ProcessStateInfo
|
||||||
|
CredName *ProcessCredName
|
||||||
|
Mem *ProcessMemInfo
|
||||||
|
Cpu *ProcessCpuInfo
|
||||||
|
Disk *ProcessDiskInfo
|
||||||
|
Error error
|
||||||
|
}
|
||||||
|
|
||||||
|
type ProcessCredName struct {
|
||||||
|
User string
|
||||||
|
Group string
|
||||||
|
}
|
||||||
|
|
||||||
|
type ProcessStateInfo struct {
|
||||||
|
Name string
|
||||||
|
State rune
|
||||||
|
Tty int
|
||||||
|
Priority int
|
||||||
|
Nice int
|
||||||
|
Processor int
|
||||||
|
Threads uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
type ProcessMemInfo struct {
|
||||||
|
Size uint64
|
||||||
|
Resident uint64
|
||||||
|
Share uint64
|
||||||
|
MinorFaults uint64
|
||||||
|
MajorFaults uint64
|
||||||
|
PageFaults uint64
|
||||||
|
Percent float64
|
||||||
|
}
|
||||||
|
|
||||||
|
type ProcessCpuInfo struct {
|
||||||
|
StartTime uint64
|
||||||
|
User uint64
|
||||||
|
Sys uint64
|
||||||
|
Total uint64
|
||||||
|
LastTime uint64
|
||||||
|
Percent float64
|
||||||
|
}
|
||||||
|
|
||||||
|
type ProcessDiskInfo struct{ //sigar_proc_cumulative_disk_io_t
|
||||||
|
BytesRead uint64
|
||||||
|
BytesWritten uint64
|
||||||
|
BytesTotal uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func _getProcInfo(pid uint64, infoTypesMask ProcInfoType, sysMemInfoIn *MemInfo, sigar *C.sigar_t) (procInfo *ProcessInfo, sysMemInfo *MemInfo, err error) {
|
||||||
|
|
||||||
|
procInfo = &ProcessInfo{ Pid : pid }
|
||||||
|
|
||||||
|
sigarPid := C.sigar_pid_t(pid)
|
||||||
|
|
||||||
|
if infoTypesMask&MEM != 0 {
|
||||||
|
sysMemInfo = sysMemInfoIn
|
||||||
|
if sysMemInfo == nil {
|
||||||
|
sysMemInfo,err = GetMemInfo()
|
||||||
|
if err != nil {
|
||||||
|
return nil,nil,err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err = _populateProcessMemInfo(sigarPid, procInfo, sysMemInfo, sigar) ; err != nil {
|
||||||
|
return nil,nil,err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if infoTypesMask&CPU != 0 {
|
||||||
|
if err = _populateProcessCpuInfo(sigarPid, procInfo, sigar) ; err != nil {
|
||||||
|
return nil,nil,err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if infoTypesMask&TIME != 0 {
|
||||||
|
}
|
||||||
|
|
||||||
|
if infoTypesMask&DISK != 0 {
|
||||||
|
if err = _populateProcessDiskInfo(sigarPid, procInfo, sigar) ; err != nil {
|
||||||
|
return nil,nil,err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if infoTypesMask&ARGS != 0 {
|
||||||
|
if err = _populateProcessArgs(sigarPid, procInfo, sigar) ; err != nil {
|
||||||
|
return nil,nil,err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if infoTypesMask&STATE != 0 {
|
||||||
|
if err = _populateProcessState(sigarPid, procInfo, sigar) ; err != nil {
|
||||||
|
return nil,nil,err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if infoTypesMask&CRED_NAME != 0 {
|
||||||
|
if err = _populateProcessCredName(sigarPid, procInfo, sigar) ; err != nil {
|
||||||
|
return nil,nil,err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return procInfo,sysMemInfo,nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func _populateProcessMemInfo(pid C.sigar_pid_t, procInfo *ProcessInfo, sysMemInfo *MemInfo, sigar *C.sigar_t) error {
|
||||||
|
|
||||||
|
var procMem C.sigar_proc_mem_t
|
||||||
|
status := int(C.sigar_proc_mem_get(sigar, pid, &procMem))
|
||||||
|
if status != SIGAR_OK {
|
||||||
|
return fmt.Errorf("Failed to rertieve proc mem info for pid: "+ strconv.FormatUint(procInfo.Pid,10) +" with error: " + strconv.Itoa(status))
|
||||||
|
}
|
||||||
|
|
||||||
|
procInfo.Mem = &ProcessMemInfo{
|
||||||
|
Size : uint64(procMem.size),
|
||||||
|
Resident : uint64(procMem.resident),
|
||||||
|
Share : uint64(procMem.share),
|
||||||
|
MinorFaults : uint64(procMem.minor_faults),
|
||||||
|
MajorFaults : uint64(procMem.major_faults),
|
||||||
|
PageFaults : uint64(procMem.page_faults),
|
||||||
|
}
|
||||||
|
|
||||||
|
procInfo.Mem.Percent = float64(sysMemInfo.Mem.Total/procInfo.Mem.Resident)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func _populateProcessCpuInfo(pid C.sigar_pid_t, procInfo *ProcessInfo, sigar *C.sigar_t) error {
|
||||||
|
|
||||||
|
var procCpu C.sigar_proc_cpu_t
|
||||||
|
status := int(C.sigar_proc_cpu_get(sigar, pid, &procCpu))
|
||||||
|
if status != SIGAR_OK {
|
||||||
|
return fmt.Errorf("Failed to rertieve proc mem info for pid: %v", procInfo.Pid)
|
||||||
|
}
|
||||||
|
|
||||||
|
procInfo.Cpu = &ProcessCpuInfo{
|
||||||
|
StartTime : uint64(procCpu.start_time),
|
||||||
|
User : uint64(procCpu.user),
|
||||||
|
Sys : uint64(procCpu.sys),
|
||||||
|
Total : uint64(procCpu.total),
|
||||||
|
LastTime : uint64(procCpu.last_time),
|
||||||
|
Percent : float64(procCpu.percent),
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func _populateProcessDiskInfo(pid C.sigar_pid_t, procInfo *ProcessInfo, sigar *C.sigar_t) error {
|
||||||
|
|
||||||
|
var c_procDiskIo C.sigar_proc_disk_io_t
|
||||||
|
status := int(C.sigar_proc_disk_io_get(sigar, pid, &c_procDiskIo))
|
||||||
|
if status != SIGAR_OK {
|
||||||
|
//TODO: restore error (unsupported on mac)
|
||||||
|
//return fmt.Errorf("Failed to rertieve proc disk io info for pid: %v with error: %v", procInfo.Pid, status)
|
||||||
|
procInfo.Disk = &ProcessDiskInfo{
|
||||||
|
BytesRead : 100000,
|
||||||
|
BytesWritten : 23423432,
|
||||||
|
BytesTotal : 2345543,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
procInfo.Disk = &ProcessDiskInfo{
|
||||||
|
BytesRead : uint64(c_procDiskIo.bytes_read),
|
||||||
|
BytesWritten : uint64(c_procDiskIo.bytes_written),
|
||||||
|
BytesTotal : uint64(c_procDiskIo.bytes_total),
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func _populateProcessArgs(pid C.sigar_pid_t, procInfo *ProcessInfo, sigar *C.sigar_t) error {
|
||||||
|
|
||||||
|
var c_procArgs C.sigar_proc_args_t
|
||||||
|
defer C.sigar_proc_args_destroy(sigar, &c_procArgs)
|
||||||
|
|
||||||
|
status := int(C.sigar_proc_args_get(sigar, pid, &c_procArgs))
|
||||||
|
if status != SIGAR_OK {
|
||||||
|
return fmt.Errorf("error: proc args for pid: " + strconv.FormatUint(procInfo.Pid ,10))
|
||||||
|
}
|
||||||
|
|
||||||
|
noOfArgs := int(c_procArgs.number)
|
||||||
|
args := *(*[]*C.char) (CArr2SlicePtr(noOfArgs, c_procArgs.data))
|
||||||
|
|
||||||
|
procInfo.Args = make([]string, noOfArgs)
|
||||||
|
for i,arg := range args {
|
||||||
|
procInfo.Args[i] = C.GoString(arg)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func _populateProcessState(pid C.sigar_pid_t, procInfo *ProcessInfo, sigar *C.sigar_t) error {
|
||||||
|
|
||||||
|
var c_procState C.sigar_proc_state_t
|
||||||
|
status := int(C.sigar_proc_state_get(sigar, pid, &c_procState))
|
||||||
|
if status != SIGAR_OK {
|
||||||
|
return fmt.Errorf("Failed to rertieve proc state info for pid: %v", procInfo.Pid)
|
||||||
|
}
|
||||||
|
|
||||||
|
procInfo.State = &ProcessStateInfo{
|
||||||
|
Name : C.GoString(&c_procState.name[0]),
|
||||||
|
State: rune(c_procState.state),
|
||||||
|
Tty : int(c_procState.tty),
|
||||||
|
Priority : int(c_procState.priority),
|
||||||
|
Nice : int(c_procState.nice),
|
||||||
|
Processor : int(c_procState.processor),
|
||||||
|
Threads : uint64(c_procState.threads),
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var c_credName C.sigar_proc_cred_name_t
|
||||||
|
func _populateProcessCredName(pid C.sigar_pid_t, procInfo *ProcessInfo, sigar *C.sigar_t) error {
|
||||||
|
|
||||||
|
status := int(C.sigar_proc_cred_name_get(sigar, pid, &c_credName))
|
||||||
|
if status != SIGAR_OK {
|
||||||
|
return fmt.Errorf("Failed to rertieve proc cred name for pid: %v", procInfo.Pid)
|
||||||
|
}
|
||||||
|
|
||||||
|
procInfo.CredName = &ProcessCredName{
|
||||||
|
User : C.GoString(&c_credName.user[0]),
|
||||||
|
Group : C.GoString(&c_credName.group[0]),
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
package gotoc
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include "../../../../../Include/sigar.h"
|
||||||
|
#include "../../../../../Include/sigar_ptql.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/vmware/leap/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func ExecutePtql(ptql string, infoTypesMask ProcInfoType) (result []*ProcessInfo, err error){
|
||||||
|
defer util.Panic2Error(&err)
|
||||||
|
|
||||||
|
var query *C.sigar_ptql_query_t
|
||||||
|
var queryError *C.sigar_ptql_error_t
|
||||||
|
var proclist C.sigar_proc_list_t
|
||||||
|
|
||||||
|
sigar := GetSigarHandle()
|
||||||
|
ptqlC := C.CString(ptql)
|
||||||
|
//defer C.sigar_ptql_query_destroy(query)
|
||||||
|
defer C.sigar_proc_list_destroy(sigar, &proclist)
|
||||||
|
defer C.sigar_ptql_re_impl_set(sigar, nil, nil)
|
||||||
|
defer Free(ptqlC)
|
||||||
|
|
||||||
|
if status := C.sigar_ptql_query_create(&query, ptqlC, queryError) ; status != SIGAR_OK {
|
||||||
|
err = fmt.Errorf("Failed to create sigar ptql query for: %v with errorcode: %v", ptql, status)
|
||||||
|
return nil,err
|
||||||
|
}
|
||||||
|
|
||||||
|
C.sigar_ptql_query_find(sigar, query, &proclist)
|
||||||
|
C.sigar_ptql_query_destroy(query)
|
||||||
|
|
||||||
|
/*
|
||||||
|
noOfProcesses := int(proclist.number)
|
||||||
|
result = make([]*ProcessInfo, noOfProcesses)
|
||||||
|
pids := *(*[]C.sigar_pid_t) (CArr2SlicePtr(noOfProcesses, proclist.data))
|
||||||
|
for i,pid := range pids {
|
||||||
|
procInfo,err := GetProcInfo(uint64(pid), infoTypesMask)
|
||||||
|
if err != nil {
|
||||||
|
return nil,err
|
||||||
|
}
|
||||||
|
result[i] = procInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
return result,nil*/
|
||||||
|
|
||||||
|
processes,err := getProcInfos(&proclist, infoTypesMask, sigar)
|
||||||
|
return processes.Processes,err
|
||||||
|
}
|
||||||
|
|
|
@ -1,25 +1,63 @@
|
||||||
package gotoc
|
package gotoc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
||||||
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
"github.com/vmware/leap/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
#include "../../../../../Include/sigar.h"
|
#include "../../../../../Include/sigar.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#cgo CFLAGS: -I../../../../../Include
|
#cgo CFLAGS: -I../../../../../Include
|
||||||
#cgo LDFLAGS: C:/Users/iuriel/workspace/vmeerkat/leap-project/Include/sigar-amd64-winnt.dll
|
#cgo darwin LDFLAGS: -L ${SRCDIR}/../../../../../Libs/darwin/ -lsigar
|
||||||
|
#cgo linux LDFLAGS: -ldl -L ${SRCDIR}/../../../../../Libs/linux-amd64/ -lsigar
|
||||||
|
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
|
var SYS_INFO *SysInfo
|
||||||
|
|
||||||
func SysInfo() (C.sigar_sys_info_t, []C.sigar_who_t) {
|
func init() {
|
||||||
|
|
||||||
|
var err error
|
||||||
|
if SYS_INFO,err = GetSysInfo() ; err != nil {
|
||||||
|
panic("Failed to extract system info due to " + err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type SysInfo struct {
|
||||||
|
Name string `json:"type"`
|
||||||
|
Version string `json:"version"`
|
||||||
|
Arch string `json:"arch"`
|
||||||
|
Machine string `json:"-"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
PatchLevel string `json:"patchLevel"`
|
||||||
|
Vendor string `json:"vendor"`
|
||||||
|
VendorVersion string `json:"version"`
|
||||||
|
VendorName string `json:"vendorName"`
|
||||||
|
VendorCodeName string `json:"codeName"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetSysInfo() (sysinfo *SysInfo, err error) {
|
||||||
|
defer util.Panic2Error(&err)
|
||||||
|
|
||||||
|
var sigar *C.sigar_t=GetSigarHandle()
|
||||||
|
var c_sysInfo C.sigar_sys_info_t
|
||||||
|
C.sigar_sys_info_get(sigar, &c_sysInfo)
|
||||||
|
|
||||||
|
return &SysInfo{
|
||||||
|
Name : C.GoString(&c_sysInfo.name[0]),
|
||||||
|
Version : C.GoString(&c_sysInfo.version[0]),
|
||||||
|
Arch : C.GoString(&c_sysInfo.arch[0]),
|
||||||
|
Machine : C.GoString(&c_sysInfo.machine[0]),
|
||||||
|
Description : C.GoString(&c_sysInfo.description[0]),
|
||||||
|
PatchLevel : C.GoString(&c_sysInfo.patch_level[0]),
|
||||||
|
Vendor : C.GoString(&c_sysInfo.vendor[0]),
|
||||||
|
VendorName : C.GoString(&c_sysInfo.vendor_name[0]),
|
||||||
|
VendorVersion : C.GoString(&c_sysInfo.vendor_version[0]),
|
||||||
|
VendorCodeName : C.GoString(&c_sysInfo.vendor_code_name[0]),
|
||||||
|
},nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func _GetSysInfo() (C.sigar_sys_info_t, []C.sigar_who_t) {
|
||||||
|
|
||||||
var sigar *C.sigar_t=GetSigarHandle()
|
var sigar *C.sigar_t=GetSigarHandle()
|
||||||
|
|
||||||
|
|
|
@ -1,27 +1,97 @@
|
||||||
package gotoc
|
package gotoc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
"strconv"
|
||||||
|
"github.com/vmware/leap/util"
|
||||||
)
|
)
|
||||||
/*
|
/*
|
||||||
|
|
||||||
#include "../../../../../Include/sigar.h"
|
#include "../../../../../Include/sigar.h"
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
func UpTime()C.sigar_uptime_t{
|
type UptimeInfo struct {
|
||||||
|
Time time.Time
|
||||||
|
Uptime float64
|
||||||
|
LoadAvg []float64
|
||||||
|
}
|
||||||
|
func (this *UptimeInfo) String() string {
|
||||||
|
|
||||||
|
_uptime := this.Time.Format(time.Kitchen) + " up"
|
||||||
|
days := int((this.Uptime / (60 * 60 * 24)))
|
||||||
|
var minutes, hours int
|
||||||
|
|
||||||
|
if days != 0 {
|
||||||
|
_uptime = _uptime + " " + strconv.Itoa(days) + " "
|
||||||
|
if days > 1 {
|
||||||
|
_uptime = _uptime + "days"
|
||||||
|
}else{
|
||||||
|
_uptime = _uptime + "day"
|
||||||
|
}
|
||||||
|
_uptime = _uptime + ", "
|
||||||
|
}
|
||||||
|
|
||||||
|
minutes = int(this.Uptime / 60)
|
||||||
|
hours = int(minutes / 60)
|
||||||
|
hours = hours % 24
|
||||||
|
minutes = minutes % 60
|
||||||
|
|
||||||
|
if hours != 0 {
|
||||||
|
_uptime = _uptime + strconv.Itoa(hours) + ":"
|
||||||
|
if minutes < 10 {
|
||||||
|
_uptime = _uptime + "0"
|
||||||
|
}
|
||||||
|
_uptime = _uptime + strconv.Itoa(minutes);
|
||||||
|
}else{
|
||||||
|
_uptime = _uptime + strconv.Itoa(minutes) + " min";
|
||||||
|
}
|
||||||
|
|
||||||
|
for _,d := range this.LoadAvg {
|
||||||
|
_uptime = _uptime + ", " + strconv.FormatFloat(d, 'f', 2, 64)
|
||||||
|
}
|
||||||
|
|
||||||
|
return _uptime
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func GetUptimeInfo() (result *UptimeInfo, err error) {
|
||||||
|
defer util.Panic2Error(&err)
|
||||||
var sigar *C.sigar_t=GetSigarHandle()
|
var sigar *C.sigar_t=GetSigarHandle()
|
||||||
|
|
||||||
|
uptime, err := _uptime(sigar)
|
||||||
|
if err != nil {
|
||||||
|
return nil,err
|
||||||
|
}
|
||||||
|
|
||||||
|
loadAvg, err := _loadAvg(sigar)
|
||||||
|
if err != nil {
|
||||||
|
return nil,err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &UptimeInfo{ Time: time.Now(), Uptime : uptime, LoadAvg : loadAvg},nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func _uptime(sigar *C.sigar_t) (result float64, err error){
|
||||||
|
|
||||||
var uptime C.sigar_uptime_t
|
var uptime C.sigar_uptime_t
|
||||||
|
|
||||||
C.sigar_uptime_get(sigar, &uptime)
|
if status := int(C.sigar_uptime_get(sigar, &uptime)); status != SIGAR_OK {
|
||||||
|
return -1,fmt.Errorf("Failed to rertieve uptime with error: %v", status)
|
||||||
|
}
|
||||||
return uptime
|
return float64(uptime.uptime),nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func _loadAvg(sigar *C.sigar_t) (result []float64, err error){
|
||||||
|
var c_loadAvg C.sigar_loadavg_t
|
||||||
|
|
||||||
|
if status := int(C.sigar_loadavg_get(sigar, &c_loadAvg)) ; status != SIGAR_OK {
|
||||||
|
return nil,fmt.Errorf("Failed to rertieve load avg with error: %v", status)
|
||||||
|
}
|
||||||
|
|
||||||
|
loadAvg := (([3]C.double)(c_loadAvg.loadavg)) //[:length]
|
||||||
|
|
||||||
|
return []float64{ float64(loadAvg[0]), float64(loadAvg[1]), float64(loadAvg[2]) },nil
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,14 +1,17 @@
|
||||||
package gotoc
|
package gotoc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
//#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
|
const (
|
||||||
|
SIGAR_OK = 0
|
||||||
|
)
|
||||||
|
|
||||||
func SigarStringToGoString(cstring *C.char) string{
|
func SigarStringToGoString(cstring *C.char) string{
|
||||||
|
|
||||||
|
@ -17,4 +20,9 @@ func SigarStringToGoString(cstring *C.char) string{
|
||||||
defer C.free(unsafe.Pointer(cstring))
|
defer C.free(unsafe.Pointer(cstring))
|
||||||
return theString
|
return theString
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Free(cstring *C.char) {
|
||||||
|
C.free(unsafe.Pointer(cstring))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue