123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- // Copyright The OpenTelemetry Authors
- // SPDX-License-Identifier: Apache-2.0
- package syslogexporter
- import (
- "context"
- "errors"
- "io"
- "net"
- "strconv"
- "testing"
- "time"
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
- "go.opentelemetry.io/collector/component"
- "go.opentelemetry.io/collector/consumer/consumererror"
- "go.opentelemetry.io/collector/exporter"
- "go.opentelemetry.io/collector/pdata/pcommon"
- "go.opentelemetry.io/collector/pdata/plog"
- "go.uber.org/zap"
- )
- var expectedForm = "<165>1 2003-08-24T12:14:15Z 192.0.2.1 myproc 8710 - - It's time to make the do-nuts.\n"
- var originalForm = "<165>1 2003-08-24T05:14:15-07:00 192.0.2.1 myproc 8710 - - It's time to make the do-nuts."
- type exporterTest struct {
- srv net.TCPListener
- exp *syslogexporter
- }
- func exampleLog(t *testing.T) plog.LogRecord {
- buffer := plog.NewLogRecord()
- buffer.Body().SetStr(originalForm)
- timestamp := "2003-08-24T05:14:15-07:00"
- timeStr, err := time.Parse(time.RFC3339, timestamp)
- require.NoError(t, err, "failed to start test syslog server")
- ts := pcommon.NewTimestampFromTime(timeStr)
- buffer.SetTimestamp(ts)
- attrMap := map[string]any{"proc_id": "8710", "message": "It's time to make the do-nuts.",
- "appname": "myproc", "hostname": "192.0.2.1", "priority": int64(165),
- "version": int64(1)}
- for k, v := range attrMap {
- if _, ok := v.(string); ok {
- buffer.Attributes().PutStr(k, v.(string))
- } else {
- buffer.Attributes().PutInt(k, v.(int64))
- }
- }
- return buffer
- }
- func logRecordsToLogs(record plog.LogRecord) plog.Logs {
- logs := plog.NewLogs()
- logsSlice := logs.ResourceLogs().AppendEmpty().ScopeLogs().AppendEmpty().LogRecords()
- ls := logsSlice.AppendEmpty()
- record.CopyTo(ls)
- return logs
- }
- func createExporterCreateSettings() exporter.CreateSettings {
- return exporter.CreateSettings{
- TelemetrySettings: component.TelemetrySettings{
- Logger: zap.NewNop(),
- },
- }
- }
- func TestInitExporter(t *testing.T) {
- _, err := initExporter(&Config{Endpoint: "test.com",
- Network: "tcp",
- Port: 514,
- Protocol: "rfc5424"}, createExporterCreateSettings())
- assert.NoError(t, err)
- }
- func buildValidExporter(t *testing.T, server net.TCPListener, cfg *Config) (*syslogexporter, error) {
- var port string
- var err error
- hostPort := server.Addr().String()
- cfg.Endpoint, port, err = net.SplitHostPort(hostPort)
- require.NoError(t, err, "could not parse port")
- cfg.Port, err = strconv.Atoi(port)
- require.NoError(t, err, "type error")
- exp, err := initExporter(cfg, createExporterCreateSettings())
- require.NoError(t, err)
- return exp, err
- }
- func buildInvalidExporter(t *testing.T, server net.TCPListener, cfg *Config) (*syslogexporter, error) {
- var port string
- var err error
- hostPort := server.Addr().String()
- cfg.Endpoint, port, err = net.SplitHostPort(hostPort)
- require.NoError(t, err, "could not parse endpoint")
- require.NotNil(t, port)
- invalidPort := "112" // Assign invalid port
- cfg.Port, err = strconv.Atoi(invalidPort)
- require.NoError(t, err, "type error")
- exp, err := initExporter(cfg, createExporterCreateSettings())
- require.NoError(t, err)
- return exp, err
- }
- func createServer() (net.TCPListener, error) {
- var addr net.TCPAddr
- addr.IP = net.IP{127, 0, 0, 1}
- addr.Port = 0
- testServer, err := net.ListenTCP("tcp", &addr)
- return *testServer, err
- }
- func prepareExporterTest(t *testing.T, cfg *Config, invalidExporter bool) *exporterTest {
- // Start a test syslog server
- var err error
- testServer, err := createServer()
- require.NoError(t, err, "failed to start test syslog server")
- var exp *syslogexporter
- if invalidExporter {
- exp, err = buildInvalidExporter(t, testServer, cfg)
- } else {
- exp, err = buildValidExporter(t, testServer, cfg)
- }
- require.NoError(t, err, "Error building exporter")
- require.NotNil(t, exp)
- return &exporterTest{
- srv: testServer,
- exp: exp,
- }
- }
- func createTestConfig() *Config {
- config := createDefaultConfig().(*Config)
- config.Network = "tcp"
- config.TLSSetting.Insecure = true
- return config
- }
- func TestSyslogExportSuccess(t *testing.T) {
- test := prepareExporterTest(t, createTestConfig(), false)
- require.NotNil(t, test.exp)
- defer test.srv.Close()
- go func() {
- buffer := exampleLog(t)
- logs := logRecordsToLogs(buffer)
- err := test.exp.pushLogsData(context.Background(), logs)
- require.NoError(t, err, "could not send message")
- }()
- err := test.srv.SetDeadline(time.Now().Add(time.Second * 1))
- require.NoError(t, err, "cannot set deadline")
- conn, err := test.srv.AcceptTCP()
- require.NoError(t, err, "could not accept connection")
- defer conn.Close()
- b, err := io.ReadAll(conn)
- require.NoError(t, err, "could not read all")
- assert.Equal(t, string(b), expectedForm)
- }
- func TestSyslogExportFail(t *testing.T) {
- test := prepareExporterTest(t, createTestConfig(), true)
- defer test.srv.Close()
- buffer := exampleLog(t)
- logs := logRecordsToLogs(buffer)
- consumerErr := test.exp.pushLogsData(context.Background(), logs)
- var consumerErrorLogs consumererror.Logs
- ok := errors.As(consumerErr, &consumerErrorLogs)
- assert.Equal(t, ok, true)
- consumerLogs := consumererror.Logs.Data(consumerErrorLogs)
- rls := consumerLogs.ResourceLogs()
- require.Equal(t, 1, rls.Len())
- scl := rls.At(0).ScopeLogs()
- require.Equal(t, 1, scl.Len())
- lrs := scl.At(0).LogRecords()
- require.Equal(t, 1, lrs.Len())
- droppedLog := lrs.At(0).Body().AsString()
- err := test.srv.SetDeadline(time.Now().Add(time.Second * 1))
- require.NoError(t, err, "cannot set deadline")
- conn, err := test.srv.AcceptTCP()
- require.ErrorContains(t, err, "i/o timeout")
- require.Nil(t, conn)
- assert.ErrorContains(t, consumerErr, "dial tcp 127.0.0.1:112: connect")
- assert.Equal(t, droppedLog, originalForm)
- }
|