Skip to content

Commit 40bc68c

Browse files
authored
Correctly handle unix signals in EDOT (#10908)
* Handle unix signals in EDOT * Add changelog entry * Fix changelog entry * Move removing agent config file to fixture.ConfigureOtel
1 parent a24b6fa commit 40bc68c

File tree

4 files changed

+111
-3
lines changed

4 files changed

+111
-3
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Kind can be one of:
2+
# - breaking-change: a change to previously-documented behavior
3+
# - deprecation: functionality that is being removed in a later release
4+
# - bug-fix: fixes a problem in a previous version
5+
# - enhancement: extends functionality but does not break or fix existing behavior
6+
# - feature: new functionality
7+
# - known-issue: problems that we are aware of in a given version
8+
# - security: impacts on the security of a product or a user’s deployment.
9+
# - upgrade: important information for someone upgrading from a prior version
10+
# - other: does not fit into any of the other categories
11+
kind: bug-fix
12+
13+
# Change summary; a 80ish characters long description of the change.
14+
summary: Fix signal handling for the EDOT Collector
15+
16+
# Long description; in case the summary is not enough to describe the change
17+
# this field accommodate a description without length limits.
18+
# NOTE: This field will be rendered only for breaking-change and known-issue kinds at the moment.
19+
#description:
20+
21+
# Affected component; usually one of "elastic-agent", "fleet-server", "filebeat", "metricbeat", "auditbeat", "all", etc.
22+
component: elastic-agent
23+
24+
# PR URL; optional; the PR number that added the changeset.
25+
# If not present is automatically filled by the tooling finding the PR where this changelog fragment has been added.
26+
# NOTE: the tooling supports backports, so it's able to fill the original PR number instead of the backport PR number.
27+
# Please provide it if you are adding a fragment for a different PR.
28+
#pr: https://github.com/owner/repo/1234
29+
30+
# Issue URL; optional; the GitHub issue related to this changeset (either closes or is part of).
31+
# If not present is automatically filled by the tooling with the issue linked to the PR number.
32+
#issue: https://github.com/owner/repo/1234

internal/pkg/agent/cmd/otel.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,9 @@ func RunCollector(cmdCtx context.Context, configFiles []string, supervised bool,
119119
}
120120

121121
defer cancel()
122-
go service.ProcessWindowsControlEvents(stopCollector)
122+
if settings.otelSettings.DisableGracefulShutdown { // TODO: Harmonize these settings
123+
service.HandleSignals(stopCollector, cancel)
124+
}
123125

124126
return otel.Run(ctx, stop, settings.otelSettings)
125127
}

pkg/testing/fixture.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,23 @@ func (f *Fixture) Configure(ctx context.Context, yamlConfig []byte) error {
277277
return os.WriteFile(cfgFilePath, yamlConfig, 0600)
278278
}
279279

280+
// ConfigureOtel replaces the default Agent otel mode configuration file with the provided
281+
// configuration. This must be called after `Prepare` is called.
282+
func (f *Fixture) ConfigureOtel(ctx context.Context, yamlConfig []byte) error {
283+
err := f.EnsurePrepared(ctx)
284+
if err != nil {
285+
return err
286+
}
287+
288+
// remove elastic-agent.yml, otel should be independent
289+
if removeErr := os.Remove(filepath.Join(f.WorkDir(), "elastic-agent.yml")); removeErr != nil && !os.IsNotExist(removeErr) {
290+
return removeErr
291+
}
292+
293+
cfgFilePath := filepath.Join(f.workDir, "otel.yml")
294+
return os.WriteFile(cfgFilePath, yamlConfig, 0600)
295+
}
296+
280297
// SetUninstallToken sets uninstall token
281298
func (f *Fixture) SetUninstallToken(uninstallToken string) {
282299
f.uninstallToken = uninstallToken

testing/integration/ess/otel_test.go

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@ import (
2828
"github.com/stretchr/testify/assert"
2929
"github.com/stretchr/testify/require"
3030

31-
"github.com/elastic/go-elasticsearch/v8"
32-
3331
"github.com/elastic/elastic-agent-libs/mapstr"
3432
"github.com/elastic/elastic-agent-libs/testing/estools"
3533
"github.com/elastic/elastic-agent-libs/transport/tlscommontest"
@@ -38,6 +36,7 @@ import (
3836
"github.com/elastic/elastic-agent/pkg/testing/define"
3937
"github.com/elastic/elastic-agent/pkg/testing/tools/testcontext"
4038
"github.com/elastic/elastic-agent/testing/integration"
39+
"github.com/elastic/go-elasticsearch/v8"
4140
)
4241

4342
const apmProcessingContent = `2023-06-19 05:20:50 ERROR This is a test error message
@@ -87,6 +86,64 @@ service:
8786
- debug
8887
- otlp/elastic`
8988

89+
func TestOtelStartShutdown(t *testing.T) {
90+
define.Require(t, define.Requirements{
91+
Group: integration.Default,
92+
Local: true,
93+
OS: []define.OS{
94+
{Type: define.Linux},
95+
{Type: define.Darwin},
96+
},
97+
})
98+
99+
otelConfig := `receivers:
100+
nop:
101+
exporters:
102+
nop:
103+
service:
104+
pipelines:
105+
logs:
106+
receivers:
107+
- nop
108+
exporters:
109+
- nop
110+
`
111+
fixture, err := define.NewFixtureFromLocalBuild(t, define.Version())
112+
require.NoError(t, err)
113+
114+
ctx, cancel := testcontext.WithDeadline(t, context.Background(), time.Now().Add(10*time.Minute))
115+
defer cancel()
116+
err = fixture.Prepare(ctx)
117+
require.NoError(t, err)
118+
119+
err = fixture.ConfigureOtel(t.Context(), []byte(otelConfig))
120+
require.NoError(t, err)
121+
122+
cmd, err := fixture.PrepareAgentCommand(ctx, []string{"otel"})
123+
require.NoError(t, err)
124+
125+
output := strings.Builder{}
126+
cmd.Stderr = &output
127+
cmd.Stdout = &output
128+
129+
t.Cleanup(func() {
130+
if t.Failed() {
131+
t.Log("Elastic-Agent output:")
132+
t.Log(output.String())
133+
}
134+
})
135+
136+
require.NoError(t, cmd.Start(), "could not start otel collector")
137+
require.EventuallyWithT(t, func(collect *assert.CollectT) {
138+
assert.Contains(collect, output.String(), "Everything is ready")
139+
}, time.Second*30, time.Second)
140+
141+
// stop the collector and check that it emitted logs indicating a graceful shutdown
142+
require.NoError(t, cmd.Process.Signal(os.Interrupt))
143+
require.NoError(t, cmd.Wait())
144+
assert.Contains(t, output.String(), "Shutdown complete")
145+
}
146+
90147
func TestOtelFileProcessing(t *testing.T) {
91148
define.Require(t, define.Requirements{
92149
Group: integration.Default,

0 commit comments

Comments
 (0)