Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Add Catchpoint Exporter #6942

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
574 changes: 245 additions & 329 deletions CHANGELOG.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
---
aliases:
- /docs/grafana-cloud/agent/flow/reference/components/prometheus.exporter.catchpoint/
- /docs/grafana-cloud/monitor-infrastructure/agent/flow/reference/components/prometheus.exporter.catchpoint/
- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/reference/components/prometheus.exporter.catchpoint/
- /docs/grafana-cloud/send-data/agent/flow/reference/components/prometheus.exporter.catchpoint/
canonical: https://grafana.com/docs/agent/latest/flow/reference/components/prometheus.exporter.catchpoint/
description: Learn about prometheus.exporter.catchpoint
title: prometheus.exporter.catchpoint
---

# prometheus.exporter.catchpoint

The `prometheus.exporter.catchpoint` component embeds
[catchpoint_exporter](https://github.com/grafana/catchpoint-prometheus-exporter) for collecting statistics from a Catchpoint account.

## Usage

```river
prometheus.exporter.catchpoint "LABEL" {
port = PORT
verbosity_logging = VERBOSITY_LOGGING
webhook_path = WEBHOOK_PATH
}
```

## Arguments

The following arguments can be used to configure the exporter's behavior.
Omitted fields take their default values.

| Name | Type | Description | Default | Required |
| ------------------- | -------- | ----------------------------------------------------- | ----------------------- | -------- |
| `port` | `string` | The account to collect metrics for. | `"9090"` | yes |
| `verbosity_logging` | `bool` | The username for the user used when querying metrics. | `false` | yes |
| `webhook_path` | `string` | The password for the user used when querying metrics. | `"/catchpoint-webhook"` | yes |

## Blocks

The `prometheus.exporter.catchpoint` component does not support any blocks, and is configured
fully through arguments.

## Exported fields

{{< docs/shared lookup="flow/reference/components/exporter-component-exports.md" source="agent" version="<AGENT_VERSION>" >}}

## Component health

`prometheus.exporter.catchpoint` is only reported as unhealthy if given
an invalid configuration. In those cases, exported fields retain their last
healthy values.

## Debug information

`prometheus.exporter.catchpoint` does not expose any component-specific
debug information.

## Debug metrics

`prometheus.exporter.catchpoint` does not expose any component-specific
debug metrics.

## Example

This example uses a [`prometheus.scrape` component][scrape] to collect metrics
from `prometheus.exporter.catchpoint`:

```river
prometheus.exporter.catchpoint "example" {
port = "9090"
verbose_logging = false
webhook_path = "/catchpoint-webhook"
}

// Configure a prometheus.scrape component to collect catchpoint metrics.
prometheus.scrape "demo" {
targets = prometheus.exporter.catchpoint.example.targets
forward_to = [prometheus.remote_write.demo.receiver]
}

prometheus.remote_write "demo" {
endpoint {
url = PROMETHEUS_REMOTE_WRITE_URL

basic_auth {
username = USERNAME
password = PASSWORD
}
}
}
```

Replace the following:

- `PROMETHEUS_REMOTE_WRITE_URL`: The URL of the Prometheus remote_write-compatible server to send metrics to.
- `USERNAME`: The username to use for authentication to the remote_write API.
- `PASSWORD`: The password to use for authentication to the remote_write API.

[scrape]: {{< relref "./prometheus.scrape.md" >}}

<!-- START GENERATED COMPATIBLE COMPONENTS -->

## Compatible components

`prometheus.exporter.catchpoint` has exports that can be consumed by the following components:

- Components that consume [Targets](../../compatibility/#targets-consumers)

{{< admonition type="note" >}}
Connecting some components may not be sensible or components may require further configuration to make the connection work correctly.
Refer to the linked documentation for more details.
{{< /admonition >}}

<!-- END GENERATED COMPATIBLE COMPONENTS -->
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,9 @@ integrations:

cloudwatch_configs:
[- <cloudwatch_config>]

catchpoint_configs:
[- <catchpoint_config>]
```

Note that most integrations are no longer configured with the `_exporter` name.
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,7 @@ require (
github.com/dimchansky/utfbom v1.1.1
github.com/githubexporter/github-exporter v0.0.0-20231025122338-656e7dc33fe7
github.com/grafana/agent-remote-config v0.0.2
github.com/grafana/catchpoint-prometheus-exporter v0.0.0-20240606062944-e55f3668661d
github.com/grafana/jfr-parser/pprof v0.0.0-20240126072739-986e71dc0361
github.com/grafana/jsonparser v0.0.0-20240209175146-098958973a2d
github.com/grafana/kafka_exporter v0.0.0-20240409084445-5e3488ad9f9a
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1024,6 +1024,8 @@ github.com/grafana/agent-remote-config v0.0.2 h1:s3FKgVzfY5Ij+xG0wVKgVvtDrh/Bz0Z
github.com/grafana/agent-remote-config v0.0.2/go.mod h1:amyG3pVNXKcMo+kNN46yhnAXAz/m/9Ew9MRf53n7XBg=
github.com/grafana/cadvisor v0.0.0-20231110094609-5f7917925dea h1:Q5f5/nJJ0SbusZjA6F6XkJuHDbl2/PqdTGw6wHsuccA=
github.com/grafana/cadvisor v0.0.0-20231110094609-5f7917925dea/go.mod h1:XjiOCFjmxXIWwauV5p39Mr2Yxlpyk72uKQH1UZvd4fQ=
github.com/grafana/catchpoint-prometheus-exporter v0.0.0-20240606062944-e55f3668661d h1:6sNPBwOokfCxAyateu7iLdtyWDUzaLLShPs7F4eTLfw=
github.com/grafana/catchpoint-prometheus-exporter v0.0.0-20240606062944-e55f3668661d/go.mod h1:aGPSALDAkw18nn8M7gumhM/MbJG+zgOA3jNWTwPYtLg=
github.com/grafana/ckit v0.0.0-20230906125525-c046c99a5c04 h1:tG8Qxq4dN1WqakMmsPaxaH4+OQhYg5HVsarw5acLBX8=
github.com/grafana/ckit v0.0.0-20230906125525-c046c99a5c04/go.mod h1:HOnDIbkxfvVlDM5FBujt0uawGLfdpdTeqE7fIwfBmQk=
github.com/grafana/cloudflare-go v0.0.0-20230110200409-c627cf6792f2 h1:qhugDMdQ4Vp68H0tp/0iN17DM2ehRo1rLEdOFe/gB8I=
Expand Down
1 change: 1 addition & 0 deletions internal/component/all/all.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ import (
_ "github.com/grafana/agent/internal/component/prometheus/exporter/azure" // Import prometheus.exporter.azure
_ "github.com/grafana/agent/internal/component/prometheus/exporter/blackbox" // Import prometheus.exporter.blackbox
_ "github.com/grafana/agent/internal/component/prometheus/exporter/cadvisor" // Import prometheus.exporter.cadvisor
_ "github.com/grafana/agent/internal/component/prometheus/exporter/catchpoint" // Import prometheus.exporter.catchpoint
_ "github.com/grafana/agent/internal/component/prometheus/exporter/cloudwatch" // Import prometheus.exporter.cloudwatch
_ "github.com/grafana/agent/internal/component/prometheus/exporter/consul" // Import prometheus.exporter.consul
_ "github.com/grafana/agent/internal/component/prometheus/exporter/dnsmasq" // Import prometheus.exporter.dnsmasq
Expand Down
54 changes: 54 additions & 0 deletions internal/component/prometheus/exporter/catchpoint/catchpoint.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package catchpoint

import (
"github.com/grafana/agent/internal/component"
"github.com/grafana/agent/internal/component/prometheus/exporter"
"github.com/grafana/agent/internal/featuregate"
"github.com/grafana/agent/static/integrations"
"github.com/grafana/agent/static/integrations/catchpoint_exporter"
)

func init() {
component.Register(component.Registration{
Name: "prometheus.exporter.catchpoint",
Stability: featuregate.StabilityStable,
Args: Arguments{},
Exports: exporter.Exports{},
Build: exporter.New(createExporter, "catchpoint"),
})
}

func createExporter(opts component.Options, args component.Arguments, defaultInstanceKey string) (integrations.Integration, string, error) {
a := args.(Arguments)
return integrations.NewIntegrationWithInstanceKey(opts.Logger, a.Convert(), defaultInstanceKey)
}

// DefaultArguments holds the default settings for the catchpoint exporter
var DefaultArguments = Arguments{
VerboseLogging: false,
WebhookPath: "/catchpoint-webhook",
Port: "9090",
}

// Arguments controls the catchpoint exporter.
type Arguments struct {
VerboseLogging bool `river:"verbose_logging,attr"`
WebhookPath string `river:"webhook_path,attr"`
Port string `river:"port,attr"`
}

// UnmarshalRiver implements River unmarshalling for Arguments.
func (a *Arguments) UnmarshalRiver(f func(interface{}) error) error {
*a = DefaultArguments

type args Arguments
return f((*args)(a))
}

func (a *Arguments) Convert() *catchpoint_exporter.Config {
return &catchpoint_exporter.Config{
VerboseLogging: a.VerboseLogging,
WebhookPath: a.WebhookPath,
Port: a.Port,
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package catchpoint

import (
"testing"

"github.com/grafana/agent/static/integrations/catchpoint_exporter"
"github.com/grafana/river"
"github.com/stretchr/testify/require"
)

func TestRiverUnmarshal(t *testing.T) {
riverConfig := `
port = "3030"
verbose_logging = true
webhook_path = "/nondefault-webhook-path"
`

var args Arguments
err := river.Unmarshal([]byte(riverConfig), &args)
require.NoError(t, err)

expected := Arguments{
VerboseLogging: true,
Port: "3030",
WebhookPath: "/nondefault-webhook-path",
}

require.Equal(t, expected, args)
}

func TestConvert(t *testing.T) {
riverConfig := `
port = "3030"
verbose_logging = true
webhook_path = "/nondefault-webhook-path"
`

var args Arguments
err := river.Unmarshal([]byte(riverConfig), &args)
require.NoError(t, err)

res := args.Convert()

expected := catchpoint_exporter.Config{
VerboseLogging: true,
Port: "3030",
WebhookPath: "/nondefault-webhook-path",
}
require.Equal(t, expected, *res)
}
3 changes: 3 additions & 0 deletions internal/converter/internal/staticconvert/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/grafana/agent/static/integrations/azure_exporter"
"github.com/grafana/agent/static/integrations/blackbox_exporter"
"github.com/grafana/agent/static/integrations/cadvisor"
"github.com/grafana/agent/static/integrations/catchpoint_exporter"
"github.com/grafana/agent/static/integrations/cloudwatch_exporter"
"github.com/grafana/agent/static/integrations/consul_exporter"
"github.com/grafana/agent/static/integrations/dnsmasq_exporter"
Expand Down Expand Up @@ -149,6 +150,7 @@ func validateIntegrationsV1(integrationsConfig *v1.ManagerConfig) diag.Diagnosti
case *redis_exporter.Config:
case *snmp_exporter.Config:
case *snowflake_exporter.Config:
case *catchpoint_exporter.Config:
case *squid_exporter.Config:
case *statsd_exporter.Config:
case *windows_exporter.Config:
Expand Down Expand Up @@ -196,6 +198,7 @@ func validateIntegrationsV2(integrationsConfig *v2.SubsystemOptions) diag.Diagno
case *process_exporter.Config:
case *redis_exporter.Config:
case *snowflake_exporter.Config:
case *catchpoint_exporter.Config:
case *squid_exporter.Config:
case *statsd_exporter.Config:
case *windows_exporter.Config:
Expand Down
66 changes: 66 additions & 0 deletions static/integrations/catchpoint_exporter/catchpoint_exporter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package catchpoint_exporter

import (
"github.com/go-kit/log"
"github.com/grafana/agent/static/integrations"
integrations_v2 "github.com/grafana/agent/static/integrations/v2"
"github.com/grafana/agent/static/integrations/v2/metricsutils"

collector "github.com/grafana/catchpoint-prometheus-exporter/collector"
)

// DefaultConfig is the default config for the catchpoint integration
var DefaultConfig = Config{
VerboseLogging: false,
WebhookPath: "/catchpoint-webhook",
Port: "9090",
}

// Config is the configuration for the catchpoint integration
type Config struct {
VerboseLogging bool `yaml:"verbose_logging,omitempty"`
WebhookPath string `yaml:"webhook_path,omitempty"`
Port string `yaml:"port,omitempty"`
}

func (c *Config) exporterConfig() *collector.Config {
return &collector.Config{
VerboseLogging: c.VerboseLogging,
WebhookPath: c.WebhookPath,
Port: c.Port,
}
}

// Identifier returns a string that identifies the integration.
func (c *Config) InstanceKey(agentKey string) (string, error) {
return c.Port, nil
}

// UnmarshalYAML implements yaml.Unmarshaler for Config
func (c *Config) UnmarshalYAML(unmarshal func(interface{}) error) error {
*c = DefaultConfig

type plain Config
return unmarshal((*plain)(c))
}

// Name returns the name of the integration this config is for.
func (c *Config) Name() string {
return "catchpoint"
}

func init() {
integrations.RegisterIntegration(&Config{})
integrations_v2.RegisterLegacy(&Config{}, integrations_v2.TypeMultiplex, metricsutils.NewNamedShim("catchpoint"))
}

// NewIntegration creates a new integration from the config.
func (c *Config) NewIntegration(l log.Logger) (integrations.Integration, error) {
exporterConfig := c.exporterConfig()

col := collector.NewCollector(l, exporterConfig)
return integrations.NewCollectorIntegration(
c.Name(),
integrations.WithCollectors(col),
), nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package catchpoint_exporter

import (
"os"
"testing"

"github.com/go-kit/log"
"github.com/stretchr/testify/require"
"gopkg.in/yaml.v2"
)

func TestConfig_UnmarshalYaml(t *testing.T) {
strConfig := `
port: "3030"
verbose_logging: true
webhook_path: "/nondefault-webhook-path"`

var c Config

require.NoError(t, yaml.UnmarshalStrict([]byte(strConfig), &c))

require.Equal(t, Config{
VerboseLogging: true,
Port: "3030",
WebhookPath: "/nondefault-webhook-path",
}, c)
}

func TestConfig_NewIntegration(t *testing.T) {
t.Run("integration with valid config", func(t *testing.T) {
c := &Config{
VerboseLogging: true,
Port: "3030",
WebhookPath: "/nondefault-webhook-path",
}

i, err := c.NewIntegration(log.NewJSONLogger(os.Stdout))
require.NoError(t, err)
require.NotNil(t, i)
})
}

func TestConfig_AgentKey(t *testing.T) {
c := DefaultConfig
c.Port = "3030"

ik := "agent-key"
id, err := c.InstanceKey(ik)
require.NoError(t, err)
require.Equal(t, "3030", id)
}
Loading
Loading