-
Notifications
You must be signed in to change notification settings - Fork 3
/
pinba.go
110 lines (79 loc) · 2.48 KB
/
pinba.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package gopinba
import (
"code.google.com/p/goprotobuf/proto"
"fmt"
ProtoMessage "github.com/kshvakov/gopinba/Pinba"
"net"
"os"
"runtime"
"time"
)
var memStats runtime.MemStats
// Pinba access object
type Pinba struct {
hostname string
serverName string
connect net.Conn
connected bool
}
// New Pinba request object
func (pinba *Pinba) Request() *request {
runtime.ReadMemStats(&memStats)
request := &request{
timeStart: time.Now(),
scriptName: os.Args[0],
memoryUsage: memStats.TotalAlloc,
timers: make([]*timer, 0, 10),
}
return request
}
// Flush request and send data to Pinba server
func (pinba *Pinba) Flush(request *request) error {
if !pinba.connected {
return fmt.Errorf("Could not connect to pinba server")
}
runtime.ReadMemStats(&memStats)
req := ProtoMessage.Request{
Hostname: proto.String(pinba.hostname),
ServerName: proto.String(pinba.serverName),
ScriptName: proto.String(request.scriptName),
RequestCount: proto.Uint32(1),
DocumentSize: proto.Uint32(0),
MemoryPeak: proto.Uint32(0),
MemoryFootprint: proto.Uint32(uint32(memStats.TotalAlloc - request.memoryUsage)),
RequestTime: proto.Float32(float32(time.Since(request.timeStart).Seconds())),
RuUtime: proto.Float32(0),
RuStime: proto.Float32(0),
Schema: proto.String(request.schema),
Dictionary: make([]string, 0, 20),
TimerTagName: make([]uint32, 0, 20),
TimerTagValue: make([]uint32, 0, 20),
}
for _, timer := range request.timers {
req.TimerTagCount = append(req.TimerTagCount, uint32(len(*timer.tags)))
req.TimerHitCount = append(req.TimerHitCount, 1)
req.TimerValue = append(req.TimerValue, float32(timer.timeEnd.Sub(timer.timeStart).Seconds()))
for tag, value := range *timer.tags {
if pos, exists := inSlice(tag, req.Dictionary); exists {
req.TimerTagName = append(req.TimerTagName, uint32(pos))
} else {
req.Dictionary = append(req.Dictionary, tag)
req.TimerTagName = append(req.TimerTagName, uint32(len(req.Dictionary)-1))
}
if pos, exists := inSlice(value, req.Dictionary); exists {
req.TimerTagValue = append(req.TimerTagValue, uint32(pos))
} else {
req.Dictionary = append(req.Dictionary, value)
req.TimerTagValue = append(req.TimerTagValue, uint32(len(req.Dictionary)-1))
}
}
}
message, err := proto.Marshal(&req)
if err != nil {
return err
}
if _, err = pinba.connect.Write(message); err != nil {
return err
}
return nil
}