influxdb-logger 1.0.0
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 +7 -0
- data/.gitignore +22 -0
- data/.travis.yml +30 -0
- data/Appraisals +29 -0
- data/CHANGELOG.md +69 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +115 -0
- data/Rakefile +6 -0
- data/gemfiles/rails_4.0.gemfile +10 -0
- data/gemfiles/rails_4.1.gemfile +10 -0
- data/gemfiles/rails_4.2.gemfile +10 -0
- data/gemfiles/rails_5.0.gemfile +10 -0
- data/gemfiles/rails_5.1.gemfile +10 -0
- data/gemfiles/rails_5.2.gemfile +11 -0
- data/influxdb-logger.gemspec +25 -0
- data/lib/influxdb-logger/logger.rb +222 -0
- data/lib/influxdb-logger/version.rb +3 -0
- data/lib/influxdb-logger.rb +2 -0
- data/spec/logger_spec.rb +202 -0
- data/spec/spec_helper.rb +10 -0
- metadata +134 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: a108e31a9049f7e781a2e049c130c0f7453d38c0
|
|
4
|
+
data.tar.gz: d15563795730d1197bcd81e6fa430913a7f923e6
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 072df960c685702015d306b87881b2527d4a1268250cccb7274824aa4c5b928676b6fd4a07a596c1f0f5486862ab6c40868f4e67e5e59393db38c8f6a621dc1e
|
|
7
|
+
data.tar.gz: e31a48b3229760476d8d6119ec97f4ca39f88b445d4fa5b82c0f4da20691f2b78bda168718fbba3706cd9853f543b4751a0d49b9f86cb81834b1767d2eff5bed
|
data/.gitignore
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
*.gem
|
|
2
|
+
*.rbc
|
|
3
|
+
*~
|
|
4
|
+
.bundle
|
|
5
|
+
.config
|
|
6
|
+
.yardoc
|
|
7
|
+
/vendor
|
|
8
|
+
Gemfile.lock
|
|
9
|
+
gemfiles/*.lock
|
|
10
|
+
InstalledFiles
|
|
11
|
+
_yardoc
|
|
12
|
+
coverage
|
|
13
|
+
doc/
|
|
14
|
+
lib/bundler/man
|
|
15
|
+
pkg
|
|
16
|
+
rdoc
|
|
17
|
+
spec/reports
|
|
18
|
+
test/tmp
|
|
19
|
+
test/version_tmp
|
|
20
|
+
tmp
|
|
21
|
+
.ruby-version
|
|
22
|
+
.idea
|
data/.travis.yml
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
language: ruby
|
|
2
|
+
rvm:
|
|
3
|
+
- 2.1.10
|
|
4
|
+
- 2.2.10
|
|
5
|
+
- 2.3.7
|
|
6
|
+
- 2.4.4
|
|
7
|
+
- 2.5.1
|
|
8
|
+
gemfile:
|
|
9
|
+
- gemfiles/rails_4.0.gemfile
|
|
10
|
+
- gemfiles/rails_4.1.gemfile
|
|
11
|
+
- gemfiles/rails_4.2.gemfile
|
|
12
|
+
- gemfiles/rails_5.0.gemfile
|
|
13
|
+
- gemfiles/rails_5.1.gemfile
|
|
14
|
+
- gemfiles/rails_5.2.gemfile
|
|
15
|
+
matrix:
|
|
16
|
+
exclude:
|
|
17
|
+
- rvm: 2.1.10
|
|
18
|
+
gemfile: gemfiles/rails_5.0.gemfile
|
|
19
|
+
- rvm: 2.1.10
|
|
20
|
+
gemfile: gemfiles/rails_5.1.gemfile
|
|
21
|
+
- rvm: 2.1.10
|
|
22
|
+
gemfile: gemfiles/rails_5.2.gemfile
|
|
23
|
+
- rvm: 2.4.4
|
|
24
|
+
gemfile: gemfiles/rails_4.0.gemfile
|
|
25
|
+
- rvm: 2.4.4
|
|
26
|
+
gemfile: gemfiles/rails_4.1.gemfile
|
|
27
|
+
- rvm: 2.5.1
|
|
28
|
+
gemfile: gemfiles/rails_4.0.gemfile
|
|
29
|
+
- rvm: 2.5.1
|
|
30
|
+
gemfile: gemfiles/rails_4.1.gemfile
|
data/Appraisals
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
appraise 'rails-4.0' do
|
|
2
|
+
gem 'railties', '4.0.13'
|
|
3
|
+
gem 'activesupport', '4.0.13'
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
appraise 'rails-4.1' do
|
|
7
|
+
gem 'railties', '4.1.16'
|
|
8
|
+
gem 'activesupport', '4.1.16'
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
appraise 'rails-4.2' do
|
|
12
|
+
gem 'railties', '4.2.8'
|
|
13
|
+
gem 'activesupport', '4.2.8'
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
appraise 'rails-5.0' do
|
|
17
|
+
gem 'railties', '5.0.2'
|
|
18
|
+
gem 'activesupport', '5.0.2'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
appraise 'rails-5.1' do
|
|
22
|
+
gem 'railties', '5.1.0'
|
|
23
|
+
gem 'activesupport', '5.1.0'
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
appraise 'rails-5.2' do
|
|
27
|
+
gem 'railties', '5.2.0'
|
|
28
|
+
gem 'activesupport', '5.2.0'
|
|
29
|
+
end
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
## 0.5.0 / April 29 2017
|
|
2
|
+
|
|
3
|
+
* Rails 5.2
|
|
4
|
+
* support nanosecond_precision(Support nanosecond precision when sending logs to Fluentd #43)*
|
|
5
|
+
|
|
6
|
+
## 0.4.0 / April 29 2017
|
|
7
|
+
|
|
8
|
+
* Rails 5.1
|
|
9
|
+
|
|
10
|
+
## 0.3.1 / August 18 2016
|
|
11
|
+
|
|
12
|
+
* Replace dependency from rails to railties and activesupport.
|
|
13
|
+
|
|
14
|
+
## 0.3.0 / July 12 2016
|
|
15
|
+
|
|
16
|
+
* Rails 5
|
|
17
|
+
|
|
18
|
+
## 0.2.0 / Mar 20 2016
|
|
19
|
+
|
|
20
|
+
* Add severity_key parameter. It is The key of severity(DEBUG, INFO, WARN, ERROR).
|
|
21
|
+
|
|
22
|
+
## 0.1.10 / Dec 23 2015
|
|
23
|
+
|
|
24
|
+
* flush immediately.
|
|
25
|
+
|
|
26
|
+
## 0.1.9 / Dec 16 2015
|
|
27
|
+
|
|
28
|
+
* Added settings: parameter to InfluxdbLogger::Logger.new.
|
|
29
|
+
|
|
30
|
+
## 0.1.8 / Nov 14 2015
|
|
31
|
+
|
|
32
|
+
* Output Object#inspect if message is not String and not Exception.
|
|
33
|
+
|
|
34
|
+
## 0.1.7 / July 30 2015
|
|
35
|
+
|
|
36
|
+
* Be able to log exceptions #15.
|
|
37
|
+
|
|
38
|
+
## 0.1.6 / March 20 2015
|
|
39
|
+
|
|
40
|
+
* Fix incompatible character encodings #13.
|
|
41
|
+
|
|
42
|
+
## 0.1.5 / July 19 2014
|
|
43
|
+
|
|
44
|
+
* Fix keynames of EVN['FLUENTD_URL']
|
|
45
|
+
|
|
46
|
+
## 0.1.4 / July 18 2014
|
|
47
|
+
|
|
48
|
+
* Enable to use EVN['FLUENTD_URL']
|
|
49
|
+
|
|
50
|
+
## 0.1.3 / April 11 2014
|
|
51
|
+
|
|
52
|
+
* Rails 4.1.0
|
|
53
|
+
|
|
54
|
+
## 0.1.2 / September 30 2013
|
|
55
|
+
|
|
56
|
+
* Add 'gem.license = "MIT"' to gemspec.
|
|
57
|
+
|
|
58
|
+
## 0.1.1 / September 26 2013
|
|
59
|
+
|
|
60
|
+
* Add log_tags feature.
|
|
61
|
+
|
|
62
|
+
## 0.1.0 / September 16 2013
|
|
63
|
+
|
|
64
|
+
* Rails 4.0.0
|
|
65
|
+
|
|
66
|
+
## 0.0.4 / January 19 2013
|
|
67
|
+
|
|
68
|
+
* Add messages_type parameter to fluent-logger.yml to specifying
|
|
69
|
+
output messages type 'string' or 'array'. Thanks to davidrenne.
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) 2012 Yoshinori Tahara
|
|
2
|
+
|
|
3
|
+
MIT License
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Act::Fluent::Logger::Rails
|
|
2
|
+
|
|
3
|
+
Fluent logger.
|
|
4
|
+
|
|
5
|
+
## Supported versions
|
|
6
|
+
|
|
7
|
+
* Rails 4 and 5
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
Add this line to your application's Gemfile:
|
|
12
|
+
|
|
13
|
+
gem 'influxdb-logger
|
|
14
|
+
|
|
15
|
+
And then execute:
|
|
16
|
+
|
|
17
|
+
$ bundle
|
|
18
|
+
|
|
19
|
+
Or install it yourself as:
|
|
20
|
+
|
|
21
|
+
$ gem install influxdb-logger
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
in config/environments/production.rb
|
|
26
|
+
|
|
27
|
+
config.log_level = :info
|
|
28
|
+
config.logger = InfluxdbLogger::Logger.
|
|
29
|
+
new(log_tags: {
|
|
30
|
+
ip: :ip,
|
|
31
|
+
ua: :user_agent,
|
|
32
|
+
uid: ->(request) { request.session[:uid] }
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
Don't use config.log_tags.
|
|
36
|
+
|
|
37
|
+
### To define where to send messages to, either:
|
|
38
|
+
|
|
39
|
+
#### create config/fluent-logger.yml
|
|
40
|
+
|
|
41
|
+
development:
|
|
42
|
+
fluent_host: '127.0.0.1'
|
|
43
|
+
fluent_port: 24224
|
|
44
|
+
tag: 'foo'
|
|
45
|
+
messages_type: 'string'
|
|
46
|
+
severity_key: 'level' # default severity
|
|
47
|
+
|
|
48
|
+
test:
|
|
49
|
+
fluent_host: '127.0.0.1'
|
|
50
|
+
fluent_port: 24224
|
|
51
|
+
tag: 'foo'
|
|
52
|
+
messages_type: 'string'
|
|
53
|
+
severity_key: 'level' # default severity
|
|
54
|
+
|
|
55
|
+
production:
|
|
56
|
+
fluent_host: '127.0.0.1'
|
|
57
|
+
fluent_port: 24224
|
|
58
|
+
tag: 'foo'
|
|
59
|
+
messages_type: 'string'
|
|
60
|
+
severity_key: 'level' # default severity
|
|
61
|
+
|
|
62
|
+
#### set an environment variable FLUENTD_URL
|
|
63
|
+
|
|
64
|
+
http://fluentd.example.com:42442/foo?messages_type=string&severity_key=level
|
|
65
|
+
|
|
66
|
+
#### pass a settings object to InfluxdbLogger::Logger.new
|
|
67
|
+
|
|
68
|
+
config.logger = InfluxdbLogger::Logger.
|
|
69
|
+
new(settings: {
|
|
70
|
+
host: '127.0.0.1',
|
|
71
|
+
port: 24224,
|
|
72
|
+
tag: 'foo',
|
|
73
|
+
messages_type: 'string',
|
|
74
|
+
severity_key: 'level'
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
### Setting
|
|
78
|
+
|
|
79
|
+
* fluent_host: The host name of Fluentd.
|
|
80
|
+
* fluent_port: The port number of Fluentd.
|
|
81
|
+
* tag: The tag of the Fluentd event.
|
|
82
|
+
* messages_type: The type of log messages. 'string' or 'array'.
|
|
83
|
+
If it is 'string', the log messages is a String.
|
|
84
|
+
```
|
|
85
|
+
2013-01-18T15:04:50+09:00 foo {"messages":"Started GET \"/\" for 127.0.0.1 at 2013-01-18 15:04:49 +0900\nProcessing by TopController#index as HTML\nCompleted 200 OK in 635ms (Views: 479.3ms | ActiveRecord: 39.6ms)"],"severity":"INFO"}
|
|
86
|
+
```
|
|
87
|
+
If it is 'array', the log messages is an Array.
|
|
88
|
+
```
|
|
89
|
+
2013-01-18T15:04:50+09:00 foo {"messages":["Started GET \"/\" for 127.0.0.1 at 2013-01-18 15:04:49 +0900","Processing by TopController#index as HTML","Completed 200 OK in 635ms (Views: 479.3ms | ActiveRecord: 39.6ms)"],"severity":"INFO"}
|
|
90
|
+
```
|
|
91
|
+
* severity_key: The key of severity(DEBUG, INFO, WARN, ERROR).
|
|
92
|
+
|
|
93
|
+
You can add any tags at run time.
|
|
94
|
+
|
|
95
|
+
logger[:foo] = "foo value"
|
|
96
|
+
|
|
97
|
+
### Usage as a standalone logger
|
|
98
|
+
|
|
99
|
+
Typical usage is as a replacement for the default Rails logger, in which case
|
|
100
|
+
messages are collected and flushed automatically as part of the request
|
|
101
|
+
lifecycle. If you wish to use it instead as a separate logger and log to it
|
|
102
|
+
manually then it is necessary to initialize with the `flush_immediately` flag.
|
|
103
|
+
|
|
104
|
+
```ruby
|
|
105
|
+
InfluxdbLogger::Logger.new(flush_immediately: true)
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
## Contributing
|
|
110
|
+
|
|
111
|
+
1. Fork it
|
|
112
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
113
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
114
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
|
115
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'influxdb-logger/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |gem|
|
|
7
|
+
gem.name = "influxdb-logger"
|
|
8
|
+
gem.version = InfluxdbLogger::VERSION
|
|
9
|
+
gem.authors = ["Rallets"]
|
|
10
|
+
gem.email = ["info@rallets.com"]
|
|
11
|
+
gem.description = %q{Influxdb logger}
|
|
12
|
+
gem.summary = %q{Influxdb logger}
|
|
13
|
+
gem.homepage = "https://github.com/rallets-network/influxdb-logger"
|
|
14
|
+
gem.license = "MIT"
|
|
15
|
+
|
|
16
|
+
gem.files = `git ls-files`.split($/)
|
|
17
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
|
18
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
|
19
|
+
gem.require_paths = ["lib"]
|
|
20
|
+
|
|
21
|
+
gem.add_development_dependency "rspec", '~> 3.5.0'
|
|
22
|
+
gem.add_runtime_dependency "railties", ">= 4", "< 5.3"
|
|
23
|
+
gem.add_runtime_dependency "activesupport", ">= 4", "< 5.3"
|
|
24
|
+
gem.add_runtime_dependency "influxdb", "~> 0.5.3"
|
|
25
|
+
end
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
require 'influxdb'
|
|
2
|
+
require 'active_support/core_ext'
|
|
3
|
+
require 'uri'
|
|
4
|
+
require 'cgi'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Time
|
|
8
|
+
def to_ms
|
|
9
|
+
(self.to_f * 1000.0).to_i
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
module InfluxdbLogger
|
|
14
|
+
|
|
15
|
+
module Logger
|
|
16
|
+
|
|
17
|
+
# Severity label for logging. (max 5 char)
|
|
18
|
+
SEV_LABEL = %w(DEBUG INFO WARN ERROR FATAL ANY)
|
|
19
|
+
|
|
20
|
+
def self.new(log_tags: {}, settings: {}, batch_size: 1000, interval: 1000)
|
|
21
|
+
Rails.application.config.log_tags = log_tags.values
|
|
22
|
+
if Rails.application.config.respond_to?(:action_cable)
|
|
23
|
+
Rails.application.config.action_cable.log_tags = log_tags.values.map do |x|
|
|
24
|
+
case
|
|
25
|
+
when x.respond_to?(:call)
|
|
26
|
+
x
|
|
27
|
+
when x.is_a?(Symbol)
|
|
28
|
+
-> (request) { request.send(x) }
|
|
29
|
+
else
|
|
30
|
+
-> (request) { x }
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
if (0 == settings.length)
|
|
35
|
+
fluent_config = if ENV["FLUENTD_URL"]
|
|
36
|
+
self.parse_url(ENV["FLUENTD_URL"])
|
|
37
|
+
end
|
|
38
|
+
settings = {
|
|
39
|
+
tag: fluent_config['tag'],
|
|
40
|
+
host: fluent_config['fluent_host'],
|
|
41
|
+
port: fluent_config['fluent_port'],
|
|
42
|
+
nanosecond_precision: fluent_config['nanosecond_precision'],
|
|
43
|
+
messages_type: fluent_config['messages_type'],
|
|
44
|
+
severity_key: fluent_config['severity_key'],
|
|
45
|
+
}
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
settings[:batch_size] ||= batch_size
|
|
49
|
+
settings[:interval] ||= interval
|
|
50
|
+
|
|
51
|
+
level = SEV_LABEL.index(Rails.application.config.log_level.to_s.upcase)
|
|
52
|
+
logger = InfluxdbLogger::FluentLogger.new(settings, level, log_tags)
|
|
53
|
+
logger = ActiveSupport::TaggedLogging.new(logger)
|
|
54
|
+
logger.extend self
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def self.parse_url(fluentd_url)
|
|
58
|
+
uri = URI.parse fluentd_url
|
|
59
|
+
params = CGI.parse uri.query
|
|
60
|
+
|
|
61
|
+
{
|
|
62
|
+
fluent_host: uri.host,
|
|
63
|
+
fluent_port: uri.port,
|
|
64
|
+
tag: uri.path[1..-1],
|
|
65
|
+
nanosecond_precision: params['nanosecond_precision'].try(:first),
|
|
66
|
+
messages_type: params['messages_type'].try(:first),
|
|
67
|
+
severity_key: params['severity_key'].try(:first),
|
|
68
|
+
}.stringify_keys
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def tagged(*tags)
|
|
72
|
+
@tags = tags.flatten
|
|
73
|
+
yield self
|
|
74
|
+
ensure
|
|
75
|
+
flush
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
class FluentLogger < ActiveSupport::Logger
|
|
80
|
+
def initialize(options, level, log_tags)
|
|
81
|
+
self.level = level
|
|
82
|
+
@messages_type = (options[:messages_type] || :array).to_sym
|
|
83
|
+
@tag = options[:tag]
|
|
84
|
+
@severity_key = (options[:severity_key] || :severity).to_sym
|
|
85
|
+
@batch_size = options[:batch_size]
|
|
86
|
+
@interval = options[:interval]
|
|
87
|
+
@series = options[:series]
|
|
88
|
+
@global_tags = {}
|
|
89
|
+
@last_flush_time = Time.now.to_ms
|
|
90
|
+
@value_filter = options[:value_filter] || {}
|
|
91
|
+
|
|
92
|
+
@influxdb_logger = InfluxDB::Client.new(
|
|
93
|
+
host: options[:host],
|
|
94
|
+
database: options[:database],
|
|
95
|
+
retry: options[:retry],
|
|
96
|
+
username: options[:username],
|
|
97
|
+
password: options[:password],
|
|
98
|
+
time_precision: options[:time_precision]
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
@severity = 0
|
|
102
|
+
@messages = []
|
|
103
|
+
@log_tags = log_tags
|
|
104
|
+
after_initialize if respond_to? :after_initialize
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def [](key)
|
|
108
|
+
@global_tags[key]
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def []=(key, value)
|
|
112
|
+
@global_tags[key] = value
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def add(severity, message = nil, progname = nil, &block)
|
|
116
|
+
return true if severity < level
|
|
117
|
+
message = (block_given? ? block.call : progname) if message.blank?
|
|
118
|
+
return true if message.blank?
|
|
119
|
+
add_message(severity, message)
|
|
120
|
+
true
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def utf8_encoded(message)
|
|
124
|
+
if message.encoding == Encoding::UTF_8
|
|
125
|
+
message
|
|
126
|
+
else
|
|
127
|
+
message.dup.force_encoding(Encoding::UTF_8)
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def add_message(severity, message)
|
|
132
|
+
@severity = severity if @severity < severity
|
|
133
|
+
|
|
134
|
+
values =
|
|
135
|
+
case message
|
|
136
|
+
when ::String
|
|
137
|
+
{
|
|
138
|
+
message_type: 'String',
|
|
139
|
+
message: utf8_encoded(message)
|
|
140
|
+
}
|
|
141
|
+
when ::Hash
|
|
142
|
+
message.slice!(*@value_filter[:only]) if @value_filter[:only].present?
|
|
143
|
+
message.except!(*@value_filter[:except]) if @value_filter[:except].present?
|
|
144
|
+
message.merge({
|
|
145
|
+
message_type: 'Hash'
|
|
146
|
+
})
|
|
147
|
+
when ::Exception
|
|
148
|
+
{
|
|
149
|
+
message_type: 'Exception',
|
|
150
|
+
message: message.message,
|
|
151
|
+
class: message.class,
|
|
152
|
+
backtrace: message.backtrace
|
|
153
|
+
}
|
|
154
|
+
else
|
|
155
|
+
{
|
|
156
|
+
message_type: 'Others',
|
|
157
|
+
message: message.inspect
|
|
158
|
+
}
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
tags = @global_tags.clone
|
|
162
|
+
|
|
163
|
+
if @tags
|
|
164
|
+
@log_tags.keys.zip(@tags).each do |k, v|
|
|
165
|
+
tags[k] = v
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
message = {
|
|
170
|
+
series: @series,
|
|
171
|
+
timestamp: Time.now.to_ms,
|
|
172
|
+
tags: tags,
|
|
173
|
+
values: values.merge({
|
|
174
|
+
severity: format_severity(@severity)
|
|
175
|
+
}).transform_values {|value|
|
|
176
|
+
case value
|
|
177
|
+
when ::Numeric, ::String
|
|
178
|
+
value
|
|
179
|
+
when ::Hash
|
|
180
|
+
value.to_json
|
|
181
|
+
when ::Symbol
|
|
182
|
+
value.to_s
|
|
183
|
+
else
|
|
184
|
+
value.inspect
|
|
185
|
+
end
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
@messages << message
|
|
190
|
+
flush if @messages.size >= @batch_size || (Time.now.to_ms - @last_flush_time) > @interval
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def flush
|
|
194
|
+
return if @messages.empty?
|
|
195
|
+
# test switch
|
|
196
|
+
# open("#{Rails.root}/log/my.log", 'w') { |f|
|
|
197
|
+
# f.puts @messages
|
|
198
|
+
# }
|
|
199
|
+
@influxdb_logger.write_points(@messages)
|
|
200
|
+
@severity = 0
|
|
201
|
+
@messages.clear
|
|
202
|
+
@last_flush_time = Time.now.to_ms
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def close
|
|
206
|
+
# @fluent_logger.close
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
def level
|
|
210
|
+
@level
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def level=(l)
|
|
214
|
+
@level = l
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def format_severity(severity)
|
|
218
|
+
InfluxdbLogger::Logger::SEV_LABEL[severity] || 'ANY'
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
|
data/spec/logger_spec.rb
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'tempfile'
|
|
3
|
+
|
|
4
|
+
class Time
|
|
5
|
+
def to_ms # for convenience of comparing timestamps
|
|
6
|
+
(self.to_f * 1000.0).to_i
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
describe InfluxdbLogger::Logger do
|
|
11
|
+
before do
|
|
12
|
+
stub_const('Rails', Class.new) unless defined?(Rails)
|
|
13
|
+
allow(Rails).to receive(:env).and_return('test')
|
|
14
|
+
allow(Rails).to receive_message_chain(:application, :config, :log_level).and_return(:debug)
|
|
15
|
+
allow(Rails).to receive_message_chain(:application, :config, :log_tags=)
|
|
16
|
+
|
|
17
|
+
class MyLogger
|
|
18
|
+
attr_accessor :log
|
|
19
|
+
def post(tag, map)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def clear
|
|
23
|
+
@log.clear
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def close
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def write_point(point)
|
|
30
|
+
@log ||= []
|
|
31
|
+
@log << point
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def write_points(points)
|
|
35
|
+
@log ||= []
|
|
36
|
+
@log.concat(points)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
@my_logger = MyLogger.new
|
|
40
|
+
allow(InfluxDB::Client).to receive(:new).and_return(@my_logger)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
let(:series) { 'Request' }
|
|
44
|
+
|
|
45
|
+
let(:log_tags) {
|
|
46
|
+
{
|
|
47
|
+
uuid: :uuid,
|
|
48
|
+
foo: ->(request) { 'foo_value' }
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
let(:settings) {
|
|
53
|
+
{
|
|
54
|
+
host: 'influxdb',
|
|
55
|
+
database: 'rallets',
|
|
56
|
+
series: series,
|
|
57
|
+
retry: 3,
|
|
58
|
+
username: 'user',
|
|
59
|
+
password: 'password',
|
|
60
|
+
time_precision: 'ms'
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
let(:logger) {
|
|
65
|
+
InfluxdbLogger::Logger.new(log_tags: log_tags, settings: settings)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
let(:request) {
|
|
69
|
+
double('request', uuid: 'uuid_value')
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
describe 'logging' do
|
|
73
|
+
|
|
74
|
+
describe 'basic' do
|
|
75
|
+
it 'info' do
|
|
76
|
+
# see Rails::Rack::compute_tags
|
|
77
|
+
tags = log_tags.values.collect do |tag|
|
|
78
|
+
case tag
|
|
79
|
+
when Proc
|
|
80
|
+
tag.call(request)
|
|
81
|
+
when Symbol
|
|
82
|
+
request.send(tag)
|
|
83
|
+
else
|
|
84
|
+
tag
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
logger[:abc] = 'xyz'
|
|
88
|
+
logger.tagged(tags) { logger.info('hello') }
|
|
89
|
+
expect(@my_logger.log).to eq(
|
|
90
|
+
[{
|
|
91
|
+
series: series,
|
|
92
|
+
timestamp: Time.now.to_ms,
|
|
93
|
+
tags: {
|
|
94
|
+
abc: 'xyz',
|
|
95
|
+
uuid: 'uuid_value',
|
|
96
|
+
foo: 'foo_value'
|
|
97
|
+
},
|
|
98
|
+
values: {
|
|
99
|
+
message_type: 'String',
|
|
100
|
+
message: 'hello',
|
|
101
|
+
severity: 'INFO'
|
|
102
|
+
}
|
|
103
|
+
}])
|
|
104
|
+
@my_logger.clear
|
|
105
|
+
logger.tagged(tags) { logger.info('world'); logger.info('bye') }
|
|
106
|
+
expect(@my_logger.log).to eq(
|
|
107
|
+
[{
|
|
108
|
+
series: series,
|
|
109
|
+
timestamp: Time.now.to_ms,
|
|
110
|
+
tags: {
|
|
111
|
+
abc: 'xyz',
|
|
112
|
+
uuid: 'uuid_value',
|
|
113
|
+
foo: 'foo_value'
|
|
114
|
+
},
|
|
115
|
+
values: {
|
|
116
|
+
message_type: 'String',
|
|
117
|
+
message: 'world',
|
|
118
|
+
severity: 'INFO'
|
|
119
|
+
}
|
|
120
|
+
}, {
|
|
121
|
+
series: series,
|
|
122
|
+
timestamp: Time.now.to_ms,
|
|
123
|
+
tags: {
|
|
124
|
+
abc: 'xyz',
|
|
125
|
+
uuid: 'uuid_value',
|
|
126
|
+
foo: 'foo_value'
|
|
127
|
+
},
|
|
128
|
+
values: {
|
|
129
|
+
message_type: 'String',
|
|
130
|
+
message: 'bye',
|
|
131
|
+
severity: 'INFO'
|
|
132
|
+
}
|
|
133
|
+
}])
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
describe 'frozen ascii-8bit string' do
|
|
138
|
+
before do
|
|
139
|
+
logger.instance_variable_set(:@messages_type, :string)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
after do
|
|
143
|
+
logger.instance_variable_set(:@messages_type, :array)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
it 'join messages' do
|
|
147
|
+
ascii = "\xe8\x8a\xb1".force_encoding('ascii-8bit').freeze
|
|
148
|
+
logger.tagged([request]) {
|
|
149
|
+
logger.info(ascii)
|
|
150
|
+
logger.info('咲く')
|
|
151
|
+
}
|
|
152
|
+
expect(@my_logger.log[0][:values][:message]).to eq("花")
|
|
153
|
+
expect(@my_logger.log[1][:values][:message]).to eq("咲く")
|
|
154
|
+
expect(ascii.encoding).to eq(Encoding::ASCII_8BIT)
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
describe 'Exception' do
|
|
159
|
+
it 'output message, class, backtrace' do
|
|
160
|
+
begin
|
|
161
|
+
3 / 0
|
|
162
|
+
rescue => e
|
|
163
|
+
logger.tagged([request]) {
|
|
164
|
+
logger.error(e)
|
|
165
|
+
}
|
|
166
|
+
expect(@my_logger.log[0][:values][:message]).to eq("divided by 0")
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
describe 'Object' do
|
|
172
|
+
it 'output inspect' do
|
|
173
|
+
x = Object.new
|
|
174
|
+
logger.tagged([request]) {
|
|
175
|
+
logger.info(x)
|
|
176
|
+
}
|
|
177
|
+
expect(@my_logger.log[0][:values][:message]).to eq(x.inspect)
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
describe "use ENV['FLUENTD_URL']" do
|
|
183
|
+
let(:fluentd_url) { "http://fluentd.example.com:42442/hoge?messages_type=string&severity_key=level" }
|
|
184
|
+
|
|
185
|
+
describe ".parse_url" do
|
|
186
|
+
subject { described_class.parse_url(fluentd_url) }
|
|
187
|
+
it { expect(subject['tag']).to eq 'hoge' }
|
|
188
|
+
it { expect(subject['fluent_host']).to eq 'fluentd.example.com' }
|
|
189
|
+
it { expect(subject['fluent_port']).to eq 42442 }
|
|
190
|
+
it { expect(subject['messages_type']).to eq 'string' }
|
|
191
|
+
it { expect(subject['severity_key']).to eq 'level' }
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
describe 'batch size' do
|
|
196
|
+
it 'works well with batch size' do
|
|
197
|
+
# logger = InfluxdbLogger::Logger.new(settings: settings, batch_size: 2))
|
|
198
|
+
# logger.info('Immediately!')
|
|
199
|
+
# expect(@my_logger.log).to eq(nil)
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
|
3
|
+
|
|
4
|
+
require 'active_support'
|
|
5
|
+
require 'active_support/deprecation'
|
|
6
|
+
require 'active_support/core_ext/module'
|
|
7
|
+
require 'active_support/logger'
|
|
8
|
+
require 'active_support/tagged_logging'
|
|
9
|
+
require 'yaml'
|
|
10
|
+
require 'influxdb-logger/logger'
|
metadata
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: influxdb-logger
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Rallets
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2018-05-25 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: rspec
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: 3.5.0
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: 3.5.0
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: railties
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '4'
|
|
34
|
+
- - "<"
|
|
35
|
+
- !ruby/object:Gem::Version
|
|
36
|
+
version: '5.3'
|
|
37
|
+
type: :runtime
|
|
38
|
+
prerelease: false
|
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
40
|
+
requirements:
|
|
41
|
+
- - ">="
|
|
42
|
+
- !ruby/object:Gem::Version
|
|
43
|
+
version: '4'
|
|
44
|
+
- - "<"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '5.3'
|
|
47
|
+
- !ruby/object:Gem::Dependency
|
|
48
|
+
name: activesupport
|
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '4'
|
|
54
|
+
- - "<"
|
|
55
|
+
- !ruby/object:Gem::Version
|
|
56
|
+
version: '5.3'
|
|
57
|
+
type: :runtime
|
|
58
|
+
prerelease: false
|
|
59
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
60
|
+
requirements:
|
|
61
|
+
- - ">="
|
|
62
|
+
- !ruby/object:Gem::Version
|
|
63
|
+
version: '4'
|
|
64
|
+
- - "<"
|
|
65
|
+
- !ruby/object:Gem::Version
|
|
66
|
+
version: '5.3'
|
|
67
|
+
- !ruby/object:Gem::Dependency
|
|
68
|
+
name: influxdb
|
|
69
|
+
requirement: !ruby/object:Gem::Requirement
|
|
70
|
+
requirements:
|
|
71
|
+
- - "~>"
|
|
72
|
+
- !ruby/object:Gem::Version
|
|
73
|
+
version: 0.5.3
|
|
74
|
+
type: :runtime
|
|
75
|
+
prerelease: false
|
|
76
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
77
|
+
requirements:
|
|
78
|
+
- - "~>"
|
|
79
|
+
- !ruby/object:Gem::Version
|
|
80
|
+
version: 0.5.3
|
|
81
|
+
description: Influxdb logger
|
|
82
|
+
email:
|
|
83
|
+
- info@rallets.com
|
|
84
|
+
executables: []
|
|
85
|
+
extensions: []
|
|
86
|
+
extra_rdoc_files: []
|
|
87
|
+
files:
|
|
88
|
+
- ".gitignore"
|
|
89
|
+
- ".travis.yml"
|
|
90
|
+
- Appraisals
|
|
91
|
+
- CHANGELOG.md
|
|
92
|
+
- Gemfile
|
|
93
|
+
- LICENSE.txt
|
|
94
|
+
- README.md
|
|
95
|
+
- Rakefile
|
|
96
|
+
- gemfiles/rails_4.0.gemfile
|
|
97
|
+
- gemfiles/rails_4.1.gemfile
|
|
98
|
+
- gemfiles/rails_4.2.gemfile
|
|
99
|
+
- gemfiles/rails_5.0.gemfile
|
|
100
|
+
- gemfiles/rails_5.1.gemfile
|
|
101
|
+
- gemfiles/rails_5.2.gemfile
|
|
102
|
+
- influxdb-logger.gemspec
|
|
103
|
+
- lib/influxdb-logger.rb
|
|
104
|
+
- lib/influxdb-logger/logger.rb
|
|
105
|
+
- lib/influxdb-logger/version.rb
|
|
106
|
+
- spec/logger_spec.rb
|
|
107
|
+
- spec/spec_helper.rb
|
|
108
|
+
homepage: https://github.com/rallets-network/influxdb-logger
|
|
109
|
+
licenses:
|
|
110
|
+
- MIT
|
|
111
|
+
metadata: {}
|
|
112
|
+
post_install_message:
|
|
113
|
+
rdoc_options: []
|
|
114
|
+
require_paths:
|
|
115
|
+
- lib
|
|
116
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
117
|
+
requirements:
|
|
118
|
+
- - ">="
|
|
119
|
+
- !ruby/object:Gem::Version
|
|
120
|
+
version: '0'
|
|
121
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
122
|
+
requirements:
|
|
123
|
+
- - ">="
|
|
124
|
+
- !ruby/object:Gem::Version
|
|
125
|
+
version: '0'
|
|
126
|
+
requirements: []
|
|
127
|
+
rubyforge_project:
|
|
128
|
+
rubygems_version: 2.6.14
|
|
129
|
+
signing_key:
|
|
130
|
+
specification_version: 4
|
|
131
|
+
summary: Influxdb logger
|
|
132
|
+
test_files:
|
|
133
|
+
- spec/logger_spec.rb
|
|
134
|
+
- spec/spec_helper.rb
|