Godep: Add raidman riemann client
This commit is contained in:
parent
0823eed546
commit
a8294c2c34
|
@ -22,6 +22,10 @@
|
||||||
"Comment": "v0.8.6-7-g9c060de",
|
"Comment": "v0.8.6-7-g9c060de",
|
||||||
"Rev": "9c060de643590dae45da9d7c26276463bfc46fa0"
|
"Rev": "9c060de643590dae45da9d7c26276463bfc46fa0"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/amir/raidman",
|
||||||
|
"Rev": "6a8e089bbe32e6b907feae5ba688841974b3c339"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/armon/go-metrics",
|
"ImportPath": "github.com/armon/go-metrics",
|
||||||
"Rev": "b2d95e5291cdbc26997d1301a5e467ecbb240e25"
|
"Rev": "b2d95e5291cdbc26997d1301a5e467ecbb240e25"
|
||||||
|
@ -164,7 +168,47 @@
|
||||||
"Rev": "5bb5cfc093ad18a28148c578f8632cfdb4d802e4"
|
"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",
|
"Comment": "1.0.0-173-g1e9aabb",
|
||||||
"Rev": "1e9aabb3c8132314662698c9d1c0aef68d9da617"
|
"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 aerospike -p "3000:3000" -d aerospike
|
||||||
docker run --name nsq -p "4150:4150" -d nsqio/nsq /nsqd
|
docker run --name nsq -p "4150:4150" -d nsqio/nsq /nsqd
|
||||||
docker run --name mqtt -p "1883:1883" -d ncarlier/mqtt
|
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
|
# Run docker containers necessary for CircleCI unit tests
|
||||||
docker-run-circle:
|
docker-run-circle:
|
||||||
|
@ -69,11 +70,12 @@ docker-run-circle:
|
||||||
docker run --name aerospike -p "3000:3000" -d aerospike
|
docker run --name aerospike -p "3000:3000" -d aerospike
|
||||||
docker run --name nsq -p "4150:4150" -d nsqio/nsq /nsqd
|
docker run --name nsq -p "4150:4150" -d nsqio/nsq /nsqd
|
||||||
docker run --name mqtt -p "1883:1883" -d ncarlier/mqtt
|
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
|
# Kill all docker containers, ignore errors
|
||||||
docker-kill:
|
docker-kill:
|
||||||
-docker kill 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
|
-docker rm nsq aerospike redis opentsdb rabbitmq postgres memcached mysql kafka mqtt riemann
|
||||||
|
|
||||||
# Run full unit tests using docker containers (includes setup and teardown)
|
# Run full unit tests using docker containers (includes setup and teardown)
|
||||||
test: docker-kill prepare docker-run
|
test: docker-kill prepare docker-run
|
||||||
|
|
Loading…
Reference in New Issue