Godep: Add raidman riemann client
This commit is contained in:
parent
0823eed546
commit
a8294c2c34
|
@ -22,6 +22,10 @@
|
|||
"Comment": "v0.8.6-7-g9c060de",
|
||||
"Rev": "9c060de643590dae45da9d7c26276463bfc46fa0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/amir/raidman",
|
||||
"Rev": "6a8e089bbe32e6b907feae5ba688841974b3c339"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/armon/go-metrics",
|
||||
"Rev": "b2d95e5291cdbc26997d1301a5e467ecbb240e25"
|
||||
|
@ -164,7 +168,47 @@
|
|||
"Rev": "5bb5cfc093ad18a28148c578f8632cfdb4d802e4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/shirou/gopsutil",
|
||||
"ImportPath": "github.com/shirou/gopsutil/common",
|
||||
"Comment": "1.0.0-173-g1e9aabb",
|
||||
"Rev": "1e9aabb3c8132314662698c9d1c0aef68d9da617"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/shirou/gopsutil/cpu",
|
||||
"Comment": "1.0.0-173-g1e9aabb",
|
||||
"Rev": "1e9aabb3c8132314662698c9d1c0aef68d9da617"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/shirou/gopsutil/disk",
|
||||
"Comment": "1.0.0-173-g1e9aabb",
|
||||
"Rev": "1e9aabb3c8132314662698c9d1c0aef68d9da617"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/shirou/gopsutil/docker",
|
||||
"Comment": "1.0.0-173-g1e9aabb",
|
||||
"Rev": "1e9aabb3c8132314662698c9d1c0aef68d9da617"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/shirou/gopsutil/host",
|
||||
"Comment": "1.0.0-173-g1e9aabb",
|
||||
"Rev": "1e9aabb3c8132314662698c9d1c0aef68d9da617"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/shirou/gopsutil/load",
|
||||
"Comment": "1.0.0-173-g1e9aabb",
|
||||
"Rev": "1e9aabb3c8132314662698c9d1c0aef68d9da617"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/shirou/gopsutil/mem",
|
||||
"Comment": "1.0.0-173-g1e9aabb",
|
||||
"Rev": "1e9aabb3c8132314662698c9d1c0aef68d9da617"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/shirou/gopsutil/net",
|
||||
"Comment": "1.0.0-173-g1e9aabb",
|
||||
"Rev": "1e9aabb3c8132314662698c9d1c0aef68d9da617"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/shirou/gopsutil/process",
|
||||
"Comment": "1.0.0-173-g1e9aabb",
|
||||
"Rev": "1e9aabb3c8132314662698c9d1c0aef68d9da617"
|
||||
},
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
Raidman
|
||||
=======
|
||||
|
||||
Go Riemann client
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/amir/raidman"
|
||||
)
|
||||
|
||||
func main() {
|
||||
c, err := raidman.Dial("tcp", "localhost:5555")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var event = &raidman.Event{
|
||||
State: "success",
|
||||
Host: "raidman",
|
||||
Service: "raidman-sample",
|
||||
Metric: 100,
|
||||
Ttl: 10,
|
||||
}
|
||||
|
||||
// send one event
|
||||
err = c.Send(event)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// send multiple events at once
|
||||
err = c.SendMulti([]*raidman.Event{
|
||||
&raidman.Event{
|
||||
State: "success",
|
||||
Host: "raidman",
|
||||
Service: "raidman-sample",
|
||||
Metric: 100,
|
||||
Ttl: 10,
|
||||
},
|
||||
&raidman.Event{
|
||||
State: "failure",
|
||||
Host: "raidman",
|
||||
Service: "raidman-sample",
|
||||
Metric: 100,
|
||||
Ttl: 10,
|
||||
},
|
||||
&raidman.Event{
|
||||
State: "success",
|
||||
Host: "raidman",
|
||||
Service: "raidman-sample",
|
||||
Metric: 100,
|
||||
Ttl: 10,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
events, err := c.Query("host = \"raidman\"")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if len(events) < 1 {
|
||||
panic("Submitted event not found")
|
||||
}
|
||||
|
||||
c.Close()
|
||||
}
|
||||
|
||||
```
|
|
@ -0,0 +1,24 @@
|
|||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to <http://unlicense.org/>
|
|
@ -0,0 +1,6 @@
|
|||
proto.pb.go: proto.proto
|
||||
mkdir -p _pb
|
||||
protoc --go_out=_pb $<
|
||||
cat _pb/$@\
|
||||
|gofmt >$@
|
||||
rm -rf _pb
|
|
@ -0,0 +1,273 @@
|
|||
// Code generated by protoc-gen-go.
|
||||
// source: proto.proto
|
||||
// DO NOT EDIT!
|
||||
|
||||
package proto
|
||||
|
||||
import proto1 "github.com/golang/protobuf/proto"
|
||||
import json "encoding/json"
|
||||
import math "math"
|
||||
|
||||
// Reference proto, json, and math imports to suppress error if they are not otherwise used.
|
||||
var _ = proto1.Marshal
|
||||
var _ = &json.SyntaxError{}
|
||||
var _ = math.Inf
|
||||
|
||||
type State struct {
|
||||
Time *int64 `protobuf:"varint,1,opt,name=time" json:"time,omitempty"`
|
||||
State *string `protobuf:"bytes,2,opt,name=state" json:"state,omitempty"`
|
||||
Service *string `protobuf:"bytes,3,opt,name=service" json:"service,omitempty"`
|
||||
Host *string `protobuf:"bytes,4,opt,name=host" json:"host,omitempty"`
|
||||
Description *string `protobuf:"bytes,5,opt,name=description" json:"description,omitempty"`
|
||||
Once *bool `protobuf:"varint,6,opt,name=once" json:"once,omitempty"`
|
||||
Tags []string `protobuf:"bytes,7,rep,name=tags" json:"tags,omitempty"`
|
||||
Ttl *float32 `protobuf:"fixed32,8,opt,name=ttl" json:"ttl,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (this *State) Reset() { *this = State{} }
|
||||
func (this *State) String() string { return proto1.CompactTextString(this) }
|
||||
func (*State) ProtoMessage() {}
|
||||
|
||||
func (this *State) GetTime() int64 {
|
||||
if this != nil && this.Time != nil {
|
||||
return *this.Time
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (this *State) GetState() string {
|
||||
if this != nil && this.State != nil {
|
||||
return *this.State
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (this *State) GetService() string {
|
||||
if this != nil && this.Service != nil {
|
||||
return *this.Service
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (this *State) GetHost() string {
|
||||
if this != nil && this.Host != nil {
|
||||
return *this.Host
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (this *State) GetDescription() string {
|
||||
if this != nil && this.Description != nil {
|
||||
return *this.Description
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (this *State) GetOnce() bool {
|
||||
if this != nil && this.Once != nil {
|
||||
return *this.Once
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (this *State) GetTags() []string {
|
||||
if this != nil {
|
||||
return this.Tags
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *State) GetTtl() float32 {
|
||||
if this != nil && this.Ttl != nil {
|
||||
return *this.Ttl
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type Event struct {
|
||||
Time *int64 `protobuf:"varint,1,opt,name=time" json:"time,omitempty"`
|
||||
State *string `protobuf:"bytes,2,opt,name=state" json:"state,omitempty"`
|
||||
Service *string `protobuf:"bytes,3,opt,name=service" json:"service,omitempty"`
|
||||
Host *string `protobuf:"bytes,4,opt,name=host" json:"host,omitempty"`
|
||||
Description *string `protobuf:"bytes,5,opt,name=description" json:"description,omitempty"`
|
||||
Tags []string `protobuf:"bytes,7,rep,name=tags" json:"tags,omitempty"`
|
||||
Ttl *float32 `protobuf:"fixed32,8,opt,name=ttl" json:"ttl,omitempty"`
|
||||
Attributes []*Attribute `protobuf:"bytes,9,rep,name=attributes" json:"attributes,omitempty"`
|
||||
MetricSint64 *int64 `protobuf:"zigzag64,13,opt,name=metric_sint64" json:"metric_sint64,omitempty"`
|
||||
MetricD *float64 `protobuf:"fixed64,14,opt,name=metric_d" json:"metric_d,omitempty"`
|
||||
MetricF *float32 `protobuf:"fixed32,15,opt,name=metric_f" json:"metric_f,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (this *Event) Reset() { *this = Event{} }
|
||||
func (this *Event) String() string { return proto1.CompactTextString(this) }
|
||||
func (*Event) ProtoMessage() {}
|
||||
|
||||
func (this *Event) GetTime() int64 {
|
||||
if this != nil && this.Time != nil {
|
||||
return *this.Time
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (this *Event) GetState() string {
|
||||
if this != nil && this.State != nil {
|
||||
return *this.State
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (this *Event) GetService() string {
|
||||
if this != nil && this.Service != nil {
|
||||
return *this.Service
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (this *Event) GetHost() string {
|
||||
if this != nil && this.Host != nil {
|
||||
return *this.Host
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (this *Event) GetDescription() string {
|
||||
if this != nil && this.Description != nil {
|
||||
return *this.Description
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (this *Event) GetTags() []string {
|
||||
if this != nil {
|
||||
return this.Tags
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *Event) GetTtl() float32 {
|
||||
if this != nil && this.Ttl != nil {
|
||||
return *this.Ttl
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (this *Event) GetAttributes() []*Attribute {
|
||||
if this != nil {
|
||||
return this.Attributes
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *Event) GetMetricSint64() int64 {
|
||||
if this != nil && this.MetricSint64 != nil {
|
||||
return *this.MetricSint64
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (this *Event) GetMetricD() float64 {
|
||||
if this != nil && this.MetricD != nil {
|
||||
return *this.MetricD
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (this *Event) GetMetricF() float32 {
|
||||
if this != nil && this.MetricF != nil {
|
||||
return *this.MetricF
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type Query struct {
|
||||
String_ *string `protobuf:"bytes,1,opt,name=string" json:"string,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (this *Query) Reset() { *this = Query{} }
|
||||
func (this *Query) String() string { return proto1.CompactTextString(this) }
|
||||
func (*Query) ProtoMessage() {}
|
||||
|
||||
func (this *Query) GetString_() string {
|
||||
if this != nil && this.String_ != nil {
|
||||
return *this.String_
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type Msg struct {
|
||||
Ok *bool `protobuf:"varint,2,opt,name=ok" json:"ok,omitempty"`
|
||||
Error *string `protobuf:"bytes,3,opt,name=error" json:"error,omitempty"`
|
||||
States []*State `protobuf:"bytes,4,rep,name=states" json:"states,omitempty"`
|
||||
Query *Query `protobuf:"bytes,5,opt,name=query" json:"query,omitempty"`
|
||||
Events []*Event `protobuf:"bytes,6,rep,name=events" json:"events,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (this *Msg) Reset() { *this = Msg{} }
|
||||
func (this *Msg) String() string { return proto1.CompactTextString(this) }
|
||||
func (*Msg) ProtoMessage() {}
|
||||
|
||||
func (this *Msg) GetOk() bool {
|
||||
if this != nil && this.Ok != nil {
|
||||
return *this.Ok
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (this *Msg) GetError() string {
|
||||
if this != nil && this.Error != nil {
|
||||
return *this.Error
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (this *Msg) GetStates() []*State {
|
||||
if this != nil {
|
||||
return this.States
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *Msg) GetQuery() *Query {
|
||||
if this != nil {
|
||||
return this.Query
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *Msg) GetEvents() []*Event {
|
||||
if this != nil {
|
||||
return this.Events
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Attribute struct {
|
||||
Key *string `protobuf:"bytes,1,req,name=key" json:"key,omitempty"`
|
||||
Value *string `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (this *Attribute) Reset() { *this = Attribute{} }
|
||||
func (this *Attribute) String() string { return proto1.CompactTextString(this) }
|
||||
func (*Attribute) ProtoMessage() {}
|
||||
|
||||
func (this *Attribute) GetKey() string {
|
||||
if this != nil && this.Key != nil {
|
||||
return *this.Key
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (this *Attribute) GetValue() string {
|
||||
if this != nil && this.Value != nil {
|
||||
return *this.Value
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func init() {
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
option java_package = "com.aphyr.riemann";
|
||||
option java_outer_classname = "Proto";
|
||||
|
||||
message State {
|
||||
optional int64 time = 1;
|
||||
optional string state = 2;
|
||||
optional string service = 3;
|
||||
optional string host = 4;
|
||||
optional string description = 5;
|
||||
optional bool once = 6;
|
||||
repeated string tags = 7;
|
||||
optional float ttl = 8;
|
||||
}
|
||||
|
||||
message Event {
|
||||
optional int64 time = 1;
|
||||
optional string state = 2;
|
||||
optional string service = 3;
|
||||
optional string host = 4;
|
||||
optional string description = 5;
|
||||
repeated string tags = 7;
|
||||
optional float ttl = 8;
|
||||
repeated Attribute attributes = 9;
|
||||
|
||||
optional sint64 metric_sint64 = 13;
|
||||
optional double metric_d = 14;
|
||||
optional float metric_f = 15;
|
||||
}
|
||||
|
||||
message Query {
|
||||
optional string string = 1;
|
||||
}
|
||||
|
||||
message Msg {
|
||||
optional bool ok = 2;
|
||||
optional string error = 3;
|
||||
repeated State states = 4;
|
||||
optional Query query = 5;
|
||||
repeated Event events = 6;
|
||||
}
|
||||
|
||||
message Attribute {
|
||||
required string key = 1;
|
||||
optional string value = 2;
|
||||
}
|
|
@ -0,0 +1,313 @@
|
|||
// Go Riemann client
|
||||
package raidman
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"reflect"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/amir/raidman/proto"
|
||||
pb "github.com/golang/protobuf/proto"
|
||||
)
|
||||
|
||||
type network interface {
|
||||
Send(message *proto.Msg, conn net.Conn) (*proto.Msg, error)
|
||||
}
|
||||
|
||||
type tcp struct{}
|
||||
|
||||
type udp struct{}
|
||||
|
||||
// Client represents a connection to a Riemann server
|
||||
type Client struct {
|
||||
sync.Mutex
|
||||
net network
|
||||
connection net.Conn
|
||||
timeout time.Duration
|
||||
}
|
||||
|
||||
// An Event represents a single Riemann event
|
||||
type Event struct {
|
||||
Ttl float32
|
||||
Time int64
|
||||
Tags []string
|
||||
Host string // Defaults to os.Hostname()
|
||||
State string
|
||||
Service string
|
||||
Metric interface{} // Could be Int, Float32, Float64
|
||||
Description string
|
||||
Attributes map[string]string
|
||||
}
|
||||
|
||||
// Dial establishes a connection to a Riemann server at addr, on the network
|
||||
// netwrk, with a timeout of timeout
|
||||
//
|
||||
// Known networks are "tcp", "tcp4", "tcp6", "udp", "udp4", and "udp6".
|
||||
func DialWithTimeout(netwrk, addr string, timeout time.Duration) (c *Client, err error) {
|
||||
c = new(Client)
|
||||
|
||||
var cnet network
|
||||
switch netwrk {
|
||||
case "tcp", "tcp4", "tcp6":
|
||||
cnet = new(tcp)
|
||||
case "udp", "udp4", "udp6":
|
||||
cnet = new(udp)
|
||||
default:
|
||||
return nil, fmt.Errorf("dial %q: unsupported network %q", netwrk, netwrk)
|
||||
}
|
||||
|
||||
c.net = cnet
|
||||
c.timeout = timeout
|
||||
c.connection, err = net.Dial(netwrk, addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// Dial establishes a connection to a Riemann server at addr, on the network
|
||||
// netwrk.
|
||||
//
|
||||
// Known networks are "tcp", "tcp4", "tcp6", "udp", "udp4", and "udp6".
|
||||
func Dial(netwrk, addr string) (c *Client, err error) {
|
||||
return DialWithTimeout(netwrk, addr, 0)
|
||||
}
|
||||
|
||||
func (network *tcp) Send(message *proto.Msg, conn net.Conn) (*proto.Msg, error) {
|
||||
msg := &proto.Msg{}
|
||||
data, err := pb.Marshal(message)
|
||||
if err != nil {
|
||||
return msg, err
|
||||
}
|
||||
b := new(bytes.Buffer)
|
||||
if err = binary.Write(b, binary.BigEndian, uint32(len(data))); err != nil {
|
||||
return msg, err
|
||||
}
|
||||
if _, err = conn.Write(b.Bytes()); err != nil {
|
||||
return msg, err
|
||||
}
|
||||
if _, err = conn.Write(data); err != nil {
|
||||
return msg, err
|
||||
}
|
||||
var header uint32
|
||||
if err = binary.Read(conn, binary.BigEndian, &header); err != nil {
|
||||
return msg, err
|
||||
}
|
||||
response := make([]byte, header)
|
||||
if err = readFully(conn, response); err != nil {
|
||||
return msg, err
|
||||
}
|
||||
if err = pb.Unmarshal(response, msg); err != nil {
|
||||
return msg, err
|
||||
}
|
||||
if msg.GetOk() != true {
|
||||
return msg, errors.New(msg.GetError())
|
||||
}
|
||||
return msg, nil
|
||||
}
|
||||
|
||||
func readFully(r io.Reader, p []byte) error {
|
||||
for len(p) > 0 {
|
||||
n, err := r.Read(p)
|
||||
p = p[n:]
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (network *udp) Send(message *proto.Msg, conn net.Conn) (*proto.Msg, error) {
|
||||
data, err := pb.Marshal(message)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err = conn.Write(data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func isZero(v reflect.Value) bool {
|
||||
switch v.Kind() {
|
||||
case reflect.Map:
|
||||
return v.IsNil()
|
||||
case reflect.Slice:
|
||||
zero := true
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
zero = zero && isZero(v.Index(i))
|
||||
}
|
||||
return zero
|
||||
}
|
||||
zero := reflect.Zero(v.Type())
|
||||
return v.Interface() == zero.Interface()
|
||||
}
|
||||
|
||||
func eventToPbEvent(event *Event) (*proto.Event, error) {
|
||||
var e proto.Event
|
||||
|
||||
if event.Host == "" {
|
||||
event.Host, _ = os.Hostname()
|
||||
}
|
||||
t := reflect.ValueOf(&e).Elem()
|
||||
s := reflect.ValueOf(event).Elem()
|
||||
typeOfEvent := s.Type()
|
||||
for i := 0; i < s.NumField(); i++ {
|
||||
f := s.Field(i)
|
||||
value := reflect.ValueOf(f.Interface())
|
||||
if !isZero(f) {
|
||||
name := typeOfEvent.Field(i).Name
|
||||
switch name {
|
||||
case "State", "Service", "Host", "Description":
|
||||
tmp := reflect.ValueOf(pb.String(value.String()))
|
||||
t.FieldByName(name).Set(tmp)
|
||||
case "Ttl":
|
||||
tmp := reflect.ValueOf(pb.Float32(float32(value.Float())))
|
||||
t.FieldByName(name).Set(tmp)
|
||||
case "Time":
|
||||
tmp := reflect.ValueOf(pb.Int64(value.Int()))
|
||||
t.FieldByName(name).Set(tmp)
|
||||
case "Tags":
|
||||
tmp := reflect.ValueOf(value.Interface().([]string))
|
||||
t.FieldByName(name).Set(tmp)
|
||||
case "Metric":
|
||||
switch reflect.TypeOf(f.Interface()).Kind() {
|
||||
case reflect.Int:
|
||||
tmp := reflect.ValueOf(pb.Int64(int64(value.Int())))
|
||||
t.FieldByName("MetricSint64").Set(tmp)
|
||||
case reflect.Int64:
|
||||
tmp := reflect.ValueOf(pb.Int64(int64(value.Int())))
|
||||
t.FieldByName("MetricSint64").Set(tmp)
|
||||
case reflect.Float32:
|
||||
tmp := reflect.ValueOf(pb.Float32(float32(value.Float())))
|
||||
t.FieldByName("MetricF").Set(tmp)
|
||||
case reflect.Float64:
|
||||
tmp := reflect.ValueOf(pb.Float64(value.Float()))
|
||||
t.FieldByName("MetricD").Set(tmp)
|
||||
default:
|
||||
return nil, fmt.Errorf("Metric of invalid type (type %v)",
|
||||
reflect.TypeOf(f.Interface()).Kind())
|
||||
}
|
||||
case "Attributes":
|
||||
var attrs []*proto.Attribute
|
||||
for k, v := range value.Interface().(map[string]string) {
|
||||
// Copy k,v so we can take
|
||||
// pointers to the new
|
||||
// temporaries
|
||||
k_, v_ := k, v
|
||||
attrs = append(attrs, &proto.Attribute{
|
||||
Key: &k_,
|
||||
Value: &v_,
|
||||
})
|
||||
}
|
||||
t.FieldByName(name).Set(reflect.ValueOf(attrs))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &e, nil
|
||||
}
|
||||
|
||||
func pbEventsToEvents(pbEvents []*proto.Event) []Event {
|
||||
var events []Event
|
||||
|
||||
for _, event := range pbEvents {
|
||||
e := Event{
|
||||
State: event.GetState(),
|
||||
Service: event.GetService(),
|
||||
Host: event.GetHost(),
|
||||
Description: event.GetDescription(),
|
||||
Ttl: event.GetTtl(),
|
||||
Time: event.GetTime(),
|
||||
Tags: event.GetTags(),
|
||||
}
|
||||
if event.MetricF != nil {
|
||||
e.Metric = event.GetMetricF()
|
||||
} else if event.MetricD != nil {
|
||||
e.Metric = event.GetMetricD()
|
||||
} else {
|
||||
e.Metric = event.GetMetricSint64()
|
||||
}
|
||||
if event.Attributes != nil {
|
||||
e.Attributes = make(map[string]string, len(event.GetAttributes()))
|
||||
for _, attr := range event.GetAttributes() {
|
||||
e.Attributes[attr.GetKey()] = attr.GetValue()
|
||||
}
|
||||
}
|
||||
|
||||
events = append(events, e)
|
||||
}
|
||||
|
||||
return events
|
||||
}
|
||||
|
||||
// Send sends an event to Riemann
|
||||
func (c *Client) Send(event *Event) error {
|
||||
return c.SendMulti([]*Event{event})
|
||||
}
|
||||
|
||||
// SendMulti sends multiple events to Riemann
|
||||
func (c *Client) SendMulti(events []*Event) error {
|
||||
message := &proto.Msg{}
|
||||
|
||||
for _, event := range events {
|
||||
e, err := eventToPbEvent(event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
message.Events = append(message.Events, e)
|
||||
}
|
||||
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
|
||||
if c.timeout > 0 {
|
||||
err := c.connection.SetDeadline(time.Now().Add(c.timeout))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
_, err := c.net.Send(message, c.connection)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Query returns a list of events matched by query
|
||||
func (c *Client) Query(q string) ([]Event, error) {
|
||||
switch c.net.(type) {
|
||||
case *udp:
|
||||
return nil, errors.New("Querying over UDP is not supported")
|
||||
}
|
||||
query := &proto.Query{}
|
||||
query.String_ = pb.String(q)
|
||||
message := &proto.Msg{}
|
||||
message.Query = query
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
response, err := c.net.Send(message, c.connection)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return pbEventsToEvents(response.GetEvents()), nil
|
||||
}
|
||||
|
||||
// Close closes the connection to Riemann
|
||||
func (c *Client) Close() {
|
||||
c.Lock()
|
||||
c.connection.Close()
|
||||
c.Unlock()
|
||||
}
|
|
@ -0,0 +1,268 @@
|
|||
package raidman
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestTCP(t *testing.T) {
|
||||
c, err := Dial("tcp", "localhost:5555")
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
var event = &Event{
|
||||
State: "success",
|
||||
Host: "raidman",
|
||||
Service: "tcp",
|
||||
Metric: 42,
|
||||
Ttl: 1,
|
||||
Tags: []string{"tcp", "test", "raidman"},
|
||||
Attributes: map[string]string{"type": "test"},
|
||||
}
|
||||
|
||||
err = c.Send(event)
|
||||
if err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
|
||||
events, err := c.Query("tagged \"test\"")
|
||||
if err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
|
||||
if len(events) < 1 {
|
||||
t.Error("Submitted event not found")
|
||||
}
|
||||
|
||||
testAttributeExists := false
|
||||
for _, event := range events {
|
||||
if val, ok := event.Attributes["type"]; ok && val == "test" {
|
||||
testAttributeExists = true
|
||||
}
|
||||
}
|
||||
|
||||
if !testAttributeExists {
|
||||
t.Error("Attribute \"type\" is missing")
|
||||
}
|
||||
|
||||
c.Close()
|
||||
}
|
||||
|
||||
func TestMultiTCP(t *testing.T) {
|
||||
c, err := Dial("tcp", "localhost:5555")
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
err = c.SendMulti([]*Event{
|
||||
&Event{
|
||||
State: "success",
|
||||
Host: "raidman",
|
||||
Service: "tcp-multi-1",
|
||||
Metric: 42,
|
||||
Ttl: 1,
|
||||
Tags: []string{"tcp", "test", "raidman", "multi"},
|
||||
Attributes: map[string]string{"type": "test"},
|
||||
},
|
||||
&Event{
|
||||
State: "success",
|
||||
Host: "raidman",
|
||||
Service: "tcp-multi-2",
|
||||
Metric: 42,
|
||||
Ttl: 1,
|
||||
Tags: []string{"tcp", "test", "raidman", "multi"},
|
||||
Attributes: map[string]string{"type": "test"},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
|
||||
events, err := c.Query("tagged \"test\" and tagged \"multi\"")
|
||||
if err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
|
||||
if len(events) != 2 {
|
||||
t.Error("Submitted event not found")
|
||||
}
|
||||
|
||||
c.Close()
|
||||
}
|
||||
|
||||
func TestMetricIsInt64(t *testing.T) {
|
||||
c, err := Dial("tcp", "localhost:5555")
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
|
||||
var int64metric int64 = 9223372036854775807
|
||||
|
||||
var event = &Event{
|
||||
State: "success",
|
||||
Host: "raidman",
|
||||
Service: "tcp",
|
||||
Metric: int64metric,
|
||||
Ttl: 1,
|
||||
Tags: []string{"tcp", "test", "raidman"},
|
||||
Attributes: map[string]string{"type": "test"},
|
||||
}
|
||||
|
||||
err = c.Send(event)
|
||||
if err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestUDP(t *testing.T) {
|
||||
c, err := Dial("udp", "localhost:5555")
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
var event = &Event{
|
||||
State: "warning",
|
||||
Host: "raidman",
|
||||
Service: "udp",
|
||||
Metric: 3.4,
|
||||
Ttl: 10.7,
|
||||
}
|
||||
|
||||
err = c.Send(event)
|
||||
if err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
c.Close()
|
||||
}
|
||||
|
||||
func TestTCPWithoutHost(t *testing.T) {
|
||||
c, err := Dial("tcp", "localhost:5555")
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
var event = &Event{
|
||||
State: "success",
|
||||
Service: "tcp-host-not-set",
|
||||
Ttl: 5,
|
||||
}
|
||||
|
||||
err = c.Send(event)
|
||||
if err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
|
||||
events, err := c.Query("service = \"tcp-host-not-set\"")
|
||||
if err != nil {
|
||||
t.Error(err.Error())
|
||||
}
|
||||
|
||||
if len(events) < 1 {
|
||||
t.Error("Submitted event not found")
|
||||
}
|
||||
|
||||
for _, e := range events {
|
||||
if e.Host == "" {
|
||||
t.Error("Default host name is not set")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsZero(t *testing.T) {
|
||||
event := &Event{
|
||||
Time: 1,
|
||||
}
|
||||
elem := reflect.ValueOf(event).Elem()
|
||||
eventType := elem.Type()
|
||||
for i := 0; i < elem.NumField(); i++ {
|
||||
field := elem.Field(i)
|
||||
name := eventType.Field(i).Name
|
||||
if name == "Time" {
|
||||
if isZero(field) {
|
||||
t.Error("Time should not be zero")
|
||||
}
|
||||
} else {
|
||||
if !isZero(field) {
|
||||
t.Errorf("%s should be zero", name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkTCP(b *testing.B) {
|
||||
c, err := Dial("tcp", "localhost:5555")
|
||||
|
||||
var event = &Event{
|
||||
State: "good",
|
||||
Host: "raidman",
|
||||
Service: "benchmark",
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
for i := 0; i < b.N; i++ {
|
||||
c.Send(event)
|
||||
}
|
||||
}
|
||||
c.Close()
|
||||
}
|
||||
|
||||
func BenchmarkUDP(b *testing.B) {
|
||||
c, err := Dial("udp", "localhost:5555")
|
||||
|
||||
var event = &Event{
|
||||
State: "good",
|
||||
Host: "raidman",
|
||||
Service: "benchmark",
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
for i := 0; i < b.N; i++ {
|
||||
c.Send(event)
|
||||
}
|
||||
}
|
||||
c.Close()
|
||||
}
|
||||
|
||||
func BenchmarkConcurrentTCP(b *testing.B) {
|
||||
c, err := Dial("tcp", "localhost:5555")
|
||||
|
||||
var event = &Event{
|
||||
Host: "raidman",
|
||||
Service: "tcp_concurrent",
|
||||
Tags: []string{"concurrent", "tcp", "benchmark"},
|
||||
}
|
||||
|
||||
ch := make(chan int, b.N)
|
||||
for i := 0; i < b.N; i++ {
|
||||
go func(metric int) {
|
||||
event.Metric = metric
|
||||
err = c.Send(event)
|
||||
ch <- i
|
||||
}(i)
|
||||
}
|
||||
<-ch
|
||||
|
||||
c.Close()
|
||||
}
|
||||
|
||||
func BenchmarkConcurrentUDP(b *testing.B) {
|
||||
c, err := Dial("udp", "localhost:5555")
|
||||
|
||||
var event = &Event{
|
||||
Host: "raidman",
|
||||
Service: "udp_concurrent",
|
||||
Tags: []string{"concurrent", "udp", "benchmark"},
|
||||
}
|
||||
|
||||
ch := make(chan int, b.N)
|
||||
for i := 0; i < b.N; i++ {
|
||||
go func(metric int) {
|
||||
event.Metric = metric
|
||||
err = c.Send(event)
|
||||
ch <- i
|
||||
}(i)
|
||||
}
|
||||
<-ch
|
||||
|
||||
c.Close()
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
*~
|
||||
#*
|
||||
_obj
|
||||
*.tmp
|
|
@ -1,27 +0,0 @@
|
|||
gopsutil is distributed under BSD license reproduced below.
|
||||
|
||||
Copyright (c) 2014, WAKAYAMA Shirou
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Neither the name of the gopsutil authors nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -1,270 +0,0 @@
|
|||
gopsutil: psutil for golang
|
||||
==============================
|
||||
|
||||
.. image:: https://drone.io/github.com/shirou/gopsutil/status.png
|
||||
:target: https://drone.io/github.com/shirou/gopsutil
|
||||
|
||||
.. image:: https://coveralls.io/repos/shirou/gopsutil/badge.png?branch=master
|
||||
:target: https://coveralls.io/r/shirou/gopsutil?branch=master
|
||||
|
||||
|
||||
This is a port of psutil (http://pythonhosted.org/psutil/). The challenge is porting all
|
||||
psutil functions on some architectures...
|
||||
|
||||
.. highlights:: Package Structure Changed!
|
||||
|
||||
Package (a.k.a. directory) structure has been changed!! see `issue 24 <https://github.com/shirou/gopsutil/issues/24>`_
|
||||
|
||||
.. highlights:: golang 1.4 will become REQUIRED!
|
||||
|
||||
Since syscall package becomes frozen, we should use golang/x/sys of golang 1.4 as soon as possible.
|
||||
|
||||
|
||||
Available Architectures
|
||||
------------------------------------
|
||||
|
||||
- FreeBSD i386/amd64
|
||||
- Linux i386/amd64/arm(raspberry pi)
|
||||
- Windows/amd64
|
||||
- Darwin/amd64
|
||||
|
||||
All works are implemented without cgo by porting c struct to golang struct.
|
||||
|
||||
|
||||
Usage
|
||||
---------
|
||||
|
||||
.. code:: go
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/shirou/gopsutil/mem"
|
||||
)
|
||||
|
||||
func main() {
|
||||
v, _ := mem.VirtualMemory()
|
||||
|
||||
// almost every return value is a struct
|
||||
fmt.Printf("Total: %v, Free:%v, UsedPercent:%f%%\n", v.Total, v.Free, v.UsedPercent)
|
||||
|
||||
// convert to JSON. String() is also implemented
|
||||
fmt.Println(v)
|
||||
}
|
||||
|
||||
The output is below.
|
||||
|
||||
::
|
||||
|
||||
Total: 3179569152, Free:284233728, UsedPercent:84.508194%
|
||||
{"total":3179569152,"available":492572672,"used":2895335424,"usedPercent":84.50819439828305, (snip)}
|
||||
|
||||
You can set an alternative location to /proc by setting the HOST_PROC environment variable.
|
||||
|
||||
Documentation
|
||||
------------------------
|
||||
|
||||
see http://godoc.org/github.com/shirou/gopsutil
|
||||
|
||||
|
||||
More Info
|
||||
--------------------
|
||||
|
||||
Several methods have been added which are not present in psutil, but will provide useful information.
|
||||
|
||||
- host/HostInfo() (linux)
|
||||
|
||||
- Hostname
|
||||
- Uptime
|
||||
- Procs
|
||||
- OS (ex: "linux")
|
||||
- Platform (ex: "ubuntu", "arch")
|
||||
- PlatformFamily (ex: "debian")
|
||||
- PlatformVersion (ex: "Ubuntu 13.10")
|
||||
- VirtualizationSystem (ex: "LXC")
|
||||
- VirtualizationRole (ex: "guest"/"host")
|
||||
|
||||
- cpu/CPUInfo() (linux, freebsd)
|
||||
|
||||
- CPU (ex: 0, 1, ...)
|
||||
- VendorID (ex: "GenuineIntel")
|
||||
- Family
|
||||
- Model
|
||||
- Stepping
|
||||
- PhysicalID
|
||||
- CoreID
|
||||
- Cores (ex: 2)
|
||||
- ModelName (ex: "Intel(R) Core(TM) i7-2640M CPU @ 2.80GHz")
|
||||
- Mhz
|
||||
- CacheSize
|
||||
- Flags (ex: "fpu vme de pse tsc msr pae mce cx8 ...")
|
||||
|
||||
- load/LoadAvg() (linux, freebsd)
|
||||
|
||||
- Load1
|
||||
- Load5
|
||||
- Load15
|
||||
|
||||
- docker/GetDockerIDList() (linux only)
|
||||
|
||||
- container id list ([]string)
|
||||
|
||||
- docker/CgroupCPU() (linux only)
|
||||
|
||||
- user
|
||||
- system
|
||||
|
||||
- docker/CgroupMem() (linux only)
|
||||
|
||||
- various status
|
||||
|
||||
Some codes are ported from Ohai. many thanks.
|
||||
|
||||
|
||||
Current Status
|
||||
------------------
|
||||
|
||||
- x: work
|
||||
- b: almost work but something broken
|
||||
|
||||
================= ====== ======= ====== =======
|
||||
name Linux FreeBSD MacOSX Windows
|
||||
cpu_times x x x x
|
||||
cpu_count x x x x
|
||||
cpu_percent x x x x
|
||||
cpu_times_percent x x x x
|
||||
virtual_memory x x x x
|
||||
swap_memory x x x
|
||||
disk_partitions x x x x
|
||||
disk_io_counters x x
|
||||
disk_usage x x x x
|
||||
net_io_counters x x b x
|
||||
boot_time x x x x
|
||||
users x x x x
|
||||
pids x x x x
|
||||
pid_exists x x x x
|
||||
net_connections x x
|
||||
net_if_addrs
|
||||
net_if_stats
|
||||
================= ====== ======= ====== =======
|
||||
|
||||
Process class
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
================ ===== ======= ====== =======
|
||||
name Linux FreeBSD MacOSX Windows
|
||||
pid x x x x
|
||||
ppid x x x x
|
||||
name x x x x
|
||||
cmdline x x x
|
||||
create_time x
|
||||
status x x x
|
||||
cwd x
|
||||
exe x x x
|
||||
uids x x x
|
||||
gids x x x
|
||||
terminal x x x
|
||||
io_counters x
|
||||
nice x x x
|
||||
num_fds x
|
||||
num_ctx_switches x
|
||||
num_threads x x x x
|
||||
cpu_times x
|
||||
memory_info x x x
|
||||
memory_info_ex x
|
||||
memory_maps x
|
||||
open_files x
|
||||
send_signal x x x
|
||||
suspend x x x
|
||||
resume x x x
|
||||
terminate x x x
|
||||
kill x x x
|
||||
username x
|
||||
ionice
|
||||
rlimit
|
||||
num_handlres
|
||||
threads
|
||||
cpu_percent x x
|
||||
cpu_affinity
|
||||
memory_percent
|
||||
parent x x
|
||||
children
|
||||
connections x x
|
||||
is_running
|
||||
================ ===== ======= ====== =======
|
||||
|
||||
Original Metrics
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
================== ===== ======= ====== =======
|
||||
item Linux FreeBSD MacOSX Windows
|
||||
**HostInfo**
|
||||
hostname x x x x
|
||||
uptime x x x
|
||||
proces x x
|
||||
os x x x x
|
||||
platform x x x
|
||||
platformfamiliy x x x
|
||||
virtualization x
|
||||
**CPU**
|
||||
VendorID x x x x
|
||||
Family x x x x
|
||||
Model x x x x
|
||||
Stepping x x x x
|
||||
PhysicalID x
|
||||
CoreID x
|
||||
Cores x x
|
||||
ModelName x x x x
|
||||
**LoadAvg**
|
||||
Load1 x x x
|
||||
Load5 x x x
|
||||
Load15 x x x
|
||||
**GetDockerID**
|
||||
container id x no no no
|
||||
**CgroupsCPU**
|
||||
user x no no no
|
||||
system x no no no
|
||||
**CgroupsMem**
|
||||
various x no no no
|
||||
================== ===== ======= ====== =======
|
||||
|
||||
- future work
|
||||
|
||||
- process_iter
|
||||
- wait_procs
|
||||
- Process class
|
||||
|
||||
- as_dict
|
||||
- wait
|
||||
|
||||
|
||||
License
|
||||
------------
|
||||
|
||||
New BSD License (same as psutil)
|
||||
|
||||
|
||||
Related Works
|
||||
-----------------------
|
||||
|
||||
I have been influenced by the following great works:
|
||||
|
||||
- psutil: http://pythonhosted.org/psutil/
|
||||
- dstat: https://github.com/dagwieers/dstat
|
||||
- gosigar: https://github.com/cloudfoundry/gosigar/
|
||||
- goprocinfo: https://github.com/c9s/goprocinfo
|
||||
- go-ps: https://github.com/mitchellh/go-ps
|
||||
- ohai: https://github.com/opscode/ohai/
|
||||
- bosun: https://github.com/bosun-monitor/bosun/tree/master/cmd/scollector/collectors
|
||||
- mackerel: https://github.com/mackerelio/mackerel-agent/tree/master/metrics
|
||||
|
||||
How to Contribute
|
||||
---------------------------
|
||||
|
||||
1. Fork it
|
||||
2. Create your feature branch (git checkout -b my-new-feature)
|
||||
3. Commit your changes (git commit -am 'Add some feature')
|
||||
4. Push to the branch (git push origin my-new-feature)
|
||||
5. Create new Pull Request
|
||||
|
||||
My English is terrible, so documentation or correcting comments are also
|
||||
welcome.
|
|
@ -1,26 +0,0 @@
|
|||
#/bin/sh
|
||||
|
||||
# see http://www.songmu.jp/riji/entry/2015-01-15-goveralls-multi-package.html
|
||||
|
||||
set -e
|
||||
# cleanup
|
||||
cleanup() {
|
||||
if [ $tmpprof != "" ] && [ -f $tmpprof ]; then
|
||||
rm -f $tmpprof
|
||||
fi
|
||||
exit
|
||||
}
|
||||
trap cleanup INT QUIT TERM EXIT
|
||||
|
||||
# メインの処理
|
||||
prof=${1:-".profile.cov"}
|
||||
echo "mode: count" > $prof
|
||||
gopath1=$(echo $GOPATH | cut -d: -f1)
|
||||
for pkg in $(go list ./...); do
|
||||
tmpprof=$gopath1/src/$pkg/profile.tmp
|
||||
go test -covermode=count -coverprofile=$tmpprof $pkg
|
||||
if [ -f $tmpprof ]; then
|
||||
cat $tmpprof | tail -n +2 >> $prof
|
||||
rm $tmpprof
|
||||
fi
|
||||
done
|
|
@ -1 +0,0 @@
|
|||
package gopsutil
|
|
@ -1,37 +0,0 @@
|
|||
|
||||
DIRS="cpu disk docker host load mem net process"
|
||||
|
||||
GOOS=`uname | tr '[:upper:]' '[:lower:]'`
|
||||
ARCH=`uname -m`
|
||||
|
||||
case $ARCH in
|
||||
amd64)
|
||||
GOARCH="amd64"
|
||||
;;
|
||||
x86_64)
|
||||
GOARCH="amd64"
|
||||
;;
|
||||
i386)
|
||||
GOARCH="386"
|
||||
;;
|
||||
i686)
|
||||
GOARCH="386"
|
||||
;;
|
||||
arm)
|
||||
GOARCH="arm"
|
||||
;;
|
||||
*)
|
||||
echo "unknown arch: $ARCH"
|
||||
exit 1
|
||||
esac
|
||||
|
||||
for DIR in $DIRS
|
||||
do
|
||||
if [ -e ${DIR}/types_${GOOS}.go ]; then
|
||||
echo "// +build $GOOS" > ${DIR}/${DIR}_${GOOS}_${GOARCH}.go
|
||||
echo "// +build $GOARCH" >> ${DIR}/${DIR}_${GOOS}_${GOARCH}.go
|
||||
go tool cgo -godefs ${DIR}/types_${GOOS}.go >> ${DIR}/${DIR}_${GOOS}_${GOARCH}.go
|
||||
fi
|
||||
done
|
||||
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
Windows memo
|
||||
=====================
|
||||
|
||||
Size
|
||||
----------
|
||||
|
||||
DWORD
|
||||
32-bit unsigned integer
|
||||
DWORDLONG
|
||||
64-bit unsigned integer
|
||||
DWORD_PTR
|
||||
unsigned long type for pointer precision
|
||||
DWORD32
|
||||
32-bit unsigned integer
|
||||
DWORD64
|
||||
64-bit unsigned integer
|
||||
HALF_PTR
|
||||
_WIN64 = int, else short
|
||||
INT
|
||||
32-bit signed integer
|
||||
INT_PTR
|
||||
_WIN64 = __int64 else int
|
||||
LONG
|
||||
32-bit signed integer
|
||||
LONGLONG
|
||||
64-bit signed integer
|
||||
LONG_PTR
|
||||
_WIN64 = __int64 else long
|
||||
SHORT
|
||||
16-bit integer
|
||||
SIZE_T
|
||||
maximum number of bytes to which a pointer can point. typedef ULONG_PTR SIZE_T;
|
||||
SSIZE_T
|
||||
signed version of SIZE_T. typedef LONG_PTR SSIZE_T;
|
||||
WORD
|
||||
16-bit unsigned integer
|
6
Makefile
6
Makefile
|
@ -57,6 +57,7 @@ endif
|
|||
docker run --name aerospike -p "3000:3000" -d aerospike
|
||||
docker run --name nsq -p "4150:4150" -d nsqio/nsq /nsqd
|
||||
docker run --name mqtt -p "1883:1883" -d ncarlier/mqtt
|
||||
docker run --name riemann -p "5555:5555" -d blalor/riemann
|
||||
|
||||
# Run docker containers necessary for CircleCI unit tests
|
||||
docker-run-circle:
|
||||
|
@ -69,11 +70,12 @@ docker-run-circle:
|
|||
docker run --name aerospike -p "3000:3000" -d aerospike
|
||||
docker run --name nsq -p "4150:4150" -d nsqio/nsq /nsqd
|
||||
docker run --name mqtt -p "1883:1883" -d ncarlier/mqtt
|
||||
docker run --name riemann -p "5555:5555" -d blalor/riemann
|
||||
|
||||
# Kill all docker containers, ignore errors
|
||||
docker-kill:
|
||||
-docker kill nsq aerospike redis opentsdb rabbitmq postgres memcached mysql kafka mqtt
|
||||
-docker rm nsq aerospike redis opentsdb rabbitmq postgres memcached mysql kafka mqtt
|
||||
-docker kill nsq aerospike redis opentsdb rabbitmq postgres memcached mysql kafka mqtt riemann
|
||||
-docker rm nsq aerospike redis opentsdb rabbitmq postgres memcached mysql kafka mqtt riemann
|
||||
|
||||
# Run full unit tests using docker containers (includes setup and teardown)
|
||||
test: docker-kill prepare docker-run
|
||||
|
|
Loading…
Reference in New Issue