Skip to content

Commit

Permalink
Feat: Add Catchpoint Exporter (#1027)
Browse files Browse the repository at this point in the history
  • Loading branch information
BominRahmani committed Jun 19, 2024
1 parent 80c313d commit c636f0e
Show file tree
Hide file tree
Showing 11 changed files with 337 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ v1.2.0-rc.0
- (_Experimental_) Add an `otelcol.receiver.datadog` component to receive
metrics and traces from Datadog. (@carrieedwards, @jesusvazquez, @alexgreenbank, @fedetorres93)

- Add a `prometheus.exporter.catchpoint` component to collect metrics from Catchpoint. (@bominrahmani)

### Enhancements

- (_Public preview_) Add native histogram support to `otelcol.receiver.prometheus`. (@wildum)
Expand Down
1 change: 1 addition & 0 deletions docs/sources/reference/compatibility/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ The following components, grouped by namespace, _export_ Targets.
- [prometheus.exporter.azure](../components/prometheus.exporter.azure)
- [prometheus.exporter.blackbox](../components/prometheus.exporter.blackbox)
- [prometheus.exporter.cadvisor](../components/prometheus.exporter.cadvisor)
- [prometheus.exporter.catchpoint](../components/prometheus.exporter.catchpoint)
- [prometheus.exporter.cloudwatch](../components/prometheus.exporter.cloudwatch)
- [prometheus.exporter.consul](../components/prometheus.exporter.consul)
- [prometheus.exporter.dnsmasq](../components/prometheus.exporter.dnsmasq)
Expand Down
110 changes: 110 additions & 0 deletions docs/sources/reference/components/prometheus.exporter.catchpoint.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
---
canonical: https://grafana.com/docs/alloy/latest/reference/components/prometheus.exporter.catchpoint/
description: Learn about prometheus.exporter.catchpoint
title: prometheus.exporter.catchpoint
---

# prometheus.exporter.catchpoint

{{< docs/shared lookup="stability/experimental.md" source="alloy" version="<ALLOY_VERSION>" >}}

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

## Usage

```alloy
prometheus.exporter.catchpoint "<LABEL>" {
port = PORT
verbose_logging = <VERBOSE_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` | Sets the port on which the exporter will run. | `"9090"` | no |
| `verbose_logging` | `bool` | Enables verbose logging to provide more detailed output for debugging purposes. | `false` | no |
| `webhook_path` | `string` | Defines the path where the exporter will receive webhook data from Catchpoint | `"/catchpoint-webhook"` | no |

## Blocks

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

## Exported fields

{{< docs/shared lookup="reference/components/exporter-component-exports.md" source="alloy" version="<ALLOY_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`:

```alloy
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]: ../prometheus.scrape/

<!-- 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 -->
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ require (
github.com/grafana/alloy-remote-config v0.0.4
github.com/grafana/alloy/syntax v0.1.0
github.com/grafana/beyla v1.6.3
github.com/grafana/catchpoint-prometheus-exporter v0.0.0-20240606062944-e55f3668661d
github.com/grafana/ckit v0.0.0-20230906125525-c046c99a5c04
github.com/grafana/cloudflare-go v0.0.0-20230110200409-c627cf6792f2
github.com/grafana/dskit v0.0.0-20240104111617-ea101a3b86eb
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1011,6 +1011,8 @@ github.com/grafana/beyla v1.6.3 h1:Jonwtz2BouJ0A6vgcKZyZ4+zI22LAKDUm+NAD4WbwLI=
github.com/grafana/beyla v1.6.3/go.mod h1:kNi1vKt2ESdoOy84+zq6Z7z67+BqwaMfEngcM/K8yKA=
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 @@ -102,6 +102,7 @@ import (
_ "github.com/grafana/alloy/internal/component/prometheus/exporter/azure" // Import prometheus.exporter.azure
_ "github.com/grafana/alloy/internal/component/prometheus/exporter/blackbox" // Import prometheus.exporter.blackbox
_ "github.com/grafana/alloy/internal/component/prometheus/exporter/cadvisor" // Import prometheus.exporter.cadvisor
_ "github.com/grafana/alloy/internal/component/prometheus/exporter/catchpoint" // Import prometheus.exporter.catchpoint
_ "github.com/grafana/alloy/internal/component/prometheus/exporter/cloudwatch" // Import prometheus.exporter.cloudwatch
_ "github.com/grafana/alloy/internal/component/prometheus/exporter/consul" // Import prometheus.exporter.consul
_ "github.com/grafana/alloy/internal/component/prometheus/exporter/dnsmasq" // Import prometheus.exporter.dnsmasq
Expand Down
51 changes: 51 additions & 0 deletions internal/component/prometheus/exporter/catchpoint/catchpoint.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package catchpoint

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

func init() {
component.Register(component.Registration{
Name: "prometheus.exporter.catchpoint",
Stability: featuregate.StabilityExperimental,
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 `alloy:"verbose_logging,attr,optional"`
WebhookPath string `alloy:"webhook_path,attr,optional"`
Port string `alloy:"port,attr,optional"`
}

// SetToDefault implements syntax.Defaulter.
func (a *Arguments) SetToDefault() {
*a = DefaultArguments
}

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/alloy/internal/static/integrations/catchpoint_exporter"
"github.com/grafana/alloy/syntax"
"github.com/stretchr/testify/require"
)

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

var args Arguments
err := syntax.Unmarshal([]byte(alloyConfig), &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) {
alloyConfig := `
port = "3030"
verbose_logging = true
webhook_path = "/nondefault-webhook-path"
`

var args Arguments
err := syntax.Unmarshal([]byte(alloyConfig), &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)
}
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/alloy/internal/static/integrations"
integrations_v2 "github.com/grafana/alloy/internal/static/integrations/v2"
"github.com/grafana/alloy/internal/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,52 @@
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)
}
1 change: 1 addition & 0 deletions internal/static/integrations/install/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
_ "github.com/grafana/alloy/internal/static/integrations/azure_exporter" // register azure_exporter
_ "github.com/grafana/alloy/internal/static/integrations/blackbox_exporter" // register blackbox_exporter
_ "github.com/grafana/alloy/internal/static/integrations/cadvisor" // register cadvisor
_ "github.com/grafana/alloy/internal/static/integrations/catchpoint_exporter" // register catchpoint_exporter
_ "github.com/grafana/alloy/internal/static/integrations/cloudwatch_exporter" // register cloudwatch_exporter
_ "github.com/grafana/alloy/internal/static/integrations/consul_exporter" // register consul_exporter
_ "github.com/grafana/alloy/internal/static/integrations/dnsmasq_exporter" // register dnsmasq_exporter
Expand Down

0 comments on commit c636f0e

Please sign in to comment.