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

[exporter/syslog] Add syslog exporter #19647

Merged
merged 12 commits into from
May 15, 2023
Merged
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
16 changes: 16 additions & 0 deletions .chloggen/add-syslog-exporter.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: new_component

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

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Add syslogexporter for sending logs to syslog server

# One or more tracking issues related to the change
issues: [17982]

# (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:
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ exporter/signalfxexporter/ @open-telemetry/collect
exporter/skywalkingexporter/ @open-telemetry/collector-contrib-approvers @liqiangz
exporter/splunkhecexporter/ @open-telemetry/collector-contrib-approvers @atoulme @dmitryax
exporter/sumologicexporter/ @open-telemetry/collector-contrib-approvers @sumo-drosiek
exporter/syslogexporter/ @open-telemetry/collector-contrib-approvers @kkujawa-sumo @rnishtala-sumo @astencel-sumo
exporter/tanzuobservabilityexporter/ @open-telemetry/collector-contrib-approvers @oppegard @thepeterstone @keep94
exporter/tencentcloudlogserviceexporter/ @open-telemetry/collector-contrib-approvers @wgliang @yiyang5055
exporter/zipkinexporter/ @open-telemetry/collector-contrib-approvers
Expand Down
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ body:
- exporter/skywalking
- exporter/splunkhec
- exporter/sumologic
- exporter/syslog
- exporter/tanzuobservability
- exporter/tencentcloudlogservice
- exporter/zipkin
Expand Down
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ body:
- exporter/skywalking
- exporter/splunkhec
- exporter/sumologic
- exporter/syslog
- exporter/tanzuobservability
- exporter/tencentcloudlogservice
- exporter/zipkin
Expand Down
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/other.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ body:
- exporter/skywalking
- exporter/splunkhec
- exporter/sumologic
- exporter/syslog
- exporter/tanzuobservability
- exporter/tencentcloudlogservice
- exporter/zipkin
Expand Down
10 changes: 5 additions & 5 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,11 @@ updates:
schedule:
interval: "weekly"
day: "wednesday"
- package-ecosystem: "gomod"
directory: "/exporter/syslogexporter"
schedule:
interval: "weekly"
day: "wednesday"
- package-ecosystem: "gomod"
directory: "/exporter/tanzuobservabilityexporter"
schedule:
Expand Down Expand Up @@ -1097,8 +1102,3 @@ updates:
schedule:
interval: "weekly"
day: "wednesday"
- package-ecosystem: "gomod"
directory: "/receiver/windowsperfcountersreceiver"
schedule:
interval: "weekly"
day: "wednesday"
1 change: 1 addition & 0 deletions exporter/syslogexporter/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include ../../Makefile.Common
62 changes: 62 additions & 0 deletions exporter/syslogexporter/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Syslog Exporter

<!-- status autogenerated section -->
| Status | |
| ------------- |-----------|
| Stability | [development]: logs |
| Distributions | [] |

[development]: https://github.com/open-telemetry/opentelemetry-collector#development
<!-- end autogenerated section -->

The syslog exporter supports sending messages to a remote syslog server.

- This exporter can forward syslog messages to syslog server using [RFC5424][RFC5424] and [RFC3164][RFC3164].
- It is recommended that this syslog exporter be used with the [syslog receiver][syslog_receiver] or with [filelog receiver][filelog_receiver] along with [syslog_parser][syslog_parser] configured in the receiver, please see [examples](./examples/)
This ensures that all the syslog message headers are populated with the expected values.
- Not using the `syslog_parser` will result in the syslog message being populated with default header values.

## Configuration
kasia-kujawa marked this conversation as resolved.
Show resolved Hide resolved

**The following configuration options are available**:

- `endpoint` - (required) syslog endpoint
- `network` - (default = `tcp`) tcp/udp
- `port` - (default = `514`) A syslog port
- `protocol` - (default = `rfc5424`) rfc5424/rfc3164
- `rfc5424` - Expects the syslog messages to be rfc5424 compliant
- `rfc3164` - Expects the syslog messages to be rfc3164 compliant
- `tls` - configuration for TLS/mTLS
- `insecure` (default = `false`) whether to enable client transport security, by default, TLS is enabled.
- `cert_file` - Path to the TLS cert to use for TLS required connections. Should only be used if `insecure` is set to `false`.
- `key_file` - Path to the TLS key to use for TLS required connections. Should only be used if `insecure` is set to `false`.
- `ca_file` - Path to the CA cert. For a client this verifies the server certificate. For a server this verifies client certificates. If empty uses system root CA. Should only be used if `insecure` is set to `false`.
- `insecure_skip_verify` - (default = `false`) whether to skip verifying the certificate or not.
- `min_version` (default = `1.2`) Minimum acceptable TLS version
- `max_version` (default = `""` handled by [crypto/tls][cryptoTLS] - currently TLS 1.3) Maximum acceptable TLS version.
- `reload_interval` - Specifies the duration after which the certificate will be reloaded. If not set, it will never be reloaded.
- `retry_on_failure`
- `enabled` (default = `true`)
- `initial_interval` (default = `5s`): Time to wait after the first failure before retrying; ignored if `enabled` is `false`
- `max_interval` (default = 30s): Is the upper bound on backoff; ignored if `enabled` is `false`
- `max_elapsed_time` (default = `120s`): Is the maximum amount of time spent trying to send a batch; ignored if `enabled` is `false`
- `sending_queue`
- `enabled` (default = `false`)
- `num_consumers` (default = `10`): Number of consumers that dequeue batches; ignored if `enabled` is `false`
- `queue_size` (default = `5000`): Maximum number of batches kept in memory before data; ignored if `enabled` is `false`;
User should calculate this as `num_seconds * requests_per_second` where:
- `num_seconds` is the number of seconds to buffer in case of a backend outage
- `requests_per_second` is the average number of requests per seconds.
- `storage` (default = `none`): When set, enables persistence and uses the component specified as a storage extension for the [persistent queue][persistent_queue]
- `timeout` (default = 5s) Time to wait per individual attempt to send data to a backend

Please see [example configurations](./examples/).

[RFC5424]: https://www.rfc-editor.org/rfc/rfc5424
[RFC3164]: https://www.rfc-editor.org/rfc/rfc3164
[syslog_parser]: https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/pkg/stanza/docs/operators/syslog_parser.md
[syslog_receiver]: https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/syslogreceiver
[filelog_receiver]: https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/filelogreceiver
[cryptoTLS]: https://github.com/golang/go/blob/518889b35cb07f3e71963f2ccfc0f96ee26a51ce/src/crypto/tls/common.go#L706-L709
[development]: https://github.com/open-telemetry/opentelemetry-collector#development
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line is probably not needed anymore, as the link is being autogenerated together with the status table.

Suggested change
[development]: https://github.com/open-telemetry/opentelemetry-collector#development

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kkujawa-sumo, please take note of this. It can be done in a follow up PR.

[persistent_queue]: https://github.com/open-telemetry/opentelemetry-collector/blob/main/exporter/exporterhelper/README.md#persistent-queue
90 changes: 90 additions & 0 deletions exporter/syslogexporter/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package syslogexporter // import "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/syslogexporter"

import (
"errors"
"strings"

"go.opentelemetry.io/collector/config/configtls"
"go.opentelemetry.io/collector/exporter/exporterhelper"
"go.uber.org/multierr"
)

var (
errUnsupportedPort = errors.New("unsupported port: port is required, must be in the range 1-65535")
errInvalidEndpoint = errors.New("invalid endpoint: endpoint is required but it is not configured")
errUnsupportedNetwork = errors.New("unsupported network: network is required, only tcp/udp supported")
errUnsupportedProtocol = errors.New("unsupported protocol: Only rfc5424 and rfc3164 supported")
)

// Config defines configuration for Syslog exporter.
type Config struct {
// Syslog server address
Endpoint string `mapstructure:"endpoint"`
// Syslog server port
Port int `mapstructure:"port"`
// Network for syslog communication
// options: tcp, udp
Network string `mapstructure:"network"`
// Protocol of syslog messages
// options: rfc5424, rfc3164
Protocol string `mapstructure:"protocol"`

// TLSSetting struct exposes TLS client configuration.
TLSSetting configtls.TLSClientSetting `mapstructure:"tls"`

exporterhelper.QueueSettings `mapstructure:"sending_queue"`
exporterhelper.RetrySettings `mapstructure:"retry_on_failure"`
exporterhelper.TimeoutSettings `mapstructure:",squash"` // squash ensures fields are correctly decoded in embedded struct
}

// Validate the configuration for errors. This is required by component.Config.
func (cfg *Config) Validate() error {
invalidFields := []error{}
if cfg.Port < 1 || cfg.Port > 65535 {
invalidFields = append(invalidFields, errUnsupportedPort)
}

if cfg.Endpoint == "" {
invalidFields = append(invalidFields, errInvalidEndpoint)
}

if strings.ToLower(cfg.Network) != "tcp" && strings.ToLower(cfg.Network) != "udp" {
invalidFields = append(invalidFields, errUnsupportedNetwork)
}

switch cfg.Protocol {
case protocolRFC3164Str:
case protocolRFC5424Str:
default:
invalidFields = append(invalidFields, errUnsupportedProtocol)
}

if len(invalidFields) > 0 {
return multierr.Combine(invalidFields...)
}

return nil
}

const (
// Syslog Network
DefaultNetwork = "tcp"
// Syslog Port
DefaultPort = 514
// Syslog Protocol
DefaultProtocol = "rfc5424"
)
82 changes: 82 additions & 0 deletions exporter/syslogexporter/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package syslogexporter

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestValidate(t *testing.T) {

tests := []struct {
name string
cfg *Config
err string
}{
{
name: "invalid Port",
cfg: &Config{
Port: 515444,
Endpoint: "host.domain.com",
Protocol: "rfc542",
Network: "udp",
},
err: "unsupported port: port is required, must be in the range 1-65535; " +
"unsupported protocol: Only rfc5424 and rfc3164 supported",
},
{
name: "invalid Endpoint",
cfg: &Config{
Port: 514,
Endpoint: "",
Protocol: "rfc5424",
Network: "udp",
},
err: "invalid endpoint: endpoint is required but it is not configured",
},
{
name: "unsupported Network",
cfg: &Config{
Port: 514,
Endpoint: "host.domain.com",
Protocol: "rfc5424",
Network: "ftp",
},
err: "unsupported network: network is required, only tcp/udp supported",
},
{
name: "Unsupported Protocol",
cfg: &Config{
Port: 514,
Endpoint: "host.domain.com",
Network: "udp",
Protocol: "rfc",
},
err: "unsupported protocol: Only rfc5424 and rfc3164 supported",
},
}
for _, testInstance := range tests {
t.Run(testInstance.name, func(t *testing.T) {
err := testInstance.cfg.Validate()
if testInstance.err != "" {
assert.EqualError(t, err, testInstance.err)
} else {
assert.NoError(t, err)
}
})
}
}
17 changes: 17 additions & 0 deletions exporter/syslogexporter/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//go:generate mdatagen metadata.yaml

package syslogexporter // import "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/syslogexporter"
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
extensions:
file_storage/syslog:
directory: /tmp/otc
timeout: 10s

exporters:
syslog:
network: tcp
port: 514
endpoint: 127.0.0.1
tls:
ca_file: certs/servercert.pem
cert_file: certs/cert.pem
key_file: certs/key.pem
protocol: rfc5424

# for below described queueing and retry related configuration please refer to:
# https://github.com/open-telemetry/opentelemetry-collector/blob/main/exporter/exporterhelper/README.md#configuration
retry_on_failure:
# default = true
enabled: true
# time to wait after the first failure before retrying;
# ignored if enabled is false, default = 5s
initial_interval: 10s
# is the upper bound on backoff; ignored if enabled is false, default = 30s
max_interval: 40s
# is the maximum amount of time spent trying to send a batch;
# ignored if enabled is false, default = 120s
max_elapsed_time: 150s

sending_queue:
# default = false
enabled: true
# number of consumers that dequeue batches; ignored if enabled is false,
# default = 10
num_consumers: 20
# when set, enables persistence and uses the component specified as a storage extension for the persistent queue
# make sure to configure and add a `file_storage` extension in `service.extensions`.
# default = None
storage: file_storage/syslog
# maximum number of batches kept in memory before data;
# ignored if enabled is false, default = 5000
#
# user should calculate this as num_seconds * requests_per_second where:
# num_seconds is the number of seconds to buffer in case of a backend outage,
# requests_per_second is the average number of requests per seconds.
queue_size: 10000
# Time to wait per individual attempt to send data to a backend
# default = 5s
timeout: 1s
receivers:
filelog:
start_at: beginning
include:
- /other/path/**/*.txt
operators:
- type: syslog_parser
protocol: rfc5424

service:
telemetry:
logs:
level: "debug"
extensions:
- file_storage/syslog
pipelines:
logs:
receivers:
- filelog
exporters:
- syslog
Loading