Skip to content

Commit 2e70c50

Browse files
authored
Support metrics report API for plugin and implement runtime metrics report (#66)
1 parent b75bbbd commit 2e70c50

File tree

41 files changed

+1723
-36
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1723
-36
lines changed

Diff for: .github/workflows/plugin-tests.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ jobs:
8080
- mongo
8181
- mysql
8282
- plugin_exclusion
83+
- runtime_metrics
8384
steps:
8485
- uses: actions/checkout@v2
8586
with:

Diff for: .golangci.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,10 @@ linters:
9393
- typecheck
9494
- unconvert
9595
- unparam
96-
- unused
9796
- varcheck
9897
- whitespace
98+
disable:
99+
- unused
99100

100101
service:
101102
golangci-lint-version: 1.20.x

Diff for: agent/core/compile.go

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ import (
2929
_ "reflect"
3030
_ "runtime"
3131
_ "runtime/debug"
32+
_ "runtime/metrics"
33+
_ "sort"
3234
_ "strconv"
3335
_ "strings"
3436
_ "sync"

Diff for: docs/en/development-and-contribution/development-guide.md

+81
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,87 @@ Typically, use APIs as following to control or switch the context:
452452
2. Propagate the snapshot context to any other goroutine in your plugin.
453453
3. Use `tracing.ContinueContext(snapshot)` to continue the snapshot context in the target goroutine.
454454

455+
### Meter API
456+
457+
The Meter API is used to record the metrics of the target program, and currently supports the following methods:
458+
459+
```go
460+
// NewCounter creates a new counter metrics.
461+
// name is the name of the metrics
462+
// opts is the options for the metrics
463+
func NewCounter(name string, opts ...Opt) Counter
464+
465+
// NewGauge creates a new gauge metrics.
466+
// name is the name of the metrics
467+
// getter is the function to get the value of the gauge meter
468+
// opts is the options for the metrics
469+
func NewGauge(name string, getter func() float64, opts ...Opt) Gauge
470+
471+
// NewHistogram creates a new histogram metrics.
472+
// name is the name of the metrics
473+
// steps is the buckets of the histogram
474+
// opts is the options for the metrics
475+
func NewHistogram(name string, steps []float64, opts ...Opt) Histogram
476+
477+
// NewHistogramWithMinValue creates a new histogram metrics.
478+
// name is the name of the metrics
479+
// minVal is the min value of the histogram bucket
480+
// steps is the buckets of the histogram
481+
// opts is the options for the metrics
482+
func NewHistogramWithMinValue(name string, minVal float64, steps []float64, opts ...Opt) Histogram
483+
484+
// RegisterBeforeCollectHook registers a hook function which will be called before metrics collect.
485+
func RegisterBeforeCollectHook(f func())
486+
```
487+
488+
#### Meter Option
489+
490+
The Meter Options can be passed when creating a Meter to configure the information in the Meter.
491+
492+
```go
493+
// WithLabel adds a label to the metrics.
494+
func WithLabel(key, value string) Opt
495+
```
496+
497+
#### Meter Type
498+
499+
##### Counter
500+
501+
Counter is a cumulative metric that represents a single monotonically increasing counter whose value can only increase.
502+
503+
```go
504+
type Counter interface {
505+
// Get returns the current value of the counter.
506+
Get() float64
507+
// Inc increments the counter with value.
508+
Inc(val float64)
509+
}
510+
```
511+
512+
##### Gauge
513+
514+
Gauge is a metric that represents a single numerical value that can arbitrarily go up and down.
515+
516+
```go
517+
type Gauge interface {
518+
// Get returns the current value of the gauge.
519+
Get() float64
520+
}
521+
```
522+
523+
##### Histogram
524+
525+
Histogram is a metric that represents the distribution of a set of values.
526+
527+
```go
528+
type Histogram interface {
529+
// Observe find the value associate bucket and add 1.
530+
Observe(val float64)
531+
// ObserveWithCount find the value associate bucket and add specific count.
532+
ObserveWithCount(val float64, count int64)
533+
}
534+
```
535+
455536
## Import Plugin
456537

457538
Once you have finished developing the plugin, you need to import the completed module into the Agent program and [define it in the corresponding file](../../../tools/go-agent/instrument/plugins/register.go).

Diff for: go.work

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use (
1515
./plugins/microv4
1616
./plugins/mongo
1717
./plugins/sql
18+
./plugins/runtimemetrics
1819

1920
./test/benchmark-codebase/consumer
2021
./test/benchmark-codebase/provider
@@ -34,6 +35,7 @@ use (
3435
./test/plugins/scenarios/mysql
3536

3637
./test/plugins/scenarios/plugin_exclusion
38+
./test/plugins/scenarios/runtime_metrics
3739

3840
./tools/go-agent
3941

Diff for: plugins/core/context.go

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ var (
2525
SetGlobalOperator = func(interface{}) {}
2626
GetGlobalOperator = func() interface{} { return nil }
2727
GetInitNotify = func() []func() { return nil }
28+
MetricsObtain = func() ([]interface{}, []func()) { return nil, nil }
2829
)
2930

3031
type ContextSnapshoter interface {

Diff for: plugins/core/instrument/enhance.go

+7
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ type EnhanceType int
2424
var (
2525
EnhanceTypeMethod EnhanceType = 1
2626
EnhanceTypeStruct EnhanceType = 2
27+
EnhanceTypeForce EnhanceType = 3
2728
)
2829

2930
type MethodFilterOption func(decl *dst.FuncDecl, files []*dst.File) bool
@@ -35,6 +36,8 @@ type EnhanceMatcher struct {
3536
Receiver string
3637
MethodFilters []MethodFilterOption
3738
StructFilters []StructFilterOption
39+
40+
ForceEnhance bool
3841
}
3942

4043
// NewStaticMethodEnhance creates a new EnhanceMatcher for static method.
@@ -52,6 +55,10 @@ func NewStructEnhance(name string, filters ...StructFilterOption) *EnhanceMatche
5255
return &EnhanceMatcher{Type: EnhanceTypeStruct, Name: name, StructFilters: filters}
5356
}
5457

58+
func NewForceEnhance() *EnhanceMatcher {
59+
return &EnhanceMatcher{Type: EnhanceTypeForce, ForceEnhance: true}
60+
}
61+
5562
func verifyTypeName(exp dst.Expr, val string) bool {
5663
data := generateTypeNameByExp(exp)
5764
return data == val

0 commit comments

Comments
 (0)