observability 0.2.0 → 0.3.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
  SHA256:
3
- metadata.gz: eb2bcfb9c815937bbc46798e8645ccc77e0a7e87dfa5024d327c9e9d4db5a1ff
4
- data.tar.gz: c561389042c72073f21a5e18c06252a36177cd19022e6330c2633f8368953a8f
3
+ metadata.gz: ca1dcfc173024a7ef76eb412bc386cae1e45ccc1844cd79bae98cea45377b110
4
+ data.tar.gz: b3c53287536774ec9d33c3acc63fe10856921cdccdb2485850191924e2ed707c
5
5
  SHA512:
6
- metadata.gz: 4295af2f27a6d6eed728608896ae92fd79736d159c9b2f4c0595b5918708e6b6f63cde95d9824450daa741db481b0ecc7331c842fd43006eb03e704a35b9e603
7
- data.tar.gz: e98b10c101567afa169e55d4b75dffa400d06491ff0320e3c9f01c72d73349ca413655697bb4e69b6493bfa676b2682ff1a48a035f3474de9552e349f9734fbf
6
+ metadata.gz: 81a5b9df54dd9cc7d350a61f186741e0dd74f7651d8c21a527592dcfe10d1463a4c86b332de3351e5bfab44030a431169e2b4c587a1a86de764073f9e517468c
7
+ data.tar.gz: 52002d309d9ee18d8ca6a26d7f02023bfdbd10e5b9ebf6a1959b678a7f4f17878a2f3567ec046a34bd47b0d02221a0cb77e0232ab62b394e7dbd171541dc2629
Binary file
data.tar.gz.sig CHANGED
Binary file
data/History.md CHANGED
@@ -2,6 +2,20 @@
2
2
 
3
3
  ---
4
4
 
5
+ ## v0.3.0 [2020-02-21] Michael Granger <ged@faeriemud.org>
6
+
7
+ Improvements:
8
+
9
+ - Add `requires` to instrumentation, add a PG instrument
10
+ - Add an event ID for cross-application context
11
+ - Update for Ruby 2.7.
12
+
13
+ Bugfixes:
14
+
15
+ - Add a provisional fix for observing arity-0 methods
16
+ - Guard against blockless observe calls
17
+
18
+
5
19
  ## v0.2.0 [2019-10-16] Michael Granger <ged@faeriemud.org>
6
20
 
7
21
  Improvements:
data/README.md CHANGED
@@ -19,7 +19,7 @@ Observability is a toolkit for instrumenting code to make it more observable.
19
19
  It follows the principle of Observability-Oriented Design as expressed by Charity
20
20
  Majors (@mipsytipsy).
21
21
 
22
- Its goals are [stolen from https://charity.wtf/2019/02/05/logs-vs-structured-events/]:
22
+ Its goals are stolen from https://charity.wtf/2019/02/05/logs-vs-structured-events/:
23
23
 
24
24
  * Emit a rich record from the perspective of a single action as the code is
25
25
  executing.
@@ -35,6 +35,8 @@ Its goals are [stolen from https://charity.wtf/2019/02/05/logs-vs-structured-eve
35
35
  system quality, system behavior, outliers, error conditions, etc. You will be
36
36
  absolutely amazed how useful it is … and appalled by what you turn up. 🙂
37
37
 
38
+ [![builds.sr.ht status](https://builds.sr.ht/~ged/Observability.svg)](https://builds.sr.ht/~ged/Observability?)
39
+
38
40
 
39
41
  ## Prerequisites
40
42
 
@@ -52,13 +54,6 @@ You can check out the current development source with Mercurial via its
52
54
  [project page][sourcehut]. Or if you prefer Git, via
53
55
  [its Github mirror][github].
54
56
 
55
- After checking out the source, run:
56
-
57
- $ rake newb
58
-
59
- This task will install any missing dependencies, run the tests/specs,
60
- and generate the API documentation.
61
-
62
57
 
63
58
  ## Author
64
59
 
@@ -67,7 +62,7 @@ and generate the API documentation.
67
62
 
68
63
  ## License
69
64
 
70
- Copyright (c) 2019, Michael Granger
65
+ Copyright (c) 2019-2020, Michael Granger
71
66
  All rights reserved.
72
67
 
73
68
  Redistribution and use in source and binary forms, with or without
@@ -13,11 +13,14 @@ module Observability
13
13
 
14
14
 
15
15
  # Package version
16
- VERSION = '0.2.0'
16
+ VERSION = '0.3.0'
17
17
 
18
18
  # Version control revision
19
19
  REVISION = %q$Revision$
20
20
 
21
+ # The default port to use for network communications
22
+ DEFAULT_PORT = 15775
23
+
21
24
 
22
25
  # Loggability -- Create a logger
23
26
  log_as :observability
@@ -93,13 +96,27 @@ module Observability
93
96
  ### Make a body for a wrapping method for the method with the given +name+ and
94
97
  ### +context+, passing the given +options+.
95
98
  def self::make_wrapped_method( name, context, options, &callback )
96
- return Proc.new do |*m_args, **m_options, &block|
97
- Loggability[ Observability ].debug "Wrapped method %p: %p" %
98
- [ name, context ]
99
- Observability.observer.event( context, **options ) do
100
- # :TODO: Freeze or dup the arguments to prevent accidental modification?
101
- callback.call( *m_args, **m_options, &block ) if callback
102
- super( *m_args, **m_options, &block )
99
+
100
+ # Supering into arity-zero methods with (empty) *args and **options raises an
101
+ # ArgumentError for some reason.
102
+ if context.first.arity.zero?
103
+ return Proc.new do |*m_args, **m_options, &block|
104
+ Loggability[ Observability ].debug "Wrapped zero-arity method %p: %p" %
105
+ [ name, context ]
106
+ Observability.observer.event( context, **options ) do
107
+ callback.call( *m_args, **m_options, &block ) if callback
108
+ super( *m_args, &block )
109
+ end
110
+ end
111
+ else
112
+ return Proc.new do |*m_args, **m_options, &block|
113
+ Loggability[ Observability ].debug "Wrapped method %p: %p" %
114
+ [ name, context ]
115
+ Observability.observer.event( context, **options ) do
116
+ # :TODO: Freeze or dup the arguments to prevent accidental modification?
117
+ callback.call( *m_args, **m_options, &block ) if callback
118
+ super( *m_args, **m_options, &block )
119
+ end
103
120
  end
104
121
  end
105
122
  end
@@ -36,7 +36,7 @@ class Observability::Collector::RabbitMQ < Observability::Collector
36
36
 
37
37
  ##
38
38
  # The port to bind to
39
- setting :port, default: 15775
39
+ setting :port, default: Observability::DEFAULT_PORT
40
40
 
41
41
  ##
42
42
  # The broker_uri to use when connecting to RabbitMQ
@@ -37,7 +37,7 @@ class Observability::Collector::Timescale < Observability::Collector
37
37
 
38
38
  ##
39
39
  # The port to bind to
40
- setting :port, default: 15775
40
+ setting :port, default: Observability::DEFAULT_PORT
41
41
 
42
42
  ##
43
43
  # The URL of the timescale DB to store events in
@@ -106,7 +106,6 @@ class Observability::Collector::Timescale < Observability::Collector
106
106
 
107
107
  ### Read the next event from the socket
108
108
  def read_next_event
109
- self.log.debug "Reading next event."
110
109
  data = @socket.recv_nonblock( MAX_EVENT_BYTES, exception: false )
111
110
 
112
111
  if data == :wait_readable
@@ -123,6 +122,8 @@ class Observability::Collector::Timescale < Observability::Collector
123
122
 
124
123
  ### Store the specified +event+.
125
124
  def store_event( event )
125
+ self.log.debug "Storing event: %p" % [ event ]
126
+
126
127
  time = event.delete('@timestamp')
127
128
  type = event.delete('@type')
128
129
  version = event.delete('@version')
@@ -3,6 +3,7 @@
3
3
 
4
4
  require 'time'
5
5
  require 'forwardable'
6
+ require 'uuid'
6
7
  require 'loggability'
7
8
  require 'concurrent'
8
9
 
@@ -22,8 +23,23 @@ class Observability::Event
22
23
  log_to :observability
23
24
 
24
25
 
26
+ ### Return a generator that can return a unique ID string for identifying Events
27
+ ### across application boundaries.
28
+ def self::id_generator
29
+ return @id_generator ||= UUID.new
30
+ end
31
+
32
+
33
+ ### Generate a new Event ID.
34
+ def self::generate_id
35
+ return self.id_generator.generate
36
+ end
37
+
38
+
25
39
  ### Create a new event
26
- def initialize( type, **fields )
40
+ def initialize( type, parent=nil, **fields )
41
+ @id = self.class.generate_id
42
+ @parent_id = parent&.id
27
43
  @type = type.freeze
28
44
  @timestamp = Time.now
29
45
  @start = Concurrent.monotonic_time
@@ -35,6 +51,14 @@ class Observability::Event
35
51
  public
36
52
  ######
37
53
 
54
+ ##
55
+ # The ID of the event, used to pass context through application boundaries
56
+ attr_reader :id
57
+
58
+ ##
59
+ # The ID of the containing context event, if there is one
60
+ attr_reader :parent_id
61
+
38
62
  ##
39
63
  # The type of the event, which should be a string of the form: 'foo.bar.baz'
40
64
  attr_reader :type
@@ -71,6 +95,8 @@ class Observability::Event
71
95
  unless @fields.frozen?
72
96
  self.log.debug "Resolving event %#x" % [ self.object_id ]
73
97
  data = self.fields.merge(
98
+ :@id => self.id,
99
+ :@parent_id => self.parent_id,
74
100
  :@type => self.type,
75
101
  :@timestamp => self.timestamp,
76
102
  :@version => FORMAT_VERSION
@@ -45,6 +45,7 @@ module Observability::Instrumentation
45
45
  mod.extend( Loggability )
46
46
  mod.log_to( :observability )
47
47
  mod.instance_variable_set( :@depends_on, Set.new )
48
+ mod.instance_variable_set( :@requires, Set.new )
48
49
  mod.instance_variable_set( :@installation_callbacks, Set.new )
49
50
  mod.singleton_class.attr_reader( :installation_callbacks )
50
51
  else
@@ -81,11 +82,18 @@ module Observability::Instrumentation
81
82
  ### If they are not present when the instrumentation loads, it will be skipped
82
83
  ### entirely.
83
84
  def depends_on( *modules )
84
- @depends_on.merge( modules.flatten(1) )
85
+ @depends_on.merge( modules.flatten )
85
86
  return @depends_on
86
87
  end
87
88
 
88
89
 
90
+ ### Specified +files+ to require if this instrumentation is loaded.
91
+ def requires( *files )
92
+ @requires.merge( files.flatten )
93
+ return @requires
94
+ end
95
+
96
+
89
97
  ### Register a +callback+ that will be called when instrumentation is installed,
90
98
  ### if and only if all of the given +modules+ are present (may be empty).
91
99
  def when_installed( *modules, &callback )
@@ -101,6 +109,9 @@ module Observability::Instrumentation
101
109
 
102
110
  ### Call installation callbacks which meet their prerequistes.
103
111
  def install
112
+ self.requires.each do |file|
113
+ require( file )
114
+ end
104
115
  self.installation_callbacks.each do |callback, dependencies|
105
116
  missing = dependencies.
106
117
  reject {|mod| Observability::Instrumentation.check_for_module(mod) }
@@ -112,6 +123,8 @@ module Observability::Instrumentation
112
123
  self.log.info "Skipping %p: missing %s" % [ callback, missing.join(', ') ]
113
124
  end
114
125
  end
126
+ rescue LoadError => err
127
+ raise "%p while loading instrumentation"
115
128
  end
116
129
 
117
130
  end # module Observability::Instrumentation
@@ -0,0 +1,39 @@
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
3
+
4
+ require 'observability/instrumentation' unless defined?( Observability::Instrumentation )
5
+
6
+
7
+ # Instrumentation for the CZTop library
8
+ # Refs:
9
+ # - https://gitlab.com/paddor/cztop
10
+ module Observability::Instrumentation::CZTop
11
+ extend Observability::Instrumentation
12
+
13
+ depends_on 'CZTop'
14
+
15
+
16
+ when_installed( 'CZTop::Socket' ) do
17
+ CZTop::Socket.extend( Observability )
18
+ CZTop::Socket.observe_method( :CURVE_server! )
19
+ CZTop::Socket.observe_method( :CURVE_client! )
20
+ CZTop::Socket.observe_method( :connect )
21
+ CZTop::Socket.observe_method( :disconnect )
22
+ CZTop::Socket.observe_method( :close )
23
+ CZTop::Socket.observe_method( :bind )
24
+ CZTop::Socket.observe_method( :unbind )
25
+ CZTop::Socket.observe_method( :signal )
26
+ CZTop::Socket.observe_method( :wait )
27
+ end
28
+
29
+
30
+ when_installed( 'CZTop::Message' ) do
31
+ CZTop::Message.extend( Observability )
32
+ CZTop::Message.observe_class_method( :receive_from )
33
+ CZTop::Message.observe_method( :send_to )
34
+ CZTop::Message.observe_method( :<< )
35
+ CZTop::Message.observe_method( :routing_id= )
36
+ end
37
+
38
+ end # module Observability::Instrumentation::CZTop
39
+
@@ -0,0 +1,70 @@
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
3
+
4
+ require 'observability/instrumentation' unless defined?( Observability::Instrumentation )
5
+
6
+
7
+ # Instrumentation for the 'pg' PostgreSQL driver
8
+ # Refs:
9
+ # - https://github.com/ged/ruby-pg
10
+ module Observability::Instrumentation::PG
11
+ extend Observability::Instrumentation
12
+
13
+ depends_on 'PG'
14
+
15
+ requires 'pg_query'
16
+
17
+ when_installed( 'PG::Connection' ) do
18
+ PG::Connection.extend( Observability )
19
+ PG::Connection.observe_class_method( :connect_start )
20
+ PG::Connection.observe_class_method( :ping, timed: true )
21
+ PG::Connection.observe_method( :connect_poll )
22
+ PG::Connection.observe_method( :reset )
23
+ PG::Connection.observe_method( :reset_start )
24
+ PG::Connection.observe_method( :reset_poll )
25
+ PG::Connection.observe_method( :sync_exec )
26
+ PG::Connection.observe_method( :finish )
27
+
28
+ PG::Connection.observe_method( :exec, timed: true, &self.method(:observe_exec) )
29
+ PG::Connection.observe_method( :exec_params, timed: true, &self.method(:observe_exec) )
30
+
31
+ PG::Connection.observe_method( :sync_exec, timed: true, &self.method(:observe_exec) )
32
+ PG::Connection.observe_method( :sync_exec_params, timed: true, &self.method(:observe_exec) )
33
+
34
+ PG::Connection.observe_method( :prepare, timed: true, &self.method(:observe_prepare) )
35
+ PG::Connection.observe_method( :exec_prepared, timed: true, &self.method(:observe_exec_prepared) )
36
+
37
+ PG::Connection.observe_method( :sync_prepare, timed: true, &self.method(:observe_prepare) )
38
+ PG::Connection.observe_method( :sync_exec_prepared, timed: true, &self.method(:observe_exec_prepared) )
39
+ end
40
+
41
+
42
+ ###############
43
+ module_function
44
+ ###############
45
+
46
+ ### Observer callback for the *exec methods.
47
+ def observe_exec( sql, * )
48
+ nsql = PgQuery.normalize( sql )
49
+ Observability.observer.add( query: nsql )
50
+ rescue => err
51
+ Loggability[ Observability ].warn "Couldn't normalize query: %p" % [ sql ]
52
+ end
53
+
54
+
55
+ ### Observer callback for *prepare methods.
56
+ def observe_prepare( name, query, * )
57
+ nsql = PgQuery.normalize( query )
58
+ Observability.observer.add( statement_name: name, query: nsql )
59
+ rescue => err
60
+ Loggability[ Observability ].warn "Couldn't normalize query: %p" % [ sql ]
61
+ end
62
+
63
+
64
+ ### Observer callback for *exec_prepared methods.
65
+ def observe_exec_prepared( name, query, * )
66
+ Observability.observer.add( statement_name: name )
67
+ end
68
+
69
+ end # module Observability::Instrumentation::PG
70
+
@@ -32,6 +32,5 @@ module Observability::Instrumentation::Sequel
32
32
  end
33
33
  end
34
34
 
35
-
36
35
  end # module Observability::Instrumentation::Sequel
37
36
 
@@ -54,7 +54,8 @@ class Observability::Observer
54
54
  type = self.type_from_object( type )
55
55
  fields = self.fields_from_options( options )
56
56
 
57
- event = Observability::Event.new( type, **fields )
57
+ parent = @event_stack.value.last
58
+ event = Observability::Event.new( type, parent, **fields )
58
59
  @event_stack.value.push( event )
59
60
 
60
61
  new_context = @context_stack.value.last&.dup || {}
@@ -11,10 +11,13 @@ module Observability::ObserverHooks
11
11
  ### context, then yield to the method's block. Finish the event when the yield
12
12
  ### returns, handling exceptions that are being raised automatically.
13
13
  def observe( detail, **options, &block )
14
- raise LocalJumpError, "no block given" unless block
15
-
16
- marker = Observability.observer.event( [block, detail], **options )
17
- Observability.observer.finish_after_block( marker, &block )
14
+ if block
15
+ marker = Observability.observer.event( [block, detail], **options )
16
+ Observability.observer.finish_after_block( marker, &block )
17
+ else
18
+ Loggability[ Observability ].warn "No block given for %p -> %p with options: %p" %
19
+ [ self, detail, options ]
20
+ end
18
21
  end
19
22
 
20
23
 
@@ -28,7 +28,7 @@ class Observability::Sender::UDP < Observability::Sender
28
28
 
29
29
  ##
30
30
  # The port to send events to
31
- setting :port, default: 15775
31
+ setting :port, default: Observability::DEFAULT_PORT
32
32
 
33
33
  end
34
34
 
@@ -35,7 +35,7 @@ class Observability::Sender::UdpMulticast < Observability::Sender
35
35
 
36
36
  ##
37
37
  # The port to bind to
38
- setting :port, default: 15775
38
+ setting :port, default: Observability::DEFAULT_PORT
39
39
 
40
40
  end
41
41
 
@@ -35,6 +35,26 @@ describe Observability::Event do
35
35
  end
36
36
 
37
37
 
38
+ it "can be created with a parent event" do
39
+ parent_event = described_class.new( 'acme.server.request', score: 100, time: 48 )
40
+ child_event = described_class.new( 'acme.user.created', parent_event )
41
+
42
+ expect( child_event.parent_id ).to eq( parent_event.id )
43
+ end
44
+
45
+
46
+ it "is created with a unique ID" do
47
+ event1 = described_class.new( 'acme.server.request' )
48
+ event2 = described_class.new( 'acme.server.request' )
49
+
50
+ expect( event1.id ).to be_a( String )
51
+ expect( event1.id.length ).to be > 16
52
+ expect( event2.id ).to be_a( String )
53
+ expect( event2.id.length ).to be == event1.id.length
54
+ expect( event2.id ).to_not eq( event1.id )
55
+ end
56
+
57
+
38
58
  it "returns a structured log entry when resolved" do
39
59
  event = described_class.new( 'acme.user.review', score: 100, time: 48 )
40
60
  expect( event.resolve ).to be_a( Hash ).and( include(score: 100, time: 48) )
@@ -99,7 +119,7 @@ describe Observability::Event do
99
119
 
100
120
  sleep 0.25
101
121
 
102
- expect( event.resolve[:duration] ).to be_within( 0.01 ).of( 0.25 )
122
+ expect( event.resolve[:duration] ).to be_a( Float ).and( be > 0.25 )
103
123
  end
104
124
 
105
125
  end
@@ -34,7 +34,7 @@ describe Observability::Sender::UDP do
34
34
  block.call( *args )
35
35
  end
36
36
  expect( udp_socket ).to receive( :connect ).with( 'localhost', 8787 )
37
- expect( udp_socket ).to receive( :sendmsg_nonblock ) do |msg, flags, **opts|
37
+ expect( udp_socket ).to receive( :sendmsg_nonblock ) do |msg, flags, opts={}|
38
38
  expect( msg ).to match( /\{.*"@type":"acme\.engine\.startup".*\}/ )
39
39
  expect( flags ).to eq( 0 )
40
40
  expect( opts ).to include( exception: false )
@@ -55,7 +55,7 @@ describe Observability::Sender::UDP do
55
55
  block.call( *args )
56
56
  end
57
57
  expect( udp_socket ).to receive( :connect ).with( 'localhost', 8787 )
58
- expect( udp_socket ).to receive( :sendmsg_nonblock ) do |msg, flags, **opts|
58
+ expect( udp_socket ).to receive( :sendmsg_nonblock ) do |msg, flags, opts={}|
59
59
  if !blocked_once
60
60
  blocked_once = true
61
61
  :wait_writable
@@ -147,6 +147,8 @@ RSpec.configure do |config|
147
147
  config.mock_with( :rspec ) do |mock|
148
148
  mock.syntax = :expect
149
149
  end
150
+ config.warnings = true
151
+ config.profile_examples = 5
150
152
 
151
153
  config.include( Loggability::SpecHelpers )
152
154
  config.include( Observability::SpecHelpers )
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: observability
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Granger
@@ -34,7 +34,7 @@ cert_chain:
34
34
  jBZSA+N+xUTgUWpXjjwsLZjzJkhWATJWq+krNXcqpwXo6HsjmdUxoFMt63RBb+sI
35
35
  XrxOxp8o0uOkU7FdLSGsyqJ2LzsR4obN
36
36
  -----END CERTIFICATE-----
37
- date: 2019-10-17 00:00:00.000000000 Z
37
+ date: 2020-02-21 00:00:00.000000000 Z
38
38
  dependencies:
39
39
  - !ruby/object:Gem::Dependency
40
40
  name: concurrent-ruby
@@ -70,42 +70,42 @@ dependencies:
70
70
  requirements:
71
71
  - - "~>"
72
72
  - !ruby/object:Gem::Version
73
- version: '0.11'
73
+ version: '0.15'
74
74
  type: :runtime
75
75
  prerelease: false
76
76
  version_requirements: !ruby/object:Gem::Requirement
77
77
  requirements:
78
78
  - - "~>"
79
79
  - !ruby/object:Gem::Version
80
- version: '0.11'
80
+ version: '0.15'
81
81
  - !ruby/object:Gem::Dependency
82
82
  name: configurability
83
83
  requirement: !ruby/object:Gem::Requirement
84
84
  requirements:
85
85
  - - "~>"
86
86
  - !ruby/object:Gem::Version
87
- version: '3.3'
87
+ version: '4.0'
88
88
  type: :runtime
89
89
  prerelease: false
90
90
  version_requirements: !ruby/object:Gem::Requirement
91
91
  requirements:
92
92
  - - "~>"
93
93
  - !ruby/object:Gem::Version
94
- version: '3.3'
94
+ version: '4.0'
95
95
  - !ruby/object:Gem::Dependency
96
96
  name: pluggability
97
97
  requirement: !ruby/object:Gem::Requirement
98
98
  requirements:
99
99
  - - "~>"
100
100
  - !ruby/object:Gem::Version
101
- version: '0.6'
101
+ version: '0.7'
102
102
  type: :runtime
103
103
  prerelease: false
104
104
  version_requirements: !ruby/object:Gem::Requirement
105
105
  requirements:
106
106
  - - "~>"
107
107
  - !ruby/object:Gem::Version
108
- version: '0.6'
108
+ version: '0.7'
109
109
  - !ruby/object:Gem::Dependency
110
110
  name: msgpack
111
111
  requirement: !ruby/object:Gem::Requirement
@@ -120,6 +120,48 @@ dependencies:
120
120
  - - "~>"
121
121
  - !ruby/object:Gem::Version
122
122
  version: '1.3'
123
+ - !ruby/object:Gem::Dependency
124
+ name: uuid
125
+ requirement: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - "~>"
128
+ - !ruby/object:Gem::Version
129
+ version: '2.3'
130
+ type: :runtime
131
+ prerelease: false
132
+ version_requirements: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - "~>"
135
+ - !ruby/object:Gem::Version
136
+ version: '2.3'
137
+ - !ruby/object:Gem::Dependency
138
+ name: pg
139
+ requirement: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - "~>"
142
+ - !ruby/object:Gem::Version
143
+ version: '1.1'
144
+ type: :development
145
+ prerelease: false
146
+ version_requirements: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - "~>"
149
+ - !ruby/object:Gem::Version
150
+ version: '1.1'
151
+ - !ruby/object:Gem::Dependency
152
+ name: sequel
153
+ requirement: !ruby/object:Gem::Requirement
154
+ requirements:
155
+ - - "~>"
156
+ - !ruby/object:Gem::Version
157
+ version: '5.26'
158
+ type: :development
159
+ prerelease: false
160
+ version_requirements: !ruby/object:Gem::Requirement
161
+ requirements:
162
+ - - "~>"
163
+ - !ruby/object:Gem::Version
164
+ version: '5.26'
123
165
  - !ruby/object:Gem::Dependency
124
166
  name: timecop
125
167
  requirement: !ruby/object:Gem::Requirement
@@ -140,14 +182,14 @@ dependencies:
140
182
  requirements:
141
183
  - - "~>"
142
184
  - !ruby/object:Gem::Version
143
- version: '0.4'
185
+ version: '0.10'
144
186
  type: :development
145
187
  prerelease: false
146
188
  version_requirements: !ruby/object:Gem::Requirement
147
189
  requirements:
148
190
  - - "~>"
149
191
  - !ruby/object:Gem::Version
150
- version: '0.4'
192
+ version: '0.10'
151
193
  - !ruby/object:Gem::Dependency
152
194
  name: simplecov
153
195
  requirement: !ruby/object:Gem::Requirement
@@ -182,7 +224,8 @@ description: |-
182
224
  Majors (@mipsytipsy).
183
225
  email:
184
226
  - ged@faeriemud.org
185
- executables: []
227
+ executables:
228
+ - observability-collector
186
229
  extensions: []
187
230
  extra_rdoc_files: []
188
231
  files:
@@ -198,7 +241,9 @@ files:
198
241
  - lib/observability/event.rb
199
242
  - lib/observability/instrumentation.rb
200
243
  - lib/observability/instrumentation/bunny.rb
244
+ - lib/observability/instrumentation/cztop.rb
201
245
  - lib/observability/instrumentation/grape.rb
246
+ - lib/observability/instrumentation/pg.rb
202
247
  - lib/observability/instrumentation/rack.rb
203
248
  - lib/observability/instrumentation/sequel.rb
204
249
  - lib/observability/observer.rb
@@ -237,7 +282,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
237
282
  - !ruby/object:Gem::Version
238
283
  version: '0'
239
284
  requirements: []
240
- rubygems_version: 3.0.3
285
+ rubygems_version: 3.1.2
241
286
  signing_key:
242
287
  specification_version: 4
243
288
  summary: Observability is a toolkit for instrumenting code to make it more observable.
metadata.gz.sig CHANGED
Binary file