Skip to content

Commit

Permalink
Adds phlare.scrape and phlare.write component to support Profilin…
Browse files Browse the repository at this point in the history
…g. (grafana#2552)

Adds pprof.scrape and phlare.write component to support Profiling.

Co-authored-by: Karen Germond <110922559+karengermond@users.noreply.github.com>
Co-authored-by: Robert Fratto <robertfratto@gmail.com>
  • Loading branch information
3 people committed Jan 6, 2023
1 parent af97242 commit 308955c
Show file tree
Hide file tree
Showing 18 changed files with 2,915 additions and 50 deletions.
23 changes: 12 additions & 11 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ Main (unreleased)
- New Grafana Agent Flow components:

- `otelcol.receiver.kafka` receives telemetry data from Kafka. (@rfratto)
- `phlare.scrape` collects application performance profiles. (@cyriltovena)
- `phlare.write` sends application performance profiles to Grafana Phlare. (@cyriltovena)

### Enhancements

Expand Down Expand Up @@ -440,7 +442,6 @@ v0.25.1 (2022-06-16)

- Unwrap replayWAL error before attempting corruption repair. (@rlankfo)


v0.25.0 (2022-06-06)
--------------------

Expand Down Expand Up @@ -479,7 +480,7 @@ v0.25.0 (2022-06-06)

- Enable `proxy_url` support on `oauth2` for metrics and logs (update **prometheus/common** dependency to `v0.33.0`). (@martin-jaeger-maersk)

- `extra-scrape-metrics` can now be enabled with the `--enable-features=extra-scrape-metrics` feature flag. See https://prometheus.io/docs/prometheus/2.31/feature_flags/#extra-scrape-metrics for details. (@rlankfo)
- `extra-scrape-metrics` can now be enabled with the `--enable-features=extra-scrape-metrics` feature flag. See <https://prometheus.io/docs/prometheus/2.31/feature_flags/#extra-scrape-metrics> for details. (@rlankfo)

- Resolved issue in v2 integrations where if an instance name was a prefix of another the route handler would fail to
match requests on the longer name (@mattdurham)
Expand Down Expand Up @@ -895,7 +896,7 @@ v0.21.0 (2021-11-17)
v0.20.1 (2021-12-08)
--------------------

> *NOTE*: The fixes in this patch are only present in v0.20.1 and >=v0.21.2.
> _NOTE_: The fixes in this patch are only present in v0.20.1 and >=v0.21.2.
### Security fixes

Expand Down Expand Up @@ -994,8 +995,8 @@ v0.19.0 (2021-09-29)
- Reduced verbosity of tracing autologging by not logging `STATUS_CODE_UNSET`
status codes. (@mapno)

- Operator: rename Prometheus* CRDs to Metrics* and Prometheus* fields to
Metrics*. (@rfratto)
- Operator: rename `Prometheus*` CRDs to `Metrics*` and `Prometheus*` fields to
`Metrics*`. (@rfratto)

- Operator: CRDs are no longer referenced using a hyphen in the name to be
consistent with how Kubernetes refers to resources. (@rfratto)
Expand Down Expand Up @@ -1254,15 +1255,15 @@ v0.14.0 (2021-05-24)
### Security fixes

* The Scraping service API will now reject configs that read credentials from
- The Scraping service API will now reject configs that read credentials from
disk by default. This prevents malicious users from reading arbitrary files
and sending their contents over the network. The old behavior can be
re-enabled by setting `dangerous_allow_reading_files: true` in the scraping
service config. (@rfratto)

### Breaking changes

* Configuration for SigV4 has changed. (@rfratto)
- Configuration for SigV4 has changed. (@rfratto)

### Deprecations

Expand Down Expand Up @@ -1415,9 +1416,9 @@ v0.12.0 (2021-02-05)
### Breaking Changes

* The configuration format for the `loki` block has changed. (@rfratto)
- The configuration format for the `loki` block has changed. (@rfratto)

* The configuration format for the `tempo` block has changed. (@rfratto)
- The configuration format for the `tempo` block has changed. (@rfratto)

### Features

Expand Down Expand Up @@ -1601,7 +1602,7 @@ v0.8.0 (2020-11-06)
### Enhancements

- Add `<integration name>_build_info` metric to all integrations. The build
info displayed will match the build information of the Agent and *not* the
info displayed will match the build information of the Agent and _not_ the
embedded exporter. This metric is used by community dashboards, so adding it
to the Agent increases compatibility with existing dashboards that depend on
it existing. (@rfratto)
Expand Down Expand Up @@ -1980,7 +1981,7 @@ v0.1.0 (2020-03-16)
### Features

* Support for scraping Prometheus metrics and sharding the agent through the
- Support for scraping Prometheus metrics and sharding the agent through the
presence of a `host_filter` flag within the Agent configuration file.

[upgrade guide]: https://grafana.com/docs/agent/latest/upgrade-guide/
Expand Down
2 changes: 2 additions & 0 deletions component/all/all.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import (
_ "github.com/grafana/agent/component/otelcol/receiver/kafka" // Import otelcol.receiver.kafka
_ "github.com/grafana/agent/component/otelcol/receiver/otlp" // Import otelcol.receiver.otlp
_ "github.com/grafana/agent/component/otelcol/receiver/prometheus" // Import otelcol.receiver.prometheus
_ "github.com/grafana/agent/component/phlare/scrape" // Import phlare.scrape
_ "github.com/grafana/agent/component/phlare/write" // Import phlare.write
_ "github.com/grafana/agent/component/prometheus/integration/node_exporter" // Import prometheus.integration.node_exporter
_ "github.com/grafana/agent/component/prometheus/relabel" // Import prometheus.relabel
_ "github.com/grafana/agent/component/prometheus/remotewrite" // Import prometheus.remote_write
Expand Down
119 changes: 119 additions & 0 deletions component/phlare/appender.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package phlare

import (
"context"
"sync"
"time"

"github.com/hashicorp/go-multierror"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/prometheus/model/labels"
)

var NoopAppendable = AppendableFunc(func(_ context.Context, _ labels.Labels, _ []*RawSample) error { return nil })

type Appendable interface {
Appender() Appender
}

type Appender interface {
Append(ctx context.Context, labels labels.Labels, samples []*RawSample) error
}

type RawSample struct {
// raw_profile is the set of bytes of the pprof profile
RawProfile []byte
}

var _ Appendable = (*Fanout)(nil)

// Fanout supports the default Flow style of appendables since it can go to multiple outputs. It also allows the intercepting of appends.
type Fanout struct {
mut sync.RWMutex
// children is where to fan out.
children []Appendable
// ComponentID is what component this belongs to.
componentID string
writeLatency prometheus.Histogram
}

// NewFanout creates a fanout appendable.
func NewFanout(children []Appendable, componentID string, register prometheus.Registerer) *Fanout {
wl := prometheus.NewHistogram(prometheus.HistogramOpts{
Name: "phlare_fanout_latency",
Help: "Write latency for sending to phlare profiles",
})
_ = register.Register(wl)
return &Fanout{
children: children,
componentID: componentID,
writeLatency: wl,
}
}

// UpdateChildren allows changing of the children of the fanout.
func (f *Fanout) UpdateChildren(children []Appendable) {
f.mut.Lock()
defer f.mut.Unlock()
f.children = children
}

// Children returns the children of the fanout.
func (f *Fanout) Children() []Appendable {
f.mut.Lock()
defer f.mut.Unlock()
return f.children
}

// Appender satisfies the Appendable interface.
func (f *Fanout) Appender() Appender {
f.mut.RLock()
defer f.mut.RUnlock()

app := &appender{
children: make([]Appender, 0),
componentID: f.componentID,
writeLatency: f.writeLatency,
}
for _, x := range f.children {
if x == nil {
continue
}
app.children = append(app.children, x.Appender())
}
return app
}

var _ Appender = (*appender)(nil)

type appender struct {
children []Appender
componentID string
writeLatency prometheus.Histogram
}

// Append satisfies the Appender interface.
func (a *appender) Append(ctx context.Context, labels labels.Labels, samples []*RawSample) error {
now := time.Now()
defer func() {
a.writeLatency.Observe(time.Since(now).Seconds())
}()
var multiErr error
for _, x := range a.children {
err := x.Append(ctx, labels, samples)
if err != nil {
multiErr = multierror.Append(multiErr, err)
}
}
return multiErr
}

type AppendableFunc func(ctx context.Context, labels labels.Labels, samples []*RawSample) error

func (f AppendableFunc) Append(ctx context.Context, labels labels.Labels, samples []*RawSample) error {
return f(ctx, labels, samples)
}

func (f AppendableFunc) Appender() Appender {
return f
}
53 changes: 53 additions & 0 deletions component/phlare/appender_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package phlare

import (
"context"
"errors"
"testing"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/prometheus/model/labels"
"github.com/stretchr/testify/require"
"go.uber.org/atomic"
)

func Test_FanOut(t *testing.T) {
totalAppend := atomic.NewInt32(0)
lbls := labels.Labels{
{Name: "foo", Value: "bar"},
}
f := NewFanout([]Appendable{
AppendableFunc(func(_ context.Context, labels labels.Labels, _ []*RawSample) error {
require.Equal(t, lbls, labels)
totalAppend.Inc()
return nil
}),
AppendableFunc(func(_ context.Context, labels labels.Labels, _ []*RawSample) error {
require.Equal(t, lbls, labels)
totalAppend.Inc()
return nil
}),
AppendableFunc(func(_ context.Context, labels labels.Labels, _ []*RawSample) error {
require.Equal(t, lbls, labels)
totalAppend.Inc()
return nil
}),
}, "foo", prometheus.NewRegistry())
require.NoError(t, f.Appender().Append(context.Background(), lbls, []*RawSample{}))
require.Equal(t, int32(3), totalAppend.Load())
f.UpdateChildren([]Appendable{
AppendableFunc(func(_ context.Context, labels labels.Labels, _ []*RawSample) error {
require.Equal(t, lbls, labels)
totalAppend.Inc()
return errors.New("foo")
}),
AppendableFunc(func(_ context.Context, labels labels.Labels, _ []*RawSample) error {
require.Equal(t, lbls, labels)
totalAppend.Inc()
return nil
}),
})
totalAppend.Store(0)
require.Error(t, f.Appender().Append(context.Background(), lbls, []*RawSample{}))
require.Equal(t, int32(2), totalAppend.Load())
}
Loading

0 comments on commit 308955c

Please sign in to comment.