Skip to content

Commit d8cad1c

Browse files
authored
[extension/opamp] Implement ReportsHealth capability (#35488)
1 parent e9efb40 commit d8cad1c

File tree

7 files changed

+99
-0
lines changed

7 files changed

+99
-0
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: enhancement
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
7+
component: opampextension
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Implement `ReportsHealth` capability in OpAMP extension
11+
12+
# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
13+
issues: [35433]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext:
19+
20+
# If your change doesn't affect end users or the exported elements of any package,
21+
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
22+
# Optional: The change log or logs in which this entry should be included.
23+
# e.g. '[user]' or '[user, api]'
24+
# Include 'user' if the change is relevant to end users.
25+
# Include 'api' if there is a change to a library API.
26+
# Default: '[user]'
27+
change_logs: []

extension/opampextension/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ The following settings are optional for both transports:
4343
instance UID remains constant across process restarts.
4444
- `capabilities`: Keys with boolean true/false values that enable a particular OpAMP capability.
4545
- `reports_effective_config`: Whether to enable the OpAMP ReportsEffectiveConfig capability. Default is `true`.
46+
- `reports_health`: Whether to enable the OpAMP ReportsHealth capability. Default is `true`.
4647
- `agent_description`: Setting that modifies the agent description reported to the OpAMP server.
4748
- `non_identifying_attributes`: A map of key value pairs that will be added to the [non-identifying attributes](https://github.com/open-telemetry/opamp-spec/blob/main/specification.md#agentdescriptionnon_identifying_attributes) reported to the OpAMP server. If an attribute collides with the default non-identifying attributes that are automatically added, the ones specified here take precedence.
4849
- `ppid`: An optional process ID to monitor. When this process is no longer running, the extension will emit a fatal error, causing the collector to exit. This is meant to be set by the Supervisor or some other parent process, and should not be configured manually.

extension/opampextension/config.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ type AgentDescription struct {
5454
type Capabilities struct {
5555
// ReportsEffectiveConfig enables the OpAMP ReportsEffectiveConfig Capability. (default: true)
5656
ReportsEffectiveConfig bool `mapstructure:"reports_effective_config"`
57+
// ReportsHealth enables the OpAMP ReportsHealth Capability. (default: true)
58+
ReportsHealth bool `mapstructure:"reports_health"`
5759
}
5860

5961
func (caps Capabilities) toAgentCapabilities() protobufs.AgentCapabilities {
@@ -63,6 +65,9 @@ func (caps Capabilities) toAgentCapabilities() protobufs.AgentCapabilities {
6365
if caps.ReportsEffectiveConfig {
6466
agentCapabilities |= protobufs.AgentCapabilities_AgentCapabilities_ReportsEffectiveConfig
6567
}
68+
if caps.ReportsHealth {
69+
agentCapabilities |= protobufs.AgentCapabilities_AgentCapabilities_ReportsHealth
70+
}
6671

6772
return agentCapabilities
6873
}

extension/opampextension/config_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"testing"
99
"time"
1010

11+
"github.com/open-telemetry/opamp-go/protobufs"
1112
"github.com/stretchr/testify/assert"
1213
"github.com/stretchr/testify/require"
1314
"go.opentelemetry.io/collector/config/configopaque"
@@ -39,6 +40,7 @@ func TestUnmarshalConfig(t *testing.T) {
3940
InstanceUID: "01BX5ZZKBKACTAV9WEVGEMMVRZ",
4041
Capabilities: Capabilities{
4142
ReportsEffectiveConfig: true,
43+
ReportsHealth: true,
4244
},
4345
PPIDPollInterval: 5 * time.Second,
4446
}, cfg)
@@ -63,6 +65,7 @@ func TestUnmarshalHttpConfig(t *testing.T) {
6365
InstanceUID: "01BX5ZZKBKACTAV9WEVGEMMVRZ",
6466
Capabilities: Capabilities{
6567
ReportsEffectiveConfig: true,
68+
ReportsHealth: true,
6669
},
6770
PPIDPollInterval: 5 * time.Second,
6871
}, cfg)
@@ -286,3 +289,41 @@ func TestConfig_Validate(t *testing.T) {
286289
})
287290
}
288291
}
292+
293+
func TestCapabilities_toAgentCapabilities(t *testing.T) {
294+
type fields struct {
295+
ReportsEffectiveConfig bool
296+
ReportsHealth bool
297+
}
298+
tests := []struct {
299+
name string
300+
fields fields
301+
want protobufs.AgentCapabilities
302+
}{
303+
{
304+
name: "default capabilities",
305+
fields: fields{
306+
ReportsEffectiveConfig: false,
307+
ReportsHealth: false,
308+
},
309+
want: protobufs.AgentCapabilities_AgentCapabilities_ReportsStatus,
310+
},
311+
{
312+
name: "all supported capabilities enabled",
313+
fields: fields{
314+
ReportsEffectiveConfig: true,
315+
ReportsHealth: true,
316+
},
317+
want: protobufs.AgentCapabilities_AgentCapabilities_ReportsStatus | protobufs.AgentCapabilities_AgentCapabilities_ReportsEffectiveConfig | protobufs.AgentCapabilities_AgentCapabilities_ReportsHealth,
318+
},
319+
}
320+
for _, tt := range tests {
321+
t.Run(tt.name, func(t *testing.T) {
322+
caps := Capabilities{
323+
ReportsEffectiveConfig: tt.fields.ReportsEffectiveConfig,
324+
ReportsHealth: tt.fields.ReportsHealth,
325+
}
326+
assert.Equalf(t, tt.want, caps.toAgentCapabilities(), "toAgentCapabilities()")
327+
})
328+
}
329+
}

extension/opampextension/factory.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ func createDefaultConfig() component.Config {
2727
Server: &OpAMPServer{},
2828
Capabilities: Capabilities{
2929
ReportsEffectiveConfig: true,
30+
ReportsHealth: true,
3031
},
3132
PPIDPollInterval: 5 * time.Second,
3233
}

extension/opampextension/opamp_agent.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ import (
3232
"github.com/open-telemetry/opentelemetry-collector-contrib/extension/opampcustommessages"
3333
)
3434

35+
var _ extensioncapabilities.PipelineWatcher = (*opampAgent)(nil)
36+
3537
type opampAgent struct {
3638
cfg *Config
3739
logger *zap.Logger
@@ -121,6 +123,8 @@ func (o *opampAgent) Start(ctx context.Context, host component.Host) error {
121123
return err
122124
}
123125

126+
o.setHealth(&protobufs.ComponentHealth{Healthy: false})
127+
124128
o.logger.Debug("Starting OpAMP client...")
125129

126130
if err := o.opampClient.Start(context.Background(), settings); err != nil {
@@ -141,6 +145,7 @@ func (o *opampAgent) Shutdown(ctx context.Context) error {
141145
if o.opampClient == nil {
142146
return nil
143147
}
148+
144149
o.logger.Debug("Stopping OpAMP client...")
145150
err := o.opampClient.Stop(ctx)
146151
// Opamp-go considers this an error, but the collector does not.
@@ -178,6 +183,16 @@ func (o *opampAgent) Register(capability string, opts ...opampcustommessages.Cus
178183
return o.customCapabilityRegistry.Register(capability, opts...)
179184
}
180185

186+
func (o *opampAgent) Ready() error {
187+
o.setHealth(&protobufs.ComponentHealth{Healthy: true})
188+
return nil
189+
}
190+
191+
func (o *opampAgent) NotReady() error {
192+
o.setHealth(&protobufs.ComponentHealth{Healthy: false})
193+
return nil
194+
}
195+
181196
func (o *opampAgent) updateEffectiveConfig(conf *confmap.Conf) {
182197
o.eclk.Lock()
183198
defer o.eclk.Unlock()
@@ -344,3 +359,11 @@ func (o *opampAgent) onMessage(_ context.Context, msg *types.MessageData) {
344359
o.customCapabilityRegistry.ProcessMessage(msg.CustomMessage)
345360
}
346361
}
362+
363+
func (o *opampAgent) setHealth(ch *protobufs.ComponentHealth) {
364+
if o.capabilities.ReportsHealth && o.opampClient != nil {
365+
if err := o.opampClient.SetHealth(ch); err != nil {
366+
o.logger.Error("Could not report health to OpAMP server", zap.Error(err))
367+
}
368+
}
369+
}

extension/opampextension/opamp_agent_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ func TestNewOpampAgent(t *testing.T) {
3131
assert.Equal(t, "test version", o.agentVersion)
3232
assert.NotEmpty(t, o.instanceID.String())
3333
assert.True(t, o.capabilities.ReportsEffectiveConfig)
34+
assert.True(t, o.capabilities.ReportsHealth)
3435
assert.Empty(t, o.effectiveConfig)
3536
assert.Nil(t, o.agentDescription)
3637
}

0 commit comments

Comments
 (0)