Move to vendor
Signed-off-by: Olivier Gambier <olivier@docker.com>
This commit is contained in:
parent
c8d8e7e357
commit
77e69b9cf3
1268 changed files with 34 additions and 24 deletions
4
vendor/github.com/yvasiyarov/gorelic/.gitignore
generated
vendored
Normal file
4
vendor/github.com/yvasiyarov/gorelic/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
*.nut
|
||||
*.swp
|
||||
examples/example1
|
||||
examples/example_web
|
1
vendor/github.com/yvasiyarov/gorelic/.travis.yml
generated
vendored
Normal file
1
vendor/github.com/yvasiyarov/gorelic/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
language: go
|
24
vendor/github.com/yvasiyarov/gorelic/LICENSE
generated
vendored
Normal file
24
vendor/github.com/yvasiyarov/gorelic/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
Copyright (c) 2013 Yuriy Vasiyarov. 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.
|
||||
|
||||
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.
|
119
vendor/github.com/yvasiyarov/gorelic/README.md
generated
vendored
Normal file
119
vendor/github.com/yvasiyarov/gorelic/README.md
generated
vendored
Normal file
|
@ -0,0 +1,119 @@
|
|||
# GoRelic
|
||||
|
||||
New Relic agent for Go runtime. It collect a lot of metrics about scheduler, garbage collector and memory allocator and
|
||||
send them to NewRelic.
|
||||
|
||||
### Requirements
|
||||
- Go 1.1 or higher
|
||||
- github.com/yvasiyarov/gorelic
|
||||
- github.com/yvasiyarov/newrelic_platform_go
|
||||
- github.com/yvasiyarov/go-metrics
|
||||
|
||||
You have to install manually only first two dependencies. All other dependencies will be installed automatically
|
||||
by Go toolchain.
|
||||
|
||||
### Installation
|
||||
```bash
|
||||
go get github.com/yvasiyarov/gorelic
|
||||
```
|
||||
and add to the initialization part of your application following code:
|
||||
```go
|
||||
import (
|
||||
"github.com/yvasiyarov/gorelic"
|
||||
)
|
||||
....
|
||||
|
||||
agent := gorelic.NewAgent()
|
||||
agent.Verbose = true
|
||||
agent.NewrelicLicense = "YOUR NEWRELIC LICENSE KEY THERE"
|
||||
agent.Run()
|
||||
|
||||
```
|
||||
|
||||
### Middleware
|
||||
If you using Beego, Martini, Revel or Gin framework you can hook up gorelic with your application by using the following middleware:
|
||||
- https://github.com/yvasiyarov/beego_gorelic
|
||||
- https://github.com/yvasiyarov/martini_gorelic
|
||||
- https://github.com/yvasiyarov/gocraft_gorelic
|
||||
- http://wiki.colar.net/revel_newelic
|
||||
- https://github.com/jingweno/negroni-gorelic
|
||||
- https://github.com/brandfolder/gin-gorelic
|
||||
|
||||
|
||||
### Configuration
|
||||
- NewrelicLicense - its the only mandatory setting of this agent.
|
||||
- NewrelicName - component name in NewRelic dashboard. Default value: "Go daemon"
|
||||
- NewrelicPollInterval - how often metrics will be sent to NewRelic. Default value: 60 seconds
|
||||
- Verbose - print some usefull for debugging information. Default value: false
|
||||
- CollectGcStat - should agent collect garbage collector statistic or not. Default value: true
|
||||
- CollectHTTPStat - should agent collect HTTP metrics. Default value: false
|
||||
- CollectMemoryStat - should agent collect memory allocator statistic or not. Default value: true
|
||||
- GCPollInterval - how often should GC statistic collected. Default value: 10 seconds. It has performance impact. For more information, please, see metrics documentation.
|
||||
- MemoryAllocatorPollInterval - how often should memory allocator statistic collected. Default value: 60 seconds. It has performance impact. For more information, please, read metrics documentation.
|
||||
|
||||
|
||||
## Metrics reported by plugin
|
||||
This agent use functions exposed by runtime or runtime/debug packages to collect most important information about Go runtime.
|
||||
|
||||
### General metrics
|
||||
- Runtime/General/NOGoroutines - number of runned go routines, as it reported by NumGoroutine() from runtime package
|
||||
- Runtime/General/NOCgoCalls - number of runned cgo calls, as it reported by NumCgoCall() from runtime package
|
||||
|
||||
### Garbage collector metrics
|
||||
- Runtime/GC/NumberOfGCCalls - Nuber of GC calls, as it reported by ReadGCStats() from runtime/debug
|
||||
- Runtime/GC/PauseTotalTime - Total pause time diring GC calls, as it reported by ReadGCStats() from runtime/debug (in nanoseconds)
|
||||
- Runtime/GC/GCTime/Max - max GC time
|
||||
- Runtime/GC/GCTime/Min - min GC time
|
||||
- Runtime/GC/GCTime/Mean - GC mean time
|
||||
- Runtime/GC/GCTime/Percentile95 - 95% percentile of GC time
|
||||
|
||||
All this metrics are measured in nanoseconds. Last 4 of them can be inaccurate if GC called more often then once in GCPollInterval.
|
||||
If in your workload GC is called more often - you can consider decreasing value of GCPollInterval.
|
||||
But be carefull, ReadGCStats() blocks mheap, so its not good idea to set GCPollInterval to very low values.
|
||||
|
||||
### Memory allocator
|
||||
- Component/Runtime/Memory/SysMem/Total - number of bytes/minute allocated from OS totally.
|
||||
- Component/Runtime/Memory/SysMem/Stack - number of bytes/minute allocated from OS for stacks.
|
||||
- Component/Runtime/Memory/SysMem/MSpan - number of bytes/minute allocated from OS for internal MSpan structs.
|
||||
- Component/Runtime/Memory/SysMem/MCache - number of bytes/minute allocated from OS for internal MCache structs.
|
||||
- Component/Runtime/Memory/SysMem/Heap - number of bytes/minute allocated from OS for heap.
|
||||
- Component/Runtime/Memory/SysMem/BuckHash - number of bytes/minute allocated from OS for internal BuckHash structs.
|
||||
- Component/Runtime/Memory/Operations/NoFrees - number of memory frees per minute
|
||||
- Component/Runtime/Memory/Operations/NoMallocs - number of memory allocations per minute
|
||||
- Component/Runtime/Memory/Operations/NoPointerLookups - number of pointer lookups per minute
|
||||
- Component/Runtime/Memory/InUse/Total - total amount of memory in use
|
||||
- Component/Runtime/Memory/InUse/Heap - amount of memory in use for heap
|
||||
- Component/Runtime/Memory/InUse/MCacheInuse - amount of memory in use for MCache internal structures
|
||||
- Component/Runtime/Memory/InUse/MSpanInuse - amount of memory in use for MSpan internal structures
|
||||
- Component/Runtime/Memory/InUse/Stack - amount of memory in use for stacks
|
||||
|
||||
### Process metrics
|
||||
- Component/Runtime/System/Threads - number of OS threads used
|
||||
- Runtime/System/FDSize - number of file descriptors, used by process
|
||||
- Runtime/System/Memory/VmPeakSize - VM max size
|
||||
- Runtime/System/Memory/VmCurrent - VM current size
|
||||
- Runtime/System/Memory/RssPeak - max size of resident memory set
|
||||
- Runtime/System/Memory/RssCurrent - current size of resident memory set
|
||||
|
||||
All this metrics collected once in MemoryAllocatorPollInterval. In order to collect this statistic agent use ReadMemStats() routine.
|
||||
This routine calls stoptheworld() internally and it block everything. So, please, consider this when you change MemoryAllocatorPollInterval value.
|
||||
|
||||
### HTTP metrics
|
||||
- throughput (requests per second), calculated for last minute
|
||||
- mean throughput (requests per second)
|
||||
- mean response time
|
||||
- min response time
|
||||
- max response time
|
||||
- 75%, 90%, 95% percentiles for response time
|
||||
|
||||
|
||||
In order to collect HTTP metrics, handler functions must be wrapped using WrapHTTPHandlerFunc:
|
||||
|
||||
```go
|
||||
http.HandleFunc("/", agent.WrapHTTPHandlerFunc(handler))
|
||||
```
|
||||
|
||||
## TODO
|
||||
- Collect per-size allocation statistic
|
||||
- Collect user defined metrics
|
||||
|
137
vendor/github.com/yvasiyarov/gorelic/agent.go
generated
vendored
Normal file
137
vendor/github.com/yvasiyarov/gorelic/agent.go
generated
vendored
Normal file
|
@ -0,0 +1,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)
|
||||
}
|
||||
}
|
2
vendor/github.com/yvasiyarov/gorelic/doc.go
generated
vendored
Normal file
2
vendor/github.com/yvasiyarov/gorelic/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
// Package gorelic is an New Relic agent implementation for Go runtime. It collect a lot of metrics about Go scheduler, garbage collector and memory allocator and send them to NewRelic.
|
||||
package gorelic
|
52
vendor/github.com/yvasiyarov/gorelic/examples/example1.go
generated
vendored
Normal file
52
vendor/github.com/yvasiyarov/gorelic/examples/example1.go
generated
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"github.com/yvasiyarov/gorelic"
|
||||
"log"
|
||||
"math/rand"
|
||||
"runtime"
|
||||
"time"
|
||||
)
|
||||
|
||||
var newrelicLicense = flag.String("newrelic-license", "", "Newrelic license")
|
||||
|
||||
func allocateAndSum(arraySize int) int {
|
||||
arr := make([]int, arraySize, arraySize)
|
||||
for i := range arr {
|
||||
arr[i] = rand.Int()
|
||||
}
|
||||
time.Sleep(time.Duration(rand.Intn(3000)) * time.Millisecond)
|
||||
|
||||
result := 0
|
||||
for _, v := range arr {
|
||||
result += v
|
||||
}
|
||||
//log.Printf("Array size is: %d, sum is: %d\n", arraySize, result)
|
||||
return result
|
||||
}
|
||||
|
||||
func doSomeJob(numRoutines int) {
|
||||
for {
|
||||
for i := 0; i < numRoutines; i++ {
|
||||
go allocateAndSum(rand.Intn(1024) * 1024)
|
||||
}
|
||||
log.Printf("All %d routines started\n", numRoutines)
|
||||
time.Sleep(1000 * time.Millisecond)
|
||||
runtime.GC()
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
flag.Parse()
|
||||
if *newrelicLicense == "" {
|
||||
log.Fatalf("Please, pass a valid newrelic license key.\n Use --help to get more information about available options\n")
|
||||
}
|
||||
agent := gorelic.NewAgent()
|
||||
agent.Verbose = true
|
||||
agent.NewrelicLicense = *newrelicLicense
|
||||
agent.Run()
|
||||
|
||||
doSomeJob(100)
|
||||
}
|
63
vendor/github.com/yvasiyarov/gorelic/examples/example_web.go
generated
vendored
Normal file
63
vendor/github.com/yvasiyarov/gorelic/examples/example_web.go
generated
vendored
Normal file
|
@ -0,0 +1,63 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"expvar"
|
||||
"flag"
|
||||
"github.com/yvasiyarov/gorelic"
|
||||
"io"
|
||||
"log"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"runtime"
|
||||
"time"
|
||||
)
|
||||
|
||||
var newrelicLicense = flag.String("newrelic-license", "", "Newrelic license")
|
||||
|
||||
var numCalls = expvar.NewInt("num_calls")
|
||||
|
||||
func allocateAndSum(arraySize int) int {
|
||||
arr := make([]int, arraySize, arraySize)
|
||||
for i := range arr {
|
||||
arr[i] = rand.Int()
|
||||
}
|
||||
time.Sleep(time.Duration(rand.Intn(3000)) * time.Millisecond)
|
||||
|
||||
result := 0
|
||||
for _, v := range arr {
|
||||
result += v
|
||||
}
|
||||
//log.Printf("Array size is: %d, sum is: %d\n", arraySize, result)
|
||||
return result
|
||||
}
|
||||
|
||||
func doSomeJob(numRoutines int) {
|
||||
for i := 0; i < numRoutines; i++ {
|
||||
go allocateAndSum(rand.Intn(1024) * 1024)
|
||||
}
|
||||
log.Printf("All %d routines started\n", numRoutines)
|
||||
time.Sleep(1000 * time.Millisecond)
|
||||
runtime.GC()
|
||||
}
|
||||
|
||||
func helloServer(w http.ResponseWriter, req *http.Request) {
|
||||
|
||||
doSomeJob(5)
|
||||
io.WriteString(w, "Did some work")
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
if *newrelicLicense == "" {
|
||||
log.Fatalf("Please, pass a valid newrelic license key.\n Use --help to get more information about available options\n")
|
||||
}
|
||||
agent := gorelic.NewAgent()
|
||||
agent.Verbose = true
|
||||
agent.CollectHTTPStat = true
|
||||
agent.NewrelicLicense = *newrelicLicense
|
||||
agent.Run()
|
||||
|
||||
http.HandleFunc("/", agent.WrapHTTPHandlerFunc(helloServer))
|
||||
http.ListenAndServe(":8080", nil)
|
||||
|
||||
}
|
65
vendor/github.com/yvasiyarov/gorelic/gc_metrics.go
generated
vendored
Normal file
65
vendor/github.com/yvasiyarov/gorelic/gc_metrics.go
generated
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
package gorelic
|
||||
|
||||
import (
|
||||
metrics "github.com/yvasiyarov/go-metrics"
|
||||
"github.com/yvasiyarov/newrelic_platform_go"
|
||||
"time"
|
||||
)
|
||||
|
||||
func newGCMetricaDataSource(pollInterval int) goMetricaDataSource {
|
||||
r := metrics.NewRegistry()
|
||||
|
||||
metrics.RegisterDebugGCStats(r)
|
||||
go metrics.CaptureDebugGCStats(r, time.Duration(pollInterval)*time.Second)
|
||||
return goMetricaDataSource{r}
|
||||
}
|
||||
|
||||
func addGCMericsToComponent(component newrelic_platform_go.IComponent, pollInterval int) {
|
||||
metrics := []*baseGoMetrica{
|
||||
&baseGoMetrica{
|
||||
name: "NumberOfGCCalls",
|
||||
units: "calls",
|
||||
dataSourceKey: "debug.GCStats.NumGC",
|
||||
},
|
||||
&baseGoMetrica{
|
||||
name: "PauseTotalTime",
|
||||
units: "nanoseconds",
|
||||
dataSourceKey: "debug.GCStats.PauseTotal",
|
||||
},
|
||||
}
|
||||
|
||||
ds := newGCMetricaDataSource(pollInterval)
|
||||
for _, m := range metrics {
|
||||
m.basePath = "Runtime/GC/"
|
||||
m.dataSource = ds
|
||||
component.AddMetrica(&gaugeMetrica{m})
|
||||
}
|
||||
|
||||
histogramMetrics := []*histogramMetrica{
|
||||
&histogramMetrica{
|
||||
statFunction: histogramMax,
|
||||
baseGoMetrica: &baseGoMetrica{name: "Max"},
|
||||
},
|
||||
&histogramMetrica{
|
||||
statFunction: histogramMin,
|
||||
baseGoMetrica: &baseGoMetrica{name: "Min"},
|
||||
},
|
||||
&histogramMetrica{
|
||||
statFunction: histogramMean,
|
||||
baseGoMetrica: &baseGoMetrica{name: "Mean"},
|
||||
},
|
||||
&histogramMetrica{
|
||||
statFunction: histogramPercentile,
|
||||
percentileValue: 0.95,
|
||||
baseGoMetrica: &baseGoMetrica{name: "Percentile95"},
|
||||
},
|
||||
}
|
||||
for _, m := range histogramMetrics {
|
||||
m.baseGoMetrica.units = "nanoseconds"
|
||||
m.baseGoMetrica.dataSourceKey = "debug.GCStats.Pause"
|
||||
m.baseGoMetrica.basePath = "Runtime/GC/GCTime/"
|
||||
m.baseGoMetrica.dataSource = ds
|
||||
|
||||
component.AddMetrica(m)
|
||||
}
|
||||
}
|
105
vendor/github.com/yvasiyarov/gorelic/gometrica.go
generated
vendored
Normal file
105
vendor/github.com/yvasiyarov/gorelic/gometrica.go
generated
vendored
Normal file
|
@ -0,0 +1,105 @@
|
|||
package gorelic
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
metrics "github.com/yvasiyarov/go-metrics"
|
||||
)
|
||||
|
||||
const (
|
||||
histogramMin = iota
|
||||
histogramMax
|
||||
histogramMean
|
||||
histogramPercentile
|
||||
histogramStdDev
|
||||
histogramVariance
|
||||
noHistogramFunctions
|
||||
)
|
||||
|
||||
type goMetricaDataSource struct {
|
||||
metrics.Registry
|
||||
}
|
||||
|
||||
func (ds goMetricaDataSource) GetGaugeValue(key string) (float64, error) {
|
||||
if valueContainer := ds.Get(key); valueContainer == nil {
|
||||
return 0, fmt.Errorf("metrica with name %s is not registered\n", key)
|
||||
} else if gauge, ok := valueContainer.(metrics.Gauge); ok {
|
||||
return float64(gauge.Value()), nil
|
||||
} else {
|
||||
return 0, fmt.Errorf("metrica container has unexpected type: %T\n", valueContainer)
|
||||
}
|
||||
}
|
||||
|
||||
func (ds goMetricaDataSource) GetHistogramValue(key string, statFunction int, percentile float64) (float64, error) {
|
||||
if valueContainer := ds.Get(key); valueContainer == nil {
|
||||
return 0, fmt.Errorf("metrica with name %s is not registered\n", key)
|
||||
} else if histogram, ok := valueContainer.(metrics.Histogram); ok {
|
||||
switch statFunction {
|
||||
default:
|
||||
return 0, fmt.Errorf("unsupported stat function for histogram: %s\n", statFunction)
|
||||
case histogramMax:
|
||||
return float64(histogram.Max()), nil
|
||||
case histogramMin:
|
||||
return float64(histogram.Min()), nil
|
||||
case histogramMean:
|
||||
return float64(histogram.Mean()), nil
|
||||
case histogramStdDev:
|
||||
return float64(histogram.StdDev()), nil
|
||||
case histogramVariance:
|
||||
return float64(histogram.Variance()), nil
|
||||
case histogramPercentile:
|
||||
return float64(histogram.Percentile(percentile)), nil
|
||||
}
|
||||
} else {
|
||||
return 0, fmt.Errorf("metrica container has unexpected type: %T\n", valueContainer)
|
||||
}
|
||||
}
|
||||
|
||||
type baseGoMetrica struct {
|
||||
dataSource goMetricaDataSource
|
||||
basePath string
|
||||
name string
|
||||
units string
|
||||
dataSourceKey string
|
||||
}
|
||||
|
||||
func (metrica *baseGoMetrica) GetName() string {
|
||||
return metrica.basePath + metrica.name
|
||||
}
|
||||
|
||||
func (metrica *baseGoMetrica) GetUnits() string {
|
||||
return metrica.units
|
||||
}
|
||||
|
||||
type gaugeMetrica struct {
|
||||
*baseGoMetrica
|
||||
}
|
||||
|
||||
func (metrica *gaugeMetrica) GetValue() (float64, error) {
|
||||
return metrica.dataSource.GetGaugeValue(metrica.dataSourceKey)
|
||||
}
|
||||
|
||||
type gaugeIncMetrica struct {
|
||||
*baseGoMetrica
|
||||
previousValue float64
|
||||
}
|
||||
|
||||
func (metrica *gaugeIncMetrica) GetValue() (float64, error) {
|
||||
var value float64
|
||||
var currentValue float64
|
||||
var err error
|
||||
if currentValue, err = metrica.dataSource.GetGaugeValue(metrica.dataSourceKey); err == nil {
|
||||
value = currentValue - metrica.previousValue
|
||||
metrica.previousValue = currentValue
|
||||
}
|
||||
return value, err
|
||||
}
|
||||
|
||||
type histogramMetrica struct {
|
||||
*baseGoMetrica
|
||||
statFunction int
|
||||
percentileValue float64
|
||||
}
|
||||
|
||||
func (metrica *histogramMetrica) GetValue() (float64, error) {
|
||||
return metrica.dataSource.GetHistogramValue(metrica.dataSourceKey, metrica.statFunction, metrica.percentileValue)
|
||||
}
|
194
vendor/github.com/yvasiyarov/gorelic/http_metrics.go
generated
vendored
Normal file
194
vendor/github.com/yvasiyarov/gorelic/http_metrics.go
generated
vendored
Normal file
|
@ -0,0 +1,194 @@
|
|||
package gorelic
|
||||
|
||||
import (
|
||||
metrics "github.com/yvasiyarov/go-metrics"
|
||||
"github.com/yvasiyarov/newrelic_platform_go"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
type tHTTPHandlerFunc func(http.ResponseWriter, *http.Request)
|
||||
type tHTTPHandler struct {
|
||||
originalHandler http.Handler
|
||||
originalHandlerFunc tHTTPHandlerFunc
|
||||
isFunc bool
|
||||
timer metrics.Timer
|
||||
}
|
||||
|
||||
var httpTimer metrics.Timer
|
||||
|
||||
func newHTTPHandlerFunc(h tHTTPHandlerFunc) *tHTTPHandler {
|
||||
return &tHTTPHandler{
|
||||
isFunc: true,
|
||||
originalHandlerFunc: h,
|
||||
}
|
||||
}
|
||||
func newHTTPHandler(h http.Handler) *tHTTPHandler {
|
||||
return &tHTTPHandler{
|
||||
isFunc: false,
|
||||
originalHandler: h,
|
||||
}
|
||||
}
|
||||
|
||||
func (handler *tHTTPHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
startTime := time.Now()
|
||||
defer handler.timer.UpdateSince(startTime)
|
||||
|
||||
if handler.isFunc {
|
||||
handler.originalHandlerFunc(w, req)
|
||||
} else {
|
||||
handler.originalHandler.ServeHTTP(w, req)
|
||||
}
|
||||
}
|
||||
|
||||
type baseTimerMetrica struct {
|
||||
dataSource metrics.Timer
|
||||
name string
|
||||
units string
|
||||
}
|
||||
|
||||
func (metrica *baseTimerMetrica) GetName() string {
|
||||
return metrica.name
|
||||
}
|
||||
|
||||
func (metrica *baseTimerMetrica) GetUnits() string {
|
||||
return metrica.units
|
||||
}
|
||||
|
||||
type timerRate1Metrica struct {
|
||||
*baseTimerMetrica
|
||||
}
|
||||
|
||||
func (metrica *timerRate1Metrica) GetValue() (float64, error) {
|
||||
return metrica.dataSource.Rate1(), nil
|
||||
}
|
||||
|
||||
type timerRateMeanMetrica struct {
|
||||
*baseTimerMetrica
|
||||
}
|
||||
|
||||
func (metrica *timerRateMeanMetrica) GetValue() (float64, error) {
|
||||
return metrica.dataSource.RateMean(), nil
|
||||
}
|
||||
|
||||
type timerMeanMetrica struct {
|
||||
*baseTimerMetrica
|
||||
}
|
||||
|
||||
func (metrica *timerMeanMetrica) GetValue() (float64, error) {
|
||||
return metrica.dataSource.Mean() / float64(time.Millisecond), nil
|
||||
}
|
||||
|
||||
type timerMinMetrica struct {
|
||||
*baseTimerMetrica
|
||||
}
|
||||
|
||||
func (metrica *timerMinMetrica) GetValue() (float64, error) {
|
||||
return float64(metrica.dataSource.Min()) / float64(time.Millisecond), nil
|
||||
}
|
||||
|
||||
type timerMaxMetrica struct {
|
||||
*baseTimerMetrica
|
||||
}
|
||||
|
||||
func (metrica *timerMaxMetrica) GetValue() (float64, error) {
|
||||
return float64(metrica.dataSource.Max()) / float64(time.Millisecond), nil
|
||||
}
|
||||
|
||||
type timerPercentile75Metrica struct {
|
||||
*baseTimerMetrica
|
||||
}
|
||||
|
||||
func (metrica *timerPercentile75Metrica) GetValue() (float64, error) {
|
||||
return metrica.dataSource.Percentile(0.75) / float64(time.Millisecond), nil
|
||||
}
|
||||
|
||||
type timerPercentile90Metrica struct {
|
||||
*baseTimerMetrica
|
||||
}
|
||||
|
||||
func (metrica *timerPercentile90Metrica) GetValue() (float64, error) {
|
||||
return metrica.dataSource.Percentile(0.90) / float64(time.Millisecond), nil
|
||||
}
|
||||
|
||||
type timerPercentile95Metrica struct {
|
||||
*baseTimerMetrica
|
||||
}
|
||||
|
||||
func (metrica *timerPercentile95Metrica) GetValue() (float64, error) {
|
||||
return metrica.dataSource.Percentile(0.95) / float64(time.Millisecond), nil
|
||||
}
|
||||
|
||||
func addHTTPMericsToComponent(component newrelic_platform_go.IComponent, timer metrics.Timer) {
|
||||
rate1 := &timerRate1Metrica{
|
||||
baseTimerMetrica: &baseTimerMetrica{
|
||||
name: "http/throughput/1minute",
|
||||
units: "rps",
|
||||
dataSource: timer,
|
||||
},
|
||||
}
|
||||
component.AddMetrica(rate1)
|
||||
|
||||
rateMean := &timerRateMeanMetrica{
|
||||
baseTimerMetrica: &baseTimerMetrica{
|
||||
name: "http/throughput/rateMean",
|
||||
units: "rps",
|
||||
dataSource: timer,
|
||||
},
|
||||
}
|
||||
component.AddMetrica(rateMean)
|
||||
|
||||
responseTimeMean := &timerMeanMetrica{
|
||||
baseTimerMetrica: &baseTimerMetrica{
|
||||
name: "http/responseTime/mean",
|
||||
units: "ms",
|
||||
dataSource: timer,
|
||||
},
|
||||
}
|
||||
component.AddMetrica(responseTimeMean)
|
||||
|
||||
responseTimeMax := &timerMaxMetrica{
|
||||
baseTimerMetrica: &baseTimerMetrica{
|
||||
name: "http/responseTime/max",
|
||||
units: "ms",
|
||||
dataSource: timer,
|
||||
},
|
||||
}
|
||||
component.AddMetrica(responseTimeMax)
|
||||
|
||||
responseTimeMin := &timerMinMetrica{
|
||||
baseTimerMetrica: &baseTimerMetrica{
|
||||
name: "http/responseTime/min",
|
||||
units: "ms",
|
||||
dataSource: timer,
|
||||
},
|
||||
}
|
||||
component.AddMetrica(responseTimeMin)
|
||||
|
||||
responseTimePercentile75 := &timerPercentile75Metrica{
|
||||
baseTimerMetrica: &baseTimerMetrica{
|
||||
name: "http/responseTime/percentile75",
|
||||
units: "ms",
|
||||
dataSource: timer,
|
||||
},
|
||||
}
|
||||
component.AddMetrica(responseTimePercentile75)
|
||||
|
||||
responseTimePercentile90 := &timerPercentile90Metrica{
|
||||
baseTimerMetrica: &baseTimerMetrica{
|
||||
name: "http/responseTime/percentile90",
|
||||
units: "ms",
|
||||
dataSource: timer,
|
||||
},
|
||||
}
|
||||
component.AddMetrica(responseTimePercentile90)
|
||||
|
||||
responseTimePercentile95 := &timerPercentile95Metrica{
|
||||
baseTimerMetrica: &baseTimerMetrica{
|
||||
name: "http/responseTime/percentile95",
|
||||
units: "ms",
|
||||
dataSource: timer,
|
||||
},
|
||||
}
|
||||
component.AddMetrica(responseTimePercentile95)
|
||||
}
|
110
vendor/github.com/yvasiyarov/gorelic/memory_metrics.go
generated
vendored
Normal file
110
vendor/github.com/yvasiyarov/gorelic/memory_metrics.go
generated
vendored
Normal file
|
@ -0,0 +1,110 @@
|
|||
package gorelic
|
||||
|
||||
import (
|
||||
metrics "github.com/yvasiyarov/go-metrics"
|
||||
"github.com/yvasiyarov/newrelic_platform_go"
|
||||
"time"
|
||||
)
|
||||
|
||||
func newMemoryMetricaDataSource(pollInterval int) goMetricaDataSource {
|
||||
r := metrics.NewRegistry()
|
||||
|
||||
metrics.RegisterRuntimeMemStats(r)
|
||||
metrics.CaptureRuntimeMemStatsOnce(r)
|
||||
go metrics.CaptureRuntimeMemStats(r, time.Duration(pollInterval)*time.Second)
|
||||
return goMetricaDataSource{r}
|
||||
}
|
||||
|
||||
func addMemoryMericsToComponent(component newrelic_platform_go.IComponent, pollInterval int) {
|
||||
gaugeMetrics := []*baseGoMetrica{
|
||||
//Memory in use metrics
|
||||
&baseGoMetrica{
|
||||
name: "InUse/Total",
|
||||
units: "bytes",
|
||||
dataSourceKey: "runtime.MemStats.Alloc",
|
||||
},
|
||||
&baseGoMetrica{
|
||||
name: "InUse/Heap",
|
||||
units: "bytes",
|
||||
dataSourceKey: "runtime.MemStats.HeapAlloc",
|
||||
},
|
||||
&baseGoMetrica{
|
||||
name: "InUse/Stack",
|
||||
units: "bytes",
|
||||
dataSourceKey: "runtime.MemStats.StackInuse",
|
||||
},
|
||||
&baseGoMetrica{
|
||||
name: "InUse/MSpanInuse",
|
||||
units: "bytes",
|
||||
dataSourceKey: "runtime.MemStats.MSpanInuse",
|
||||
},
|
||||
&baseGoMetrica{
|
||||
name: "InUse/MCacheInuse",
|
||||
units: "bytes",
|
||||
dataSourceKey: "runtime.MemStats.MCacheInuse",
|
||||
},
|
||||
}
|
||||
ds := newMemoryMetricaDataSource(pollInterval)
|
||||
for _, m := range gaugeMetrics {
|
||||
m.basePath = "Runtime/Memory/"
|
||||
m.dataSource = ds
|
||||
component.AddMetrica(&gaugeMetrica{m})
|
||||
}
|
||||
|
||||
gaugeIncMetrics := []*baseGoMetrica{
|
||||
//NO operations graph
|
||||
&baseGoMetrica{
|
||||
name: "Operations/NoPointerLookups",
|
||||
units: "lookups",
|
||||
dataSourceKey: "runtime.MemStats.Lookups",
|
||||
},
|
||||
&baseGoMetrica{
|
||||
name: "Operations/NoMallocs",
|
||||
units: "mallocs",
|
||||
dataSourceKey: "runtime.MemStats.Mallocs",
|
||||
},
|
||||
&baseGoMetrica{
|
||||
name: "Operations/NoFrees",
|
||||
units: "frees",
|
||||
dataSourceKey: "runtime.MemStats.Frees",
|
||||
},
|
||||
|
||||
// Sytem memory allocations
|
||||
&baseGoMetrica{
|
||||
name: "SysMem/Total",
|
||||
units: "bytes",
|
||||
dataSourceKey: "runtime.MemStats.Sys",
|
||||
},
|
||||
&baseGoMetrica{
|
||||
name: "SysMem/Heap",
|
||||
units: "bytes",
|
||||
dataSourceKey: "runtime.MemStats.HeapSys",
|
||||
},
|
||||
&baseGoMetrica{
|
||||
name: "SysMem/Stack",
|
||||
units: "bytes",
|
||||
dataSourceKey: "runtime.MemStats.StackSys",
|
||||
},
|
||||
&baseGoMetrica{
|
||||
name: "SysMem/MSpan",
|
||||
units: "bytes",
|
||||
dataSourceKey: "runtime.MemStats.MSpanSys",
|
||||
},
|
||||
&baseGoMetrica{
|
||||
name: "SysMem/MCache",
|
||||
units: "bytes",
|
||||
dataSourceKey: "runtime.MemStats.MCacheSys",
|
||||
},
|
||||
&baseGoMetrica{
|
||||
name: "SysMem/BuckHash",
|
||||
units: "bytes",
|
||||
dataSourceKey: "runtime.MemStats.BuckHashSys",
|
||||
},
|
||||
}
|
||||
|
||||
for _, m := range gaugeIncMetrics {
|
||||
m.basePath = "Runtime/Memory/"
|
||||
m.dataSource = ds
|
||||
component.AddMetrica(&gaugeIncMetrica{baseGoMetrica: m})
|
||||
}
|
||||
}
|
15
vendor/github.com/yvasiyarov/gorelic/nut.json
generated
vendored
Normal file
15
vendor/github.com/yvasiyarov/gorelic/nut.json
generated
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"Version": "0.0.6",
|
||||
"Vendor": "yvasiyarov",
|
||||
"Authors": [
|
||||
{
|
||||
"FullName": "Yuriy Vasiyarov",
|
||||
"Email": "varyous@gmail.com"
|
||||
}
|
||||
],
|
||||
"ExtraFiles": [
|
||||
"README.md",
|
||||
"LICENSE"
|
||||
],
|
||||
"Homepage": "https://github.com/yvasiyarov/gorelic"
|
||||
}
|
196
vendor/github.com/yvasiyarov/gorelic/runtime_metrics.go
generated
vendored
Normal file
196
vendor/github.com/yvasiyarov/gorelic/runtime_metrics.go
generated
vendored
Normal file
|
@ -0,0 +1,196 @@
|
|||
package gorelic
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/yvasiyarov/newrelic_platform_go"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const linuxSystemQueryInterval = 60
|
||||
|
||||
// Number of goroutines metrica
|
||||
type noGoroutinesMetrica struct{}
|
||||
|
||||
func (metrica *noGoroutinesMetrica) GetName() string {
|
||||
return "Runtime/General/NOGoroutines"
|
||||
}
|
||||
func (metrica *noGoroutinesMetrica) GetUnits() string {
|
||||
return "goroutines"
|
||||
}
|
||||
func (metrica *noGoroutinesMetrica) GetValue() (float64, error) {
|
||||
return float64(runtime.NumGoroutine()), nil
|
||||
}
|
||||
|
||||
// Number of CGO calls metrica
|
||||
type noCgoCallsMetrica struct {
|
||||
lastValue int64
|
||||
}
|
||||
|
||||
func (metrica *noCgoCallsMetrica) GetName() string {
|
||||
return "Runtime/General/NOCgoCalls"
|
||||
}
|
||||
func (metrica *noCgoCallsMetrica) GetUnits() string {
|
||||
return "calls"
|
||||
}
|
||||
func (metrica *noCgoCallsMetrica) GetValue() (float64, error) {
|
||||
currentValue := runtime.NumCgoCall()
|
||||
value := float64(currentValue - metrica.lastValue)
|
||||
metrica.lastValue = currentValue
|
||||
|
||||
return value, nil
|
||||
}
|
||||
|
||||
//OS specific metrics data source interface
|
||||
type iSystemMetricaDataSource interface {
|
||||
GetValue(key string) (float64, error)
|
||||
}
|
||||
|
||||
// iSystemMetricaDataSource fabrica
|
||||
func newSystemMetricaDataSource() iSystemMetricaDataSource {
|
||||
var ds iSystemMetricaDataSource
|
||||
switch runtime.GOOS {
|
||||
default:
|
||||
ds = &systemMetricaDataSource{}
|
||||
case "linux":
|
||||
ds = &linuxSystemMetricaDataSource{
|
||||
systemData: make(map[string]string),
|
||||
}
|
||||
}
|
||||
return ds
|
||||
}
|
||||
|
||||
//Default implementation of iSystemMetricaDataSource. Just return an error
|
||||
type systemMetricaDataSource struct{}
|
||||
|
||||
func (ds *systemMetricaDataSource) GetValue(key string) (float64, error) {
|
||||
return 0, fmt.Errorf("this metrica was not implemented yet for %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
// Linux OS implementation of ISystemMetricaDataSource
|
||||
type linuxSystemMetricaDataSource struct {
|
||||
lastUpdate time.Time
|
||||
systemData map[string]string
|
||||
}
|
||||
|
||||
func (ds *linuxSystemMetricaDataSource) GetValue(key string) (float64, error) {
|
||||
if err := ds.checkAndUpdateData(); err != nil {
|
||||
return 0, err
|
||||
} else if val, ok := ds.systemData[key]; !ok {
|
||||
return 0, fmt.Errorf("system data with key %s was not found", key)
|
||||
} else if key == "VmSize" || key == "VmPeak" || key == "VmHWM" || key == "VmRSS" {
|
||||
valueParts := strings.Split(val, " ")
|
||||
if len(valueParts) != 2 {
|
||||
return 0, fmt.Errorf("invalid format for value %s", key)
|
||||
}
|
||||
valConverted, err := strconv.ParseFloat(valueParts[0], 64)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
switch valueParts[1] {
|
||||
case "kB":
|
||||
valConverted *= 1 << 10
|
||||
case "mB":
|
||||
valConverted *= 1 << 20
|
||||
case "gB":
|
||||
valConverted *= 1 << 30
|
||||
}
|
||||
return valConverted, nil
|
||||
} else if valConverted, err := strconv.ParseFloat(val, 64); err != nil {
|
||||
return valConverted, nil
|
||||
} else {
|
||||
return valConverted, nil
|
||||
}
|
||||
}
|
||||
func (ds *linuxSystemMetricaDataSource) checkAndUpdateData() error {
|
||||
startTime := time.Now()
|
||||
if startTime.Sub(ds.lastUpdate) > time.Second*linuxSystemQueryInterval {
|
||||
path := fmt.Sprintf("/proc/%d/status", os.Getpid())
|
||||
rawStats, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
lines := strings.Split(string(rawStats), "\n")
|
||||
for _, line := range lines {
|
||||
parts := strings.Split(line, ":")
|
||||
if len(parts) == 2 {
|
||||
k := strings.TrimSpace(parts[0])
|
||||
v := strings.TrimSpace(parts[1])
|
||||
|
||||
ds.systemData[k] = v
|
||||
}
|
||||
}
|
||||
ds.lastUpdate = startTime
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// OS specific metrica
|
||||
type systemMetrica struct {
|
||||
sourceKey string
|
||||
newrelicName string
|
||||
units string
|
||||
dataSource iSystemMetricaDataSource
|
||||
}
|
||||
|
||||
func (metrica *systemMetrica) GetName() string {
|
||||
return metrica.newrelicName
|
||||
}
|
||||
func (metrica *systemMetrica) GetUnits() string {
|
||||
return metrica.units
|
||||
}
|
||||
func (metrica *systemMetrica) GetValue() (float64, error) {
|
||||
return metrica.dataSource.GetValue(metrica.sourceKey)
|
||||
}
|
||||
|
||||
func addRuntimeMericsToComponent(component newrelic_platform_go.IComponent) {
|
||||
component.AddMetrica(&noGoroutinesMetrica{})
|
||||
component.AddMetrica(&noCgoCallsMetrica{})
|
||||
|
||||
ds := newSystemMetricaDataSource()
|
||||
metrics := []*systemMetrica{
|
||||
&systemMetrica{
|
||||
sourceKey: "Threads",
|
||||
units: "Threads",
|
||||
newrelicName: "Runtime/System/Threads",
|
||||
},
|
||||
&systemMetrica{
|
||||
sourceKey: "FDSize",
|
||||
units: "fd",
|
||||
newrelicName: "Runtime/System/FDSize",
|
||||
},
|
||||
// Peak virtual memory size
|
||||
&systemMetrica{
|
||||
sourceKey: "VmPeak",
|
||||
units: "bytes",
|
||||
newrelicName: "Runtime/System/Memory/VmPeakSize",
|
||||
},
|
||||
//Virtual memory size
|
||||
&systemMetrica{
|
||||
sourceKey: "VmSize",
|
||||
units: "bytes",
|
||||
newrelicName: "Runtime/System/Memory/VmCurrent",
|
||||
},
|
||||
//Peak resident set size
|
||||
&systemMetrica{
|
||||
sourceKey: "VmHWM",
|
||||
units: "bytes",
|
||||
newrelicName: "Runtime/System/Memory/RssPeak",
|
||||
},
|
||||
//Resident set size
|
||||
&systemMetrica{
|
||||
sourceKey: "VmRSS",
|
||||
units: "bytes",
|
||||
newrelicName: "Runtime/System/Memory/RssCurrent",
|
||||
},
|
||||
}
|
||||
for _, m := range metrics {
|
||||
m.dataSource = ds
|
||||
component.AddMetrica(m)
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue