[UII] Expose advanced file logging config in UI (#200274)

## Summary

Resolves [#192237](https://github.com/elastic/kibana/issues/192237).
This PR exposes the following Elastic Agent file logging configuration
options in the agent policy advanced settings UI:

```
agent.logging.to_files
agent.logging.files.rotateeverybytes 
agent.logging.files.keepfiles
agent.logging.files.interval
```

<img width="1237" alt="image"
src="https://github.com/user-attachments/assets/8de9023c-29a0-4ecf-803a-d8c0c4b87616">

This PR also does some clean up on the default values for all these
configured advanced settings so that when user has not touched them, the
default values do not get written into the agent policy saved object.
[More info
here](https://github.com/elastic/kibana/pull/200274#discussion_r1849142612).

It also fixes adds missing response schemas for the advanced settings.

### Checklist

Check the PR satisfies following conditions. 

Reviewers should verify this PR satisfies this list as well.

- [x] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)
- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Jen Huang 2024-11-20 09:41:50 -08:00 committed by GitHub
parent e082cd1dfa
commit 0aa63a7ecc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 647 additions and 147 deletions

View file

@ -6355,18 +6355,27 @@
"nullable": true
},
"agent_download_timeout": {
"default": "2h",
"nullable": true
},
"agent_limits_go_max_procs": {
"nullable": true
},
"agent_logging_files_interval": {
"nullable": true
},
"agent_logging_files_keepfiles": {
"nullable": true
},
"agent_logging_files_rotateeverybytes": {
"nullable": true
},
"agent_logging_level": {
"default": "info",
"nullable": true
},
"agent_logging_metrics_period": {
"default": "30s",
"nullable": true
},
"agent_logging_to_files": {
"nullable": true
}
},
@ -7113,18 +7122,27 @@
"nullable": true
},
"agent_download_timeout": {
"default": "2h",
"nullable": true
},
"agent_limits_go_max_procs": {
"nullable": true
},
"agent_logging_files_interval": {
"nullable": true
},
"agent_logging_files_keepfiles": {
"nullable": true
},
"agent_logging_files_rotateeverybytes": {
"nullable": true
},
"agent_logging_level": {
"default": "info",
"nullable": true
},
"agent_logging_metrics_period": {
"default": "30s",
"nullable": true
},
"agent_logging_to_files": {
"nullable": true
}
},
@ -7361,18 +7379,27 @@
"nullable": true
},
"agent_download_timeout": {
"default": "2h",
"nullable": true
},
"agent_limits_go_max_procs": {
"nullable": true
},
"agent_logging_files_interval": {
"nullable": true
},
"agent_logging_files_keepfiles": {
"nullable": true
},
"agent_logging_files_rotateeverybytes": {
"nullable": true
},
"agent_logging_level": {
"default": "info",
"nullable": true
},
"agent_logging_metrics_period": {
"default": "30s",
"nullable": true
},
"agent_logging_to_files": {
"nullable": true
}
},
@ -8145,18 +8172,27 @@
"nullable": true
},
"agent_download_timeout": {
"default": "2h",
"nullable": true
},
"agent_limits_go_max_procs": {
"nullable": true
},
"agent_logging_files_interval": {
"nullable": true
},
"agent_logging_files_keepfiles": {
"nullable": true
},
"agent_logging_files_rotateeverybytes": {
"nullable": true
},
"agent_logging_level": {
"default": "info",
"nullable": true
},
"agent_logging_metrics_period": {
"default": "30s",
"nullable": true
},
"agent_logging_to_files": {
"nullable": true
}
},
@ -9190,18 +9226,27 @@
"nullable": true
},
"agent_download_timeout": {
"default": "2h",
"nullable": true
},
"agent_limits_go_max_procs": {
"nullable": true
},
"agent_logging_files_interval": {
"nullable": true
},
"agent_logging_files_keepfiles": {
"nullable": true
},
"agent_logging_files_rotateeverybytes": {
"nullable": true
},
"agent_logging_level": {
"default": "info",
"nullable": true
},
"agent_logging_metrics_period": {
"default": "30s",
"nullable": true
},
"agent_logging_to_files": {
"nullable": true
}
},
@ -9947,18 +9992,27 @@
"nullable": true
},
"agent_download_timeout": {
"default": "2h",
"nullable": true
},
"agent_limits_go_max_procs": {
"nullable": true
},
"agent_logging_files_interval": {
"nullable": true
},
"agent_logging_files_keepfiles": {
"nullable": true
},
"agent_logging_files_rotateeverybytes": {
"nullable": true
},
"agent_logging_level": {
"default": "info",
"nullable": true
},
"agent_logging_metrics_period": {
"default": "30s",
"nullable": true
},
"agent_logging_to_files": {
"nullable": true
}
},
@ -10195,18 +10249,27 @@
"nullable": true
},
"agent_download_timeout": {
"default": "2h",
"nullable": true
},
"agent_limits_go_max_procs": {
"nullable": true
},
"agent_logging_files_interval": {
"nullable": true
},
"agent_logging_files_keepfiles": {
"nullable": true
},
"agent_logging_files_rotateeverybytes": {
"nullable": true
},
"agent_logging_level": {
"default": "info",
"nullable": true
},
"agent_logging_metrics_period": {
"default": "30s",
"nullable": true
},
"agent_logging_to_files": {
"nullable": true
}
},
@ -10980,18 +11043,27 @@
"nullable": true
},
"agent_download_timeout": {
"default": "2h",
"nullable": true
},
"agent_limits_go_max_procs": {
"nullable": true
},
"agent_logging_files_interval": {
"nullable": true
},
"agent_logging_files_keepfiles": {
"nullable": true
},
"agent_logging_files_rotateeverybytes": {
"nullable": true
},
"agent_logging_level": {
"default": "info",
"nullable": true
},
"agent_logging_metrics_period": {
"default": "30s",
"nullable": true
},
"agent_logging_to_files": {
"nullable": true
}
},
@ -11890,6 +11962,42 @@
},
"type": "object"
},
"limits": {
"additionalProperties": false,
"properties": {
"go_max_procs": {
"type": "number"
}
},
"type": "object"
},
"logging": {
"additionalProperties": false,
"properties": {
"files": {
"additionalProperties": false,
"properties": {
"interval": {
"type": "string"
},
"keepfiles": {
"type": "number"
},
"rotateeverybytes": {
"type": "number"
}
},
"type": "object"
},
"level": {
"type": "string"
},
"to_files": {
"type": "boolean"
}
},
"type": "object"
},
"monitoring": {
"additionalProperties": false,
"properties": {

View file

@ -6355,18 +6355,27 @@
"nullable": true
},
"agent_download_timeout": {
"default": "2h",
"nullable": true
},
"agent_limits_go_max_procs": {
"nullable": true
},
"agent_logging_files_interval": {
"nullable": true
},
"agent_logging_files_keepfiles": {
"nullable": true
},
"agent_logging_files_rotateeverybytes": {
"nullable": true
},
"agent_logging_level": {
"default": "info",
"nullable": true
},
"agent_logging_metrics_period": {
"default": "30s",
"nullable": true
},
"agent_logging_to_files": {
"nullable": true
}
},
@ -7113,18 +7122,27 @@
"nullable": true
},
"agent_download_timeout": {
"default": "2h",
"nullable": true
},
"agent_limits_go_max_procs": {
"nullable": true
},
"agent_logging_files_interval": {
"nullable": true
},
"agent_logging_files_keepfiles": {
"nullable": true
},
"agent_logging_files_rotateeverybytes": {
"nullable": true
},
"agent_logging_level": {
"default": "info",
"nullable": true
},
"agent_logging_metrics_period": {
"default": "30s",
"nullable": true
},
"agent_logging_to_files": {
"nullable": true
}
},
@ -7361,18 +7379,27 @@
"nullable": true
},
"agent_download_timeout": {
"default": "2h",
"nullable": true
},
"agent_limits_go_max_procs": {
"nullable": true
},
"agent_logging_files_interval": {
"nullable": true
},
"agent_logging_files_keepfiles": {
"nullable": true
},
"agent_logging_files_rotateeverybytes": {
"nullable": true
},
"agent_logging_level": {
"default": "info",
"nullable": true
},
"agent_logging_metrics_period": {
"default": "30s",
"nullable": true
},
"agent_logging_to_files": {
"nullable": true
}
},
@ -8145,18 +8172,27 @@
"nullable": true
},
"agent_download_timeout": {
"default": "2h",
"nullable": true
},
"agent_limits_go_max_procs": {
"nullable": true
},
"agent_logging_files_interval": {
"nullable": true
},
"agent_logging_files_keepfiles": {
"nullable": true
},
"agent_logging_files_rotateeverybytes": {
"nullable": true
},
"agent_logging_level": {
"default": "info",
"nullable": true
},
"agent_logging_metrics_period": {
"default": "30s",
"nullable": true
},
"agent_logging_to_files": {
"nullable": true
}
},
@ -9190,18 +9226,27 @@
"nullable": true
},
"agent_download_timeout": {
"default": "2h",
"nullable": true
},
"agent_limits_go_max_procs": {
"nullable": true
},
"agent_logging_files_interval": {
"nullable": true
},
"agent_logging_files_keepfiles": {
"nullable": true
},
"agent_logging_files_rotateeverybytes": {
"nullable": true
},
"agent_logging_level": {
"default": "info",
"nullable": true
},
"agent_logging_metrics_period": {
"default": "30s",
"nullable": true
},
"agent_logging_to_files": {
"nullable": true
}
},
@ -9947,18 +9992,27 @@
"nullable": true
},
"agent_download_timeout": {
"default": "2h",
"nullable": true
},
"agent_limits_go_max_procs": {
"nullable": true
},
"agent_logging_files_interval": {
"nullable": true
},
"agent_logging_files_keepfiles": {
"nullable": true
},
"agent_logging_files_rotateeverybytes": {
"nullable": true
},
"agent_logging_level": {
"default": "info",
"nullable": true
},
"agent_logging_metrics_period": {
"default": "30s",
"nullable": true
},
"agent_logging_to_files": {
"nullable": true
}
},
@ -10195,18 +10249,27 @@
"nullable": true
},
"agent_download_timeout": {
"default": "2h",
"nullable": true
},
"agent_limits_go_max_procs": {
"nullable": true
},
"agent_logging_files_interval": {
"nullable": true
},
"agent_logging_files_keepfiles": {
"nullable": true
},
"agent_logging_files_rotateeverybytes": {
"nullable": true
},
"agent_logging_level": {
"default": "info",
"nullable": true
},
"agent_logging_metrics_period": {
"default": "30s",
"nullable": true
},
"agent_logging_to_files": {
"nullable": true
}
},
@ -10980,18 +11043,27 @@
"nullable": true
},
"agent_download_timeout": {
"default": "2h",
"nullable": true
},
"agent_limits_go_max_procs": {
"nullable": true
},
"agent_logging_files_interval": {
"nullable": true
},
"agent_logging_files_keepfiles": {
"nullable": true
},
"agent_logging_files_rotateeverybytes": {
"nullable": true
},
"agent_logging_level": {
"default": "info",
"nullable": true
},
"agent_logging_metrics_period": {
"default": "30s",
"nullable": true
},
"agent_logging_to_files": {
"nullable": true
}
},
@ -11890,6 +11962,42 @@
},
"type": "object"
},
"limits": {
"additionalProperties": false,
"properties": {
"go_max_procs": {
"type": "number"
}
},
"type": "object"
},
"logging": {
"additionalProperties": false,
"properties": {
"files": {
"additionalProperties": false,
"properties": {
"interval": {
"type": "string"
},
"keepfiles": {
"type": "number"
},
"rotateeverybytes": {
"type": "number"
}
},
"type": "object"
},
"level": {
"type": "string"
},
"to_files": {
"type": "boolean"
}
},
"type": "object"
},
"monitoring": {
"additionalProperties": false,
"properties": {

View file

@ -9522,15 +9522,20 @@ paths:
agent_download_target_directory:
nullable: true
agent_download_timeout:
default: 2h
nullable: true
agent_limits_go_max_procs:
nullable: true
agent_logging_files_interval:
nullable: true
agent_logging_files_keepfiles:
nullable: true
agent_logging_files_rotateeverybytes:
nullable: true
agent_logging_level:
default: info
nullable: true
agent_logging_metrics_period:
default: 30s
nullable: true
agent_logging_to_files:
nullable: true
agent_features:
items:
@ -10047,15 +10052,20 @@ paths:
agent_download_target_directory:
nullable: true
agent_download_timeout:
default: 2h
nullable: true
agent_limits_go_max_procs:
nullable: true
agent_logging_files_interval:
nullable: true
agent_logging_files_keepfiles:
nullable: true
agent_logging_files_rotateeverybytes:
nullable: true
agent_logging_level:
default: info
nullable: true
agent_logging_metrics_period:
default: 30s
nullable: true
agent_logging_to_files:
nullable: true
agent_features:
items:
@ -10221,15 +10231,20 @@ paths:
agent_download_target_directory:
nullable: true
agent_download_timeout:
default: 2h
nullable: true
agent_limits_go_max_procs:
nullable: true
agent_logging_files_interval:
nullable: true
agent_logging_files_keepfiles:
nullable: true
agent_logging_files_rotateeverybytes:
nullable: true
agent_logging_level:
default: info
nullable: true
agent_logging_metrics_period:
default: 30s
nullable: true
agent_logging_to_files:
nullable: true
agent_features:
items:
@ -10765,15 +10780,20 @@ paths:
agent_download_target_directory:
nullable: true
agent_download_timeout:
default: 2h
nullable: true
agent_limits_go_max_procs:
nullable: true
agent_logging_files_interval:
nullable: true
agent_logging_files_keepfiles:
nullable: true
agent_logging_files_rotateeverybytes:
nullable: true
agent_logging_level:
default: info
nullable: true
agent_logging_metrics_period:
default: 30s
nullable: true
agent_logging_to_files:
nullable: true
agent_features:
items:
@ -11289,15 +11309,20 @@ paths:
agent_download_target_directory:
nullable: true
agent_download_timeout:
default: 2h
nullable: true
agent_limits_go_max_procs:
nullable: true
agent_logging_files_interval:
nullable: true
agent_logging_files_keepfiles:
nullable: true
agent_logging_files_rotateeverybytes:
nullable: true
agent_logging_level:
default: info
nullable: true
agent_logging_metrics_period:
default: 30s
nullable: true
agent_logging_to_files:
nullable: true
agent_features:
items:
@ -11813,15 +11838,20 @@ paths:
agent_download_target_directory:
nullable: true
agent_download_timeout:
default: 2h
nullable: true
agent_limits_go_max_procs:
nullable: true
agent_logging_files_interval:
nullable: true
agent_logging_files_keepfiles:
nullable: true
agent_logging_files_rotateeverybytes:
nullable: true
agent_logging_level:
default: info
nullable: true
agent_logging_metrics_period:
default: 30s
nullable: true
agent_logging_to_files:
nullable: true
agent_features:
items:
@ -11987,15 +12017,20 @@ paths:
agent_download_target_directory:
nullable: true
agent_download_timeout:
default: 2h
nullable: true
agent_limits_go_max_procs:
nullable: true
agent_logging_files_interval:
nullable: true
agent_logging_files_keepfiles:
nullable: true
agent_logging_files_rotateeverybytes:
nullable: true
agent_logging_level:
default: info
nullable: true
agent_logging_metrics_period:
default: 30s
nullable: true
agent_logging_to_files:
nullable: true
agent_features:
items:
@ -12531,15 +12566,20 @@ paths:
agent_download_target_directory:
nullable: true
agent_download_timeout:
default: 2h
nullable: true
agent_limits_go_max_procs:
nullable: true
agent_logging_files_interval:
nullable: true
agent_logging_files_keepfiles:
nullable: true
agent_logging_files_rotateeverybytes:
nullable: true
agent_logging_level:
default: info
nullable: true
agent_logging_metrics_period:
default: 30s
nullable: true
agent_logging_to_files:
nullable: true
agent_features:
items:
@ -13153,6 +13193,30 @@ paths:
required:
- enabled
type: object
limits:
additionalProperties: false
type: object
properties:
go_max_procs:
type: number
logging:
additionalProperties: false
type: object
properties:
files:
additionalProperties: false
type: object
properties:
interval:
type: string
keepfiles:
type: number
rotateeverybytes:
type: number
level:
type: string
to_files:
type: boolean
monitoring:
additionalProperties: false
type: object

View file

@ -12378,15 +12378,20 @@ paths:
agent_download_target_directory:
nullable: true
agent_download_timeout:
default: 2h
nullable: true
agent_limits_go_max_procs:
nullable: true
agent_logging_files_interval:
nullable: true
agent_logging_files_keepfiles:
nullable: true
agent_logging_files_rotateeverybytes:
nullable: true
agent_logging_level:
default: info
nullable: true
agent_logging_metrics_period:
default: 30s
nullable: true
agent_logging_to_files:
nullable: true
agent_features:
items:
@ -12902,15 +12907,20 @@ paths:
agent_download_target_directory:
nullable: true
agent_download_timeout:
default: 2h
nullable: true
agent_limits_go_max_procs:
nullable: true
agent_logging_files_interval:
nullable: true
agent_logging_files_keepfiles:
nullable: true
agent_logging_files_rotateeverybytes:
nullable: true
agent_logging_level:
default: info
nullable: true
agent_logging_metrics_period:
default: 30s
nullable: true
agent_logging_to_files:
nullable: true
agent_features:
items:
@ -13076,15 +13086,20 @@ paths:
agent_download_target_directory:
nullable: true
agent_download_timeout:
default: 2h
nullable: true
agent_limits_go_max_procs:
nullable: true
agent_logging_files_interval:
nullable: true
agent_logging_files_keepfiles:
nullable: true
agent_logging_files_rotateeverybytes:
nullable: true
agent_logging_level:
default: info
nullable: true
agent_logging_metrics_period:
default: 30s
nullable: true
agent_logging_to_files:
nullable: true
agent_features:
items:
@ -13619,15 +13634,20 @@ paths:
agent_download_target_directory:
nullable: true
agent_download_timeout:
default: 2h
nullable: true
agent_limits_go_max_procs:
nullable: true
agent_logging_files_interval:
nullable: true
agent_logging_files_keepfiles:
nullable: true
agent_logging_files_rotateeverybytes:
nullable: true
agent_logging_level:
default: info
nullable: true
agent_logging_metrics_period:
default: 30s
nullable: true
agent_logging_to_files:
nullable: true
agent_features:
items:
@ -14142,15 +14162,20 @@ paths:
agent_download_target_directory:
nullable: true
agent_download_timeout:
default: 2h
nullable: true
agent_limits_go_max_procs:
nullable: true
agent_logging_files_interval:
nullable: true
agent_logging_files_keepfiles:
nullable: true
agent_logging_files_rotateeverybytes:
nullable: true
agent_logging_level:
default: info
nullable: true
agent_logging_metrics_period:
default: 30s
nullable: true
agent_logging_to_files:
nullable: true
agent_features:
items:
@ -14665,15 +14690,20 @@ paths:
agent_download_target_directory:
nullable: true
agent_download_timeout:
default: 2h
nullable: true
agent_limits_go_max_procs:
nullable: true
agent_logging_files_interval:
nullable: true
agent_logging_files_keepfiles:
nullable: true
agent_logging_files_rotateeverybytes:
nullable: true
agent_logging_level:
default: info
nullable: true
agent_logging_metrics_period:
default: 30s
nullable: true
agent_logging_to_files:
nullable: true
agent_features:
items:
@ -14839,15 +14869,20 @@ paths:
agent_download_target_directory:
nullable: true
agent_download_timeout:
default: 2h
nullable: true
agent_limits_go_max_procs:
nullable: true
agent_logging_files_interval:
nullable: true
agent_logging_files_keepfiles:
nullable: true
agent_logging_files_rotateeverybytes:
nullable: true
agent_logging_level:
default: info
nullable: true
agent_logging_metrics_period:
default: 30s
nullable: true
agent_logging_to_files:
nullable: true
agent_features:
items:
@ -15382,15 +15417,20 @@ paths:
agent_download_target_directory:
nullable: true
agent_download_timeout:
default: 2h
nullable: true
agent_limits_go_max_procs:
nullable: true
agent_logging_files_interval:
nullable: true
agent_logging_files_keepfiles:
nullable: true
agent_logging_files_rotateeverybytes:
nullable: true
agent_logging_level:
default: info
nullable: true
agent_logging_metrics_period:
default: 30s
nullable: true
agent_logging_to_files:
nullable: true
agent_features:
items:
@ -16002,6 +16042,30 @@ paths:
required:
- enabled
type: object
limits:
additionalProperties: false
type: object
properties:
go_max_procs:
type: number
logging:
additionalProperties: false
type: object
properties:
files:
additionalProperties: false
type: object
properties:
interval:
type: string
keepfiles:
type: number
rotateeverybytes:
type: number
level:
type: string
to_files:
type: boolean
monitoring:
additionalProperties: false
type: object

View file

@ -40,7 +40,7 @@ export const AGENT_POLICY_ADVANCED_SETTINGS: SettingsConfig[] = [
api_field: {
name: 'agent_limits_go_max_procs',
},
schema: z.number().int().min(0).default(0),
schema: z.number().int().min(0),
},
{
name: 'agent.download.timeout',
@ -59,7 +59,7 @@ export const AGENT_POLICY_ADVANCED_SETTINGS: SettingsConfig[] = [
api_field: {
name: 'agent_download_timeout',
},
schema: zodStringWithDurationValidation.default('2h'),
schema: zodStringWithDurationValidation,
},
{
name: 'agent.download.target_directory',
@ -103,7 +103,7 @@ export const AGENT_POLICY_ADVANCED_SETTINGS: SettingsConfig[] = [
),
learnMoreLink:
'https://www.elastic.co/guide/en/fleet/current/elastic-agent-standalone-logging-config.html#elastic-agent-standalone-logging-settings',
schema: zodStringWithDurationValidation.default('30s'),
schema: zodStringWithDurationValidation,
},
{
name: 'agent.logging.level',
@ -124,4 +124,76 @@ export const AGENT_POLICY_ADVANCED_SETTINGS: SettingsConfig[] = [
'https://www.elastic.co/guide/en/fleet/current/agent-policy.html#agent-policy-log-level',
schema: z.enum(AGENT_LOG_LEVELS).default(DEFAULT_LOG_LEVEL),
},
{
name: 'agent.logging.to_files',
title: i18n.translate('xpack.fleet.settings.agentPolicyAdvanced.agentLoggingToFilesTitle', {
defaultMessage: 'Agent logging to files',
}),
description: (
<FormattedMessage
id="xpack.fleet.settings.agentPolicyAdvanced.agentLoggingToFilesDescription"
defaultMessage="Enables logging to rotating files."
/>
),
api_field: {
name: 'agent_logging_to_files',
},
learnMoreLink:
'https://www.elastic.co/guide/en/fleet/current/elastic-agent-standalone-logging-config.html#elastic-agent-standalone-logging-settings',
schema: z.boolean().default(true),
},
{
name: 'agent.logging.files.rotateeverybytes',
title: i18n.translate('xpack.fleet.settings.agentPolicyAdvanced.agentLoggingFileSizeTitle', {
defaultMessage: 'Agent logging file size limit',
}),
description: (
<FormattedMessage
id="xpack.fleet.settings.agentPolicyAdvanced.agentLoggingFileSizeDescription"
defaultMessage="Configure log file size limit in bytes. If limit is reached, log file will be automatically rotated."
/>
),
api_field: {
name: 'agent_logging_files_rotateeverybytes',
},
learnMoreLink:
'https://www.elastic.co/guide/en/fleet/current/elastic-agent-standalone-logging-config.html#elastic-agent-standalone-logging-settings',
schema: z.number().int().min(0),
},
{
name: 'agent.logging.files.keepfiles',
title: i18n.translate('xpack.fleet.settings.agentPolicyAdvanced.agentLoggingFileLimitTitle', {
defaultMessage: 'Agent logging number of files',
}),
description: (
<FormattedMessage
id="xpack.fleet.settings.agentPolicyAdvanced.agentLoggingFileLimitDescription"
defaultMessage="Number of rotated log files to keep. Oldest files will be deleted first."
/>
),
api_field: {
name: 'agent_logging_files_keepfiles',
},
learnMoreLink:
'https://www.elastic.co/guide/en/fleet/current/elastic-agent-standalone-logging-config.html#elastic-agent-standalone-logging-settings',
schema: z.number().int().min(0),
},
{
name: 'agent.logging.files.interval',
title: i18n.translate('xpack.fleet.settings.agentPolicyAdvanced.agentLoggingFileIntervalitle', {
defaultMessage: 'Agent logging number of files',
}),
description: (
<FormattedMessage
id="xpack.fleet.settings.agentPolicyAdvanced.agentLoggingFileIntervalescription"
defaultMessage="Enable log file rotation on time intervals in addition to size-based rotation, i.e. 24h, 7d."
/>
),
api_field: {
name: 'agent_logging_files_interval',
},
learnMoreLink:
'https://www.elastic.co/guide/en/fleet/current/elastic-agent-standalone-logging-config.html#elastic-agent-standalone-logging-settings',
schema: zodStringWithDurationValidation,
},
];

View file

@ -185,6 +185,18 @@ export interface FullAgentPolicy {
uninstall_token_hash: string;
signing_key: string;
};
logging?: {
level?: string;
to_files?: boolean;
files?: {
rotateeverybytes?: number;
keepfiles?: number;
interval?: string;
};
};
limits?: {
go_max_procs?: number;
};
};
secret_references?: PolicySecretReference[];
signed?: {

View file

@ -102,6 +102,35 @@ describe('ConfiguredSettings', () => {
expect(mockUpdateAdvancedSettingsHasErrors).toHaveBeenCalledWith(true);
});
it('should render boolean field using checkbox', () => {
const result = render([
{
name: 'agent.logging.to_files',
title: 'Agent logging to files',
description: 'Description',
learnMoreLink: '',
api_field: {
name: 'agent_logging_to_files',
},
schema: z.boolean().default(false),
},
]);
expect(result.getByText('Agent logging to files')).not.toBeNull();
const input = result.getByTestId('configuredSetting-agent.logging.to_files');
expect(input).not.toBeChecked();
act(() => {
fireEvent.click(input);
});
expect(mockUpdateAgentPolicy).toHaveBeenCalledWith(
expect.objectContaining({
advanced_settings: expect.objectContaining({ agent_logging_to_files: true }),
})
);
});
it('should not render field if hidden', () => {
const result = render([
{

View file

@ -7,7 +7,9 @@
import { ZodFirstPartyTypeKind } from '@kbn/zod';
import React from 'react';
import { EuiFieldNumber, EuiFieldText, EuiSelect } from '@elastic/eui';
import { EuiCheckbox, EuiFieldNumber, EuiFieldText, EuiSelect } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import type { SettingsConfig } from '../../../../../common/settings/types';
@ -68,7 +70,7 @@ settingComponentRegistry.set(ZodFirstPartyTypeKind.ZodEnum, ({ disabled, ...sett
<SettingsFieldWrapper
disabled={disabled}
settingsConfig={settingsConfig}
typeName={ZodFirstPartyTypeKind.ZodString}
typeName={ZodFirstPartyTypeKind.ZodEnum}
renderItem={({ fieldKey, fieldValue, handleChange }: any) => (
<EuiSelect
data-test-subj={fieldKey}
@ -86,6 +88,30 @@ settingComponentRegistry.set(ZodFirstPartyTypeKind.ZodEnum, ({ disabled, ...sett
);
});
settingComponentRegistry.set(
ZodFirstPartyTypeKind.ZodBoolean,
({ disabled, ...settingsConfig }) => {
return (
<SettingsFieldWrapper
disabled={disabled}
settingsConfig={settingsConfig}
typeName={ZodFirstPartyTypeKind.ZodBoolean}
renderItem={({ fieldKey, fieldValue, handleChange }: any) => (
<EuiCheckbox
data-test-subj={fieldKey}
id={fieldKey}
label={i18n.translate('xpack.fleet.configuredSettings.genericCheckboxLabel', {
defaultMessage: 'Enable',
})}
checked={fieldValue}
onChange={handleChange}
/>
)}
/>
);
}
);
export function ConfiguredSettings({
configuredSettings,
disabled,
@ -101,7 +127,7 @@ export function ConfiguredSettings({
const Component = settingComponentRegistry.get(getInnerType(configuredSetting.schema));
if (!Component) {
throw new Error(`Unknown setting type: ${configuredSetting.schema._type}}`);
throw new Error(`Unknown setting type: ${configuredSetting.schema._type}`);
}
return (

View file

@ -13,12 +13,15 @@ import { EuiDescribedFormGroup, EuiFormRow, EuiLink } from '@elastic/eui';
import type { SettingsConfig } from '../../../../../common/settings/types';
import { useAgentPolicyFormContext } from '../../sections/agent_policy/components/agent_policy_form';
export const convertValue = (value: string, type: keyof typeof ZodFirstPartyTypeKind): any => {
export const convertValue = (
value: string | boolean,
type: keyof typeof ZodFirstPartyTypeKind
): any => {
if (type === ZodFirstPartyTypeKind.ZodNumber) {
if (value === '') {
return 0;
}
return parseInt(value, 10);
return parseInt(value as string, 10);
}
return value;
};
@ -48,7 +51,8 @@ export const SettingsFieldWrapper: React.FC<{
const coercedSchema = settingsConfig.schema as z.ZodString;
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const newValue = convertValue(e.target.value, typeName);
const value = typeName === ZodFirstPartyTypeKind.ZodBoolean ? e.target.checked : e.target.value;
const newValue = convertValue(value, typeName);
const validationError = validateSchema(coercedSchema, newValue);
if (validationError) {
@ -97,9 +101,13 @@ export const SettingsFieldWrapper: React.FC<{
};
export const getInnerType = (schema: z.ZodType<any, any>) => {
return schema instanceof z.ZodDefault
? schema._def.innerType._def.typeName === 'ZodEffects'
if (schema._def.innerType) {
return schema._def.innerType._def.typeName === 'ZodEffects'
? schema._def.innerType._def.schema._def.typeName
: schema._def.innerType._def.typeName
: schema._def.typeName;
: schema._def.innerType._def.typeName;
}
if (schema._def.typeName === 'ZodEffects') {
return schema._def.schema._def.typeName;
}
return schema._def.typeName;
};

View file

@ -171,6 +171,10 @@ describe('schema validation', () => {
agent_limits_go_max_procs: 1,
agent_logging_level: 'info',
agent_logging_metrics_period: '30s',
agent_logging_to_files: true,
agent_logging_files_rotateeverybytes: 10000,
agent_logging_files_keepfiles: 10,
agent_logging_files_interval: '7h',
},
keep_monitoring_alive: true,
supports_agentless: true,

View file

@ -888,6 +888,10 @@ describe('getFullAgentPolicy', () => {
advanced_settings: {
agent_limits_go_max_procs: 2,
agent_logging_level: 'debug',
agent_logging_to_files: true,
agent_logging_files_rotateeverybytes: 10000,
agent_logging_files_keepfiles: 10,
agent_logging_files_interval: '7h',
},
});
const agentPolicy = await getFullAgentPolicy(savedObjectsClientMock.create(), 'agent-policy');
@ -896,7 +900,11 @@ describe('getFullAgentPolicy', () => {
id: 'agent-policy',
agent: {
limits: { go_max_procs: 2 },
logging: { level: 'debug' },
logging: {
level: 'debug',
to_files: true,
files: { rotateeverybytes: 10000, keepfiles: 10, interval: '7h' },
},
},
});
});

View file

@ -55,10 +55,10 @@ describe('form_settings', () => {
).not.toThrow();
});
it('generate a valid API schema for api_field with default value', () => {
it('generate a valid API schema for api_field with default value but not add the value', () => {
const apiSchema = schema.object(_getSettingsAPISchema(TEST_SETTINGS));
const res = apiSchema.validate({ advanced_settings: {} });
expect(res).toEqual({ advanced_settings: { test_foo_default_value: 'test' } });
expect(res).toEqual({ advanced_settings: {} });
});
});

View file

@ -24,40 +24,19 @@ export function _getSettingsAPISchema(settings: SettingsConfig[]): Props {
if (!setting.api_field) {
return;
}
const defaultValueRes = setting.schema.safeParse(undefined);
const defaultValue = defaultValueRes.success ? defaultValueRes.data : undefined;
if (defaultValue) {
validations[setting.api_field.name] = schema.oneOf(
[
schema.any({
validate: (val: any) => {
const res = setting.schema.safeParse(val);
if (!res.success) {
return stringifyZodError(res.error);
}
},
}),
schema.literal(null),
],
{
defaultValue,
}
);
} else {
validations[setting.api_field.name] = schema.maybe(
schema.oneOf([
schema.literal(null),
schema.any({
validate: (val: any) => {
const res = setting.schema.safeParse(val);
if (!res.success) {
return stringifyZodError(res.error);
}
},
}),
])
);
}
validations[setting.api_field.name] = schema.maybe(
schema.oneOf([
schema.literal(null),
schema.any({
validate: (val: any) => {
const res = setting.schema.safeParse(val);
if (!res.success) {
return stringifyZodError(res.error);
}
},
}),
])
);
});
const advancedSettingsValidations: Props = {
@ -90,7 +69,7 @@ export function _getSettingsValuesForAgentPolicy(
}
const val = agentPolicy.advanced_settings?.[setting.api_field.name];
if (val) {
if (val !== undefined) {
settingsValues[setting.name] = val;
}
});

View file

@ -377,6 +377,24 @@ export const FullAgentPolicyResponseSchema = schema.object({
signing_key: schema.string(),
})
),
logging: schema.maybe(
schema.object({
level: schema.maybe(schema.string()),
to_files: schema.maybe(schema.boolean()),
files: schema.maybe(
schema.object({
rotateeverybytes: schema.maybe(schema.number()),
keepfiles: schema.maybe(schema.number()),
interval: schema.maybe(schema.string()),
})
),
})
),
limits: schema.maybe(
schema.object({
go_max_procs: schema.maybe(schema.number()),
})
),
})
),
secret_references: schema.maybe(