nav-logger 0.0.1 → 0.0.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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/README.md +19 -4
- data/lib/nav/logger.rb +11 -0
- data/lib/nav/logger/base_logger.rb +25 -11
- data/lib/nav/logger/console_logger.rb +40 -0
- data/lib/nav/logger/file_logger.rb +11 -0
- data/lib/nav/logger/httparty_formatter.rb +88 -0
- data/lib/nav/logger/middleware/request_logger.rb +53 -0
- data/lib/nav/logger/middleware/request_tagger.rb +36 -0
- data/lib/nav/logger/rails/logger_tie.rb +27 -0
- data/lib/nav/logger/version.rb +1 -1
- data/nav-logger.gemspec +1 -1
- metadata +12 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: efbd45d44835cf65d532397c25413d30ef449ca6
|
4
|
+
data.tar.gz: 824873b52dde3b536f20c0f9c06fa97fa0cd8074
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 32822765b8bde721698481db10e2f035305b0578d9d447972ee8ae6614553cc57ea394e888bd73212aa6134f528949e82f7c0f26aee982742cd2fb34b2fd95ff
|
7
|
+
data.tar.gz: f176b7ab2fc284f8a4b6498c1f14b9d70642c1649c04640793bf7023b1338036ee0f4f4b932f0060fc4d1065b2fc0e1cd8aab8c976116877c397b47ef9043474
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -12,15 +12,31 @@ gem "nav-logger"
|
|
12
12
|
|
13
13
|
And then execute:
|
14
14
|
|
15
|
-
|
15
|
+
`$ bundle`
|
16
16
|
|
17
17
|
Or install it yourself as:
|
18
18
|
|
19
|
-
|
19
|
+
`$ gem install nav-logger`
|
20
20
|
|
21
21
|
## Usage
|
22
22
|
|
23
|
-
|
23
|
+
#### Rails
|
24
|
+
|
25
|
+
If you only want to tag your Rails logs with request and session ids, you just need to include the gem in your gemfile.
|
26
|
+
|
27
|
+
If you also want logs being sent to the aggregator, you need add the following to the application.rb:
|
28
|
+
```ruby
|
29
|
+
config.middleware.use Nav::Logger::RequestLogger
|
30
|
+
```
|
31
|
+
|
32
|
+
#### Rack
|
33
|
+
|
34
|
+
After installing gem into rack app, add in the config.ru
|
35
|
+
```ruby
|
36
|
+
use Nav::Logger::Middleware::RequestTagger
|
37
|
+
use Nav::Logger::Middleware::RequestLogger
|
38
|
+
```
|
39
|
+
_Make sure RequestTagger comes before RequestLogger_
|
24
40
|
|
25
41
|
## Development
|
26
42
|
|
@@ -36,4 +52,3 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/credit
|
|
36
52
|
## License
|
37
53
|
|
38
54
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
39
|
-
|
data/lib/nav/logger.rb
CHANGED
@@ -6,9 +6,14 @@ require "socket"
|
|
6
6
|
require "nav/logger/base_logger"
|
7
7
|
require "nav/logger/console_logger"
|
8
8
|
require "nav/logger/default_logger"
|
9
|
+
require "nav/logger/httparty_formatter"
|
10
|
+
require "nav/logger/middleware/request_logger"
|
11
|
+
require "nav/logger/middleware/request_tagger"
|
9
12
|
require "nav/logger/test_logger"
|
10
13
|
require "nav/logger/version"
|
11
14
|
|
15
|
+
require "nav/logger/rails/logger_tie" if defined?(::Rails)
|
16
|
+
|
12
17
|
module Nav
|
13
18
|
module_function
|
14
19
|
|
@@ -33,3 +38,9 @@ module Nav
|
|
33
38
|
end
|
34
39
|
end
|
35
40
|
end
|
41
|
+
|
42
|
+
if defined? HTTParty
|
43
|
+
HTTParty::Logger.add_formatter :nav, Nav::Logger::HTTPartyFormatter
|
44
|
+
#HTTParty.logger Nav.logger, :debug, :nav
|
45
|
+
#HTTParty.headers "X-Request-Id" => RequestStore[:request_id]
|
46
|
+
end
|
@@ -4,7 +4,9 @@ module Nav
|
|
4
4
|
attr_reader :fluent_logger
|
5
5
|
|
6
6
|
def level
|
7
|
-
@level
|
7
|
+
return @level if defined? @level
|
8
|
+
self.level = ENV["LOG_LEVEL"] || "info"
|
9
|
+
@level
|
8
10
|
end
|
9
11
|
|
10
12
|
def level_name(lookup = level)
|
@@ -44,6 +46,15 @@ module Nav
|
|
44
46
|
add ::Logger::FATAL, message, hash
|
45
47
|
end
|
46
48
|
|
49
|
+
def post(tag, hash)
|
50
|
+
full_hash = generate_log_hash hash
|
51
|
+
@fluent_logger.post tag, full_hash
|
52
|
+
end
|
53
|
+
|
54
|
+
def log_tag(secondary_tag)
|
55
|
+
[app_tag, secondary_tag.downcase].compact.join "."
|
56
|
+
end
|
57
|
+
|
47
58
|
private
|
48
59
|
|
49
60
|
def add(severity, message, hash)
|
@@ -51,8 +62,13 @@ module Nav
|
|
51
62
|
return true if severity < level
|
52
63
|
|
53
64
|
severity_name = level_name severity
|
54
|
-
|
55
|
-
|
65
|
+
|
66
|
+
hash[:level] = severity_name
|
67
|
+
hash[:message] = message
|
68
|
+
|
69
|
+
log_hash = generate_log_hash hash
|
70
|
+
|
71
|
+
@fluent_logger.post log_tag(severity_name), log_hash
|
56
72
|
end
|
57
73
|
|
58
74
|
def app_tag
|
@@ -68,18 +84,16 @@ module Nav
|
|
68
84
|
@hostname ||= Socket.gethostname
|
69
85
|
end
|
70
86
|
|
71
|
-
def generate_log_hash(
|
87
|
+
def generate_log_hash(input = {})
|
72
88
|
hash = input.merge RequestStore.store
|
73
|
-
hash.merge!
|
74
|
-
level: severity,
|
75
|
-
ts: Time.now.to_f,
|
89
|
+
hash.merge! ts: Time.now.to_f,
|
76
90
|
environment: environment,
|
77
|
-
hostname: hostname
|
78
|
-
|
91
|
+
hostname: hostname,
|
92
|
+
pid: pid
|
79
93
|
end
|
80
94
|
|
81
|
-
def
|
82
|
-
|
95
|
+
def pid
|
96
|
+
@pid ||= Process.pid
|
83
97
|
end
|
84
98
|
end
|
85
99
|
end
|
@@ -1,8 +1,48 @@
|
|
1
1
|
module Nav
|
2
2
|
module Logger
|
3
3
|
class ConsoleLogger < BaseLogger
|
4
|
+
# Mapping of color/style names to ANSI control values
|
5
|
+
CODEMAP = {
|
6
|
+
normal: 0,
|
7
|
+
bold: 1,
|
8
|
+
black: 30,
|
9
|
+
red: 31,
|
10
|
+
green: 32,
|
11
|
+
yellow: 33,
|
12
|
+
blue: 34,
|
13
|
+
magenta: 35,
|
14
|
+
cyan: 36,
|
15
|
+
white: 37
|
16
|
+
}
|
17
|
+
|
18
|
+
# Map of log levels to colors
|
19
|
+
LEVELMAP = {
|
20
|
+
"FATAL" => :red,
|
21
|
+
"ERROR" => :red,
|
22
|
+
"WARN" => :yellow,
|
23
|
+
"INFO" => :green, # default color
|
24
|
+
"DEBUG" => :cyan
|
25
|
+
}
|
26
|
+
|
4
27
|
def initialize
|
5
28
|
@fluent_logger = Fluent::Logger::ConsoleLogger.open STDOUT
|
29
|
+
|
30
|
+
# Adds colorized loigging
|
31
|
+
def @fluent_logger.post_with_time(tag, map, time)
|
32
|
+
a = [time.strftime(@time_format), " ", tag, ":"]
|
33
|
+
map.each_pair { |k,v|
|
34
|
+
a << " #{k}="
|
35
|
+
a << JSON.dump(v)
|
36
|
+
}
|
37
|
+
|
38
|
+
color = LEVELMAP[map[:level]] || :green
|
39
|
+
|
40
|
+
a.unshift "\e[#{CODEMAP[color]}m"
|
41
|
+
a << "\e[#{CODEMAP[:normal]}m"
|
42
|
+
|
43
|
+
post_text a.join
|
44
|
+
true
|
45
|
+
end
|
6
46
|
end
|
7
47
|
end
|
8
48
|
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module Nav
|
2
|
+
module Logger
|
3
|
+
class HTTPartyFormatter
|
4
|
+
OUT = ">".freeze
|
5
|
+
IN = "<".freeze
|
6
|
+
|
7
|
+
attr_accessor :level, :logger
|
8
|
+
|
9
|
+
def initialize(logger, level)
|
10
|
+
@logger = logger
|
11
|
+
@level = level.to_sym
|
12
|
+
@messages = []
|
13
|
+
end
|
14
|
+
|
15
|
+
def format(request, response)
|
16
|
+
@request = request
|
17
|
+
@response = response
|
18
|
+
|
19
|
+
library_line = caller.detect{ |line| line !~ /httparty/ }
|
20
|
+
|
21
|
+
log_request
|
22
|
+
log_response
|
23
|
+
|
24
|
+
logger.send level, messages.join("\n"), caller: library_line
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
attr_reader :request, :response
|
30
|
+
attr_accessor :messages
|
31
|
+
|
32
|
+
def log_request
|
33
|
+
log_url
|
34
|
+
log_headers
|
35
|
+
log_query
|
36
|
+
log OUT, request.raw_body if request.raw_body
|
37
|
+
log OUT
|
38
|
+
end
|
39
|
+
|
40
|
+
def log_response
|
41
|
+
log IN, "HTTP/#{response.http_version} #{response.code}"
|
42
|
+
log_response_headers
|
43
|
+
log IN, "\n#{response.body}"
|
44
|
+
log IN
|
45
|
+
end
|
46
|
+
|
47
|
+
def log_url
|
48
|
+
http_method = request.http_method.name.split("::").last.upcase
|
49
|
+
uri = if request.options[:base_uri]
|
50
|
+
request.options[:base_uri] + request.path.path
|
51
|
+
else
|
52
|
+
request.path.to_s
|
53
|
+
end
|
54
|
+
|
55
|
+
log OUT, "#{http_method} #{uri}"
|
56
|
+
end
|
57
|
+
|
58
|
+
def log_headers
|
59
|
+
return unless request.options[:headers] && request.options[:headers].size > 0
|
60
|
+
|
61
|
+
log OUT, "Headers: "
|
62
|
+
log_hash request.options[:headers]
|
63
|
+
end
|
64
|
+
|
65
|
+
def log_query
|
66
|
+
return unless request.options[:query]
|
67
|
+
|
68
|
+
log OUT, "Query: "
|
69
|
+
log_hash request.options[:query]
|
70
|
+
end
|
71
|
+
|
72
|
+
def log_response_headers
|
73
|
+
headers = response.respond_to?(:headers) ? response.headers : response
|
74
|
+
response.each_header do |response_header|
|
75
|
+
log IN, "#{response_header.capitalize}: #{headers[response_header]}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def log_hash(hash)
|
80
|
+
hash.each { |k, v| log(OUT, "#{k}: #{v}") }
|
81
|
+
end
|
82
|
+
|
83
|
+
def log(direction, line = "")
|
84
|
+
messages << "#{direction} #{line}"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Nav
|
2
|
+
module Logger
|
3
|
+
module Middleware
|
4
|
+
class RequestLogger
|
5
|
+
|
6
|
+
def initialize(app)
|
7
|
+
@app = app
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
start_time = Time.now
|
12
|
+
status, headers, body = @app.call env
|
13
|
+
[status, headers, [body]]
|
14
|
+
ensure
|
15
|
+
log_request start_time, env, status, headers
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
def log_request(start_time, env, status, headers)
|
20
|
+
rack_log_hash = {
|
21
|
+
remote_addr: env["HTTP_X_FORWARDED_FOR"] || env["REMOTE_ADDR"] || "-",
|
22
|
+
remote_user: env["REMOTE_USER"] || "-",
|
23
|
+
request_method: env[Rack::REQUEST_METHOD],
|
24
|
+
request_path: env[Rack::PATH_INFO],
|
25
|
+
query_string: env[Rack::QUERY_STRING].empty? ? "" : "?#{env[Rack::QUERY_STRING]}",
|
26
|
+
status: status.to_s[0..3],
|
27
|
+
content_length: extract_content_length(headers),
|
28
|
+
duration: Time.now - start_time,
|
29
|
+
level: status_level(status)
|
30
|
+
}
|
31
|
+
tag = Nav.logger.log_tag "http"
|
32
|
+
Nav.logger.post tag, rack_log_hash
|
33
|
+
end
|
34
|
+
|
35
|
+
def status_level(status)
|
36
|
+
return "ERROR" if status.nil?
|
37
|
+
case status.to_i
|
38
|
+
when 400..499 then "WARN"
|
39
|
+
when 500..599 then "ERROR"
|
40
|
+
else "INFO"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def extract_content_length(headers)
|
45
|
+
return "-" if headers.nil?
|
46
|
+
value = headers[Rack::CONTENT_LENGTH] or return "-"
|
47
|
+
value.to_s == "0" ? "-" : value
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Nav
|
2
|
+
module Logger
|
3
|
+
module Middleware
|
4
|
+
class RequestTagger
|
5
|
+
|
6
|
+
def initialize(app)
|
7
|
+
@app = app
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
setup_request_store
|
12
|
+
store_request_var env
|
13
|
+
@app.call env
|
14
|
+
ensure
|
15
|
+
clear_request_store
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
def setup_request_store
|
20
|
+
RequestStore.begin!
|
21
|
+
end
|
22
|
+
|
23
|
+
def store_request_var(env)
|
24
|
+
RequestStore[:request_id] = env["HTTP_X_REQUEST_ID"] || SecureRandom.uuid
|
25
|
+
RequestStore[:session_id] = env["HTTP_X_SESSION_ID"] if env.key? "HTTP_X_SESSION_ID"
|
26
|
+
end
|
27
|
+
|
28
|
+
def clear_request_store
|
29
|
+
RequestStore.end!
|
30
|
+
RequestStore.clear!
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Nav
|
2
|
+
module Logger
|
3
|
+
module Rails
|
4
|
+
class LoggerTie < ::Rails::Railtie
|
5
|
+
initializer "logger_tie.configure_rails_initialization" do |app|
|
6
|
+
|
7
|
+
# We add the request id and session it from the RequestStore as tags
|
8
|
+
# on all Rails logs.
|
9
|
+
app.config.log_tags ||= []
|
10
|
+
app.config.log_tags << lambda { |_arg| RequestStore[:request_id] }
|
11
|
+
app.config.log_tags << lambda { |_arg| RequestStore[:session_id] }
|
12
|
+
|
13
|
+
# We insert the nav logger middleware into the middleware stack. We
|
14
|
+
# need to insert it before the Rails::Rack::Logger, since that is when
|
15
|
+
# the tag lambdas get executed. If the Nav Logger middleware hasn't
|
16
|
+
# already been run the request store will be empty and the lambdas
|
17
|
+
# will come back nil.
|
18
|
+
app.config.middleware.insert_before(
|
19
|
+
::Rails::Rack::Logger,
|
20
|
+
Nav::Logger::Middleware::RequestTagger
|
21
|
+
)
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/nav/logger/version.rb
CHANGED
data/nav-logger.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nav-logger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- JohnnyT
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-07-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fluent-logger
|
@@ -28,16 +28,16 @@ dependencies:
|
|
28
28
|
name: request_store
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 1.3.2
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 1.3.2
|
41
41
|
description:
|
42
42
|
email:
|
43
43
|
- ubergeek3141@gmail.com
|
@@ -63,6 +63,11 @@ files:
|
|
63
63
|
- lib/nav/logger/base_logger.rb
|
64
64
|
- lib/nav/logger/console_logger.rb
|
65
65
|
- lib/nav/logger/default_logger.rb
|
66
|
+
- lib/nav/logger/file_logger.rb
|
67
|
+
- lib/nav/logger/httparty_formatter.rb
|
68
|
+
- lib/nav/logger/middleware/request_logger.rb
|
69
|
+
- lib/nav/logger/middleware/request_tagger.rb
|
70
|
+
- lib/nav/logger/rails/logger_tie.rb
|
66
71
|
- lib/nav/logger/test_logger.rb
|
67
72
|
- lib/nav/logger/version.rb
|
68
73
|
- nav-logger.gemspec
|
@@ -86,9 +91,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
86
91
|
version: '0'
|
87
92
|
requirements: []
|
88
93
|
rubyforge_project:
|
89
|
-
rubygems_version: 2.5.
|
94
|
+
rubygems_version: 2.5.2
|
90
95
|
signing_key:
|
91
96
|
specification_version: 4
|
92
97
|
summary: Nav's logger
|
93
98
|
test_files: []
|
94
|
-
has_rdoc:
|