td-logger 0.3.24 → 0.3.25

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- NzExZTFkZTM1MDlkZDQzYjU3YzI1NGU2NTQwYTA1NzJhMGM2MTYyZg==
5
- data.tar.gz: !binary |-
6
- MWM3YWYyMmVmNzQyMmIzMTU4YjUyNWFlYWJlNTdlMTFiN2I3OGRhZQ==
2
+ SHA1:
3
+ metadata.gz: 95a36a6c7cb7b469128717a154baa2a4c4ea556a
4
+ data.tar.gz: 91edda08bbf14f498394ae9ddf8154b7be25b3ee
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- MTBiMTQ2ZDEwMTJkY2ZlN2YyMjc0OTExZDYyNWY3NmZlZTMxNTBiYjhjM2Ni
10
- MzAzZjM1ZmE5ZGY4ZTcxNTkxOTQwMTJlOWU4YzIyZThjOWExMzQxOTJiYmQ1
11
- NzdiZjk4ZDM4MWYwZTE3NTA3Y2QwMWQ3ZjM5OGM5NjQyNzc4NDc=
12
- data.tar.gz: !binary |-
13
- NzQ4MGUwYWFjOGQxOTgzYzczMThlNTA3NGI1MWRiNWExMThkNDdiZTNiNjlh
14
- NzNiYWIyOWFlN2Q4YTU5NDc1Njg1MzBmOTBhMGZjMTI0NzhmY2M3YWVjZmNm
15
- ZTYzNWVjM2Y4NDkxZDk2NWZhNDg3MGM1MWEzZDc4OTdhMDM3YjE=
6
+ metadata.gz: d2344c5248eaaee17ad48f126b64083bc984fb347c2a0544480f90ec74251aa4fedb5a5fe5b5a724bbf2915df8c6898cb2753421552ace7431cbafdb30e3d85a
7
+ data.tar.gz: a4fa052a3af4160b1c531648a3b7ac63bb4992bdde711966c1d396ff5ff823276f0a59ae9c5b68fdcaef8141873b64227b5132964aa94a649342dca09e387182
@@ -0,0 +1 @@
1
+ service_name: travis-ci
data/.gitignore CHANGED
@@ -1,2 +1,4 @@
1
1
  Gemfile.lock
2
2
  pkg/*
3
+ spec/tmp/
4
+ coverage/
@@ -3,10 +3,14 @@ language: ruby
3
3
  rvm:
4
4
  - 1.9.3
5
5
  - 2.0.0
6
- - 2.1.0
7
- - 2.1.1
6
+ - 2.1
7
+ - 2.2
8
+ - 2.3.0
8
9
  - ruby-head
9
10
  - rbx
11
+ - jruby-1.7.20
12
+
13
+ sudo: false
10
14
 
11
15
  branches:
12
16
  only:
@@ -21,3 +25,7 @@ matrix:
21
25
  allow_failures:
22
26
  - rvm: ruby-head
23
27
  - rvm: rbx
28
+ - rvm: jruby-1.7.20
29
+
30
+ notifications:
31
+ webhooks: http://td-beda.herokuapp.com/travisci_callback
data/ChangeLog CHANGED
@@ -1,3 +1,9 @@
1
+ == 2016-01-19 version 0.3.25
2
+
3
+ * can use unique_key when post td
4
+ * can set the timing of buffering
5
+ * can configurate buffering valiables
6
+
1
7
  == 2014-11-18 version 0.3.24
2
8
 
3
9
  * Pass all option hash's arguments to the td-client library to support
@@ -1,11 +1,14 @@
1
1
  = Treasure Data logging library for Rails
2
2
 
3
+ {<img src="https://travis-ci.org/treasure-data/td-logger-ruby.svg?branch=master" alt="Build Status" />}[https://travis-ci.org/treasure-data/td-logger-ruby]
4
+ {<img src="https://coveralls.io/repos/treasure-data/td-logger-ruby/badge.svg?branch=master" alt="Coverage Status" />}[https://coveralls.io/r/treasure-data/td-logger-ruby?branch=master]
5
+
3
6
  == About
4
7
 
5
8
  This gem is a *logging* *library* *for* *Treasure* *Data*. The events logged by this module will be uploaded into the cloud. There're two ways to upload:
6
9
 
7
10
  * *direct* *upload* *from* *applications*: app -> cloud. This option is easier to configure and setup, but it requires extra memory in the application processes. The data is logged directly in the Treasure Data Cloud through the REST APIs by leveraging the {Treasure Data Ruby Client (td-client-ruby)}[https://github.com/treasure-data/td-client-ruby] library.
8
- * *in-direct* *upload* *from* *td-agent*: app -> td-agent -> cloud. This option requires extra steps to install the daemons into your cluster, but lowers the logging impact on your applications. The data is sent to a td-agent running either locally or remotely by leveraging the {Fluentd Ruby Logger (fluent-logger-ruby)}[https://github.com/fluent/fluent-logger-ruby/] library.
11
+ * *indirect* *upload* *from* *td-agent*: app -> td-agent -> cloud. This option requires extra steps to install the daemons into your cluster, but lowers the logging impact on your applications. The data is sent to a td-agent running either locally or remotely by leveraging the {Fluentd Ruby Logger (fluent-logger-ruby)}[https://github.com/fluent/fluent-logger-ruby/] library.
9
12
 
10
13
  The actual upload method can be selected in the config file as described below.
11
14
 
@@ -41,7 +44,7 @@ This configuration enables the application to upload the events directly from th
41
44
 
42
45
  If you would wish to keep your API key as an environment variable, you can use this setting:
43
46
 
44
- apikey: <% ENV['TD_API_KEY'] %>
47
+ apikey: <%= ENV['TD_API_KEY'] %>
45
48
 
46
49
  Alternatively, one can initialize the Ruby Logger module for direct upload straight from within the application:
47
50
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.24
1
+ 0.3.25
@@ -0,0 +1,17 @@
1
+ ---
2
+ version: "{build}"
3
+ clone_depth: 10
4
+ install:
5
+ - SET PATH=C:\Ruby%ruby_version%\bin;%PATH%
6
+ - ruby --version
7
+ - gem --version
8
+ - gem install bundler --quiet --no-ri --no-rdoc
9
+ - bundler --version
10
+ - bundle install
11
+ build_script:
12
+ - bundle exec rake build
13
+ test_script:
14
+ - bundle exec rake spec
15
+ environment:
16
+ matrix:
17
+ - ruby_version: "22"
@@ -46,11 +46,11 @@ class TreasureDataLogger < Fluent::Logger::LoggerBase
46
46
  @map = {} # (db,table) => buffer:String
47
47
  @queue = []
48
48
 
49
- @chunk_limit = 8 * 1024 * 1024
49
+ @chunk_limit = options[:chunk_limit] || 8 * 1024 * 1024
50
50
  @queue_limit = 50
51
51
 
52
- @flush_interval = 2
53
- @max_flush_interval = 300
52
+ @flush_interval = options[:flush_interval] || 2
53
+ @max_flush_interval = options[:max_flush_interval] || 300
54
54
  @retry_wait = 1.0
55
55
  @retry_limit = 12
56
56
 
@@ -62,6 +62,8 @@ class TreasureDataLogger < Fluent::Logger::LoggerBase
62
62
  # Unicorn and Passenger.
63
63
  @upload_thread = nil
64
64
 
65
+ @use_unique_key = options[:use_unique_key]
66
+
65
67
  # The calling order of finalizer registered by define_finalizer is indeterminate,
66
68
  # so we should use at_exit instead for memory safety.
67
69
  at_exit { close }
@@ -211,6 +213,8 @@ class TreasureDataLogger < Fluent::Logger::LoggerBase
211
213
  end
212
214
 
213
215
  def add(db, table, msg)
216
+ # NOTE: TreasureData::API is defined at td-client-ruby gem
217
+ # https://github.com/treasure-data/td-client-ruby/blob/master/lib/td/client/api.rb
214
218
  begin
215
219
  TreasureData::API.validate_database_name(db)
216
220
  rescue
@@ -329,12 +333,14 @@ class TreasureDataLogger < Fluent::Logger::LoggerBase
329
333
  end
330
334
 
331
335
  def upload(db, table, data)
336
+ unique_key = @use_unique_key ? generate_unique_key : nil
337
+
332
338
  begin
333
339
  stream = StringIO.new(data)
334
340
 
335
- @logger.debug "Uploading event logs to #{db}.#{table} table on Treasure Data (#{stream.size} bytes)"
341
+ @logger.info "Uploading event logs to #{db}.#{table} table on Treasure Data (#{stream.size} bytes)"
336
342
 
337
- @client.import(db, table, "msgpack.gz", stream, stream.size)
343
+ @client.import(db, table, "msgpack.gz", stream, stream.size, unique_key)
338
344
  rescue TreasureData::NotFoundError
339
345
  unless @auto_create_table
340
346
  raise $!
@@ -350,6 +356,15 @@ class TreasureDataLogger < Fluent::Logger::LoggerBase
350
356
  end
351
357
  end
352
358
 
359
+ # NOTE fluentd unique_id and fluent-plugin-td unique_str in reference.
360
+ # https://github.com/fluent/fluentd/blob/v0.12.15/lib/fluent/plugin/buf_memory.rb#L22
361
+ # https://github.com/treasure-data/fluent-plugin-td/blob/v0.10.27/lib/fluent/plugin/out_tdlog.rb#L225
362
+ def generate_unique_key(now = Time.now)
363
+ u1 = ((now.to_i*1000*1000+now.usec) << 12 | rand(0xfff))
364
+ uid = [u1 >> 32, u1 & 0xffffffff, rand(0xffffffff), rand(0xffffffff)].pack('NNNN')
365
+ uid.unpack('C*').map { |x| "%02x" % x }.join
366
+ end
367
+
353
368
  require 'thread' # ConditionVariable
354
369
  if ConditionVariable.new.method(:wait).arity == 1
355
370
  # "WARNING: Running on Ruby 1.8. Ruby 1.9 is recommended."
@@ -1,7 +1,7 @@
1
1
  module TreasureData
2
2
  module Logger
3
3
 
4
- VERSION = '0.3.24'
4
+ VERSION = '0.3.25'
5
5
 
6
6
  end
7
7
  end
@@ -1,6 +1,24 @@
1
+ if defined?(:RUBY_ENGINE) && RUBY_ENGINE == 'ruby'
2
+ # SimpleCov officially supports MRI 1.9+ only for now
3
+ # https://github.com/colszowka/simplecov#ruby-version-compatibility
4
+
5
+ require 'simplecov'
6
+ unless ENV['APPVEYOR']
7
+ require 'coveralls'
8
+
9
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
10
+ SimpleCov::Formatter::HTMLFormatter,
11
+ Coveralls::SimpleCov::Formatter
12
+ ]
13
+ end
14
+ SimpleCov.start("test_frameworks")
15
+ end
16
+
1
17
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
18
  $LOAD_PATH.unshift(File.dirname(__FILE__))
3
19
 
20
+ REPO_ROOT = Pathname.new(File.expand_path("../", __FILE__))
21
+
4
22
  require 'td-logger'
5
23
 
6
24
  RSpec.configure do |config|
@@ -0,0 +1,260 @@
1
+ require 'spec_helper'
2
+ require 'fileutils'
3
+ require 'logger'
4
+
5
+ TMP_DIR = REPO_ROOT.join("tmp")
6
+ FileUtils.rm_rf(TMP_DIR)
7
+
8
+ class Rails
9
+ def self.configuration
10
+ self.new
11
+ end
12
+
13
+ def self.logger
14
+ Logger.new(STDOUT)
15
+ end
16
+
17
+ def self.root
18
+ TMP_DIR
19
+ end
20
+
21
+ def self.env
22
+ "test"
23
+ end
24
+
25
+ def middleware
26
+ self
27
+ end
28
+
29
+ def use(mod)
30
+ end
31
+ end
32
+
33
+ class ActionController
34
+ class Base
35
+ end
36
+ end
37
+
38
+ class ActiveSupport
39
+ class TimeWithZone
40
+ end
41
+ end
42
+
43
+ require 'td/logger/agent/rails' # NOTE: should be require after Rails goodies mocked
44
+
45
+
46
+ describe TreasureData::Logger::Agent::Rails::Config do
47
+ before(:each) do
48
+ FileUtils.rm_rf(TMP_DIR)
49
+ FileUtils.mkdir_p(TMP_DIR)
50
+ ENV.delete('TREASURE_DATA_API_KEY')
51
+ ENV.delete('TREASURE_DATA_DB')
52
+ end
53
+
54
+ context 'init' do
55
+ it 'load_env' do
56
+ ENV['TREASURE_DATA_API_KEY'] = 'test1'
57
+ ENV['TREASURE_DATA_DB'] = 'db1'
58
+ c = TreasureData::Logger::Agent::Rails::Config.init
59
+ expect(c.disabled).to eq(false)
60
+ expect(c.agent_mode?).to eq(false)
61
+ expect(c.apikey).to eq('test1')
62
+ expect(c.database).to eq('db1')
63
+ expect(c.auto_create_table).to eq(true)
64
+ end
65
+
66
+ it 'load_file' do
67
+ FileUtils.mkdir_p("#{TMP_DIR}/config")
68
+ File.open("#{TMP_DIR}/config/treasure_data.yml", "w") {|f|
69
+ f.write <<EOF
70
+ test:
71
+ apikey: test2
72
+ database: db2
73
+ debug_mode: true
74
+ EOF
75
+ }
76
+ c = TreasureData::Logger::Agent::Rails::Config.init
77
+ expect(c.disabled).to eq(false)
78
+ expect(c.agent_mode?).to eq(false)
79
+ expect(c.apikey).to eq('test2')
80
+ expect(c.database).to eq('db2')
81
+ expect(c.auto_create_table).to eq(true)
82
+ expect(c.debug_mode).to eq(true)
83
+ expect(c.access_log_enabled?).to eq false
84
+ end
85
+
86
+ it 'load_file without test' do
87
+ FileUtils.mkdir_p("#{TMP_DIR}/config")
88
+ File.open("#{TMP_DIR}/config/treasure_data.yml", "w") {|f|
89
+ f.write <<EOF
90
+ development:
91
+ apikey: test2
92
+ database: db2
93
+ debug_mode: true
94
+ EOF
95
+ }
96
+ c = TreasureData::Logger::Agent::Rails::Config.init
97
+ expect(c.disabled).to eq(true)
98
+ expect(c.access_log_enabled?).to eq false
99
+ end
100
+
101
+ it 'prefer file than env' do
102
+ ENV['TREASURE_DATA_API_KEY'] = 'test3'
103
+ ENV['TREASURE_DATA_DB'] = 'db3'
104
+
105
+ FileUtils.mkdir_p("#{TMP_DIR}/config")
106
+ File.open("#{TMP_DIR}/config/treasure_data.yml", "w") {|f|
107
+ f.write <<EOF
108
+ test:
109
+ apikey: test4
110
+ database: db4
111
+ auto_create_table: false
112
+ EOF
113
+ }
114
+ c = TreasureData::Logger::Agent::Rails::Config.init
115
+ expect(c.disabled).to eq(false)
116
+ expect(c.agent_mode?).to eq(false)
117
+ expect(c.apikey).to eq('test4')
118
+ expect(c.database).to eq('db4')
119
+ expect(c.auto_create_table).to eq(false)
120
+ expect(c.debug_mode).to eq(false)
121
+ expect(c.access_log_enabled?).to eq false
122
+ end
123
+
124
+ it 'agent mode' do
125
+ FileUtils.mkdir_p("#{TMP_DIR}/config")
126
+ File.open("#{TMP_DIR}/config/treasure_data.yml", "w") {|f|
127
+ f.write <<EOF
128
+ test:
129
+ agent: localhost
130
+ tag: td.db5
131
+ EOF
132
+ }
133
+ c = TreasureData::Logger::Agent::Rails::Config.init
134
+ expect(c.disabled).to eq(false)
135
+ expect(c.agent_mode?).to eq(true)
136
+ expect(c.tag).to eq('td.db5')
137
+ expect(c.agent_host).to eq('localhost')
138
+ expect(c.agent_port).to eq(24224)
139
+ expect(c.access_log_enabled?).to eq false
140
+ end
141
+
142
+ it 'test mode' do
143
+ FileUtils.mkdir_p("#{TMP_DIR}/config")
144
+ File.open("#{TMP_DIR}/config/treasure_data.yml", "w") {|f|
145
+ f.write <<EOF
146
+ test:
147
+ agent: localhost
148
+ tag: td.db5
149
+ test_mode: true
150
+ EOF
151
+ }
152
+ c = TreasureData::Logger::Agent::Rails::Config.init
153
+ expect(c.disabled).to eq(false)
154
+ expect(c.test_mode?).to eq(true)
155
+ expect(c.access_log_enabled?).to eq false
156
+ end
157
+
158
+ it "access_log_enabled" do
159
+ FileUtils.mkdir_p("#{TMP_DIR}/config")
160
+ File.open("#{TMP_DIR}/config/treasure_data.yml", "w") {|f|
161
+ f.write <<EOF
162
+ test:
163
+ agent: localhost
164
+ tag: foo.bar
165
+ access_log_table: log
166
+ EOF
167
+ }
168
+ c = TreasureData::Logger::Agent::Rails::Config.init
169
+ expect(c.disabled).to eq(false)
170
+ expect(c.access_log_enabled?).to eq true
171
+ end
172
+
173
+ describe "load_file_ey" do
174
+ context "config_path does not exists" do
175
+ it "load from CONFIG_PATH_EY_DEPLOY" do
176
+ FileUtils.mkdir_p("#{TMP_DIR}/config")
177
+ File.unlink("#{TMP_DIR}/config/treasure_data.yml") rescue nil
178
+ File.open(TreasureData::Logger::Agent::Rails::CONFIG_PATH_EY_DEPLOY, "w") {|f|
179
+ f.write <<EOF
180
+ td:
181
+ TREASURE_DATA_API_KEY: foo
182
+ EOF
183
+ }
184
+ c = TreasureData::Logger::Agent::Rails::Config.init
185
+ expect(c.disabled).to eq(false)
186
+ end
187
+
188
+ it "disabled true if td.TREASURE_DATA_API_KEY missing" do
189
+ FileUtils.mkdir_p("#{TMP_DIR}/config")
190
+ File.unlink("#{TMP_DIR}/config/treasure_data.yml") rescue nil
191
+ File.open(TreasureData::Logger::Agent::Rails::CONFIG_PATH_EY_DEPLOY, "w") {|f|
192
+ f.write <<EOF
193
+ EOF
194
+ }
195
+ c = TreasureData::Logger::Agent::Rails::Config.init
196
+ expect(c.disabled).to eq(true)
197
+ end
198
+ end
199
+
200
+ context "config_path and CONFIG_PATH_EY_DEPLOY does not exists" do
201
+ it "load from CONFIG_PATH_EY_LOCAL" do
202
+ FileUtils.mkdir_p("#{TMP_DIR}/config")
203
+ File.unlink("#{TMP_DIR}/config/treasure_data.yml") rescue nil
204
+ File.unlink(TreasureData::Logger::Agent::Rails::CONFIG_PATH_EY_DEPLOY) rescue nil
205
+ File.open(TreasureData::Logger::Agent::Rails::CONFIG_PATH_EY_LOCAL, "w") {|f|
206
+ f.write <<EOF
207
+ td:
208
+ TREASURE_DATA_API_KEY: foo
209
+ EOF
210
+ }
211
+ c = TreasureData::Logger::Agent::Rails::Config.init
212
+ expect(c.disabled).to eq(false)
213
+ end
214
+
215
+ it "disabled true if td.TREASURE_DATA_API_KEY missing" do
216
+ FileUtils.mkdir_p("#{TMP_DIR}/config")
217
+ File.unlink("#{TMP_DIR}/config/treasure_data.yml") rescue nil
218
+ File.open(TreasureData::Logger::Agent::Rails::CONFIG_PATH_EY_LOCAL, "w") {|f|
219
+ f.write <<EOF
220
+ EOF
221
+ }
222
+ c = TreasureData::Logger::Agent::Rails::Config.init
223
+ expect(c.disabled).to eq(true)
224
+ end
225
+ end
226
+
227
+ context "config_path, CONFIG_PATH_EY_DEPLOY, CONFIG_PATH_EY_LOCAL are all exists" do
228
+ it "load from CONFIG_PATH_EY_LOCAL" do
229
+ FileUtils.mkdir_p("#{TMP_DIR}/config")
230
+ File.open("#{TMP_DIR}/config/treasure_data.yml", "w") {|f|
231
+ f.write <<EOF
232
+ test:
233
+ agent: localhost
234
+ tag: foo.bar
235
+ test_mode: false
236
+ EOF
237
+ }
238
+ File.open(TreasureData::Logger::Agent::Rails::CONFIG_PATH_EY_DEPLOY, "w") {|f|
239
+ f.write <<EOF
240
+ test:
241
+ agent: localhost
242
+ tag: foo.bar
243
+ test_mode: true
244
+ EOF
245
+ }
246
+ File.open(TreasureData::Logger::Agent::Rails::CONFIG_PATH_EY_LOCAL, "w") {|f|
247
+ f.write <<EOF
248
+ test:
249
+ agent: localhost
250
+ tag: foo.bar
251
+ test_mode: true
252
+ EOF
253
+ }
254
+ c = TreasureData::Logger::Agent::Rails::Config.init
255
+ expect(c.test_mode).to eq(false)
256
+ end
257
+ end
258
+ end
259
+ end
260
+ end