fluent-plugin-datadog-log 0.1.0.rc6 → 0.1.0.rc7

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
  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