td-logger 0.2.3 → 0.2.4
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.
- data/ChangeLog +10 -0
- data/lib/td/logger/agent/access_log.rb +10 -0
- data/lib/td/logger/agent/rails.rb +20 -3
- data/lib/td/logger/tdlog.rb +74 -34
- data/lib/td/logger/version.rb +1 -1
- metadata +4 -4
data/ChangeLog
CHANGED
@@ -1,4 +1,14 @@
|
|
1
1
|
|
2
|
+
== 2011-09-13 version 0.2.4
|
3
|
+
|
4
|
+
* Increase flush_interval from 10 sec to 5 mins gradually
|
5
|
+
* Flush buffered logs when Rails stops
|
6
|
+
* Adds 'elapsed' column to access logs
|
7
|
+
* Use TREASURE_DATA_API_KEY environment variable by default
|
8
|
+
* Enable event logger if apikey is available with default database name
|
9
|
+
and access log table name
|
10
|
+
|
11
|
+
|
2
12
|
== 2011-09-08 version 0.2.3
|
3
13
|
|
4
14
|
* Loggers use STDERR instead of STDOUT
|
@@ -35,10 +35,20 @@ module Agent
|
|
35
35
|
data = {}
|
36
36
|
Thread.current['td.access_log'] = data
|
37
37
|
env['td.access_log'] = data
|
38
|
+
env['td.access_time'] = Time.now
|
38
39
|
end
|
39
40
|
|
40
41
|
Middleware.after do |env,result|
|
41
42
|
data = env['td.access_log'] || {}
|
43
|
+
access_time = env['td.access_time']
|
44
|
+
|
45
|
+
# add 'elapsed' column
|
46
|
+
if access_time
|
47
|
+
elapsed = Time.now - access_time
|
48
|
+
data['elapsed'] = elapsed
|
49
|
+
# set 'time' column to access time
|
50
|
+
data['time'] = access_time
|
51
|
+
end
|
42
52
|
|
43
53
|
ACCESS_LOG_PRESET_ENV_KEYS.each_pair {|key,val|
|
44
54
|
data[key] ||= env[val] if env[val]
|
@@ -86,14 +86,31 @@ EOF
|
|
86
86
|
require 'yaml'
|
87
87
|
require 'erb'
|
88
88
|
logger = ::Rails.logger || ::Logger.new(STDERR)
|
89
|
+
|
90
|
+
unless File.exist?(CONFIG_PATH)
|
91
|
+
apikey = ENV['TREASURE_DATA_API_KEY'] || ENV['TD_API_KEY']
|
92
|
+
unless apikey
|
93
|
+
logger.warn "TREASURE_DATA_API_KEY environment variable is not set"
|
94
|
+
logger.warn "#{CONFIG_PATH} does not exist."
|
95
|
+
logger.warn "Disabling Treasure Data logger."
|
96
|
+
return
|
97
|
+
end
|
98
|
+
return Config.new({
|
99
|
+
'apikey' => apikey,
|
100
|
+
'database' => ENV['TREASURE_DATA_DB'] || "rails_#{rails_env}",
|
101
|
+
'access_log_table' => ENV['TREASURE_DATA_TABLE'] || 'web_access',
|
102
|
+
'auto_create_table' => true
|
103
|
+
})
|
104
|
+
end
|
105
|
+
|
89
106
|
begin
|
90
107
|
src = File.read("#{rails_root}/#{CONFIG_PATH}")
|
91
108
|
yaml = ERB.new(src).result
|
92
109
|
env_conf = YAML.load(yaml)
|
93
110
|
rescue
|
94
|
-
logger.warn "Can't load #{CONFIG_PATH} file
|
95
|
-
logger.warn "
|
96
|
-
logger.warn "
|
111
|
+
logger.warn "Can't load #{CONFIG_PATH} file: #{$!}"
|
112
|
+
logger.warn "Disabling Treasure Data logger."
|
113
|
+
logger.warn "Example:"
|
97
114
|
logger.warn CONFIG_SAMPLE
|
98
115
|
return
|
99
116
|
end
|
data/lib/td/logger/tdlog.rb
CHANGED
@@ -2,9 +2,27 @@
|
|
2
2
|
module TreasureData
|
3
3
|
module Logger
|
4
4
|
|
5
|
-
# TODO shutdown handler (deadlock)
|
6
5
|
|
7
6
|
class TreasureDataLogger < Fluent::Logger::LoggerBase
|
7
|
+
module Finalizable
|
8
|
+
require 'delegate'
|
9
|
+
def new(*args, &block)
|
10
|
+
obj = allocate
|
11
|
+
obj.instance_eval { initialize(*args, &block) }
|
12
|
+
dc = DelegateClass(obj.class).new(obj)
|
13
|
+
ObjectSpace.define_finalizer(dc, finalizer(obj))
|
14
|
+
dc
|
15
|
+
end
|
16
|
+
|
17
|
+
def finalizer(obj)
|
18
|
+
fin = obj.method(:finalize)
|
19
|
+
proc {|id|
|
20
|
+
fin.call
|
21
|
+
}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
extend Finalizable
|
25
|
+
|
8
26
|
def initialize(apikey, tag, auto_create_table)
|
9
27
|
require 'thread'
|
10
28
|
require 'stringio'
|
@@ -18,7 +36,9 @@ class TreasureDataLogger < Fluent::Logger::LoggerBase
|
|
18
36
|
|
19
37
|
@tag = tag
|
20
38
|
@auto_create_table = auto_create_table
|
39
|
+
|
21
40
|
@logger = ::Logger.new(STDERR)
|
41
|
+
@logger.level = ::Logger::INFO
|
22
42
|
|
23
43
|
@client = TreasureData::Client.new(apikey)
|
24
44
|
|
@@ -28,7 +48,8 @@ class TreasureDataLogger < Fluent::Logger::LoggerBase
|
|
28
48
|
@queue = []
|
29
49
|
|
30
50
|
@chunk_limit = 8*1024*1024
|
31
|
-
@flush_interval =
|
51
|
+
@flush_interval = 10
|
52
|
+
@max_flush_interval = 300
|
32
53
|
@retry_wait = 1.0
|
33
54
|
@retry_limit = 8
|
34
55
|
|
@@ -41,11 +62,21 @@ class TreasureDataLogger < Fluent::Logger::LoggerBase
|
|
41
62
|
attr_accessor :logger
|
42
63
|
|
43
64
|
def close
|
44
|
-
@finish
|
45
|
-
|
46
|
-
@
|
47
|
-
|
48
|
-
|
65
|
+
unless @finish
|
66
|
+
@finish = true
|
67
|
+
@mutex.synchronize {
|
68
|
+
@flush_now = true
|
69
|
+
@cond.signal
|
70
|
+
}
|
71
|
+
@upload_thread.join
|
72
|
+
|
73
|
+
@map.each {|(db,table),buffer|
|
74
|
+
upload(db, table, buffer)
|
75
|
+
}
|
76
|
+
@queue.each {|tuple|
|
77
|
+
upload(*tuple)
|
78
|
+
}
|
79
|
+
end
|
49
80
|
end
|
50
81
|
|
51
82
|
def post(tag, record)
|
@@ -70,29 +101,32 @@ class TreasureDataLogger < Fluent::Logger::LoggerBase
|
|
70
101
|
end
|
71
102
|
|
72
103
|
def upload_main
|
73
|
-
|
74
|
-
|
75
|
-
|
104
|
+
@mutex.lock
|
105
|
+
until @finish
|
106
|
+
now = Time.now.to_i
|
107
|
+
|
108
|
+
if @next_time <= now || (@flush_now && @error_count == 0)
|
109
|
+
@mutex.unlock
|
110
|
+
begin
|
111
|
+
flushed = try_flush
|
112
|
+
ensure
|
113
|
+
@mutex.lock
|
114
|
+
end
|
115
|
+
@flush_now = false
|
116
|
+
end
|
76
117
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
118
|
+
if @error_count == 0
|
119
|
+
if flushed && @flush_interval < @max_flush_interval
|
120
|
+
@flush_interval = [@flush_interval + 60, @max_flush_interval].min
|
121
|
+
end
|
122
|
+
next_wait = @flush_interval
|
123
|
+
else
|
124
|
+
next_wait = @retry_wait * (2 ** (@error_count-1))
|
83
125
|
end
|
84
|
-
@
|
85
|
-
end
|
126
|
+
@next_time = next_wait + now
|
86
127
|
|
87
|
-
|
88
|
-
next_wait = @flush_interval
|
89
|
-
else
|
90
|
-
next_wait = @retry_wait * (2 ** (@error_count-1))
|
128
|
+
cond_wait(next_wait)
|
91
129
|
end
|
92
|
-
@next_time = next_wait + now
|
93
|
-
|
94
|
-
cond_wait(next_wait)
|
95
|
-
end
|
96
130
|
|
97
131
|
rescue
|
98
132
|
@logger.error "Unexpected error: #{$!}"
|
@@ -113,6 +147,8 @@ class TreasureDataLogger < Fluent::Logger::LoggerBase
|
|
113
147
|
end
|
114
148
|
end
|
115
149
|
|
150
|
+
flushed = false
|
151
|
+
|
116
152
|
until @queue.empty?
|
117
153
|
tuple = @queue.first
|
118
154
|
|
@@ -120,12 +156,13 @@ class TreasureDataLogger < Fluent::Logger::LoggerBase
|
|
120
156
|
upload(*tuple)
|
121
157
|
@queue.shift
|
122
158
|
@error_count = 0
|
159
|
+
flushed = true
|
123
160
|
rescue
|
124
161
|
if @error_count < @retry_limit
|
125
|
-
@logger.error "Failed to
|
162
|
+
@logger.error "Failed to import logs to Treasure Data, retrying: #{$!}"
|
126
163
|
@error_count += 1
|
127
164
|
else
|
128
|
-
@logger.error "Failed to
|
165
|
+
@logger.error "Failed to import logs to Treasure Data, trashed: #{$!}"
|
129
166
|
$!.backtrace.each {|bt|
|
130
167
|
@logger.info bt
|
131
168
|
}
|
@@ -135,14 +172,17 @@ class TreasureDataLogger < Fluent::Logger::LoggerBase
|
|
135
172
|
return
|
136
173
|
end
|
137
174
|
end
|
175
|
+
|
176
|
+
flushed
|
138
177
|
end
|
139
178
|
|
140
179
|
def upload(db, table, buffer)
|
141
|
-
|
142
|
-
Zlib::GzipWriter.wrap(out) {|gz| gz.write buffer }
|
143
|
-
stream = StringIO.new(out.string)
|
144
|
-
|
180
|
+
@logger.debug "Importing logs to #{db}.#{table} table on TreasureData"
|
145
181
|
begin
|
182
|
+
out = StringIO.new
|
183
|
+
Zlib::GzipWriter.wrap(out) {|gz| gz.write buffer }
|
184
|
+
stream = StringIO.new(out.string)
|
185
|
+
|
146
186
|
@client.import(db, table, "msgpack.gz", stream, stream.size)
|
147
187
|
rescue TreasureData::NotFoundError
|
148
188
|
unless @auto_create_table
|
@@ -159,8 +199,8 @@ class TreasureDataLogger < Fluent::Logger::LoggerBase
|
|
159
199
|
end
|
160
200
|
end
|
161
201
|
|
162
|
-
def
|
163
|
-
|
202
|
+
def finalize
|
203
|
+
close
|
164
204
|
end
|
165
205
|
|
166
206
|
if ConditionVariable.new.method(:wait).arity == 1
|
data/lib/td/logger/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: td-logger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 31
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 0.2.
|
9
|
+
- 4
|
10
|
+
version: 0.2.4
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Sadayuki Furuhashi
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-09-
|
18
|
+
date: 2011-09-13 00:00:00 +09:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|