fluent-plugin-datadog-log 0.1.0.rc6 → 0.1.0.rc7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/fluent-plugin-datadog-log.gemspec +1 -1
- data/fluent-plugin-datadog-log.gemspec~ +4 -3
- data/lib/datadog/log.rb +3 -1
- data/lib/datadog/log.rb~ +123 -0
- data/pkg/fluent-plugin-datadog-log-0.1.0.rc6.gem +0 -0
- data/test/plugin/test_out_datadog_log.rb +7 -3
- data/test/plugin/test_out_datadog_log.rb~ +73 -1
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aedaaa9c78c6fd346266540ebf04e4f91dcfab96
|
4
|
+
data.tar.gz: 885f73273fd6671a9e191051cc1afff8704af480
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3f0c941f62799dfcac25c8261665e103a14dc81410ebc9376f98fef8b0f216dce35fe53393fd410e29c13923d6bf6cf23571ac3132c564ae7453527750e6b7c2
|
7
|
+
data.tar.gz: 8aade4e0f12e9c07e87be0ccd2e8131b8d247d84c1bcc13ba9a24af0c622cc30ada70a3b336926b89767d3845b5f5a4b4d81b4b36dcf90b02d3599ba54d817a7
|
data/Gemfile.lock
CHANGED
@@ -8,7 +8,7 @@ eos
|
|
8
8
|
gem.homepage = \
|
9
9
|
'https://github.com/mumoshu/fluent-plugin-datadog-log'
|
10
10
|
gem.license = 'Apache-2.0'
|
11
|
-
gem.version = '0.1.0.
|
11
|
+
gem.version = '0.1.0.rc7'
|
12
12
|
gem.authors = ['Yusuke KUOKA']
|
13
13
|
gem.email = ['ykuoka@gmail.com']
|
14
14
|
gem.required_ruby_version = Gem::Requirement.new('>= 2.0')
|
@@ -8,7 +8,7 @@ eos
|
|
8
8
|
gem.homepage = \
|
9
9
|
'https://github.com/mumoshu/fluent-plugin-datadog-log'
|
10
10
|
gem.license = 'Apache-2.0'
|
11
|
-
gem.version = '0.1.0.
|
11
|
+
gem.version = '0.1.0.rc6'
|
12
12
|
gem.authors = ['Yusuke KUOKA']
|
13
13
|
gem.email = ['ykuoka@gmail.com']
|
14
14
|
gem.required_ruby_version = Gem::Requirement.new('>= 2.0')
|
@@ -21,11 +21,12 @@ eos
|
|
21
21
|
# gem.add_runtime_dependency 'datadog-log-api-client', '~> 0.1'
|
22
22
|
gem.add_runtime_dependency 'json', '~> 1.8'
|
23
23
|
|
24
|
-
gem.
|
24
|
+
gem.add_dependency 'net_tcp_client', '~> 2.0.1'
|
25
|
+
gem.add_dependency 'prometheus-client', '~> 0.7.1'
|
26
|
+
|
25
27
|
gem.add_development_dependency 'mocha', '~> 1.1'
|
26
28
|
gem.add_development_dependency 'rake', '~> 10.3'
|
27
29
|
gem.add_development_dependency 'rubocop', '~> 0.35.0'
|
28
30
|
gem.add_development_dependency 'webmock', '~> 2.3.1'
|
29
31
|
gem.add_development_dependency 'test-unit', '~> 3.0'
|
30
|
-
gem.add_development_dependency 'prometheus-client', '~> 0.7.1'
|
31
32
|
end
|
data/lib/datadog/log.rb
CHANGED
data/lib/datadog/log.rb~
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'net/tcp_client'
|
3
|
+
require 'socket'
|
4
|
+
require 'time'
|
5
|
+
|
6
|
+
module Datadog
|
7
|
+
module Log
|
8
|
+
TRUNCATED_MSG = '...TRUNCATED...'
|
9
|
+
|
10
|
+
TRUNCATED_LEN = TRUNCATED_MSG.size
|
11
|
+
|
12
|
+
# MaxMessageLen is the maximum length for any message we send to the intake
|
13
|
+
# see https://github.com/DataDog/datadog-log-agent/blob/2394da8c79a6cadbcd1e98d6c89c437becec2732/pkg/config/constants.go#L9-L10
|
14
|
+
DD_MAX_MESSAGE_LEN = 1 * 1000 * 1000
|
15
|
+
|
16
|
+
MAX_MESSAGE_LEN = DD_MAX_MESSAGE_LEN - TRUNCATED_LEN
|
17
|
+
|
18
|
+
def truncate_message(msg)
|
19
|
+
if msg.size > DD_MAX_MESSAGE_LEN
|
20
|
+
msg.slice(0, MAX_MESSAGE_LEN) + TRUNCATED_MSG
|
21
|
+
else
|
22
|
+
msg
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Given a list of tags, build_tags_payload generates the bytes array
|
27
|
+
# that will be inserted into messages
|
28
|
+
# @see https://github.com/DataDog/datadog-log-agent/blob/2394da8c79a6cadbcd1e98d6c89c437becec2732/pkg/config/integration_config.go#L180
|
29
|
+
def build_tags_payload(config_tags:, source:, source_category:)
|
30
|
+
payload = ''
|
31
|
+
|
32
|
+
payload = "[dd ddsource=\"#{source}\"]" if !source.nil? && source != ''
|
33
|
+
|
34
|
+
if !source_category.nil? && source_category != ''
|
35
|
+
payload = "#{payload}[dd ddsourcecategory=\"#{source_category}\"]"
|
36
|
+
end
|
37
|
+
|
38
|
+
if !config_tags.nil? && config_tags != ''
|
39
|
+
config_tags = config_tags.join(',') if config_tags.is_a? ::Array
|
40
|
+
payload = "#{payload}[dd ddtags=\"#{config_tags}\"]"
|
41
|
+
end
|
42
|
+
|
43
|
+
payload
|
44
|
+
end
|
45
|
+
|
46
|
+
# https://github.com/DataDog/datadog-log-agent/blob/db13b53dfdd036d43acfb15089a43eb31548f09f/pkg/processor/processor.go#L65
|
47
|
+
def build_extra_content(timestamp:, hostname:, service:, tags_payload:)
|
48
|
+
"<46>0 #{timestamp} #{hostname} #{service} - - #{tags_payload}"
|
49
|
+
end
|
50
|
+
|
51
|
+
def build_api_key_str(api_key:, logset:)
|
52
|
+
if !logset.nil? && logset != ''
|
53
|
+
"#{api_key}/#{logset}"
|
54
|
+
else
|
55
|
+
api_key
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# build_payload returns a processed payload from a raw message
|
60
|
+
# @param [String] api_key_str
|
61
|
+
# @param [String] extra_content
|
62
|
+
# @param [String] msg
|
63
|
+
def create_payload(api_key_str:, msg:, extra_content:)
|
64
|
+
"#{api_key_str} #{extra_content} #{msg}\n"
|
65
|
+
end
|
66
|
+
|
67
|
+
class Client
|
68
|
+
include ::Datadog::Log
|
69
|
+
|
70
|
+
def initialize(log_dd_url: 'intake.logs.datadoghq.com', log_dd_port: 10516, api_key:, hostname:, skip_ssl_validation: false)
|
71
|
+
@log_dd_url = log_dd_url
|
72
|
+
@log_dd_port = log_dd_port
|
73
|
+
@api_key = api_key
|
74
|
+
@hostname = hostname
|
75
|
+
@skip_ssl_validation = skip_ssl_validation
|
76
|
+
|
77
|
+
init_api_client
|
78
|
+
end
|
79
|
+
|
80
|
+
def send_payload(logset: 'main', msg:, datetime: nil, service:, source:, source_category:, tags:)
|
81
|
+
datetime = DateTime.now if datetime.nil?
|
82
|
+
|
83
|
+
# new_offset(0) is required. otherwise datadog will silently throws away the log..
|
84
|
+
timestamp_str = datetime.new_offset(0).rfc3339(6)
|
85
|
+
payload = create_payload(
|
86
|
+
api_key_str: build_api_key_str(api_key: @api_key, logset: logset),
|
87
|
+
msg: truncate_message(msg),
|
88
|
+
extra_content: build_extra_content(
|
89
|
+
timestamp: timestamp_str,
|
90
|
+
hostname: @hostname,
|
91
|
+
service: service,
|
92
|
+
tags_payload: build_tags_payload(
|
93
|
+
config_tags: tags,
|
94
|
+
source: source,
|
95
|
+
source_category: source_category
|
96
|
+
)
|
97
|
+
)
|
98
|
+
)
|
99
|
+
@conn.write(payload)
|
100
|
+
payload
|
101
|
+
end
|
102
|
+
|
103
|
+
def shutdown
|
104
|
+
@conn.close unless @conn.nil?
|
105
|
+
end
|
106
|
+
|
107
|
+
class << self
|
108
|
+
def from_env
|
109
|
+
new(api_key: ENV['DD_LOG_API_KEY'], hostname: Socket.gethostname)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
private
|
114
|
+
|
115
|
+
def init_api_client
|
116
|
+
ssl = true
|
117
|
+
ssl = { verify_mode: OpenSSL::SSL::VERIFY_NONE } if @skip_ssl_validation
|
118
|
+
server = "#{@log_dd_url}:#{@log_dd_port}"
|
119
|
+
@conn = Net::TCPClient.new(server: server, ssl: ssl)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
Binary file
|
@@ -79,7 +79,7 @@ class DatadogLogOutputTest < Test::Unit::TestCase
|
|
79
79
|
conn = StubConn.new
|
80
80
|
fluentd_tag = 'mytag'
|
81
81
|
Net::TCPClient.stubs(:new)
|
82
|
-
.with(server: ':10516', ssl: true)
|
82
|
+
.with(server: 'intake.logs.datadoghq.com:10516', ssl: true)
|
83
83
|
.returns(conn)
|
84
84
|
d.run(default_tag: fluentd_tag) do
|
85
85
|
record = {
|
@@ -118,7 +118,7 @@ class DatadogLogOutputTest < Test::Unit::TestCase
|
|
118
118
|
conn = StubConn.new
|
119
119
|
fluentd_tag = 'mytag'
|
120
120
|
Net::TCPClient.stubs(:new)
|
121
|
-
.with(server: ':10516', ssl: true)
|
121
|
+
.with(server: 'intake.logs.datadoghq.com:10516', ssl: true)
|
122
122
|
.returns(conn)
|
123
123
|
d.run(default_tag: fluentd_tag) do
|
124
124
|
record = {
|
@@ -179,7 +179,7 @@ class DatadogLogOutputTest < Test::Unit::TestCase
|
|
179
179
|
EOC
|
180
180
|
conn = StubConn.new
|
181
181
|
Net::TCPClient.stubs(:new)
|
182
|
-
.with(server: ':10516', ssl: true)
|
182
|
+
.with(server: 'intake.logs.datadoghq.com:10516', ssl: true)
|
183
183
|
.returns(conn)
|
184
184
|
d.run(default_tag: 'mytag') do
|
185
185
|
(1..entry_count).each do |i|
|
@@ -220,6 +220,10 @@ class DatadogLogOutputTest < Test::Unit::TestCase
|
|
220
220
|
@sent = []
|
221
221
|
end
|
222
222
|
|
223
|
+
def retry_on_connection_failure
|
224
|
+
yield
|
225
|
+
end
|
226
|
+
|
223
227
|
def write(payload)
|
224
228
|
@sent << payload
|
225
229
|
end
|
@@ -35,6 +35,31 @@ class DatadogLogOutputTest < Test::Unit::TestCase
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
+
def test_configure_with_env
|
39
|
+
new_stub_context do
|
40
|
+
setup_ec2_metadata_stubs
|
41
|
+
|
42
|
+
ENV.stubs(:[])
|
43
|
+
.with('DD_API_KEY')
|
44
|
+
.returns('myapikey_from_env')
|
45
|
+
|
46
|
+
ENV.stubs(:[])
|
47
|
+
.with(Not equals 'DD_API_KEY')
|
48
|
+
.returns('')
|
49
|
+
.times(3)
|
50
|
+
|
51
|
+
d = create_driver(<<-EOC)
|
52
|
+
type datadog_log
|
53
|
+
service myservice
|
54
|
+
source mysource
|
55
|
+
EOC
|
56
|
+
|
57
|
+
assert_equal 'myapikey_from_env', d.instance.api_key
|
58
|
+
assert_equal 'myservice', d.instance.service
|
59
|
+
assert_equal 'mysource', d.instance.source
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
38
63
|
def test_write
|
39
64
|
new_stub_context do
|
40
65
|
setup_ec2_metadata_stubs
|
@@ -53,18 +78,65 @@ class DatadogLogOutputTest < Test::Unit::TestCase
|
|
53
78
|
EOC
|
54
79
|
conn = StubConn.new
|
55
80
|
fluentd_tag = 'mytag'
|
81
|
+
Net::TCPClient.stubs(:new)
|
82
|
+
.with(server: ':10516', ssl: true)
|
83
|
+
.returns(conn)
|
84
|
+
d.run(default_tag: fluentd_tag) do
|
85
|
+
record = {
|
86
|
+
'log' => 'mymsg'
|
87
|
+
}
|
88
|
+
d.feed(time, record)
|
89
|
+
end
|
90
|
+
|
91
|
+
# fail d.logs.inspect
|
92
|
+
assert_equal(1, d.logs.count { |l| l =~ /Sent payload to Datadog/ })
|
93
|
+
assert_equal(1, conn.sent.size)
|
94
|
+
# rubocop:disable LineLength
|
95
|
+
payload = %(myapikey/mylogset <46>0 2006-01-02T15:04:05.000000+00:00 i-81c16767 myservice - - [dd ddsource="mysource"][dd ddsourcecategory="mysourcecategory"][dd ddtags="host=i-81c16767,zone=aws:us-west-2b,aws_account_id=123456789012"] mymsg\n)
|
96
|
+
# rubocop:enable LineLength
|
97
|
+
assert_equal(payload, conn.sent.first)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_write_kube
|
102
|
+
new_stub_context do
|
103
|
+
setup_ec2_metadata_stubs
|
104
|
+
|
105
|
+
timestamp_str = '2006-01-02T15:04:05.000000+00:00'
|
106
|
+
t = DateTime.rfc3339(timestamp_str).to_time
|
107
|
+
time = Fluent::EventTime.from_time(t)
|
108
|
+
d = create_driver(<<-EOC)
|
109
|
+
type datadog_log
|
110
|
+
api_key myapikey
|
111
|
+
service myservice
|
112
|
+
source mysource
|
113
|
+
source_category mysourcecategory
|
114
|
+
logset mylogset
|
115
|
+
log_level debug
|
116
|
+
tags ["kube_cluster=MyCluster", "mykey=myval"]
|
117
|
+
EOC
|
118
|
+
conn = StubConn.new
|
119
|
+
fluentd_tag = 'mytag'
|
56
120
|
Net::TCPClient.stubs(:new)
|
57
121
|
.with(server: ':10516', ssl: true)
|
58
122
|
.returns(conn)
|
59
123
|
d.run(default_tag: fluentd_tag) do
|
60
124
|
record = {
|
61
125
|
'log' => 'mymsg',
|
126
|
+
'docker' => {
|
127
|
+
'container_id' => 'myfullcontainerid'
|
128
|
+
},
|
62
129
|
'kubernetes' => {
|
63
130
|
'namespace' => 'myns',
|
64
131
|
'pod_name' => 'mypod',
|
65
132
|
'container_name' => 'mycontainer',
|
66
133
|
'labels' => {
|
67
134
|
'k8s-app' => 'myapp'
|
135
|
+
},
|
136
|
+
'annotations' => {
|
137
|
+
# rubocop:disable LineLength
|
138
|
+
'kubernetes.io/created-by' => '{"kind":"SerializedReference","apiVersion":"v1","reference":{"kind":"Deployment","namespace":"default","name":"myapp","uid":"d67e8857-c2dc-11e7-aed9-066d23381f8c","apiVersion":"extensions","resourceVersion":"289"}}'
|
139
|
+
# rubocop:enable LineLength
|
68
140
|
}
|
69
141
|
}
|
70
142
|
}
|
@@ -75,7 +147,7 @@ class DatadogLogOutputTest < Test::Unit::TestCase
|
|
75
147
|
assert_equal(1, d.logs.count { |l| l =~ /Sent payload to Datadog/ })
|
76
148
|
assert_equal(1, conn.sent.size)
|
77
149
|
# rubocop:disable LineLength
|
78
|
-
payload = %(myapikey/mylogset <46>0 2006-01-02T15:04:05.000000+00:00 i-81c16767
|
150
|
+
payload = %(myapikey/mylogset <46>0 2006-01-02T15:04:05.000000+00:00 i-81c16767 myapp - - [dd ddsource="mypod"][dd ddsourcecategory="mycontainer"][dd ddtags="pod_name=mypod,container_name=mycontainer,kube_k8s-app=myapp,kube_deployment=myapp,host=i-81c16767,zone=aws:us-west-2b,aws_account_id=123456789012,kube_cluster=MyCluster,mykey=myval"] mymsg\n)
|
79
151
|
# rubocop:enable LineLength
|
80
152
|
assert_equal(payload, conn.sent.first)
|
81
153
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-datadog-log
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.0.
|
4
|
+
version: 0.1.0.rc7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yusuke KUOKA
|
@@ -154,6 +154,7 @@ files:
|
|
154
154
|
- fluent-plugin-datadog-log.gemspec~
|
155
155
|
- fluent-plugin-datadog.gemspec~
|
156
156
|
- lib/datadog/log.rb
|
157
|
+
- lib/datadog/log.rb~
|
157
158
|
- lib/fluent/plugin/monitoring.rb
|
158
159
|
- lib/fluent/plugin/out_datadog_log.rb
|
159
160
|
- lib/fluent/plugin/out_datadog_log.rb~
|
@@ -164,6 +165,7 @@ files:
|
|
164
165
|
- pkg/fluent-plugin-datadog-log-0.1.0.rc3.gem
|
165
166
|
- pkg/fluent-plugin-datadog-log-0.1.0.rc4.gem
|
166
167
|
- pkg/fluent-plugin-datadog-log-0.1.0.rc5.gem
|
168
|
+
- pkg/fluent-plugin-datadog-log-0.1.0.rc6.gem
|
167
169
|
- test/helper.rb
|
168
170
|
- test/plugin/base_test.rb
|
169
171
|
- test/plugin/constants.rb
|