Skip to content

Commit

Permalink
[receiver/sshcheck] Include SSH endpoint resource attribute (open-tel…
Browse files Browse the repository at this point in the history
…emetry#24676)

**Description:** The metadata.yml for the SSH check receiver currently
documents a resource attribute containing the SSH endpoint but this is
not emitted. This PR updates the receiver to include this resource
attribute.

**Link to tracking Issue:** open-telemetry#24441 

**Testing:**

Example collector config:
```yaml
receivers:
  sshcheck:
    endpoint: 13.245.150.131:22
    username: ec2-user
    key_file: /Users/dewald.dejager/.ssh/sandbox.pem
    collection_interval: 15s
    known_hosts: /Users/dewald.dejager/.ssh/known_hosts
    ignore_host_key: false
    resource_attributes:
      "ssh.endpoint":
        enabled: true

exporters:
  logging:
    verbosity: detailed
  prometheus:
    endpoint: 0.0.0.0:8081
    resource_to_telemetry_conversion:
      enabled: true

service:
  pipelines:
    metrics:
      receivers: [sshcheck]
      exporters: [logging, prometheus]
```

The log output looks like this:
```
2023-07-30T16:52:38.724+0200    info    MetricsExporter {"kind": "exporter", "data_type": "metrics", "name": "logging", "resource metrics": 1, "metrics": 2, "data points": 2}
2023-07-30T16:52:38.724+0200    info    ResourceMetrics #0
Resource SchemaURL: 
Resource attributes:
     -> ssh.endpoint: Str(13.245.150.131:22)
ScopeMetrics #0
ScopeMetrics SchemaURL: 
InstrumentationScope otelcol/sshcheckreceiver 0.82.0-dev
Metric #0
Descriptor:
     -> Name: sshcheck.duration
     -> Description: Measures the duration of SSH connection.
     -> Unit: ms
     -> DataType: Gauge
NumberDataPoints #0
StartTimestamp: 2023-07-30 14:52:22.381672 +0000 UTC
Timestamp: 2023-07-30 14:52:38.404003 +0000 UTC
Value: 319
Metric #1
Descriptor:
     -> Name: sshcheck.status
     -> Description: 1 if the SSH client successfully connected, otherwise 0.
     -> Unit: 1
     -> DataType: Sum
     -> IsMonotonic: false
     -> AggregationTemporality: Cumulative
NumberDataPoints #0
StartTimestamp: 2023-07-30 14:52:22.381672 +0000 UTC
Timestamp: 2023-07-30 14:52:38.404003 +0000 UTC
Value: 1
```

And the Prometheus metrics look like this:
```
# HELP sshcheck_duration Measures the duration of SSH connection.
# TYPE sshcheck_duration gauge
sshcheck_duration{ssh_endpoint="13.245.150.131:22"} 311
# HELP sshcheck_status 1 if the SSH client successfully connected, otherwise 0.
# TYPE sshcheck_status gauge
sshcheck_status{ssh_endpoint="13.245.150.131:22"} 1
```
  • Loading branch information
DewaldDeJager authored Aug 1, 2023
1 parent 95b3bca commit 753c593
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 1 deletion.
20 changes: 20 additions & 0 deletions .chloggen/add-ssh-endpoint-resource-attribute.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Use this changelog template to create an entry for release notes.
# If your change doesn't affect end users, such as a test fix or a tooling change,
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.

# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: bug_fix

# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
component: receiver/sshcheck

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Add the SSH endpoint as a resource attribute

# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
issues: [24441]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext:
5 changes: 4 additions & 1 deletion receiver/sshcheckreceiver/scraper.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type sshcheckScraper struct {
*configssh.Client
*Config
settings component.TelemetrySettings
rb *metadata.ResourceBuilder
mb *metadata.MetricsBuilder
}

Expand Down Expand Up @@ -124,13 +125,15 @@ func (s *sshcheckScraper) scrape(ctx context.Context) (_ pmetric.Metrics, err er
}
}

return s.mb.Emit(), nil
s.rb.SetSSHEndpoint(s.Config.SSHClientSettings.Endpoint)
return s.mb.Emit(metadata.WithResource(s.rb.Emit())), nil
}

func newScraper(conf *Config, settings receiver.CreateSettings) *sshcheckScraper {
return &sshcheckScraper{
Config: conf,
settings: settings.TelemetrySettings,
rb: metadata.NewResourceBuilder(conf.MetricsBuilderConfig.ResourceAttributes),
mb: metadata.NewMetricsBuilder(conf.MetricsBuilderConfig, settings),
}
}
Expand Down
36 changes: 36 additions & 0 deletions receiver/sshcheckreceiver/scraper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,42 @@ func TestScraper(t *testing.T) {
}
}

func TestScraperPropagatesResourceAttributes(t *testing.T) {
if !supportedOS() {
t.Skip("Skip tests if not running on one of: [linux, darwin, freebsd, openbsd]")
}
endpoint := setupSSHServer(t)
require.NotEmpty(t, endpoint)

f := NewFactory()
cfg := f.CreateDefaultConfig().(*Config)
cfg.MetricsBuilderConfig.ResourceAttributes.SSHEndpoint.Enabled = true
cfg.ScraperControllerSettings.CollectionInterval = 100 * time.Millisecond
cfg.Username = "otelu"
cfg.Password = "otelp"
cfg.Endpoint = endpoint
cfg.IgnoreHostKey = true

settings := receivertest.NewNopCreateSettings()

scraper := newScraper(cfg, settings)
require.NoError(t, scraper.start(context.Background(), componenttest.NewNopHost()), "failed starting scraper")

actualMetrics, err := scraper.scrape(context.Background())
require.NoError(t, err, "failed scrape")

resourceMetrics := actualMetrics.ResourceMetrics()
expectedResourceAttributes := map[string]any{"ssh.endpoint": endpoint}
for i := 0; i < resourceMetrics.Len(); i++ {
resourceAttributes := resourceMetrics.At(i).Resource().Attributes()
for name, value := range expectedResourceAttributes {
actualAttributeValue, ok := resourceAttributes.Get(name)
require.True(t, ok)
require.Equal(t, value, actualAttributeValue.Str())
}
}
}

func TestScraperDoesNotErrForSSHErr(t *testing.T) {
if !supportedOS() {
t.Skip("Skip tests if not running on one of: [linux, darwin, freebsd, openbsd]")
Expand Down

0 comments on commit 753c593

Please sign in to comment.