Skip to content

Commit

Permalink
Support log level setting from policy (#3090)
Browse files Browse the repository at this point in the history
* migrate mockery config

* loglevel setting

* define logLevelSetter interface

* make coordinator implement logLevelSetter interface

* Add externalLogLevel to SettingsHandler

* correctly wire policy_change and settings handler for log level handling

* remove default log level from AgentInfo in case of fleet managed agent

* Set initial log level from config
  • Loading branch information
pchila authored May 14, 2024
1 parent fdba118 commit 209aff4
Show file tree
Hide file tree
Showing 27 changed files with 1,630 additions and 145 deletions.
28 changes: 24 additions & 4 deletions .mockery.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
inpackage: False
testonly: False
with-expecter: True
keeptree: True
case: underscore
inpackage: false
dir: testing/mocks/{{ replaceAll .InterfaceDirRelative "internal" "internal_" }}
mockname: "{{.InterfaceName}}"
outpkg: "{{.PackageName}}"
filename: "{{ snakecase .InterfaceName}}_mock.go"
packages:
github.com/elastic/elastic-agent/pkg/control/v2/client:
interfaces:
Client:
github.com/elastic/elastic-agent/internal/pkg/agent/application/actions/handlers:
interfaces:
Uploader:
diagnosticsProvider:
config:
mockname: "DiagnosticsProvider"
logLevelSetter:
config:
mockname: "LogLevelSetter"
github.com/elastic/elastic-agent/internal/pkg/fleetapi/acker:
interfaces:
Acker:
github.com/elastic/elastic-agent/internal/pkg/agent/application/info:
interfaces:
Agent:
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Kind can be one of:
# - breaking-change: a change to previously-documented behavior
# - deprecation: functionality that is being removed in a later release
# - bug-fix: fixes a problem in a previous version
# - enhancement: extends functionality but does not break or fix existing behavior
# - feature: new functionality
# - known-issue: problems that we are aware of in a given version
# - security: impacts on the security of a product or a user’s deployment.
# - upgrade: important information for someone upgrading from a prior version
# - other: does not fit into any of the other categories
kind: enhancement

# Change summary; a 80ish characters long description of the change.
summary: Set log level from fleet policy

# Long description; in case the summary is not enough to describe the change
# this field accommodate a description without length limits.
# NOTE: This field will be rendered only for breaking-change and known-issue kinds at the moment.
description: >
Enables setting agent logging level in policy. Setting a valid
log level (same values allowed for setting log level on the specific agent)
in fleet policy under `agent.logging.level` key will cause the agent to
change its logging level, unless an override is set for the specific
elastic-agent using a `settings` action.
The order of priority of log level for a fleet managed agent is:
1. log level set specifically to the agent via settings action, if any
2. log level specified in fleet policy, if any
3. default hard-coded log level for elastic-agent
# Affected component; a word indicating the component this changeset affects.
component: elastic-agent

# PR URL; optional; the PR number that added the changeset.
# If not present is automatically filled by the tooling finding the PR where this changelog fragment has been added.
# NOTE: the tooling supports backports, so it's able to fill the original PR number instead of the backport PR number.
# Please provide it if you are adding a fragment for a different PR.
pr: https://github.com/elastic/elastic-agent/pull/3090

# Issue URL; optional; the GitHub issue related to this changeset (either closes or is part of).
# If not present is automatically filled by the tooling with the issue linked to the PR number.
issue: https://github.com/elastic/elastic-agent/issues/2851
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func (h *AppAction) Handle(ctx context.Context, a fleetapi.Action, acker acker.A
// https://github.com/elastic/security-team/issues/6501
//
// h.log.Debugf("handlerAppAction: validate action '%+v', for agentID %s", a, h.agentID)
// validated, err := protection.ValidateAction(*action, h.coord.Protection().SignatureValidationKey, h.agentID)
// validated, err := protection.ValidateAction(*action, h.logLevelSetter.Protection().SignatureValidationKey, h.agentID)
// if err != nil {
// action.StartedAt = time.Now().UTC().Format(time.RFC3339Nano)
// action.CompletedAt = action.StartedAt
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"github.com/elastic/elastic-agent-client/v7/pkg/proto"
"github.com/elastic/elastic-agent/pkg/control/v2/cproto"

"github.com/elastic/elastic-agent/internal/pkg/agent/application/actions/handlers/mocks"
"github.com/elastic/elastic-agent/internal/pkg/agent/application/paths"
"github.com/elastic/elastic-agent/internal/pkg/agent/errors"
"github.com/elastic/elastic-agent/internal/pkg/core/monitoring/config"
Expand All @@ -29,12 +28,10 @@ import (
"github.com/elastic/elastic-agent/pkg/component"
"github.com/elastic/elastic-agent/pkg/component/runtime"
"github.com/elastic/elastic-agent/pkg/core/logger"
mockhandlers "github.com/elastic/elastic-agent/testing/mocks/internal_/pkg/agent/application/actions/handlers"
mockackers "github.com/elastic/elastic-agent/testing/mocks/internal_/pkg/fleetapi/acker"
)

//go:generate mockery --name Uploader
//go:generate mockery --name diagnosticsProvider --exported
//go:generate mockery --dir ../../../../fleetapi/acker --name Acker

var defaultRateLimit config.Limit = config.Limit{
Interval: 1 * time.Millisecond,
Burst: 10,
Expand Down Expand Up @@ -84,16 +81,16 @@ func TestDiagnosticHandlerHappyPathWithLogs(t *testing.T) {
err := os.MkdirAll(path.Join(tempAgentRoot, "data"), 0755)
require.NoError(t, err)

mockDiagProvider := mocks.NewDiagnosticsProvider(t)
mockUploader := mocks.NewUploader(t)
mockDiagProvider := mockhandlers.NewDiagnosticsProvider(t)
mockUploader := mockhandlers.NewUploader(t)
testLogger, observedLogs := logger.NewTesting("diagnostic-handler-test")
handler := NewDiagnostics(testLogger, mockDiagProvider, defaultRateLimit, mockUploader)

mockDiagProvider.EXPECT().DiagnosticHooks().Return([]diagnostics.Hook{hook1})
mockDiagProvider.EXPECT().PerformDiagnostics(mock.Anything, mock.Anything).Return([]runtime.ComponentUnitDiagnostic{mockUnitDiagnostic})
mockDiagProvider.EXPECT().PerformComponentDiagnostics(mock.Anything, mock.Anything).Return([]runtime.ComponentDiagnostic{}, nil)

mockAcker := mocks.NewAcker(t)
mockAcker := mockackers.NewAcker(t)
mockAcker.EXPECT().Ack(mock.Anything, mock.Anything).RunAndReturn(func(ctx context.Context, a fleetapi.Action) error {
require.IsType(t, new(fleetapi.ActionDiagnostics), a)
assert.NoError(t, a.(*fleetapi.ActionDiagnostics).Err)
Expand Down Expand Up @@ -165,8 +162,8 @@ func TestDiagnosticHandlerUploaderErrorWithLogs(t *testing.T) {
err := os.MkdirAll(path.Join(tempAgentRoot, "data"), 0755)
require.NoError(t, err)

mockDiagProvider := mocks.NewDiagnosticsProvider(t)
mockUploader := mocks.NewUploader(t)
mockDiagProvider := mockhandlers.NewDiagnosticsProvider(t)
mockUploader := mockhandlers.NewUploader(t)
testLogger, observedLogs := logger.NewTesting("diagnostic-handler-test")
handler := NewDiagnostics(testLogger, mockDiagProvider, defaultRateLimit, mockUploader)

Expand All @@ -178,7 +175,7 @@ func TestDiagnosticHandlerUploaderErrorWithLogs(t *testing.T) {
uploaderError := errors.New("upload went wrong!")
mockUploader.EXPECT().UploadDiagnostics(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return("", uploaderError)

mockAcker := mocks.NewAcker(t)
mockAcker := mockackers.NewAcker(t)
mockAcker.EXPECT().Ack(mock.Anything, mock.Anything).RunAndReturn(func(ctx context.Context, a fleetapi.Action) error {
require.IsType(t, new(fleetapi.ActionDiagnostics), a)
// verify that we are acking the action with the correct error set
Expand Down Expand Up @@ -206,16 +203,16 @@ func TestDiagnosticHandlerZipArchiveErrorWithLogs(t *testing.T) {
// we don't set a 'data' subdirectory in order to make the zip process return an error
// this is the only way/trick to do it with the current implementation, sadly :(

mockDiagProvider := mocks.NewDiagnosticsProvider(t)
mockUploader := mocks.NewUploader(t)
mockDiagProvider := mockhandlers.NewDiagnosticsProvider(t)
mockUploader := mockhandlers.NewUploader(t)
testLogger, observedLogs := logger.NewTesting("diagnostic-handler-test")
handler := NewDiagnostics(testLogger, mockDiagProvider, defaultRateLimit, mockUploader)

mockDiagProvider.EXPECT().DiagnosticHooks().Return([]diagnostics.Hook{})
mockDiagProvider.EXPECT().PerformDiagnostics(mock.Anything, mock.Anything).Return([]runtime.ComponentUnitDiagnostic{})
mockDiagProvider.EXPECT().PerformComponentDiagnostics(mock.Anything, mock.Anything).Return([]runtime.ComponentDiagnostic{}, nil)

mockAcker := mocks.NewAcker(t)
mockAcker := mockackers.NewAcker(t)
mockAcker.EXPECT().Ack(mock.Anything, mock.Anything).RunAndReturn(func(ctx context.Context, a fleetapi.Action) error {
require.IsType(t, new(fleetapi.ActionDiagnostics), a)
assert.Error(t, a.(*fleetapi.ActionDiagnostics).Err)
Expand All @@ -242,16 +239,16 @@ func TestDiagnosticHandlerAckErrorWithLogs(t *testing.T) {
err := os.MkdirAll(path.Join(tempAgentRoot, "data"), 0755)
require.NoError(t, err)

mockDiagProvider := mocks.NewDiagnosticsProvider(t)
mockUploader := mocks.NewUploader(t)
mockDiagProvider := mockhandlers.NewDiagnosticsProvider(t)
mockUploader := mockhandlers.NewUploader(t)
testLogger, observedLogs := logger.NewTesting("diagnostic-handler-test")
handler := NewDiagnostics(testLogger, mockDiagProvider, defaultRateLimit, mockUploader)

mockDiagProvider.EXPECT().DiagnosticHooks().Return([]diagnostics.Hook{})
mockDiagProvider.EXPECT().PerformDiagnostics(mock.Anything, mock.Anything).Return([]runtime.ComponentUnitDiagnostic{})
mockDiagProvider.EXPECT().PerformComponentDiagnostics(mock.Anything, mock.Anything).Return([]runtime.ComponentDiagnostic{}, nil)

mockAcker := mocks.NewAcker(t)
mockAcker := mockackers.NewAcker(t)
ackError := errors.New("acking went wrong")
mockAcker.EXPECT().Ack(mock.Anything, mock.Anything).RunAndReturn(func(ctx context.Context, a fleetapi.Action) error {
require.IsType(t, new(fleetapi.ActionDiagnostics), a)
Expand Down Expand Up @@ -281,16 +278,16 @@ func TestDiagnosticHandlerCommitErrorWithLogs(t *testing.T) {
err := os.MkdirAll(path.Join(tempAgentRoot, "data"), 0755)
require.NoError(t, err)

mockDiagProvider := mocks.NewDiagnosticsProvider(t)
mockUploader := mocks.NewUploader(t)
mockDiagProvider := mockhandlers.NewDiagnosticsProvider(t)
mockUploader := mockhandlers.NewUploader(t)
testLogger, observedLogs := logger.NewTesting("diagnostic-handler-test")
handler := NewDiagnostics(testLogger, mockDiagProvider, defaultRateLimit, mockUploader)

mockDiagProvider.EXPECT().DiagnosticHooks().Return([]diagnostics.Hook{})
mockDiagProvider.EXPECT().PerformDiagnostics(mock.Anything, mock.Anything).Return([]runtime.ComponentUnitDiagnostic{})
mockDiagProvider.EXPECT().PerformComponentDiagnostics(mock.Anything, mock.Anything).Return([]runtime.ComponentDiagnostic{}, nil)

mockAcker := mocks.NewAcker(t)
mockAcker := mockackers.NewAcker(t)
mockAcker.EXPECT().Ack(mock.Anything, mock.Anything).RunAndReturn(func(ctx context.Context, a fleetapi.Action) error {
require.IsType(t, new(fleetapi.ActionDiagnostics), a)
assert.NoError(t, a.(*fleetapi.ActionDiagnostics).Err)
Expand Down Expand Up @@ -321,14 +318,14 @@ func TestDiagnosticHandlerContexteExpiredErrorWithLogs(t *testing.T) {
err := os.MkdirAll(path.Join(tempAgentRoot, "data"), 0755)
require.NoError(t, err)

mockDiagProvider := mocks.NewDiagnosticsProvider(t)
mockUploader := mocks.NewUploader(t)
mockDiagProvider := mockhandlers.NewDiagnosticsProvider(t)
mockUploader := mockhandlers.NewUploader(t)
testLogger, observedLogs := logger.NewTesting("diagnostic-handler-test")
handler := NewDiagnostics(testLogger, mockDiagProvider, defaultRateLimit, mockUploader)

mockDiagProvider.EXPECT().DiagnosticHooks().Return([]diagnostics.Hook{})

mockAcker := mocks.NewAcker(t)
mockAcker := mockackers.NewAcker(t)
mockAcker.EXPECT().Ack(mock.Anything, mock.Anything).RunAndReturn(func(ctx context.Context, a fleetapi.Action) error {
require.IsType(t, new(fleetapi.ActionDiagnostics), a)
assert.ErrorIs(t, a.(*fleetapi.ActionDiagnostics).Err, context.Canceled)
Expand Down Expand Up @@ -365,8 +362,8 @@ func TestDiagnosticHandlerWithCPUProfile(t *testing.T) {
return []byte(`hello, world!`), nil
}

mockDiagProvider := mocks.NewDiagnosticsProvider(t)
mockUploader := mocks.NewUploader(t)
mockDiagProvider := mockhandlers.NewDiagnosticsProvider(t)
mockUploader := mockhandlers.NewUploader(t)
testLogger, _ := logger.NewTesting("diagnostic-handler-test")
handler := NewDiagnostics(testLogger, mockDiagProvider, defaultRateLimit, mockUploader)

Expand All @@ -383,7 +380,7 @@ func TestDiagnosticHandlerWithCPUProfile(t *testing.T) {
return false
})).Return([]runtime.ComponentDiagnostic{}, nil)

mockAcker := mocks.NewAcker(t)
mockAcker := mockackers.NewAcker(t)
mockAcker.EXPECT().Ack(mock.Anything, mock.Anything).RunAndReturn(func(ctx context.Context, a fleetapi.Action) error {
require.IsType(t, new(fleetapi.ActionDiagnostics), a)
assert.NoError(t, a.(*fleetapi.ActionDiagnostics).Err)
Expand Down
Loading

0 comments on commit 209aff4

Please sign in to comment.