vigiles 0.1.0.pre.beta8 → 0.1.0.pre.beta10

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
2
  SHA256:
3
- metadata.gz: 9ae2f2c7a8b3a0642d0fb228264821c882b9b98cf7a59380dcf139e1a514221c
4
- data.tar.gz: 7ca651c0579f55907094ade6d43825cae72627fef6c8e995fd621d7f94e9acc4
3
+ metadata.gz: cceedc075f3779ec0c77cc04a35058734cd2d2396ea67b95c6b1117763caa719
4
+ data.tar.gz: 3ea39ba08de23e8b51b66bc0e4b4cc38ca52e467ccdf671d49cdb52e7ff98453
5
5
  SHA512:
6
- metadata.gz: a942ca1c61aefdb02f843b7d3defd046ebce9935b47d406e8193c2c54b7befd360b19f974618f24f42c23278e8c313be513d25b68fece32985d2272f504b8c2e
7
- data.tar.gz: 2a70d2be56a5c86fa4f30f881b6b9002e6967cfe6cd04339f1bb4f70f1a6f8bd28b6ae34281a19b5504ad82a594fa8b0660591ff0ab28e9ad3fdd94214c26d78
6
+ metadata.gz: a884ac729b71b8351aae48ce0515d2a803f6358f03d03cc3efbbdb5304c2d811de6401eea203329fbea433c9d3896d77fc2f25bb0947226a689c1e466f64b8fd
7
+ data.tar.gz: 8a2b120ce179764649389ce270a45015e8e67379f70cb40035cef4f58cf321c6e81a376b62482842825599d7c101fec4ee69aa60aa9889146f6ed2f1daa15297
@@ -35,12 +35,21 @@ module Vigiles
35
35
  const :url, T.any(URI::HTTPS, URI::HTTP)
36
36
  const :id, String
37
37
 
38
+ sig { params(header_key: String).returns(String) }
39
+ private_class_method def self.best_effort_unfuck_http_header(header_key)
40
+ (header_key.starts_with?("HTTP_") ? T.must(header_key[5..]) : header_key)
41
+ .split(/_/)
42
+ .map(&:titlecase)
43
+ .join("-")
44
+ end
45
+
38
46
  sig { params(request: ActionDispatch::Request).returns(Request) }
39
47
  def self.from(request)
40
48
  preferred_headers = Vigiles.spec.request_headers
41
49
  available_headers = request.original_headers
42
50
  recorded_headers = (available_headers if preferred_headers.empty?)
43
- recorded_headers ||= preferred_headers.to_h { |h| [h, available_headers[h]] }
51
+ recorded_headers ||= preferred_headers.to_h { [_1, available_headers[_1]] }
52
+ unfucked_headers = recorded_headers.transform_keys { best_effort_unfuck_http_header _1 }
44
53
 
45
54
  Request.new(
46
55
  content_type: request.content_type || (raise InvalidParameterError, "content_type"),
@@ -48,7 +57,7 @@ module Vigiles
48
57
  timestamp: DateTime.now,
49
58
  remote_ip: IPAddr.new(request.remote_ip),
50
59
  protocol: request.protocol,
51
- headers: recorded_headers,
60
+ headers: unfucked_headers,
52
61
  origin: request.origin || "unknown_origin_url",
53
62
  payload: request.body.read,
54
63
  http_method: Types::HttpMethod.deserialize(request.method),
@@ -27,48 +27,5 @@ module Vigiles
27
27
 
28
28
  recorder.record(req:, res:)
29
29
  end
30
-
31
- sig do
32
- params(
33
- request: Request,
34
- response: Response,
35
- metadata: Metadata,
36
- extras: Extras
37
- )
38
- .returns(T.nilable(Conversation))
39
- end
40
- private_class_method def self.record_json_conversation(request:, response:, metadata:, extras:)
41
- Conversation.create!(
42
- request_content_type: request.content_type,
43
- request_user_agent: request.user_agent,
44
- request_timestamp: request.timestamp,
45
- request_remote_ip: request.remote_ip,
46
- request_protocol: request.protocol,
47
- request_headers: request.headers,
48
- request_origin: request.origin,
49
- request_payload: request.payload,
50
- request_method: request.http_method.serialize,
51
- request_path: request.path,
52
- request_url: request.url,
53
- request_id: request.id,
54
- response_content_type: response.content_type,
55
- response_headers: response.headers,
56
- response_payload: response.payload,
57
- response_status: response.status
58
- )
59
- rescue => e
60
- end
61
-
62
- sig { params(request: Request, response: Response, metadata: Metadata, extras: Extras).returns(T.nilable(Conversation)) }
63
- private_class_method def self.record_html_conversation(request:, response:, metadata:, extras:); end
64
-
65
- sig { params(request: Request, response: Response, metadata: Metadata, extras: Extras).returns(T.nilable(Conversation)) }
66
- private_class_method def self.record_conversation_with_unknown_content_type(
67
- request:,
68
- response:,
69
- metadata:,
70
- extras:
71
- )
72
- end
73
30
  end
74
31
  end
@@ -25,7 +25,6 @@ module Vigiles
25
25
 
26
26
  response = Response.from(res)
27
27
  request = Request.from(req)
28
-
29
28
  Conversation.create!(
30
29
  request_content_type: request.content_type,
31
30
  request_user_agent: request.user_agent,
@@ -2,15 +2,25 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "logger"
5
+
5
6
  module Vigiles
6
7
  module Middleware
7
8
  class RecordConversation
8
- sig { params(app: T.untyped).void }
9
- def initialize(app)
10
- @app = app
9
+ sig { returns(Vigiles::Options) }
10
+ attr_reader :options
11
+
12
+ delegate \
13
+ :capture_exception,
14
+ :logger,
15
+ to: :options
16
+
17
+ sig { params(app: T.untyped, options: Vigiles::Options).void }
18
+ def initialize(app, options=Vigiles::Options.make_default_options)
19
+ @app = app
20
+ @options = options
11
21
  end
12
22
 
13
- sig { params(env: T.untyped).returns(T.untyped) }
23
+ sig { params(env: T::Hash[T.untyped, T.untyped]).returns(T.untyped) }
14
24
  def call(env)
15
25
  req = ActionDispatch::Request.new(env)
16
26
  record_conversation(req) do
@@ -20,11 +30,29 @@ module Vigiles
20
30
 
21
31
  sig { params(req: ActionDispatch::Request, blk: T.proc.returns(T.untyped)).returns(T.untyped) }
22
32
  private def record_conversation(req, &blk)
23
- res = Rack::Response[*blk.call]
24
- Vigiles.maybe_record_conversation(req:, res:)
25
- res.to_a
26
- ensure
27
- res.to_a
33
+ rack_response = blk.call
34
+ begin
35
+ res = Rack::Response[*rack_response]
36
+ convo = Vigiles.maybe_record_conversation(req:, res:)
37
+ logger.info \
38
+ "[vigiles] conversation recorder: " \
39
+ "conversation=#{convo.nil? ? "not_recorded" : convo.id} " \
40
+ "request=#{req.request_id}"
41
+ rescue => e
42
+ capture_exception.call(e)
43
+ logger.warn \
44
+ "[vigiles] conversation recorder error: " \
45
+ "error_message=#{e.message} " \
46
+ "error_class=#{e.class}"
47
+ ensure
48
+ # no matter what happens we shouldn't prevent the rack
49
+ # response from being returned. at this point, the only
50
+ # thing that could throw execution into this branch is
51
+ # an exception when the `capture_exception` proc is
52
+ # invoked.
53
+ rack_response
54
+ end
55
+ rack_response
28
56
  end
29
57
  end
30
58
  end
@@ -0,0 +1,19 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ require "logger"
5
+
6
+ module Vigiles
7
+ class Options < T::Struct
8
+ const :capture_exception, T.proc.params(a0: StandardError).void
9
+ const :logger, ::Logger
10
+
11
+ sig { returns(Options) }
12
+ def self.make_default_options
13
+ Options.new(
14
+ logger: T.unsafe(Rails).logger, # you should be using this within rails.
15
+ capture_exception: ->(e) { e } # a no-op exception capturer.
16
+ )
17
+ end
18
+ end
19
+ end
data/lib/vigiles/spec.rb CHANGED
@@ -3,9 +3,9 @@
3
3
 
4
4
  module Vigiles
5
5
  class Spec < T::Struct
6
- const :request_content_types, T::Set[String]
7
- const :request_headers, T::Set[String]
8
- const :recorders, T::Hash[String, ConversationRecorder]
6
+ const :request_content_types, T::Set[String]
7
+ const :request_headers, T::Set[String]
8
+ const :recorders, T::Hash[String, ConversationRecorder]
9
9
 
10
10
  sig { returns(Spec) }
11
11
  def self.make_default_spec
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Vigiles
5
- VERSION = "0.1.0-beta8"
5
+ VERSION = "0.1.0-beta10"
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vigiles
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.pre.beta8
4
+ version: 0.1.0.pre.beta10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yaw Boakye
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-05-24 00:00:00.000000000 Z
11
+ date: 2024-05-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sorbet-runtime
@@ -225,6 +225,7 @@ files:
225
225
  - lib/vigiles/conversation_recorders/application_json.rb
226
226
  - lib/vigiles/conversation_recorders/unknown.rb
227
227
  - lib/vigiles/middleware/record_conversation.rb
228
+ - lib/vigiles/options.rb
228
229
  - lib/vigiles/spec.rb
229
230
  - lib/vigiles/types.rb
230
231
  - lib/vigiles/utilities/uri.rb