access_watch_rails 0.0.6 → 0.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ec42186c8a728f3a04d8fa0b85fdb4df23f27892
4
- data.tar.gz: 9118ed191885c051045da51a7be4548a1bd690ca
3
+ metadata.gz: 0c771a0d72ea5fd1d9abef9afa700e8fd2d0ca14
4
+ data.tar.gz: 2508fb05f8192b23daeba64d5ec79c0836462cc7
5
5
  SHA512:
6
- metadata.gz: 3c40c872317c68826f764175e11d4f423b51e5d74997bed979a76cccdbe817a136a8d01e682a39b859e416a7f6870829abd56709db414fb92946f2e1fb1dcb7c
7
- data.tar.gz: b6848a5bfe04c744fa5cbd2ea47f27971f5804bb0caa1b56c16c04e7593cc3aed0a3574ddf3495786f868a1b1d9ec4535d529cf33b0cf57930539416f8ebae38
6
+ metadata.gz: 4bc134a59d2196038d4a2c6818832f6d7635f63943870e60ded809a54ab7f9a2d868af031ecc204de7a6a639275ad967127fe8eee331ba77df0ac0b520a6c9a8
7
+ data.tar.gz: 5a933d609219a04bb6c605972b24b92e61d1120298e6b18140338706b51fd402d67e4a9c18cab38c49a202571f978f1975022f09c169fd1d011395277821ee93
data/README.md CHANGED
@@ -14,12 +14,20 @@ You will need an API key.
14
14
 
15
15
  To get an API key, send us an email at api@access.watch and we will come back to you.
16
16
 
17
- Then add the following `after_action` callback in your `ApplicationController`.
17
+ Then create the following file `config/access_watch.yml` and restart/deploy your app.
18
+
19
+ ```yaml
20
+ development:
21
+ api_key: API_KEY
22
+
23
+ production:
24
+ api_key: API_KEY
25
+ ```
26
+
27
+ Or if you prefere add the following line in `config/application.rb` and restart/deploy your app.
18
28
 
19
29
  ```ruby
20
- class ApplicationController < ActionController::Base
21
- after_action { AccessWatch::Logger.new(api_key: API_KEY).record(request, response) }
22
- end
30
+ config.middleware.use "AccessWatch::RackLogger", api_key: API_KEY
23
31
  ```
24
32
 
25
33
  API documentation is here: https://access.watch/api-documentation/#request-logging
@@ -31,5 +31,5 @@ Gem::Specification.new do |spec|
31
31
 
32
32
  spec.add_development_dependency "bundler", "~> 1.13"
33
33
  spec.add_development_dependency "rake", "~> 10.0"
34
- spec.add_dependency "access_watch", ">= 0.0.3"
34
+ spec.add_dependency "access_watch", ">= 0.0.5"
35
35
  end
@@ -10,7 +10,6 @@ module AccessWatch
10
10
  post_request(
11
11
  time: Time.now.utc,
12
12
  address: request.remote_ip,
13
- host: request.host,
14
13
  request: {
15
14
  protocol: request.headers["Version"],
16
15
  method: request.method,
@@ -21,6 +20,7 @@ module AccessWatch
21
20
  headers: extract_http_headers(request.headers)
22
21
  },
23
22
  response: {status: response.status},
23
+ context: {memory_usage: memory_usage_in_bytes},
24
24
  )
25
25
  end
26
26
 
@@ -50,5 +50,27 @@ module AccessWatch
50
50
  def post_async(path, data)
51
51
  Thread.new { client.post(path, data) }
52
52
  end
53
+
54
+ def memory_usage_in_bytes
55
+ linux_process_memory_usage_in_bytes(Process.pid)
56
+ end
57
+
58
+ def linux_process_status(pid)
59
+ path = "/proc/#{pid}/status"
60
+ return unless File.readable?(path)
61
+ File.read(path).split("\n").reduce({}) do |hash, line|
62
+ name, value = line.split(":")
63
+ hash[name] = value.strip
64
+ hash
65
+ end
66
+ end
67
+
68
+ MEMORY_CONVERSIONS = {"kb" => 1024, "mb" => 1024 * 1024, "gb" => 1024 * 1024 * 1024}
69
+
70
+ def linux_process_memory_usage_in_bytes(pid)
71
+ return unless status = linux_process_status(pid)
72
+ value, unit = status["VmRSS"].split
73
+ value.to_i * MEMORY_CONVERSIONS[unit.downcase]
74
+ end
53
75
  end
54
76
  end
@@ -0,0 +1,86 @@
1
+ module AccessWatch
2
+ class RackLogger
3
+ attr_reader :app, :client
4
+
5
+ def initialize(app, config)
6
+ @app, @client = app, AccessWatch::Client.new(config)
7
+ end
8
+
9
+ def call(env)
10
+ started_at = Time.now.utc
11
+ status, headers, body = app.call(env)
12
+ record(env, status, started_at, Time.now.utc)
13
+ [status, headers, body]
14
+ end
15
+
16
+ def record(env, status, started_at, finished_at)
17
+ post_request(
18
+ time: started_at.iso8601(3),
19
+ address: env["REMOTE_ADDR"],
20
+ request: {
21
+ protocol: env["HTTP_VERSION"],
22
+ method: env["REQUEST_METHOD"],
23
+ scheme: env["rack.url_scheme"],
24
+ host: env["HTTP_HOST"],
25
+ port: env["SERVER_PORT"],
26
+ url: env["ORIGINAL_FULLPATH"],
27
+ headers: extract_http_headers(env),
28
+ },
29
+ response: {status: status},
30
+ context: {
31
+ execution_time: finished_at - started_at,
32
+ memory_usage: memory_usage_in_bytes,
33
+ },
34
+ )
35
+ end
36
+
37
+ #######################
38
+ ### Private methods ###
39
+ #######################
40
+
41
+ private
42
+
43
+ def extract_http_headers(headers)
44
+ headers.reduce({}) do |hash, (name, value)|
45
+ if name.index("HTTP_") == 0 && name != "HTTP_COOKIE"
46
+ hash[format_header_name(name)] = value
47
+ end
48
+ hash
49
+ end
50
+ end
51
+
52
+ def format_header_name(name)
53
+ name.sub(/^HTTP_/, '').sub("_", " ").titleize.sub(" ", "-")
54
+ end
55
+
56
+ def post_request(data)
57
+ post_async("log".freeze, data)
58
+ end
59
+
60
+ def post_async(path, data)
61
+ Thread.new { client.post(path, data) }
62
+ end
63
+
64
+ def memory_usage_in_bytes
65
+ linux_process_memory_usage_in_bytes(Process.pid)
66
+ end
67
+
68
+ def linux_process_status(pid)
69
+ path = "/proc/#{pid}/status"
70
+ return unless File.readable?(path)
71
+ File.read(path).split("\n").reduce({}) do |hash, line|
72
+ name, value = line.split(":")
73
+ hash[name] = value.strip
74
+ hash
75
+ end
76
+ end
77
+
78
+ MEMORY_CONVERSIONS = {"kb" => 1024, "mb" => 1024 * 1024, "gb" => 1024 * 1024 * 1024}
79
+
80
+ def linux_process_memory_usage_in_bytes(pid)
81
+ return unless status = linux_process_status(pid)
82
+ value, unit = status["VmRSS"].split
83
+ value.to_i * MEMORY_CONVERSIONS[unit.downcase]
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,18 @@
1
+ module AccessWacth
2
+ class RailsLoader
3
+ def self.start
4
+ return if !defined?(Rails)
5
+ Rails::Railtie.initializer "access_watch.detect_config_file" do
6
+ if (path = Rails.root.join("config/access_watch.yml")).exist?
7
+ if config = AccessWacth::RailsLoader.load_config_file(path)[Rails.env]
8
+ Rails.application.config.middleware.use(AccessWatch::RackLogger, config.symbolize_keys)
9
+ end
10
+ end
11
+ end
12
+ end
13
+
14
+ def self.load_config_file(path)
15
+ YAML.load(ERB.new(path.read).result)
16
+ end
17
+ end
18
+ end
@@ -1,3 +1,3 @@
1
1
  module AccessWatch
2
- RAILS_VERSION = "0.0.6"
2
+ RAILS_VERSION = "0.1.0"
3
3
  end
@@ -3,4 +3,10 @@ end
3
3
 
4
4
  require "access_watch"
5
5
  require "access_watch/logger"
6
+ require "access_watch/rack_logger"
6
7
  require "access_watch/rails_version"
8
+
9
+ if defined?(Rails)
10
+ require "access_watch/rails_loader"
11
+ AccessWacth::RailsLoader.start
12
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: access_watch_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexis Bernard
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: 0.0.3
47
+ version: 0.0.5
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: 0.0.3
54
+ version: 0.0.5
55
55
  description: A Rails library to log and analyse Rails HTTP requests using the Access
56
56
  Watch cloud service.
57
57
  email:
@@ -64,6 +64,8 @@ files:
64
64
  - README.md
65
65
  - access_watch_rails.gemspec
66
66
  - lib/access_watch/logger.rb
67
+ - lib/access_watch/rack_logger.rb
68
+ - lib/access_watch/rails_loader.rb
67
69
  - lib/access_watch/rails_version.rb
68
70
  - lib/access_watch_rails.rb
69
71
  homepage: https://access.watch/