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 +4 -4
- data/.github/ISSUE_TEMPLATE/bug_report.md +36 -0
- data/.github/workflows/merge-to-master.yml +40 -0
- data/.github/workflows/pr.yml +28 -0
- data/.github/workflows/repolinter.yml +31 -0
- data/README.md +31 -5
- data/examples/Windows-IIS.conf +85 -0
- data/examples/copy_output.conf +43 -0
- data/examples/custom_field.conf +32 -0
- data/examples/file_input.conf +29 -0
- data/examples/filter_logs.conf +52 -0
- data/examples/grok_parser.conf +43 -0
- data/examples/minimal_complete_config.conf +27 -0
- data/examples/multiline_log_parse.conf +11 -0
- data/examples/parse_nginx.conf +17 -0
- data/examples/readme.md +2 -2
- data/examples/syslog_input.conf +5 -0
- data/lib/fluent/plugin/out_newrelic.rb +69 -25
- data/lib/newrelic-fluentd-output/version.rb +1 -1
- data/playground/.env.example +1 -0
- data/playground/.gitignore +1 -0
- data/playground/Dockerfile +7 -0
- data/playground/README.md +40 -0
- data/playground/config/fluent.conf +23 -0
- data/playground/docker-compose.yml +12 -0
- data/playground/testlogs/.gitkeep +0 -0
- data/playground/testlogs/test.log +0 -0
- metadata +25 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 11df01d6cf7ef5b768dabccfc1d57f0aa7bf3bbd96010ab0d9109b0dae65434e
|
4
|
+
data.tar.gz: bd8b44e862c08b809fb7ad08913d679dca2ff13d3029dca8c6c31656fa317676
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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
|
-
|
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,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
|
64
|
+
#### 2. Add the contents from the [`syslog/fluentd.conf`](syslog/fluentd.config)
|
65
65
|
|
66
|
-
You can find the contents of the [`syslog
|
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
|
@@ -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, ['
|
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
|
-
|
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
|
-
|
109
|
+
logs.push(package_record(record, ts))
|
112
110
|
end
|
113
|
-
io = StringIO.new
|
114
|
-
gzip = Zlib::GzipWriter.new(io)
|
115
111
|
|
116
|
-
|
117
|
-
|
118
|
-
|
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
|
@@ -0,0 +1 @@
|
|
1
|
+
NEW_RELIC_API_KEY=REPLACE_WITH_YOUR_API_KEY
|
@@ -0,0 +1 @@
|
|
1
|
+
.env
|
@@ -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>
|
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
|
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:
|
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.
|
161
|
+
rubygems_version: 3.1.4
|
140
162
|
signing_key:
|
141
163
|
specification_version: 4
|
142
164
|
summary: Sends FluentD events to New Relic
|