fluent-plugin-newrelic 1.1.8 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: caf9616fa22e2338c4df33d70571d6a18850a17dafe98bb78c1e916aa7339ab5
4
- data.tar.gz: a23147d65d03ac2de83765856f3ee84cc2afe26fbe24bc8c7e3c8f028316fb37
3
+ metadata.gz: 11df01d6cf7ef5b768dabccfc1d57f0aa7bf3bbd96010ab0d9109b0dae65434e
4
+ data.tar.gz: bd8b44e862c08b809fb7ad08913d679dca2ff13d3029dca8c6c31656fa317676
5
5
  SHA512:
6
- metadata.gz: 991cab2d7e3060134f2f31784077d6e409c505a878a2d44a9eb1bf1d6ec8bc79752e3840881b0e7e0cddbb8547d9067bb153f76c650cded1d0c330eb9fc184bf
7
- data.tar.gz: 716cb1b8150874ecb42c09bf678baa339d0f7bc65e4ebeb30badd9c31a9258d6a60d31d6376649bbbc64329bdcfc95e3d45fbb9b1bc022ea657940c3c4be9106
6
+ metadata.gz: 2f5b0a413c051418c0635352cac3bbac7b039c00c4fef14d694cd3a531111e07f85dc9f44d87641b774cc00869a51574e161644b3fc3392c257284e0342aeead
7
+ data.tar.gz: b8da217e0801af5053fad0539680348e5e94eeec56ddf4a67872c63afd968c53647ba2cde5b98424392b2104675298ee62a29e74bbc41d5790a0aad9911c23b7
@@ -0,0 +1,36 @@
1
+ ---
2
+ name: Bug report
3
+ about: Report a bug so we can take care of it
4
+ title: ''
5
+ labels: bug
6
+ assignees: ''
7
+ ---
8
+
9
+ [NOTE]: # ( ^^ Provide a general summary of the issue in the title above ^^ )
10
+
11
+ ## Description
12
+
13
+ [NOTE]: # ( Describe the problem you're encountering )
14
+ [TIP]: # ( Do NOT share sensitive information, whether personal, proprietary, or otherwise! )
15
+
16
+ ## Expected Behavior
17
+
18
+ [NOTE]: # ( Tell us what you expected to happen )
19
+
20
+ ## [Troubleshooting](https://discuss.newrelic.com/t/troubleshooting-frameworks/108787) or [NR Diag](https://docs.newrelic.com/docs/using-new-relic/cross-product-functions/troubleshooting/new-relic-diagnostics) results
21
+
22
+ [NOTE]: # ( Provide any other relevant log data )
23
+ [TIP]: # ( Scrub logs and diagnostic information for sensitive information )
24
+
25
+ ## Steps to Reproduce
26
+
27
+ [NOTE]: # ( Please be as specific as possible )
28
+ [TIP]: # ( Link a sample application that demonstrates the issue )
29
+
30
+ ## Your Environment
31
+
32
+ [TIP]: # ( Include as many relevant details about your environment as possible including the running version of New Relic software and any relevant configurations. )
33
+
34
+ ## Additional context
35
+
36
+ [TIP]: # ( Add any other context about the problem here. For example, relevant community posts, support tickets, screenshots... )
@@ -0,0 +1,40 @@
1
+ name: New Relic Fluentd Output Plugin - Merge to master
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - master
7
+
8
+ jobs:
9
+ ci:
10
+ name: Continuous Delivery pipeline
11
+ runs-on: ubuntu-18.04
12
+
13
+ steps:
14
+ - name: Checkout code
15
+ uses: actions/checkout@v2
16
+
17
+ - name: Setup Ruby, bundler and install dependencies
18
+ uses: ruby/setup-ruby@v1
19
+ with:
20
+ ruby-version: ruby-2.7.2
21
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
22
+
23
+ - name: Run unit tests
24
+ run: bundle exec rake
25
+
26
+ - name: Publish Unit Test Results
27
+ uses: EnricoMi/publish-unit-test-result-action@v1.5
28
+ if: always()
29
+ with:
30
+ github_token: ${{ secrets.GITHUB_TOKEN }}
31
+ files: '**/TEST-*.xml'
32
+
33
+ - name: Build gem
34
+ run: gem build newrelic-fluentd-output.gemspec
35
+
36
+ - name: Publish fluent-plugin-newrelic to rubygems.org
37
+ env:
38
+ GEM_HOST_API_KEY: ${{ secrets.GEM_HOST_API_KEY }}
39
+ run: |
40
+ gem push fluent-plugin-newrelic-*.gem
@@ -0,0 +1,28 @@
1
+ name: New Relic Fluentd Output Plugin - Pull Request
2
+
3
+ on: [pull_request]
4
+
5
+ jobs:
6
+ ci:
7
+ name: Continuous Integration pipeline
8
+ runs-on: ubuntu-18.04
9
+
10
+ steps:
11
+ - name: Checkout code
12
+ uses: actions/checkout@v2
13
+
14
+ - name: Setup Ruby, bundler and install dependencies
15
+ uses: ruby/setup-ruby@v1
16
+ with:
17
+ ruby-version: ruby-2.5.8
18
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
19
+
20
+ - name: Run unit tests
21
+ run: bundle exec rake
22
+
23
+ - name: Publish Unit Test Results
24
+ uses: EnricoMi/publish-unit-test-result-action@v1.5
25
+ if: always()
26
+ with:
27
+ github_token: ${{ secrets.GITHUB_TOKEN }}
28
+ files: '**/TEST-*.xml'
@@ -0,0 +1,31 @@
1
+ # NOTE: This file should always be named `repolinter.yml` to allow
2
+ # workflow_dispatch to work properly
3
+ name: Repolinter Action
4
+
5
+ # NOTE: This workflow will ONLY check the default branch!
6
+ # Currently there is no elegant way to specify the default
7
+ # branch in the event filtering, so branches are instead
8
+ # filtered in the "Test Default Branch" step.
9
+ on: [push, workflow_dispatch]
10
+
11
+ jobs:
12
+ repolint:
13
+ name: Run Repolinter
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - name: Test Default Branch
17
+ id: default-branch
18
+ uses: actions/github-script@v2
19
+ with:
20
+ script: |
21
+ const data = await github.repos.get(context.repo)
22
+ return data.data && data.data.default_branch === context.ref.split('/').slice(-1)[0]
23
+ - name: Checkout Self
24
+ if: ${{ steps.default-branch.outputs.result == 'true' }}
25
+ uses: actions/checkout@v2
26
+ - name: Run Repolinter
27
+ if: ${{ steps.default-branch.outputs.result == 'true' }}
28
+ uses: newrelic/repolinter-action@v1
29
+ with:
30
+ config_url: https://raw.githubusercontent.com/newrelic/.github/main/repolinter-rulesets/community-plus.yml
31
+ output_type: issue
data/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ [![Community Plus header](https://github.com/newrelic/opensource-website/raw/master/src/images/categories/Community_Plus.png)](https://opensource.newrelic.com/oss-category/#community-plus)
2
+
1
3
  # fluent-plugin-newrelic
2
4
 
3
5
  A [Fluentd](https://fluentd.org/) output plugin that sends logs to New Relic
@@ -29,12 +31,12 @@ For more info, review [Fluentd's official documentation](https://docs.fluentd.or
29
31
 
30
32
  ### Required plugin configuration
31
33
 
32
- Exactly one of the following:
34
+ This plugin must be configured with either a New Relic API Insert key, or a New Relic License key.
35
+ If both types of keys are specified, the API Insert key will take precedence.
36
+
37
+ To specify an API Insert key, either set the `api_key` property in the configuration, or set the `NEW_RELIC_API_KEY` environment variable. If both are specified, the configuration property will take precedence.
33
38
 
34
- | Property | Description |
35
- |---|---|
36
- | api_key | your New Relic API Insert key |
37
- | license_key | your New Relic License key |
39
+ To specify a license key, either set the `license_key` property in the configuration, or set the `NEW_RELIC_LICENSE_KEY` environment variable. If both are specified, the configuration property will take precedence.
38
40
 
39
41
  ### Optional plugin configuration
40
42
 
@@ -84,6 +86,30 @@ Example using License key:
84
86
  Getting your New Relic license key:
85
87
  `https://rpm.newrelic.com/accounts/<ACCOUNT_ID>`
86
88
 
89
+ ## Playground
90
+
91
+ To provide a sandbox environment where you can play with the plugin while development or testing
92
+ we've added a docker-compose environment that would help to run fluend with the plugin and send
93
+ some logs. [More info](playground/README.md)
94
+
95
+ ## Community
96
+
97
+ New Relic hosts and moderates an online forum where customers can interact with New Relic employees as well as other customers to get help and share best practices. Like all official New Relic open source projects, there's a related Community topic in the New Relic Explorers Hub: [Log forwarding](https://discuss.newrelic.com/tag/log-forwarding)
98
+
99
+
100
+ **A note about vulnerabilities**
101
+
102
+ As noted in our [security policy](../../security/policy), New Relic is committed to the privacy and security of our customers and their data. We believe that providing coordinated disclosure by security researchers and engaging with the security community are important means to achieve our security goals.
103
+
104
+ If you believe you have found a security vulnerability in this project or any of New Relic's products or websites, we welcome and greatly appreciate you reporting it to New Relic through [HackerOne](https://hackerone.com/newrelic).
105
+
106
+ If you would like to contribute to this project, **please create a branch directly in this repository** and review [these guidelines](https://opensource.newrelic.com/code-of-conduct/).
107
+
108
+ ## License
109
+
110
+ newrelic-fluentd-output is licensed under the [Apache 2.0](http://apache.org/licenses/LICENSE-2.0.txt) License.
111
+
112
+
87
113
  ## Copyright
88
114
 
89
115
  * Copyright(c) 2019 - New Relic
@@ -0,0 +1,85 @@
1
+ ####
2
+ ## New Relic Logs - Basic Windows Event + IIS config v1.5
3
+ ## Built in FluentD v1.7.4
4
+ ## by AI of NR 2/4/2020
5
+ ##
6
+ ## Don't forget to add your NR license key to the <match> statement at the bottom of this file.
7
+ ##
8
+
9
+ ## Windows Event Log Input
10
+ <source>
11
+ @type windows_eventlog
12
+ @id windows_eventlog
13
+ tag winevt.raw
14
+ channels application,system,security
15
+ <storage>
16
+ @type local
17
+ persistent true
18
+ path c:/opt/td-agent/winevt.pos
19
+ </storage>
20
+ </source>
21
+
22
+ #
23
+ # Windows IIS log parsing. This config uses the standard W3C format and the standard location for IIS logs.
24
+ # It expects the log timestamp to be UTC.
25
+ # Change the path below if you store your logs elsewhere.
26
+ #
27
+ <source>
28
+ @type tail
29
+ tag iislog.raw
30
+ path c:/inetpub/logs/logfiles/*/*
31
+ pos_file c:/opt/td-agent/iislog.pos
32
+ <parse>
33
+ @type regexp
34
+ expression /(?<time>\d{4}-\d{2}-\d{2} [\d:]+) (?<message>.+)/
35
+ time_format %Y-%m-%d %H:%M:%S
36
+ utc true
37
+ </parse>
38
+ </source>
39
+
40
+ <filter iislog.raw>
41
+ @type parser
42
+ key_name message
43
+ remove_key_name_field false
44
+ reserve_data true
45
+ reserve_time true
46
+ <parse>
47
+ @type csv
48
+ delimiter ' '
49
+ keys hostname,req_method,req_uri,cs-uri-query,s_port,cs-username,c_ip,req_ua,req_referer,http_code,sc-substatus,sc-win32-status,time-taken
50
+ null_value_pattern -
51
+ null_empty_string true
52
+ </parse>
53
+ </filter>
54
+
55
+ #
56
+ # For a slightly nicer experience, add Service Name (s-sitename) to your log output, comment out the filter above and use this one instead.
57
+ #
58
+ #<filter iislog.raw>
59
+ # @type parser
60
+ # key_name message
61
+ # remove_key_name_field false
62
+ # reserve_data true
63
+ # reserve_time true
64
+ # <parse>
65
+ # @type csv
66
+ # delimiter ' '
67
+ # keys service_name,hostname,req_method,req_uri,cs-uri-query,s_port,cs-username,c_ip,req_ua,req_referer,http_code,sc-substatus,sc-win32-status,time-taken
68
+ # null_value_pattern -
69
+ # null_empty_string true
70
+ # </parse>
71
+ #</filter>
72
+
73
+ <filter winevt.raw>
74
+ @type record_transformer
75
+ <record>
76
+ message ${record["description"]}
77
+ hostname ${record["computer_name"]}
78
+ </record>
79
+ </filter>
80
+
81
+ # New Relic output
82
+ <match **>
83
+ @type newrelic
84
+ api_key <YOUR INSERT KEY>
85
+ </match>
@@ -0,0 +1,43 @@
1
+ #Tail and parse Apache access logs
2
+
3
+ <source>
4
+ @type tail
5
+ @id input_tail_apache
6
+ tag apache_access
7
+ path /var/log/apache2/access.log
8
+ pos_file /var/log/apache2/access.pos
9
+ path_key filename
10
+ <parse>
11
+ @type apache2
12
+ </parse>
13
+ </source>
14
+
15
+ #Add hostname and tag fields to all events ("records") with a Fluentd tag of apache_access
16
+
17
+ <filter apache_access>
18
+ @type record_transformer
19
+ <record>
20
+ hostname "#{Socket.gethostname}"
21
+ tag ${tag}
22
+ </record>
23
+ </filter>
24
+
25
+ #Output (https://docs.fluentd.org/output/copy) events to both New Relic and a local file.
26
+
27
+ <match **>
28
+ @type copy
29
+ <store>
30
+ @type newrelic
31
+ api_key <YOUR INSERT KEY>
32
+ </store>
33
+ <store>
34
+ @type file
35
+ path /var/log/apacheout.log
36
+ <buffer>
37
+ #Buffer settings are for testing and not recommended for use in a production environment.
38
+ timekey 10s
39
+ timekey_use_utc true
40
+ timekey_wait 15s
41
+ </buffer>
42
+ </store>
43
+ </match>
@@ -0,0 +1,32 @@
1
+ #Tail and parse Docker log files
2
+
3
+ <source>
4
+ @type tail
5
+ path /var/lib/docker/containers/*/*-json.log
6
+ pos_file /var/log/docker-log.pos
7
+ read_from_head true
8
+ tag containers
9
+ <parse>
10
+ @type json
11
+ time_format %Y-%m-%dT%H:%M:%S.%NZ
12
+ keep_time_key true
13
+ time_key time
14
+ </parse>
15
+ </source>
16
+
17
+ <filter containers>
18
+ @type record_transformer
19
+ enable_ruby true
20
+ <record>
21
+ #Add hostname and tag fields to all records
22
+ fluentd_host "#{Socket.gethostname}"
23
+ tag ${tag}
24
+ </record>
25
+ </filter>
26
+
27
+ # Forward events to New Relic
28
+
29
+ <match containers>
30
+ @type newrelic
31
+ api_key <YOUR INSERT KEY>
32
+ </match>
@@ -0,0 +1,29 @@
1
+ #Tail arbitrary text/log file
2
+
3
+ <source>
4
+ @type tail
5
+ <parse>
6
+ @type none
7
+ </parse>
8
+ path /var/log/backend-app*.log
9
+ pos_file /var/log/backend.application.pos
10
+ path_key filename # Add watched file path to path_key field for every event/record.
11
+ tag backend.application
12
+ </source>
13
+
14
+ #Add hostname and tag fields to all events ("records") with a Fluentd tag of backend.application
15
+
16
+ <filter backend.application>
17
+ @type record_transformer
18
+ <record>
19
+ hostname "#{Socket.gethostname}"
20
+ tag ${tag}
21
+ </record>
22
+ </filter>
23
+
24
+ #Write events to New Relic
25
+
26
+ <match backend.application>
27
+ @type newrelic
28
+ api_key <YOUR INSERT KEY>
29
+ </match>
@@ -0,0 +1,52 @@
1
+ #Tail and parse arbitrary text/log file
2
+
3
+ <source>
4
+ @type tail
5
+ <parse> #Parse timestamp, everything else to be stored in message field
6
+ @type regexp
7
+ expression /^\[(?<logtime>[^\]]*)\] (?<message>.*)$/
8
+ time_key logtime
9
+ time_format %Y-%m-%d %H:%M:%S %z
10
+ </parse>
11
+ path /var/log/backend-app*.log
12
+ pos_file /var/log/backend.application.pos
13
+ path_key filename # Add watched file path to path_key field for every event/record.
14
+ tag backend.application
15
+ </source>
16
+
17
+ #Add hostname and service_name fields to all events ("records") with a Fluentd tag of backend.application
18
+
19
+ <filter backend.application>
20
+ @type record_transformer
21
+ <record>
22
+ hostname "#{Socket.gethostname}"
23
+ service_name ${tag}
24
+ </record>
25
+ </filter>
26
+
27
+ # For all events with a tag of backend.application:
28
+ # Keep ONLY events where service_name field contains a value matching /backend.application/ AND where message field contains a value matching /Cannot connect to/
29
+ # Discard any events where value of hostname field matches /staging/
30
+
31
+ <filter backend.application>
32
+ @type grep
33
+ <regexp>
34
+ key service_name
35
+ pattern /backend.application/
36
+ </regexp>
37
+ <regexp>
38
+ key message
39
+ pattern /Cannot connect to/
40
+ </regexp>
41
+ <exclude>
42
+ key hostname
43
+ pattern /staging/
44
+ </exclude>
45
+ </filter>
46
+
47
+ #Write events with backend.application tag to New Relic
48
+
49
+ <match backend.application>
50
+ @type newrelic
51
+ api_key <YOUR INSERT KEY>
52
+ </match>
@@ -0,0 +1,43 @@
1
+ #Tail arbitrary log file and parse using grok pattern
2
+ #Install the required plugin: fluent-gem install fluent-plugin-grok-parser
3
+
4
+ <source>
5
+ @type tail
6
+ <parse>
7
+ @type grok
8
+ <grok>
9
+ pattern %{SYSLOGTIMESTAMP:timestamp} %{LOGLEVEL:loglevel}: %{GREEDYDATA:message}
10
+ </grok>
11
+ </parse>
12
+ path /var/log/customapp.log
13
+ pos_file /var/log/customapp.pos
14
+ path_key filename
15
+ tag custom.application
16
+ </source>
17
+
18
+ # Drop events with custom.application tag where loglevel field contains "debug" or "info" (case-insensitive match)
19
+
20
+ <filter custom.application>
21
+ @type grep
22
+ <exclude>
23
+ key loglevel
24
+ pattern /debug|info/i
25
+ </exclude>
26
+ </filter>
27
+
28
+ #Add hostname and tag fields to all events ("records") with a Fluentd tag of custom.application
29
+
30
+ <filter custom.application>
31
+ @type record_transformer
32
+ <record>
33
+ hostname "#{Socket.gethostname}"
34
+ tag ${tag}
35
+ </record>
36
+ </filter>
37
+
38
+ #Write custom.application events to New Relic
39
+
40
+ <match custom.application>
41
+ @type newrelic
42
+ api_key <YOUR INSERT KEY>
43
+ </match>
@@ -0,0 +1,27 @@
1
+ #Tail arbitrary text/log file
2
+
3
+ <source>
4
+ @type tail
5
+ <parse>
6
+ @type none
7
+ </parse>
8
+ path /home/logs/*
9
+ path_key file
10
+ tag sample.tag
11
+ </source>
12
+
13
+ #Add service_name field to all events ("records") with a Fluentd tag of sample.tag
14
+
15
+ <filter sample.tag>
16
+ @type record_transformer
17
+ <record>
18
+ service_name ${tag}
19
+ </record>
20
+ </filter>
21
+
22
+ #Write sample.tag events to New Relic
23
+
24
+ <match sample.tag>
25
+ @type newrelic
26
+ api_key <YOUR INSERT KEY>
27
+ </match>
@@ -0,0 +1,11 @@
1
+ <filter backend.application>
2
+ @type parser
3
+ <parse>
4
+ @type multiline_grok
5
+ grok_failure_key grokfailure
6
+ multiline_start_regex ^abc
7
+ <grok>
8
+ pattern %{GREEDYDATA:message}
9
+ </grok>
10
+ </parse>
11
+ </filter>
@@ -0,0 +1,17 @@
1
+ #Tail and parse NGINX log file
2
+
3
+ <source>
4
+ @type tail
5
+ <parse>
6
+ @type nginx
7
+ </parse>
8
+ path /path/to/access.log
9
+ tag nginx.access
10
+ </source>
11
+
12
+ #Write events with tag matching nginx.* to New Relic
13
+
14
+ <match nginx.*>
15
+ @type newrelic
16
+ api_key <YOUR INSERT KEY>
17
+ </match>
data/examples/readme.md CHANGED
@@ -61,9 +61,9 @@ sudo mkdir /etc/fluentd
61
61
  sudo nano /etc/fluentd/fluentd.conf
62
62
  ```
63
63
 
64
- #### 2. Add the contents from the [`syslog\fluentd.conf`](syslog\fluentd.config)
64
+ #### 2. Add the contents from the [`syslog/fluentd.conf`](syslog/fluentd.config)
65
65
 
66
- You can find the contents of the [`syslog\fluentd.conf`](syslog\fluentd.config) in the sub folder `syslog`. These contents should provide a quick start to getting started. In the provided
66
+ You can find the contents of the [`syslog/fluentd.conf`](syslog/fluentd.config) in the sub folder `syslog`. These contents should provide a quick start to getting started. In the provided
67
67
  example, the syslog details are coming from the above mentioned devices. You may need to tweak the configuration according to the server sending the syslog traffic.
68
68
 
69
69
  #### 3. Check New Relic for New Logs
@@ -0,0 +1,5 @@
1
+ <source>
2
+ @type syslog
3
+ port 5140
4
+ tag syslog.messages
5
+ </source>
@@ -33,10 +33,15 @@ module Fluent
33
33
  config_param :license_key, :string, :default => nil
34
34
 
35
35
  DEFAULT_BUFFER_TYPE = 'memory'.freeze
36
+ DEFAULT_TIMEKEY = 5
37
+ DEFAULT_TIMEKEY_WAIT = 0
38
+ MAX_PAYLOAD_SIZE = 1000000 # bytes
36
39
 
37
40
  config_section :buffer do
38
41
  config_set_default :@type, DEFAULT_BUFFER_TYPE
39
- config_set_default :chunk_keys, ['timestamp']
42
+ config_set_default :chunk_keys, ['time']
43
+ config_set_default :timekey, DEFAULT_TIMEKEY
44
+ config_set_default :timekey_wait, DEFAULT_TIMEKEY_WAIT
40
45
  end
41
46
 
42
47
  define_method('log') {$log} unless method_defined?(:log)
@@ -49,8 +54,11 @@ module Fluent
49
54
 
50
55
  def configure(conf)
51
56
  super
57
+
58
+ @api_key ||= ENV["NEW_RELIC_API_KEY"]
59
+ @license_key ||= ENV["NEW_RELIC_LICENSE_KEY"]
52
60
  if @api_key.nil? && @license_key.nil?
53
- raise Fluent::ConfigError.new("'api_key' or 'license_key' parameter is required")
61
+ raise Fluent::ConfigError.new("'api_key' or 'license_key' parameter is required")
54
62
  end
55
63
 
56
64
  # create initial sockets hash and socket based on config param
@@ -89,39 +97,23 @@ module Fluent
89
97
  packaged['message'] = record['log']
90
98
  packaged['attributes'].delete('log')
91
99
  end
92
-
100
+
93
101
  packaged
94
102
  end
95
103
 
96
104
  def write(chunk)
97
- payload = {
98
- 'common' => {
99
- 'attributes' => {
100
- 'plugin' => {
101
- 'type' => 'fluentd',
102
- 'version' => NewrelicFluentdOutput::VERSION,
103
- }
104
- }
105
- },
106
- 'logs' => []
107
- }
105
+ logs = []
108
106
  chunk.msgpack_each do |ts, record|
109
107
  next unless record.is_a? Hash
110
108
  next if record.empty?
111
- payload['logs'].push(package_record(record, ts))
109
+ logs.push(package_record(record, ts))
112
110
  end
113
- io = StringIO.new
114
- gzip = Zlib::GzipWriter.new(io)
115
111
 
116
- # Fluentd can run with a version of Ruby (2.1.0) whose to_json method doesn't support non-ASCII characters.
117
- # So we use Yajl, which can handle all Unicode characters. Apparently this library is what Fluentd uses
118
- # internally, so it is installed by default with td-agent.
119
- # See https://github.com/fluent/fluentd/issues/215
120
- gzip << Yajl.dump([payload])
121
- gzip.close
122
- send_payload(io.string)
112
+
113
+ payloads = get_compressed_payloads(logs)
114
+ payloads.each { |payload| send_payload(payload) }
123
115
  end
124
-
116
+
125
117
  def handle_response(response)
126
118
  if !(200 <= response.code.to_i && response.code.to_i < 300)
127
119
  log.error("Response was " + response.code + " " + response.body)
@@ -137,6 +129,58 @@ module Fluent
137
129
  handle_response(http.request(request))
138
130
  end
139
131
 
132
+ private
133
+
134
+ def get_compressed_payloads(logs)
135
+ return [] if logs.length == 0
136
+
137
+ payload = create_payload(logs)
138
+ compressed_payload = compress(payload)
139
+
140
+ if compressed_payload.bytesize <= MAX_PAYLOAD_SIZE
141
+ return [compressed_payload]
142
+ end
143
+
144
+ compressed_payload = nil # Free for GC
145
+
146
+ if logs.length > 1 # we can split
147
+ # let's split logs array by half, and try to create payloads again
148
+ midpoint = logs.length / 2
149
+ first_half = get_compressed_payloads(logs.slice(0, midpoint))
150
+ second_half = get_compressed_payloads(logs.slice(midpoint, logs.length))
151
+ return first_half + second_half
152
+ else
153
+ log.error("Can't compress record below required maximum packet size and it will be discarded. Record: #{logs[0]}")
154
+ return []
155
+ end
156
+ end
157
+
158
+ def create_payload(logs)
159
+ {
160
+ 'common' => {
161
+ 'attributes' => {
162
+ 'plugin' => {
163
+ 'type' => 'fluentd',
164
+ 'version' => NewrelicFluentdOutput::VERSION,
165
+ }
166
+ }
167
+ },
168
+ 'logs' => logs
169
+ }
170
+ end
171
+
172
+ def compress(payload)
173
+ io = StringIO.new
174
+ gzip = Zlib::GzipWriter.new(io)
175
+
176
+ # Fluentd can run with a version of Ruby (2.1.0) whose to_json method doesn't support non-ASCII characters.
177
+ # So we use Yajl, which can handle all Unicode characters. Apparently this library is what Fluentd uses
178
+ # internally, so it is installed by default with td-agent.
179
+ # See https://github.com/fluent/fluentd/issues/215
180
+ gzip << Yajl.dump([payload])
181
+ gzip.close
182
+ io.string
183
+ end
140
184
  end
141
185
  end
142
186
  end
@@ -1,3 +1,3 @@
1
1
  module NewrelicFluentdOutput
2
- VERSION = "1.1.8"
2
+ VERSION = "1.2.1"
3
3
  end
@@ -0,0 +1 @@
1
+ NEW_RELIC_API_KEY=REPLACE_WITH_YOUR_API_KEY
@@ -0,0 +1 @@
1
+ .env
@@ -0,0 +1,7 @@
1
+ FROM fluent/fluentd:v1.12-1
2
+
3
+ WORKDIR /usr/share/fluentd
4
+
5
+ USER root
6
+
7
+ RUN fluent-gem install fluent-plugin-newrelic
@@ -0,0 +1,40 @@
1
+ # New Relict Fluentd output plugin playground
2
+
3
+ ## Starting the environment
4
+
5
+ To run the environment first go to `./playground` folder:
6
+
7
+ 1. Copy `.env.example` to `.env` and fill your own New Relic API KEY or LICENSE KEY.
8
+ 2. Run `docker-compose up -d`
9
+
10
+ Thats it, you should have a running docker with latests new relic output plugin version.
11
+
12
+ ## Writing logs
13
+
14
+ Since the file `./testlogs/test.log` are mounted as a volume on the docker instance and
15
+ is being tailed by fluentd you could write some text to the file and it should be picked
16
+ up by fluentd.
17
+
18
+ This command should write a line on the log file and it will reach new relic in a while.
19
+
20
+ `echo "Hello world" >> ./testlogs/test.log`
21
+
22
+ If what you need is send logs every .05s, for example, you can have a big file like
23
+ [1mb of text](https://gist.github.com/khaykov/a6105154becce4c0530da38e723c2330) and
24
+ use some awk magic to send each line with .05s delay.
25
+
26
+ `awk '{print $0; system("sleep .05");}' 1mbofdata.txt >> ./testlogs/test.log`
27
+
28
+ ## Troubleshooting
29
+
30
+ If you need to go inside the container to debug something just run `docker-compose exec fluentd sh`
31
+ and you'll be inside the instance. This is a development image so you'll find that you're
32
+ logged in as root, this allows you to install the tools you need with `apk`. For example
33
+ `apk add vim`.
34
+
35
+ The plugin is located on `/usr/lib/ruby/gems/2.7.0/gems/fluent-plugin-newrelic-{version}`
36
+
37
+ ## More examples
38
+
39
+ For more examples, you could adapt the configurations on [examples](../examples/readme.md)
40
+ to use them with this playground and test whatever you need.
@@ -0,0 +1,23 @@
1
+ <source>
2
+ @type tail
3
+ <parse>
4
+ @type none
5
+ </parse>
6
+ path /testlogs/*
7
+ path_key file
8
+ tag sample.tag
9
+ </source>
10
+
11
+ # Add service_name field to all events ("records") with a Fluentd tag of sample.tag
12
+ <filter sample.tag>
13
+ @type record_transformer
14
+ <record>
15
+ logtype test
16
+ service_name fluentd-test
17
+ </record>
18
+ </filter>
19
+
20
+ # Write sample.tag events to New Relic
21
+ <match sample.tag>
22
+ @type newrelic
23
+ </match>
@@ -0,0 +1,12 @@
1
+ version: "3.0"
2
+
3
+ services:
4
+ fluentd:
5
+ env_file: .env
6
+ build:
7
+ dockerfile: ./Dockerfile
8
+ context: .
9
+ volumes:
10
+ - "./config:/fluentd/etc"
11
+ - "./testlogs/:/testlogs/:rw"
12
+ command: fluentd -c /fluentd/etc/fluent.conf -v
File without changes
File without changes
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-newrelic
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.8
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - New Relic Logging Team
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-03-09 00:00:00.000000000 Z
11
+ date: 2021-07-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fluentd
@@ -102,6 +102,10 @@ extensions: []
102
102
  extra_rdoc_files: []
103
103
  files:
104
104
  - ".dockerignore"
105
+ - ".github/ISSUE_TEMPLATE/bug_report.md"
106
+ - ".github/workflows/merge-to-master.yml"
107
+ - ".github/workflows/pr.yml"
108
+ - ".github/workflows/repolinter.yml"
105
109
  - ".gitignore"
106
110
  - DEVELOPER.md
107
111
  - Dockerfile
@@ -110,12 +114,30 @@ files:
110
114
  - README.md
111
115
  - Rakefile
112
116
  - examples/Dockerfile
117
+ - examples/Windows-IIS.conf
118
+ - examples/copy_output.conf
119
+ - examples/custom_field.conf
120
+ - examples/file_input.conf
121
+ - examples/filter_logs.conf
122
+ - examples/grok_parser.conf
123
+ - examples/minimal_complete_config.conf
124
+ - examples/multiline_log_parse.conf
125
+ - examples/parse_nginx.conf
113
126
  - examples/readme.md
114
127
  - examples/syslog/fluentd.config
128
+ - examples/syslog_input.conf
115
129
  - lib/fluent/plugin/out_newrelic.rb
116
130
  - lib/newrelic-fluentd-output/version.rb
117
131
  - merge-to-master-pipeline.yml
118
132
  - newrelic-fluentd-output.gemspec
133
+ - playground/.env.example
134
+ - playground/.gitignore
135
+ - playground/Dockerfile
136
+ - playground/README.md
137
+ - playground/config/fluent.conf
138
+ - playground/docker-compose.yml
139
+ - playground/testlogs/.gitkeep
140
+ - playground/testlogs/test.log
119
141
  - pr-pipeline.yml
120
142
  homepage: https://github.com/newrelic/newrelic-fluentd-output
121
143
  licenses:
@@ -136,7 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
136
158
  - !ruby/object:Gem::Version
137
159
  version: '0'
138
160
  requirements: []
139
- rubygems_version: 3.1.2
161
+ rubygems_version: 3.1.4
140
162
  signing_key:
141
163
  specification_version: 4
142
164
  summary: Sends FluentD events to New Relic