dry-monitor 0.1.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: ca2399eb8989f99e9840024b317599e731b2e357
4
- data.tar.gz: 01e127fab50b60edcc4ac61846907341fd826e23
2
+ SHA256:
3
+ metadata.gz: d81f64e41a8aefe7efc798b025228ea7c29d7b6228bbf6992f31b3aa2a7ae38d
4
+ data.tar.gz: b4eb4c4928bb5aacc9f160f7caba9047b2bcac5e77934407697a6f910f5808b0
5
5
  SHA512:
6
- metadata.gz: 5175053c85e8ae01f9892a3e17fe3e2c54820379cfabde8624893ff35833d7aa9c34bc3c1bf741cab7be77fd519fd6c8bc825997934b58506a3769e63d3bc669
7
- data.tar.gz: f01dc548ac3b1f02f72d6b5c7ed875b3100e86af9d6168be33b6910c1170979675cd4634e393dc41c53bc404ec947d2e3c38a11b3ae6d0e132b91298d62900fb
6
+ metadata.gz: 174dbc6c5c059a6a22ddb37b38c211690735de3e9efa97b2826e1f3190123f7a21af54f75ca72d226a18c8671eaa6856b406336217d23326ffc9561a3ed0716a
7
+ data.tar.gz: e249416fc29c6296d6c6cbe3488e5899a877224cdcc247f06cbd1fc2789c4fa4514575e884b26793947cc92f645816f765e50ccc2f8d31df4f783523f0b8220e
data/CHANGELOG.md CHANGED
@@ -1,45 +1,120 @@
1
- # v0.1.2 2018-01-04
1
+ <!--- DO NOT EDIT THIS FILE - IT'S AUTOMATICALLY GENERATED VIA DEVTOOLS --->
2
+
3
+ ## 0.4.0
4
+
2
5
 
3
6
  ### Fixed
4
7
 
5
- * Rack logger no longer prevents arbitrary payload in `:error` events (solnic)
8
+ - Compatibility with MRI 3.0 (@alex-damian-negru)
9
+
10
+
11
+ [Compare v0.3.2...master](https://github.com/dry-rb/dry-monitor/compare/v0.3.2...master)
12
+
13
+ ## 0.3.2 2020-04-09
14
+
15
+
16
+ ### Fixed
17
+
18
+ - Ensure `Dry::Monitor::Rack::Middleware` is compatible with `Rack::Builder#use` (@jodosha)
19
+
20
+ ### Changed
21
+
22
+ - Performance improvements (@davydovanton)
23
+
24
+ [Compare v0.3.1...v0.3.2](https://github.com/dry-rb/dry-monitor/compare/v0.3.1...v0.3.2)
25
+
26
+ ## 0.3.1 2019-06-18
6
27
 
7
- # v0.1.1 2018-01-03
8
28
 
9
29
  ### Fixed
10
30
 
11
- * Query params containing arrays of primitives (e.g. `?ids[]=1&ids[]=2`) no longer crash the logger (timriley)
31
+ - Uninitialized constant `Dry::Monitor::Notifications::EMPTY_HASH` when no payload given (@mensfeld)
32
+
33
+
34
+ [Compare v0.3.0...v0.3.1](https://github.com/dry-rb/dry-monitor/compare/v0.3.0...v0.3.1)
35
+
36
+ ## 0.3.0 2019-01-29
12
37
 
13
- # v0.1.0 2018-01-02
14
38
 
15
39
  ### Fixed
16
40
 
17
- * Query params are logged correctly via rack middleware (solnic)
41
+ - cannot load such file -- rack/utils (mensfeld)
18
42
 
19
43
  ### Changed
20
44
 
21
- * Uses `dry-events` for notifications (solnic)
45
+ - Make `rack` logger into a plugin (mensfeld)
46
+ - Make `sql` logger into a plugin (mensfeld)
47
+
48
+ [Compare v0.2.0...v0.3.0](https://github.com/dry-rb/dry-monitor/compare/v0.2.0...v0.3.0)
49
+
50
+ ## 0.2.0 2018-01-21
22
51
 
23
- # v0.0.3 2017-08-28
24
52
 
25
53
  ### Changed
26
54
 
27
- * Update default theme setting for compatibility with latest version of rouge (alexandru-calinoiu)
28
- * Require latest version of rouge gem (timriley)
55
+ - Make `rouge` an optional dependency (davydovanton & mensfeld)
56
+
57
+ [Compare v0.1.2...v0.2.0](https://github.com/dry-rb/dry-monitor/compare/v0.1.2...v0.2.0)
58
+
59
+ ## 0.1.2 2018-01-04
60
+
61
+
62
+ ### Fixed
63
+
64
+ - Rack logger no longer prevents arbitrary payload in `:error` events (solnic)
65
+
66
+
67
+ [Compare v0.1.1...v0.1.2](https://github.com/dry-rb/dry-monitor/compare/v0.1.1...v0.1.2)
68
+
69
+ ## 0.1.1 2018-01-03
70
+
71
+
72
+ ### Fixed
73
+
74
+ - Query params containing arrays of primitives (e.g. `?ids[]=1&ids[]=2`) no longer crash the logger (timriley)
75
+
76
+
77
+ [Compare v0.1.0...v0.1.1](https://github.com/dry-rb/dry-monitor/compare/v0.1.0...v0.1.1)
78
+
79
+ ## 0.1.0 2018-01-02
80
+
81
+
82
+ ### Fixed
83
+
84
+ - Query params are logged correctly via rack middleware (solnic)
85
+
86
+ ### Changed
87
+
88
+ - Uses `dry-events` for notifications (solnic)
89
+
90
+ [Compare v0.0.3...v0.1.0](https://github.com/dry-rb/dry-monitor/compare/v0.0.3...v0.1.0)
91
+
92
+ ## 0.0.3 2017-08-28
93
+
94
+
95
+ ### Changed
96
+
97
+ - Update default theme setting for compatibility with latest version of rouge (alexandru-calinoiu)
98
+ - Require latest version of rouge gem (timriley)
99
+
100
+ [Compare v0.0.2...v0.0.3](https://github.com/dry-rb/dry-monitor/compare/v0.0.2...v0.0.3)
101
+
102
+ ## 0.0.2 2017-02-02
29
103
 
30
- # v0.0.2 2017-02-02
31
104
 
32
105
  ### Added
33
106
 
34
- * `Dry::Monitor::Rack::Middleware#on` shortcut (solnic)
35
- * `Dry::Monitor::Rack::Middleware#instrument` shortcut (solnic)
36
- * `Dry::Monitor::SQL::Logger` can be configured with a custom message template (solnic)
107
+ - `Dry::Monitor::Rack::Middleware#on` shortcut (solnic)
108
+ - `Dry::Monitor::Rack::Middleware#instrument` shortcut (solnic)
109
+ - `Dry::Monitor::SQL::Logger` can be configured with a custom message template (solnic)
37
110
 
38
111
  ### Changed
39
112
 
40
- * `Dry::Monitor::Rack::Logger#{subscribe=>attach}` and now it accepts a rack middleware instance (solnic)
41
- * `Dry::Monitor::Rack::Logger` appends new lines when logging `:rack.request.stop` events (solnic)
113
+ - `Dry::Monitor::Rack::Logger#{subscribe=>attach}` and now it accepts a rack middleware instance (solnic)
114
+ - `Dry::Monitor::Rack::Logger` appends new lines when logging `:rack.request.stop` events (solnic)
115
+
116
+ [Compare v0.0.1...v0.0.2](https://github.com/dry-rb/dry-monitor/compare/v0.0.1...v0.0.2)
42
117
 
43
- # v0.0.1 2017-02-01
118
+ ## 0.0.1 2017-02-01
44
119
 
45
120
  First public release
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2014 Ruby Object Mapper
3
+ Copyright (c) 2015-2021 dry-rb team
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy of
6
6
  this software and associated documentation files (the "Software"), to deal in
data/README.md CHANGED
@@ -1,25 +1,28 @@
1
1
  [gem]: https://rubygems.org/gems/dry-monitor
2
- [travis]: https://travis-ci.org/dry-rb/dry-monitor
3
- [gemnasium]: https://gemnasium.com/dry-rb/dry-monitor
4
- [codeclimate]: https://codeclimate.com/github/dry-rb/dry-monitor
5
- [coveralls]: https://coveralls.io/r/dry-rb/dry-monitor
2
+ [actions]: https://github.com/dry-rb/dry-monitor/actions
3
+ [codacy]: https://www.codacy.com/gh/dry-rb/dry-monitor
4
+ [chat]: https://dry-rb.zulipchat.com
6
5
  [inchpages]: http://inch-ci.org/github/dry-rb/dry-monitor
7
6
 
8
- # dry-monitor [![Join the chat at https://gitter.im/dry-rb/chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/dry-rb/chat)
7
+ # dry-monitor [![Join the chat at https://dry-rb.zulipchat.com](https://img.shields.io/badge/dry--rb-join%20chat-%23346b7a.svg)][chat]
9
8
 
10
9
  [![Gem Version](https://badge.fury.io/rb/dry-monitor.svg)][gem]
11
- [![Build Status](https://travis-ci.org/dry-rb/dry-monitor.svg?branch=master)][travis]
12
- [![Dependency Status](https://gemnasium.com/dry-rb/dry-monitor.svg)][gemnasium]
13
- [![Code Climate](https://codeclimate.com/github/dry-rb/dry-monitor/badges/gpa.svg)][codeclimate]
14
- [![Test Coverage](https://codeclimate.com/github/dry-rb/dry-monitor/badges/coverage.svg)][codeclimate]
10
+ [![CI Status](https://github.com/dry-rb/dry-monitor/workflows/ci/badge.svg)][actions]
11
+ [![Codacy Badge](https://api.codacy.com/project/badge/Grade/984c4274e56d423a818e7a1bf5e963d0)][codacy]
12
+ [![Codacy Badge](https://api.codacy.com/project/badge/Coverage/984c4274e56d423a818e7a1bf5e963d0)][codacy]
15
13
  [![Inline docs](http://inch-ci.org/github/dry-rb/dry-monitor.svg?branch=master)][inchpages]
16
14
 
17
- Monitoring and instrumentation APIs.
15
+ ## Links
18
16
 
19
- ## Synopsis
17
+ * [User documentation](http://dry-rb.org/gems/dry-monitor)
18
+ * [API documentation](http://rubydoc.info/gems/dry-monitor)
20
19
 
21
- ``` ruby
22
- ```
20
+ ## Supported Ruby versions
21
+
22
+ This library officially supports the following Ruby versions:
23
+
24
+ * MRI >= `2.5`
25
+ * jruby >= `9.2`
23
26
 
24
27
  ## License
25
28
 
data/dry-monitor.gemspec CHANGED
@@ -1,26 +1,39 @@
1
- # coding: utf-8
2
- require File.expand_path('../lib/dry/monitor/version', __FILE__)
1
+ # frozen_string_literal: true
2
+ # this file is managed by dry-rb/devtools project
3
+
4
+ lib = File.expand_path('lib', __dir__)
5
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
+ require 'dry/monitor/version'
3
7
 
4
8
  Gem::Specification.new do |spec|
5
9
  spec.name = 'dry-monitor'
6
- spec.version = Dry::Monitor::VERSION
7
- spec.authors = ['Piotr Solnica']
8
- spec.email = ['piotr.solnica@gmail.com']
9
- spec.summary = 'Monitoring and instrumentation APIs'
10
- spec.homepage = 'https://github.com/dry-rb/dry-monitor'
10
+ spec.authors = ["Piotr Solnica"]
11
+ spec.email = ["piotr.solnica@gmail.com"]
11
12
  spec.license = 'MIT'
13
+ spec.version = Dry::Monitor::VERSION.dup
12
14
 
13
- spec.files = `git ls-files -z`.split("\x0")
14
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
15
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
15
+ spec.summary = "Monitoring and instrumentation APIs"
16
+ spec.description = spec.summary
17
+ spec.homepage = 'https://dry-rb.org/gems/dry-monitor'
18
+ spec.files = Dir["CHANGELOG.md", "LICENSE", "README.md", "dry-monitor.gemspec", "lib/**/*"]
19
+ spec.bindir = 'bin'
20
+ spec.executables = []
16
21
  spec.require_paths = ['lib']
17
22
 
18
- spec.add_runtime_dependency 'rouge', '~> 2.0', '>= 2.2.1'
19
- spec.add_runtime_dependency 'dry-equalizer', '~> 0.2'
20
- spec.add_runtime_dependency 'dry-configurable', '~> 0.5'
21
- spec.add_runtime_dependency 'dry-events', '~> 0.1'
23
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
24
+ spec.metadata['changelog_uri'] = 'https://github.com/dry-rb/dry-monitor/blob/master/CHANGELOG.md'
25
+ spec.metadata['source_code_uri'] = 'https://github.com/dry-rb/dry-monitor'
26
+ spec.metadata['bug_tracker_uri'] = 'https://github.com/dry-rb/dry-monitor/issues'
27
+
28
+ spec.required_ruby_version = ">= 2.5.0"
29
+
30
+ # to update dependencies edit project.yml
31
+ spec.add_runtime_dependency "dry-configurable", "~> 0.5"
32
+ spec.add_runtime_dependency "dry-core", "~> 0.5", ">= 0.5"
33
+ spec.add_runtime_dependency "dry-events", "~> 0.2"
22
34
 
23
- spec.add_development_dependency 'bundler'
24
- spec.add_development_dependency 'rake'
25
- spec.add_development_dependency 'rspec'
35
+ spec.add_development_dependency "bundler"
36
+ spec.add_development_dependency "rake"
37
+ spec.add_development_dependency "rouge", "~> 2.0", ">= 2.2.1"
38
+ spec.add_development_dependency "rspec"
26
39
  end
data/lib/dry-monitor.rb CHANGED
@@ -1 +1,3 @@
1
- require 'dry/monitor'
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/monitor"
data/lib/dry/monitor.rb CHANGED
@@ -1,5 +1,20 @@
1
- require 'dry/monitor/logger'
2
- require 'dry/monitor/notifications'
3
- require 'dry/monitor/rack/middleware'
4
- require 'dry/monitor/rack/logger'
5
- require 'dry/monitor/sql/logger'
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/monitor/logger"
4
+ require "dry/monitor/notifications"
5
+ require "dry/core/extensions"
6
+
7
+ module Dry
8
+ module Monitor
9
+ extend Dry::Core::Extensions
10
+
11
+ register_extension(:rack) do
12
+ require "rack/utils"
13
+ require "dry/monitor/rack/logger"
14
+ end
15
+
16
+ register_extension(:sql) do
17
+ require "dry/monitor/sql/logger"
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/core/constants"
4
+
5
+ module Dry
6
+ module Monitor
7
+ include Dry::Core::Constants
8
+ end
9
+ end
@@ -1,13 +1,17 @@
1
- require 'logger'
1
+ # frozen_string_literal: true
2
+
3
+ require "logger"
2
4
 
3
5
  module Dry
4
6
  module Monitor
5
7
  class Logger < ::Logger
8
+ DEFAULT_FORMATTER = proc do |_severity, _datetime, _progname, msg|
9
+ "#{msg}\n"
10
+ end
11
+
6
12
  def initialize(*args)
7
13
  super
8
- self.formatter = proc do |severity, datetime, progname, msg|
9
- "#{msg}\n"
10
- end
14
+ self.formatter = DEFAULT_FORMATTER
11
15
  end
12
16
  end
13
17
  end
@@ -1,28 +1,28 @@
1
- require 'dry/events/publisher'
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/events/publisher"
4
+ require "dry/monitor/constants"
2
5
 
3
6
  module Dry
4
7
  module Monitor
5
8
  class Clock
6
- def measure(&block)
9
+ def measure
7
10
  start = current
8
- result = block.()
9
- stop = current
10
- [result, ((stop - start) * 1000).round(2)]
11
+ result = yield
12
+ [result, current - start]
11
13
  end
12
14
 
13
15
  def current
14
- Time.now
16
+ Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond)
15
17
  end
16
18
  end
17
19
 
18
20
  CLOCK = Clock.new
19
21
 
20
22
  class Notifications
21
- include Events::Publisher['Dry::Monitor::Notifications']
22
-
23
- attr_reader :id
23
+ include Events::Publisher["Dry::Monitor::Notifications"]
24
24
 
25
- attr_reader :clock
25
+ attr_reader :id, :clock
26
26
 
27
27
  def initialize(id)
28
28
  @id = id
@@ -38,9 +38,7 @@ module Dry
38
38
  end
39
39
 
40
40
  def instrument(event_id, payload = EMPTY_HASH, &block)
41
- if block
42
- result, time = clock.measure(&block)
43
- end
41
+ result, time = @clock.measure(&block) if block_given?
44
42
 
45
43
  process(event_id, payload) do |event, listener|
46
44
  if time
@@ -1,4 +1,7 @@
1
- require 'dry/configurable'
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/configurable"
4
+ require "dry/monitor/rack/middleware"
2
5
 
3
6
  module Dry
4
7
  module Monitor
@@ -8,19 +11,17 @@ module Dry
8
11
 
9
12
  setting :filtered_params, %w[_csrf password]
10
13
 
11
- REQUEST_METHOD = 'REQUEST_METHOD'.freeze
12
- PATH_INFO = 'PATH_INFO'.freeze
13
- REMOTE_ADDR = 'REMOTE_ADDR'.freeze
14
- QUERY_STRING = 'QUERY_STRING'.freeze
15
-
16
- START_MSG = %(Started %s "%s" for %s at %s).freeze
17
- STOP_MSG = %(Finished %s "%s" for %s in %sms [Status: %s]\n).freeze
18
- QUERY_MSG = %( Query parameters %s).freeze
19
- FILTERED = '[FILTERED]'.freeze
14
+ REQUEST_METHOD = "REQUEST_METHOD"
15
+ PATH_INFO = "PATH_INFO"
16
+ REMOTE_ADDR = "REMOTE_ADDR"
17
+ QUERY_STRING = "QUERY_STRING"
20
18
 
21
- attr_reader :logger
19
+ START_MSG = %(Started %s "%s" for %s at %s)
20
+ STOP_MSG = %(Finished %s "%s" for %s in %sms [Status: %s]\n)
21
+ QUERY_MSG = %( Query parameters )
22
+ FILTERED = "[FILTERED]"
22
23
 
23
- attr_reader :config
24
+ attr_reader :logger, :config
24
25
 
25
26
  def initialize(logger, config = self.class.config)
26
27
  @logger = logger
@@ -28,47 +29,39 @@ module Dry
28
29
  end
29
30
 
30
31
  def attach(rack_monitor)
31
- rack_monitor.on(:start) do |env:|
32
- log_start_request(env)
33
- end
34
-
35
- rack_monitor.on(:stop) do |env:, status:, time:|
36
- log_stop_request(env, status, time)
37
- end
38
-
39
- rack_monitor.on(:error) do |event|
40
- log_exception(event[:exception])
41
- end
32
+ rack_monitor.on(:start) { |params| log_start_request(params[:env]) }
33
+ rack_monitor.on(:stop) { |params| log_stop_request(**params) }
34
+ rack_monitor.on(:error) { |event| log_exception(event[:exception]) }
42
35
  end
43
36
 
44
- def log_exception(e)
45
- logger.error e.message
46
- logger.error filter_backtrace(e.backtrace).join("\n")
37
+ def log_exception(err)
38
+ logger.error err.message
39
+ logger.error filter_backtrace(err.backtrace).join("\n")
47
40
  end
48
41
 
49
42
  def log_start_request(request)
50
- info START_MSG % [
51
- request[REQUEST_METHOD],
52
- request[PATH_INFO],
53
- request[REMOTE_ADDR],
54
- Time.now
55
- ]
43
+ logger.info START_MSG % [
44
+ request[REQUEST_METHOD],
45
+ request[PATH_INFO],
46
+ request[REMOTE_ADDR],
47
+ Time.now
48
+ ]
56
49
  log_request_params(request)
57
50
  end
58
51
 
59
- def log_stop_request(request, status, time)
60
- info STOP_MSG % [
61
- request[REQUEST_METHOD],
62
- request[PATH_INFO],
63
- request[REMOTE_ADDR],
64
- time,
65
- status
66
- ]
52
+ def log_stop_request(env:, status:, time:)
53
+ logger.info STOP_MSG % [
54
+ env[REQUEST_METHOD],
55
+ env[PATH_INFO],
56
+ env[REMOTE_ADDR],
57
+ time,
58
+ status
59
+ ]
67
60
  end
68
61
 
69
62
  def log_request_params(request)
70
63
  with_http_params(request[QUERY_STRING]) do |params|
71
- info QUERY_MSG % [params.inspect]
64
+ logger.info QUERY_MSG + params.inspect
72
65
  end
73
66
  end
74
67
 
@@ -79,28 +72,26 @@ module Dry
79
72
  def with_http_params(params)
80
73
  params = ::Rack::Utils.parse_nested_query(params)
81
74
 
82
- if params.size > 0
83
- yield(filter_params(params))
84
- end
75
+ yield(filter_params(params)) unless params.empty?
85
76
  end
86
77
 
87
78
  def filter_backtrace(backtrace)
88
79
  # TODO: what do we want to do with this?
89
- backtrace.reject { |l| l.include?('gems') }
80
+ backtrace.reject { |l| l.include?("gems") }
90
81
  end
91
82
 
92
83
  def filter_params(params)
93
- params.each_with_object({}) do |(k, v), h|
84
+ params.each do |k, v|
94
85
  if config.filtered_params.include?(k)
95
- h.update(k => FILTERED)
86
+ params[k] = FILTERED
96
87
  elsif v.is_a?(Hash)
97
- h.update(k => filter_params(v))
88
+ filter_params(v)
98
89
  elsif v.is_a?(Array)
99
- h.update(k => v.map { |m| m.is_a?(Hash) ? filter_params(m) : m })
100
- else
101
- h[k] = v
90
+ v.map! { |m| m.is_a?(Hash) ? filter_params(m) : m }
102
91
  end
103
92
  end
93
+
94
+ params
104
95
  end
105
96
  end
106
97
  end
@@ -1,5 +1,6 @@
1
- require 'rack/utils'
2
- require 'dry/monitor/notifications'
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/monitor/notifications"
3
4
 
4
5
  module Dry
5
6
  module Monitor
@@ -13,15 +14,13 @@ module Dry
13
14
  Notifications.register_event(REQUEST_STOP)
14
15
  Notifications.register_event(REQUEST_ERROR)
15
16
 
16
- attr_reader :app
17
-
18
- attr_reader :notifications
17
+ attr_reader :app, :notifications
19
18
 
20
19
  def initialize(*args)
21
20
  @notifications, @app = *args
22
21
  end
23
22
 
24
- def new(app)
23
+ def new(app, *_args, &_block)
25
24
  self.class.new(notifications, app)
26
25
  end
27
26
 
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dry
4
+ module Monitor
5
+ module SQL
6
+ module Colorizers
7
+ class Default
8
+ def initialize(_theme); end
9
+
10
+ def call(string)
11
+ string
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rouge/util"
4
+ require "rouge/token"
5
+ require "rouge/theme"
6
+ require "rouge/themes/gruvbox"
7
+ require "rouge/formatter"
8
+ require "rouge/formatters/terminal256"
9
+ require "rouge/lexer"
10
+ require "rouge/regex_lexer"
11
+ require "rouge/lexers/sql"
12
+
13
+ module Dry
14
+ module Monitor
15
+ module SQL
16
+ module Colorizers
17
+ class Rouge
18
+ attr_reader :formatter, :lexer
19
+
20
+ def initialize(theme)
21
+ @formatter = ::Rouge::Formatters::Terminal256.new(theme || ::Rouge::Themes::Gruvbox.new)
22
+ @lexer = ::Rouge::Lexers::SQL.new
23
+ end
24
+
25
+ def call(string)
26
+ formatter.format(lexer.lex(string))
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -1,6 +1,8 @@
1
- require 'dry-configurable'
2
- require 'rouge'
3
- require 'dry/monitor/notifications'
1
+ # frozen_string_literal: true
2
+
3
+ require "dry-configurable"
4
+ require "dry/core/extensions"
5
+ require "dry/monitor/notifications"
4
6
 
5
7
  module Dry
6
8
  module Monitor
@@ -8,40 +10,52 @@ module Dry
8
10
 
9
11
  module SQL
10
12
  class Logger
13
+ extend Dry::Core::Extensions
11
14
  extend Dry::Configurable
12
15
 
13
- setting :theme, Rouge::Themes::Gruvbox.new
14
- setting :colorize, true
15
- setting :message_template, %( Loaded %s in %sms %s).freeze
16
+ register_extension(:default_colorizer) do
17
+ require_relative "./colorizers/default"
18
+
19
+ module DefaultColorizer
20
+ def colorizer
21
+ @colorizer ||= Colorizers::Default.new(config.theme)
22
+ end
23
+ end
24
+
25
+ Logger.include(DefaultColorizer)
26
+ end
27
+
28
+ register_extension(:rouge_colorizer) do
29
+ require_relative "./colorizers/rouge"
30
+
31
+ module RougeColorizer
32
+ def colorizer
33
+ @colorizer ||= Colorizers::Rouge.new(config.theme)
34
+ end
35
+ end
36
+
37
+ Logger.include(RougeColorizer)
38
+ end
39
+
40
+ setting :theme, nil
41
+ setting :message_template, %( Loaded %s in %sms %s)
42
+
43
+ attr_reader :config, :logger, :template
16
44
 
17
- attr_reader :config
18
- attr_reader :logger
19
- attr_reader :formatter
20
- attr_reader :lexer
21
- attr_reader :template
45
+ load_extensions(:default_colorizer)
22
46
 
23
47
  def initialize(logger, config = self.class.config)
24
48
  @logger = logger
25
49
  @config = config
26
- @formatter = Rouge::Formatters::Terminal256.new(config.theme)
27
- @lexer = Rouge::Lexers::SQL.new
28
50
  @template = config.message_template
29
51
  end
30
52
 
31
53
  def subscribe(notifications)
32
- notifications.subscribe(:sql) do |time:, name:, query:|
33
- log_query(time, name, query)
34
- end
35
- end
36
-
37
- def log_query(time, name, query)
38
- logger.info template % [name.inspect, time, colorize(query)]
54
+ notifications.subscribe(:sql) { |params| log_query(**params) }
39
55
  end
40
56
 
41
- private
42
-
43
- def colorize(string)
44
- config.colorize ? formatter.format(lexer.lex(string)) : string
57
+ def log_query(time:, name:, query:)
58
+ logger.info template % [name.inspect, time, colorizer.call(query)]
45
59
  end
46
60
  end
47
61
  end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Dry
2
4
  module Monitor
3
- VERSION = '0.1.2'.freeze
5
+ VERSION = "0.4.0"
4
6
  end
5
7
  end
metadata CHANGED
@@ -1,54 +1,37 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dry-monitor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Solnica
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-01-04 00:00:00.000000000 Z
11
+ date: 2021-04-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rouge
14
+ name: dry-configurable
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '2.0'
20
- - - ">="
21
- - !ruby/object:Gem::Version
22
- version: 2.2.1
19
+ version: '0.5'
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
26
23
  requirements:
27
24
  - - "~>"
28
25
  - !ruby/object:Gem::Version
29
- version: '2.0'
30
- - - ">="
31
- - !ruby/object:Gem::Version
32
- version: 2.2.1
26
+ version: '0.5'
33
27
  - !ruby/object:Gem::Dependency
34
- name: dry-equalizer
28
+ name: dry-core
35
29
  requirement: !ruby/object:Gem::Requirement
36
30
  requirements:
37
31
  - - "~>"
38
32
  - !ruby/object:Gem::Version
39
- version: '0.2'
40
- type: :runtime
41
- prerelease: false
42
- version_requirements: !ruby/object:Gem::Requirement
43
- requirements:
44
- - - "~>"
45
- - !ruby/object:Gem::Version
46
- version: '0.2'
47
- - !ruby/object:Gem::Dependency
48
- name: dry-configurable
49
- requirement: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - "~>"
33
+ version: '0.5'
34
+ - - ">="
52
35
  - !ruby/object:Gem::Version
53
36
  version: '0.5'
54
37
  type: :runtime
@@ -58,20 +41,23 @@ dependencies:
58
41
  - - "~>"
59
42
  - !ruby/object:Gem::Version
60
43
  version: '0.5'
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0.5'
61
47
  - !ruby/object:Gem::Dependency
62
48
  name: dry-events
63
49
  requirement: !ruby/object:Gem::Requirement
64
50
  requirements:
65
51
  - - "~>"
66
52
  - !ruby/object:Gem::Version
67
- version: '0.1'
53
+ version: '0.2'
68
54
  type: :runtime
69
55
  prerelease: false
70
56
  version_requirements: !ruby/object:Gem::Requirement
71
57
  requirements:
72
58
  - - "~>"
73
59
  - !ruby/object:Gem::Version
74
- version: '0.1'
60
+ version: '0.2'
75
61
  - !ruby/object:Gem::Dependency
76
62
  name: bundler
77
63
  requirement: !ruby/object:Gem::Requirement
@@ -100,6 +86,26 @@ dependencies:
100
86
  - - ">="
101
87
  - !ruby/object:Gem::Version
102
88
  version: '0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: rouge
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '2.0'
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: 2.2.1
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - "~>"
104
+ - !ruby/object:Gem::Version
105
+ version: '2.0'
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: 2.2.1
103
109
  - !ruby/object:Gem::Dependency
104
110
  name: rspec
105
111
  requirement: !ruby/object:Gem::Requirement
@@ -114,44 +120,36 @@ dependencies:
114
120
  - - ">="
115
121
  - !ruby/object:Gem::Version
116
122
  version: '0'
117
- description:
123
+ description: Monitoring and instrumentation APIs
118
124
  email:
119
125
  - piotr.solnica@gmail.com
120
126
  executables: []
121
127
  extensions: []
122
128
  extra_rdoc_files: []
123
129
  files:
124
- - ".gitignore"
125
- - ".rspec"
126
- - ".rubocop.yml"
127
- - ".rubocop_todo.yml"
128
- - ".travis.yml"
129
130
  - CHANGELOG.md
130
- - CONTRIBUTING.md
131
- - Gemfile
132
131
  - LICENSE
133
132
  - README.md
134
- - Rakefile
135
133
  - dry-monitor.gemspec
136
134
  - lib/dry-monitor.rb
137
135
  - lib/dry/monitor.rb
136
+ - lib/dry/monitor/constants.rb
138
137
  - lib/dry/monitor/logger.rb
139
138
  - lib/dry/monitor/notifications.rb
140
139
  - lib/dry/monitor/rack/logger.rb
141
140
  - lib/dry/monitor/rack/middleware.rb
141
+ - lib/dry/monitor/sql/colorizers/default.rb
142
+ - lib/dry/monitor/sql/colorizers/rouge.rb
142
143
  - lib/dry/monitor/sql/logger.rb
143
144
  - lib/dry/monitor/version.rb
144
- - rakelib/rubocop.rake
145
- - spec/integration/instrumentation_spec.rb
146
- - spec/integration/logger_spec.rb
147
- - spec/integration/rack_middleware_spec.rb
148
- - spec/integration/sql_logger_spec.rb
149
- - spec/spec_helper.rb
150
- - spec/test_logs/.gitkeep
151
- homepage: https://github.com/dry-rb/dry-monitor
145
+ homepage: https://dry-rb.org/gems/dry-monitor
152
146
  licenses:
153
147
  - MIT
154
- metadata: {}
148
+ metadata:
149
+ allowed_push_host: https://rubygems.org
150
+ changelog_uri: https://github.com/dry-rb/dry-monitor/blob/master/CHANGELOG.md
151
+ source_code_uri: https://github.com/dry-rb/dry-monitor
152
+ bug_tracker_uri: https://github.com/dry-rb/dry-monitor/issues
155
153
  post_install_message:
156
154
  rdoc_options: []
157
155
  require_paths:
@@ -160,22 +158,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
160
158
  requirements:
161
159
  - - ">="
162
160
  - !ruby/object:Gem::Version
163
- version: '0'
161
+ version: 2.5.0
164
162
  required_rubygems_version: !ruby/object:Gem::Requirement
165
163
  requirements:
166
164
  - - ">="
167
165
  - !ruby/object:Gem::Version
168
166
  version: '0'
169
167
  requirements: []
170
- rubyforge_project:
171
- rubygems_version: 2.6.11
168
+ rubygems_version: 3.1.6
172
169
  signing_key:
173
170
  specification_version: 4
174
171
  summary: Monitoring and instrumentation APIs
175
- test_files:
176
- - spec/integration/instrumentation_spec.rb
177
- - spec/integration/logger_spec.rb
178
- - spec/integration/rack_middleware_spec.rb
179
- - spec/integration/sql_logger_spec.rb
180
- - spec/spec_helper.rb
181
- - spec/test_logs/.gitkeep
172
+ test_files: []
data/.gitignore DELETED
@@ -1,9 +0,0 @@
1
- .DS_Store
2
- coverage
3
- /.bundle
4
- vendor/bundle
5
- bin/
6
- tmp/
7
- .idea/
8
- Gemfile.lock
9
- spec/test_logs/*.log
data/.rspec DELETED
@@ -1,3 +0,0 @@
1
- --color
2
- --require spec_helper
3
- --order random
data/.rubocop.yml DELETED
@@ -1,16 +0,0 @@
1
- # Generated by `rubocop --auto-gen-config`
2
- inherit_from: .rubocop_todo.yml
3
-
4
- Metrics/LineLength:
5
- Max: 100
6
-
7
- Style/Documentation:
8
- Enabled: false
9
-
10
- Lint/HandleExceptions:
11
- Exclude:
12
- - rakelib/*.rake
13
-
14
- Style/FileName:
15
- Exclude:
16
- - lib/dry-logic.rb
data/.rubocop_todo.yml DELETED
@@ -1,7 +0,0 @@
1
- # This configuration was generated by
2
- # `rubocop --auto-gen-config`
3
- # on 2015-10-30 01:32:46 +0000 using RuboCop version 0.34.2.
4
- # The point is for the user to remove these configuration records
5
- # one by one as the offenses are removed from the code base.
6
- # Note that changes in the inspected code, or installation of new
7
- # versions of RuboCop, may require this file to be generated again.
data/.travis.yml DELETED
@@ -1,22 +0,0 @@
1
- language: ruby
2
- cache: bundler
3
- bundler_args: --without benchmarks console tools
4
- script: "bundle exec rake ci"
5
- before_install: gem update --system
6
- after_success:
7
- - '[ "${TRAVIS_JOB_NUMBER#*.}" = "1" ] && [ "$TRAVIS_BRANCH" = "master" ] && bundle exec codeclimate-test-reporter'
8
- rvm:
9
- - 2.5.0
10
- - 2.4.3
11
- - 2.3.6
12
- - jruby-9.1.9.0
13
- env:
14
- global:
15
- - COVERAGE='true'
16
- notifications:
17
- webhooks:
18
- urls:
19
- - https://webhooks.gitter.im/e/19098b4253a72c9796db
20
- on_success: change
21
- on_failure: always
22
- on_start: false
data/CONTRIBUTING.md DELETED
@@ -1,29 +0,0 @@
1
- # Issue Guidelines
2
-
3
- ## Reporting bugs
4
-
5
- If you found a bug, report an issue and describe what's the expected behavior versus what actually happens. If the bug causes a crash, attach a full backtrace. If possible, a reproduction script showing the problem is highly appreciated.
6
-
7
- ## Reporting feature requests
8
-
9
- Report a feature request **only after discussing it first on [discuss.dry-rb.org](https://discuss.dry-rb.org)** where it was accepted. Please provide a concise description of the feature, don't link to a discussion thread, and instead summarize what was discussed.
10
-
11
- ## Reporting questions, support requests, ideas, concerns etc.
12
-
13
- **PLEASE DON'T** - use [discuss.dry-rb.org](http://discuss.dry-rb.org) instead.
14
-
15
- # Pull Request Guidelines
16
-
17
- A Pull Request will only be accepted if it addresses a specific issue that was reported previously, or fixes typos, mistakes in documentation etc.
18
-
19
- Other requirements:
20
-
21
- 1) Do not open a pull request if you can't provide tests along with it. If you have problems writing tests, ask for help in the related issue.
22
- 2) Follow the style conventions of the surrounding code. In most cases, this is standard ruby style.
23
- 3) Add API documentation if it's a new feature
24
- 4) Update API documentation if it changes an existing feature
25
- 5) Bonus points for sending a PR to [github.com/dry-rb/dry-rb.org](github.com/dry-rb/dry-rb.org) which updates user documentation and guides
26
-
27
- # Asking for help
28
-
29
- If these guidelines aren't helpful, and you're stuck, please post a message on [discuss.dry-rb.org](https://discuss.dry-rb.org).
data/Gemfile DELETED
@@ -1,15 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gemspec
4
-
5
- gem 'dry-events', git: 'https://github.com/dry-rb/dry-events.git', branch: 'master'
6
-
7
- group :test do
8
- gem 'rack'
9
- gem 'simplecov', platform: :mri, require: false
10
- gem 'codeclimate-test-reporter', require: false
11
- end
12
-
13
- group :tools do
14
- gem 'byebug', platform: :mri
15
- end
data/Rakefile DELETED
@@ -1,15 +0,0 @@
1
- #!/usr/bin/env rake
2
- require 'bundler/gem_tasks'
3
-
4
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'lib'))
5
-
6
- require 'rspec/core'
7
- require 'rspec/core/rake_task'
8
-
9
- task default: :spec
10
-
11
- desc 'Run all specs in spec directory'
12
- RSpec::Core::RakeTask.new(:spec)
13
-
14
- desc "Run CI tasks"
15
- task ci: [:spec]
data/rakelib/rubocop.rake DELETED
@@ -1,18 +0,0 @@
1
- begin
2
- require 'rubocop/rake_task'
3
-
4
- Rake::Task[:default].enhance [:rubocop]
5
-
6
- RuboCop::RakeTask.new do |task|
7
- task.options << '--display-cop-names'
8
- end
9
-
10
- namespace :rubocop do
11
- desc 'Generate a configuration file acting as a TODO list.'
12
- task :auto_gen_config do
13
- exec 'bundle exec rubocop --auto-gen-config'
14
- end
15
- end
16
-
17
- rescue LoadError
18
- end
@@ -1,37 +0,0 @@
1
- RSpec.describe 'Subscribing to instrumentation events' do
2
- subject(:notifications) { Dry::Monitor::Notifications.new(:app) }
3
-
4
- before do
5
- Dry::Monitor::Notifications.register_event(:sql, { name: 'rom[sql]' })
6
- end
7
-
8
- describe '#instrument' do
9
- it 'allows subscribing via block' do
10
- captured = []
11
- payload = { query: 'SELECT 1 FROM users' }
12
-
13
- notifications.subscribe(:sql) do |event|
14
- captured << [event.id, event[:query]]
15
- end
16
-
17
- notifications.instrument(:sql, payload)
18
-
19
- expect(captured).to eql([[:sql, 'SELECT 1 FROM users']])
20
- end
21
-
22
- it 'allows instrumenting via block' do
23
- captured = []
24
- payload = { query: 'SELECT 1 FROM users' }
25
-
26
- notifications.subscribe(:sql) do |event|
27
- captured << [event.id, event[:query]]
28
- end
29
-
30
- notifications.instrument(:sql, payload) do
31
- payload
32
- end
33
-
34
- expect(captured).to eql([[:sql, 'SELECT 1 FROM users']])
35
- end
36
- end
37
- end
@@ -1,11 +0,0 @@
1
- RSpec.describe Dry::Monitor::Logger do
2
- subject(:logger) do
3
- Dry::Monitor::Logger.new($stdout)
4
- end
5
-
6
- describe '#info' do
7
- it 'outputs with configured formatter' do
8
- expect { logger.info('test') }.to output("test\n").to_stdout
9
- end
10
- end
11
- end
@@ -1,98 +0,0 @@
1
- RSpec.describe Dry::Monitor::Rack::Middleware do
2
- subject(:middleware) { Dry::Monitor::Rack::Middleware.new(notifications).new(rack_app) }
3
-
4
- let(:notifications) do
5
- Dry::Monitor::Notifications.new(:test)
6
- end
7
-
8
- let(:rack_app) do
9
- double(:rack_app)
10
- end
11
-
12
- let(:log_file_path) do
13
- SPEC_ROOT.join('test_logs/middleware.log')
14
- end
15
-
16
- let(:rack_logger) do
17
- Dry::Monitor::Rack::Logger.new(Dry::Monitor::Logger.new(log_file_path))
18
- end
19
-
20
- let(:env) do
21
- { 'REQUEST_METHOD' => 'GET',
22
- 'PATH_INFO' => '/hello-world',
23
- 'REMOTE_ADDR' => '0.0.0.0',
24
- 'QUERY_STRING' => query_params }
25
- end
26
-
27
- let(:query_params) do
28
- %w[
29
- _csrf=123456
30
- password=secret
31
- user[password]=secret
32
- others[][password]=secret1
33
- others[][password]=secret2
34
- foo=bar
35
- one=1
36
- ids[]=1
37
- ids[]=2
38
- ].join('&')
39
- end
40
-
41
- describe '#call' do
42
- before do
43
- File.open(log_file_path, 'w').close
44
- rack_logger.attach(middleware)
45
- end
46
-
47
- it 'triggers start/stop events for with a rack request' do
48
- expect(rack_app).to receive(:call).with(env).and_return([200, :total_success])
49
-
50
- status, response = middleware.call(env)
51
-
52
- expect(status).to be(200)
53
- expect(response).to be(:total_success)
54
-
55
- log_file_content = File.read(log_file_path)
56
-
57
- expect(log_file_content).to include('Started GET "/hello-world"')
58
- expect(log_file_content).to include('Finished GET "/hello-world"')
59
- expect(log_file_content).to include('Query parameters {"_csrf"=>"[FILTERED]", "password"=>"[FILTERED]", "user"=>{"password"=>"[FILTERED]"}, "others"=>[{"password"=>"[FILTERED]"}, {"password"=>"[FILTERED]"}], "foo"=>"bar", "one"=>"1", "ids"=>["1", "2"]}')
60
- end
61
- end
62
-
63
- describe '#on' do
64
- it 'subscribe a listener to a specific request event' do
65
- captured = []
66
-
67
- middleware.on(:error) do |event|
68
- captured << event[:exception]
69
- captured << event[:env]
70
- end
71
-
72
- exception = 'oops'
73
- env = { 'REQUEST_METHOD' => 'GET' }
74
-
75
- middleware.instrument(:error, exception: exception, env: env)
76
-
77
- expect(captured).to eql([exception, env])
78
- end
79
- end
80
-
81
- describe 'rack logger' do
82
- before do
83
- File.open(log_file_path, 'w').close
84
- rack_logger.attach(middleware)
85
- end
86
-
87
- it 'logs exceptions' do
88
- exception = double(:exception, message: 'oops', backtrace: ['/some/path.rb'])
89
-
90
- middleware.instrument(:error, exception: exception, env: env)
91
-
92
- log_file_content = File.read(log_file_path)
93
-
94
- expect(log_file_content).to include('oops')
95
- expect(log_file_content).to include('/some/path.rb')
96
- end
97
- end
98
- end
@@ -1,57 +0,0 @@
1
- RSpec.describe Dry::Monitor::SQL::Logger do
2
- subject(:logger) { sql_logger.new(Dry::Monitor::Logger.new(log_file_path)) }
3
-
4
- let(:notifications) do
5
- Dry::Monitor::Notifications.new(:test)
6
- end
7
-
8
- let(:log_file_path) do
9
- SPEC_ROOT.join('test_logs/sql.log')
10
- end
11
-
12
- let(:log_file_content) { File.read(log_file_path) }
13
-
14
- shared_context '#subscribe' do
15
- let(:query) do
16
- 'SELECT id, name FROM users'
17
- end
18
-
19
- before do
20
- File.open(log_file_path, 'w').close
21
-
22
- logger.subscribe(notifications)
23
-
24
- notifications.instrument(:sql, name: 'users', query: query) do
25
- sleep 0.0025
26
- end
27
- end
28
-
29
- it 'writes sql query info' do
30
- expect(log_file_content).to include('Loaded "users" in')
31
- end
32
- end
33
-
34
- context 'without colors' do
35
- let(:sql_logger) do
36
- Class.new(Dry::Monitor::SQL::Logger) do
37
- configure do |config|
38
- config.colorize = false
39
- end
40
- end
41
- end
42
-
43
- include_context '#subscribe' do
44
- it 'writes sql query in logs' do
45
- expect(log_file_content).to include(query)
46
- end
47
- end
48
- end
49
-
50
- context 'without colors' do
51
- let(:sql_logger) do
52
- Dry::Monitor::SQL::Logger
53
- end
54
-
55
- include_context '#subscribe'
56
- end
57
- end
data/spec/spec_helper.rb DELETED
@@ -1,21 +0,0 @@
1
- if RUBY_ENGINE == 'ruby' && ENV['CI'] == 'true'
2
- require 'simplecov'
3
- SimpleCov.start do
4
- add_filter '/spec/'
5
- end
6
- end
7
-
8
- begin
9
- require 'byebug'
10
- rescue LoadError; end
11
-
12
- require 'dry-monitor'
13
-
14
- SPEC_ROOT = Pathname(__dir__)
15
-
16
- Dir[SPEC_ROOT.join('shared/**/*.rb')].each(&method(:require))
17
- Dir[SPEC_ROOT.join('support/**/*.rb')].each(&method(:require))
18
-
19
- RSpec.configure do |config|
20
- config.disable_monkey_patching!
21
- end
File without changes