Skip to content

Commit bbb4f97

Browse files
author
Joseph Sirianni
authored
Location parameter rfc3164 syslog (#11)
* Add optional location parameter for setting the timezone for rfc3164 syslog. Original implementation can be found here: https://github.com/observIQ/stanza/pull/247/commits
1 parent 7d6eb19 commit bbb4f97

File tree

4 files changed

+92
-4
lines changed

4 files changed

+92
-4
lines changed

CHANGELOG.md

+14
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,20 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## Unreleased
8+
9+
### Added
10+
- Syslog operator RFC 3164 location parameter ([PR11](https://github.com/open-telemetry/opentelemetry-log-collection/pull/11))
11+
12+
## [0.14.0] - 2020-02-02
13+
14+
### Changed
15+
- Remove standalone agent functionality
16+
- Simplifies modules
17+
- Combines `parser/syslog` and `input/windows` modules into the primary module
18+
- Removes output operators that were previously separate modules
19+
- Leaves `input/k8sevent` and `transformer/k8smetadata` as separate modules for now. These two have extensive dependencies and their usefulness in the collector needs to be discussed before merging or removing.
20+
721
## [0.13.12] - 2020-01-26
822

923
### Changed

docs/operators/syslog_parser.md

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ The `syslog_parser` operator parses the string-type field selected by `parse_fro
1313
| `preserve_to` | | Preserves the unparsed value at the specified [field](/docs/types/field.md) |
1414
| `on_error` | `send` | The behavior of the operator if it encounters an error. See [on_error](/docs/types/on_error.md) |
1515
| `protocol` | required | The protocol to parse the syslog messages as. Options are `rfc3164` and `rfc5424` |
16+
| `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`. |
1617
| `timestamp` | `nil` | An optional [timestamp](/docs/types/timestamp.md) block which will parse a timestamp field before passing the entry to the output operator |
1718
| `severity` | `nil` | An optional [severity](/docs/types/severity.md) block which will parse a severity field before passing the entry to the output operator |
1819
| `if` | | An [expression](/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. |

operator/builtin/parser/syslog/syslog.go

+15-3
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ type SyslogParserConfig struct {
4343
helper.ParserConfig `yaml:",inline"`
4444

4545
Protocol string `json:"protocol,omitempty" yaml:"protocol,omitempty"`
46+
Location string `json:"location,omitempty" yaml:"location,omitempty"`
4647
}
4748

4849
// Build will build a JSON parser operator.
@@ -64,18 +65,28 @@ func (c SyslogParserConfig) Build(context operator.BuildContext) ([]operator.Ope
6465
return nil, fmt.Errorf("missing field 'protocol'")
6566
}
6667

68+
if c.Location == "" {
69+
c.Location = "UTC"
70+
}
71+
72+
location, err := time.LoadLocation(c.Location)
73+
if err != nil {
74+
return nil, err
75+
}
76+
6777
syslogParser := &SyslogParser{
6878
ParserOperator: parserOperator,
6979
protocol: c.Protocol,
80+
location: location,
7081
}
7182

7283
return []operator.Operator{syslogParser}, nil
7384
}
7485

75-
func buildMachine(protocol string) (sl.Machine, error) {
86+
func buildMachine(protocol string, location *time.Location) (sl.Machine, error) {
7687
switch protocol {
7788
case "rfc3164":
78-
return rfc3164.NewMachine(), nil
89+
return rfc3164.NewMachine(rfc3164.WithLocaleTimezone(location)), nil
7990
case "rfc5424":
8091
return rfc5424.NewMachine(), nil
8192
default:
@@ -87,6 +98,7 @@ func buildMachine(protocol string) (sl.Machine, error) {
8798
type SyslogParser struct {
8899
helper.ParserOperator
89100
protocol string
101+
location *time.Location
90102
}
91103

92104
// Process will parse an entry field as syslog.
@@ -104,7 +116,7 @@ func (s *SyslogParser) parse(value interface{}) (interface{}, error) {
104116
return nil, err
105117
}
106118

107-
machine, err := buildMachine(s.protocol)
119+
machine, err := buildMachine(s.protocol, s.location)
108120
if err != nil {
109121
return nil, err
110122
}

operator/builtin/parser/syslog/syslog_test.go

+62-1
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,33 @@ import (
2525
"github.com/stretchr/testify/require"
2626
)
2727

28+
func testLocations() (map[string]*time.Location, error) {
29+
locations := map[string]string{
30+
"utc": "UTC",
31+
"detroit": "America/Detroit",
32+
"athens": "Europe/Athens",
33+
}
34+
35+
l := make(map[string]*time.Location)
36+
for k, v := range locations {
37+
var err error
38+
if l[k], err = time.LoadLocation(v); err != nil {
39+
return nil, err
40+
}
41+
}
42+
return l, nil
43+
}
44+
2845
func TestSyslogParser(t *testing.T) {
2946
basicConfig := func() *SyslogParserConfig {
3047
cfg := NewSyslogParserConfig("test_operator_id")
3148
cfg.OutputIDs = []string{"fake"}
3249
return cfg
3350
}
3451

52+
location, err := testLocations()
53+
require.NoError(t, err)
54+
3555
cases := []struct {
3656
name string
3757
config *SyslogParserConfig
@@ -46,10 +66,51 @@ func TestSyslogParser(t *testing.T) {
4666
func() *SyslogParserConfig {
4767
cfg := basicConfig()
4868
cfg.Protocol = "rfc3164"
69+
cfg.Location = location["utc"].String()
4970
return cfg
5071
}(),
5172
"<34>Jan 12 06:30:00 1.2.3.4 apache_server: test message",
52-
time.Date(time.Now().Year(), 1, 12, 6, 30, 0, 0, time.UTC),
73+
time.Date(time.Now().Year(), 1, 12, 6, 30, 0, 0, location["utc"]),
74+
map[string]interface{}{
75+
"appname": "apache_server",
76+
"facility": 4,
77+
"hostname": "1.2.3.4",
78+
"message": "test message",
79+
"priority": 34,
80+
},
81+
entry.Critical,
82+
"crit",
83+
},
84+
{
85+
"RFC3164Detroit",
86+
func() *SyslogParserConfig {
87+
cfg := basicConfig()
88+
cfg.Protocol = "rfc3164"
89+
cfg.Location = location["detroit"].String()
90+
return cfg
91+
}(),
92+
"<34>Jan 12 06:30:00 1.2.3.4 apache_server: test message",
93+
time.Date(time.Now().Year(), 1, 12, 6, 30, 0, 0, location["detroit"]),
94+
map[string]interface{}{
95+
"appname": "apache_server",
96+
"facility": 4,
97+
"hostname": "1.2.3.4",
98+
"message": "test message",
99+
"priority": 34,
100+
},
101+
entry.Critical,
102+
"crit",
103+
},
104+
{
105+
"RFC3164Athens",
106+
func() *SyslogParserConfig {
107+
cfg := basicConfig()
108+
cfg.Protocol = "rfc3164"
109+
cfg.Location = location["athens"].String()
110+
return cfg
111+
}(),
112+
"<34>Jan 12 06:30:00 1.2.3.4 apache_server: test message",
113+
time.Date(time.Now().Year(), 1, 12, 6, 30, 0, 0, location["athens"]),
53114
map[string]interface{}{
54115
"appname": "apache_server",
55116
"facility": 4,

0 commit comments

Comments
 (0)