Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[receiver/syslog] expose the syslog parser config from the syslog receiver #36906

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .chloggen/syslog-receiver-add-parser-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Use this changelog template to create an entry for release notes.

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

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

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Support setting syslog parser config in the syslog receiver

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

# (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:

# If your change doesn't affect end users or the exported elements of any package,
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
# Optional: The change log or logs in which this entry should be included.
# e.g. '[user]' or '[user, api]'
# Include 'user' if the change is relevant to end users.
# Include 'api' if there is a change to a library API.
# Default: '[user]'
change_logs: [user]
19 changes: 10 additions & 9 deletions pkg/stanza/operator/input/syslog/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,17 @@ func NewConfig() *Config {
// NewConfigWithID creates a new input config with default values
func NewConfigWithID(operatorID string) *Config {
return &Config{
InputConfig: helper.NewInputConfig(operatorID, operatorType),
InputConfig: helper.NewInputConfig(operatorID, operatorType),
ParserConfig: syslog.NewConfigWithID(operatorID + "_internal_parser").ParserConfig,
}
}

type Config struct {
helper.InputConfig `mapstructure:",squash"`
syslog.BaseConfig `mapstructure:",squash"`
TCP *tcp.BaseConfig `mapstructure:"tcp"`
UDP *udp.BaseConfig `mapstructure:"udp"`
helper.InputConfig `mapstructure:",squash"`
helper.ParserConfig `mapstructure:"parser"`
syslog.BaseConfig `mapstructure:",squash"`
TCP *tcp.BaseConfig `mapstructure:"tcp"`
UDP *udp.BaseConfig `mapstructure:"udp"`
}

func (c Config) Build(set component.TelemetrySettings) (operator.Operator, error) {
Expand All @@ -47,11 +49,10 @@ func (c Config) Build(set component.TelemetrySettings) (operator.Operator, error
return nil, err
}

syslogParserCfg := syslog.NewConfigWithID(inputBase.ID() + "_internal_tcp")
syslogParserCfg := syslog.NewConfig()
syslogParserCfg.BaseConfig = c.BaseConfig
syslogParserCfg.SetID(inputBase.ID() + "_internal_parser")
syslogParserCfg.OutputIDs = c.OutputIDs
syslogParserCfg.MaxOctets = c.MaxOctets
syslogParserCfg.ParserConfig = c.ParserConfig
syslogParserCfg.ParserConfig.OutputIDs = c.InputConfig.OutputIDs
syslogParser, err := syslogParserCfg.Build(set)
if err != nil {
return nil, fmt.Errorf("failed to resolve syslog config: %w", err)
Expand Down
26 changes: 26 additions & 0 deletions pkg/stanza/operator/input/syslog/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (

"go.opentelemetry.io/collector/config/configtls"

"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/entry"
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/helper"
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/input/tcp"
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/input/udp"
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/stanza/operator/operatortest"
Expand Down Expand Up @@ -66,6 +68,30 @@ func TestUnmarshal(t *testing.T) {
return cfg
}(),
},
{
Name: "with_parser_config",
ExpectErr: false,
Expect: func() *Config {
cfg := NewConfig()
cfg.Protocol = "rfc5424"
cfg.Location = "foo"
cfg.ParserConfig.OnError = "drop"
cfg.ParserConfig.ParseFrom = entry.NewBodyField("from")
cfg.ParserConfig.ParseTo = entry.RootableField{Field: entry.NewBodyField("log")}
parseField := entry.NewBodyField("severity_field")
severityParser := helper.NewSeverityConfig()
severityParser.ParseFrom = &parseField
mapping := map[string]any{
"critical": "5xx",
"error": "4xx",
"info": "3xx",
"debug": "2xx",
}
severityParser.Mapping = mapping
cfg.SeverityConfig = &severityParser
return cfg
}(),
},
},
}.Run(t)
}
15 changes: 15 additions & 0 deletions pkg/stanza/operator/input/syslog/testdata/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,18 @@ udp:
multiline:
line_start_pattern: ABC
line_end_pattern: ""
with_parser_config:
type: syslog_input
protocol: rfc5424
location: foo
parser:
on_error: drop
parse_from: body.from
parse_to: body.log
severity:
parse_from: body.severity_field
mapping:
critical: 5xx
error: 4xx
info: 3xx
debug: 2xx
2 changes: 1 addition & 1 deletion pkg/stanza/operator/parser/syslog/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ type BaseConfig struct {
MaxOctets int `mapstructure:"max_octets,omitempty"`
}

// Build will build a JSON parser operator.
// Build will build a syslog parser operator.
func (c Config) Build(set component.TelemetrySettings) (operator.Operator, error) {
if c.ParserConfig.TimeParser == nil {
parseFromField := entry.NewAttributeField("timestamp")
Expand Down
11 changes: 8 additions & 3 deletions receiver/syslogreceiver/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ Parses Syslogs received over TCP or UDP.
| `protocol` | required | The protocol to parse the syslog messages as. Options are `rfc3164` and `rfc5424` |
| `location` | `UTC` | The geographic location (timezone) to use when parsing the timestamp (Syslog RFC 3164 only). The available locations depend on the local IANA Time Zone database. [This page](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) contains many examples, such as `America/New_York`. |
| `enable_octet_counting` | `false` | Wether or not to enable [RFC 6587](https://www.rfc-editor.org/rfc/rfc6587#section-3.4.1) Octet Counting on syslog parsing (Syslog RFC 5424 and TCP only). |
| `max_octets` | `8192` | The maximum octets for messages using [RFC 6587](https://www.rfc-editor.org/rfc/rfc6587#section-3.4.1) Octet Counting on syslog parsing (Syslog RFC 5424 and TCP only). |
| `allow_skip_pri_header` | `false` | Allow parsing records without the PRI header. If this setting is enabled, messages without the PRI header will be successfully parsed. The `SeverityNumber` and `SeverityText` fields as well as the `priority` and `facility` attributes will not be set on the log record. If this setting is disabled (the default), messages without PRI header will throw an exception. To set this setting to `true`, the `enable_octet_counting` setting must be `false`. |
| `max_octets` | `8192` | The maximum octets for messages using [RFC 6587](https://www.rfc-editor.org/rfc/rfc6587#section-3.4.1) Octet Counting on syslog parsing (Syslog RFC 5424 and TCP only). |
| `allow_skip_pri_header` | `false` | Allow parsing records without the PRI header. If this setting is enabled, messages without the PRI header will be successfully parsed. The `SeverityNumber` and `SeverityText` fields as well as the `priority` and `facility` attributes will not be set on the log record. If this setting is disabled (the default), messages without PRI header will throw an exception. To set this setting to `true`, the `enable_octet_counting` setting must be `false`. |
| `non_transparent_framing_trailer` | `nil` | The framing trailer, either `LF` or `NUL`, when using [RFC 6587](https://www.rfc-editor.org/rfc/rfc6587#section-3.4.2) Non-Transparent-Framing (Syslog RFC 5424 and TCP only). |
| `attributes` | {} | A map of `key: value` labels to add to the entry's attributes |
| `resource` | {} | A map of `key: value` labels to add to the entry's resource |
Expand All @@ -33,7 +33,12 @@ Parses Syslogs received over TCP or UDP.
| `retry_on_failure.initial_interval` | `1 second` | Time to wait after the first failure before retrying. |
| `retry_on_failure.max_interval` | `30 seconds` | Upper bound on retry backoff interval. Once this value is reached the delay between consecutive retries will remain constant at the specified value. |
| `retry_on_failure.max_elapsed_time` | `5 minutes` | Maximum amount of time (including retries) spent trying to send a logs batch to a downstream consumer. Once this value is reached, the data is discarded. Retrying never stops if set to `0`. |

| `parser.parse_from` | `body` | The [field](../../pkg/stanza/docs/types/field.md) from which the value will be parsed. |
| `parser.parse_to` | `attributes` | The [field](../../pkg/stanza/docs/types/field.md) to which the value will be parsed. |
| `parser.on_error` | `send` | The behavior of the operator if it encounters an error. See [on_error](../../pkg/stanza/docs/types/on_error.md). |
| `parser.if` | | An [expression](../../pkg/stanza/docs/types/expression.md) that, when set, will be evaluated to determine whether this operator should be used for the given entry. This allows you to do easy conditional parsing without branching logic with routers. |
| `parser.timestamp` | `nil` | An optional [timestamp](../../pkg/stanza/docs/types/timestamp.md) block which will parse a timestamp field before passing the entry to the output operator |
| `parser.severity` | `nil` | An optional [severity](../../pkg/stanza/docs/types/severity.md) block which will parse a severity field before passing the entry to the output operator |
### Operators

Each operator performs a simple responsibility, such as parsing a timestamp or JSON. Chain together operators to process logs into a desired format.
Expand Down
Loading