forked from distribution/distribution
-
Notifications
You must be signed in to change notification settings - Fork 0
/
agent.go
137 lines (116 loc) · 4.32 KB
/
agent.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package gorelic
import (
"errors"
"fmt"
metrics "github.com/yvasiyarov/go-metrics"
"github.com/yvasiyarov/newrelic_platform_go"
"log"
"net/http"
)
const (
// DefaultNewRelicPollInterval - how often we will report metrics to NewRelic.
// Recommended values is 60 seconds
DefaultNewRelicPollInterval = 60
// DefaultGcPollIntervalInSeconds - how often we will get garbage collector run statistic
// Default value is - every 10 seconds
// During GC stat pooling - mheap will be locked, so be carefull changing this value
DefaultGcPollIntervalInSeconds = 10
// DefaultMemoryAllocatorPollIntervalInSeconds - how often we will get memory allocator statistic.
// Default value is - every 60 seconds
// During this process stoptheword() is called, so be carefull changing this value
DefaultMemoryAllocatorPollIntervalInSeconds = 60
//DefaultAgentGuid is plugin ID in NewRelic.
//You should not change it unless you want to create your own plugin.
DefaultAgentGuid = "com.github.yvasiyarov.GoRelic"
//CurrentAgentVersion is plugin version
CurrentAgentVersion = "0.0.6"
//DefaultAgentName in NewRelic GUI. You can change it.
DefaultAgentName = "Go daemon"
)
//Agent - is NewRelic agent implementation.
//Agent start separate go routine which will report data to NewRelic
type Agent struct {
NewrelicName string
NewrelicLicense string
NewrelicPollInterval int
Verbose bool
CollectGcStat bool
CollectMemoryStat bool
CollectHTTPStat bool
GCPollInterval int
MemoryAllocatorPollInterval int
AgentGUID string
AgentVersion string
plugin *newrelic_platform_go.NewrelicPlugin
HTTPTimer metrics.Timer
}
//NewAgent build new Agent objects.
func NewAgent() *Agent {
agent := &Agent{
NewrelicName: DefaultAgentName,
NewrelicPollInterval: DefaultNewRelicPollInterval,
Verbose: false,
CollectGcStat: true,
CollectMemoryStat: true,
GCPollInterval: DefaultGcPollIntervalInSeconds,
MemoryAllocatorPollInterval: DefaultMemoryAllocatorPollIntervalInSeconds,
AgentGUID: DefaultAgentGuid,
AgentVersion: CurrentAgentVersion,
}
return agent
}
//WrapHTTPHandlerFunc instrument HTTP handler functions to collect HTTP metrics
func (agent *Agent) WrapHTTPHandlerFunc(h tHTTPHandlerFunc) tHTTPHandlerFunc {
agent.initTimer()
return func(w http.ResponseWriter, req *http.Request) {
proxy := newHTTPHandlerFunc(h)
proxy.timer = agent.HTTPTimer
proxy.ServeHTTP(w, req)
}
}
//WrapHTTPHandler instrument HTTP handler object to collect HTTP metrics
func (agent *Agent) WrapHTTPHandler(h http.Handler) http.Handler {
agent.initTimer()
proxy := newHTTPHandler(h)
proxy.timer = agent.HTTPTimer
return proxy
}
//Run initialize Agent instance and start harvest go routine
func (agent *Agent) Run() error {
if agent.NewrelicLicense == "" {
return errors.New("please, pass a valid newrelic license key")
}
agent.plugin = newrelic_platform_go.NewNewrelicPlugin(agent.AgentVersion, agent.NewrelicLicense, agent.NewrelicPollInterval)
component := newrelic_platform_go.NewPluginComponent(agent.NewrelicName, agent.AgentGUID)
agent.plugin.AddComponent(component)
addRuntimeMericsToComponent(component)
if agent.CollectGcStat {
addGCMericsToComponent(component, agent.GCPollInterval)
agent.debug(fmt.Sprintf("Init GC metrics collection. Poll interval %d seconds.", agent.GCPollInterval))
}
if agent.CollectMemoryStat {
addMemoryMericsToComponent(component, agent.MemoryAllocatorPollInterval)
agent.debug(fmt.Sprintf("Init memory allocator metrics collection. Poll interval %d seconds.", agent.MemoryAllocatorPollInterval))
}
if agent.CollectHTTPStat {
agent.initTimer()
addHTTPMericsToComponent(component, agent.HTTPTimer)
agent.debug(fmt.Sprintf("Init HTTP metrics collection."))
}
agent.plugin.Verbose = agent.Verbose
go agent.plugin.Run()
return nil
}
//Initialize global metrics.Timer object, used to collect HTTP metrics
func (agent *Agent) initTimer() {
if agent.HTTPTimer == nil {
agent.HTTPTimer = metrics.NewTimer()
}
agent.CollectHTTPStat = true
}
//Print debug messages
func (agent *Agent) debug(msg string) {
if agent.Verbose {
log.Println(msg)
}
}