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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ef9ed5f3814abf3c96d3658878c416efae5a5331
4
- data.tar.gz: a1db7f7c2c7534cbcc037c7eb1a5e2f3daeab860
3
+ metadata.gz: aedaaa9c78c6fd346266540ebf04e4f91dcfab96
4
+ data.tar.gz: 885f73273fd6671a9e191051cc1afff8704af480
5
5
  SHA512:
6
- metadata.gz: 4620f9e665fcf9e1e5fb218cd6be094cfc22f314e0573f494a93992c666aee61e3678a12d4ad9f408a4c78b46f900f05472f44879260cd501cafb621fc687d1b
7
- data.tar.gz: 1435a3d5d3f5470252912fe7a8e00f8d802cc411f6a42e9e97b6f2157f57c0627f3bdb5fab6fddd5a5fb66ce1804fa47224aeae9177759ab0939205cd814a013
6
+ metadata.gz: 3f0c941f62799dfcac25c8261665e103a14dc81410ebc9376f98fef8b0f216dce35fe53393fd410e29c13923d6bf6cf23571ac3132c564ae7453527750e6b7c2
7
+ data.tar.gz: 8aade4e0f12e9c07e87be0ccd2e8131b8d247d84c1bcc13ba9a24af0c622cc30ada70a3b336926b89767d3845b5f5a4b4d81b4b36dcf90b02d3599ba54d817a7
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fluent-plugin-datadog-log (0.1.0.rc6)
4
+ fluent-plugin-datadog-log (0.1.0.rc7)
5
5
  fluentd (~> 0.14)
6
6
  json (~> 1.8)
7
7
  net_tcp_client (~> 2.0.1)
@@ -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.rc6'
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.rc3'
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.add_development_dependency 'net_tcp_client', '~> 2.0.1'
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
@@ -96,7 +96,9 @@ module Datadog
96
96
  )
97
97
  )
98
98
  )
99
- @conn.write(payload)
99
+ @conn.retry_on_connection_failure do
100
+ @conn.write(payload)
101
+ end
100
102
  payload
101
103
  end
102
104
 
@@ -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
@@ -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 myservice - - [dd ddsource="mysource"][dd ddsourcecategory="mysourcecategory"][dd ddtags="pod_name=mypod,container_name=mycontainer,kube_k8s-app=myapp,host=i-81c16767,zone=aws:us-west-2b,aws_account_id=123456789012"] mymsg\n)
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.rc6
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