Module: Logging::ThirdPartyTransaction::ScopedInstanceMethods

Defined in:
lib/logging/third_party_transaction.rb

Overview

these will be included after instance instantiation, making them available to the instance and retaining their scope.

Instance Method Summary collapse

Instance Method Details

#default_logsObject



82
83
84
85
86
# File 'lib/logging/third_party_transaction.rb', line 82

def default_logs
  {
    process_id: Process.pid
  }
end

#log_3pi_begin(method_name, additional_class_logs, additional_instance_logs) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/logging/third_party_transaction.rb', line 47

def log_3pi_begin(method_name, additional_class_logs, additional_instance_logs)
  @start_time = Time.current

  log = {
    start_time: @start_time.to_s,
    wrapped_method: "#{self.class}##{method_name}"
  }

  log.merge!(default_logs)
     .merge!(additional_class_logs)
     .merge!(parse_instance_logs(additional_instance_logs))

  Rails.logger.info(log)
rescue => e
  Rails.logger.error(e)
end

#log_3pi_complete(method_name, additional_class_logs, additional_instance_logs) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/logging/third_party_transaction.rb', line 64

def log_3pi_complete(method_name, additional_class_logs, additional_instance_logs)
  now = Time.current

  log = {
    upload_duration: (now - @start_time).to_f,
    wrapped_method: "#{self.class}##{method_name}",
    end_time: now.to_s
  }

  log.merge!(default_logs)
     .merge!(additional_class_logs)
     .merge!(parse_instance_logs(additional_instance_logs))

  Rails.logger.info(log)
rescue => e
  Rails.logger.error(e)
end

#parse_instance_logs(additional_instance_logs) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/logging/third_party_transaction.rb', line 88

def parse_instance_logs(additional_instance_logs)
  # call method chains on instance and return a hash of values, e.g.
  # HAPPY PATH (where my_instance.user_account.id == s0meUs3r-Id-V@Lu3')
  # { user_uuid: [:user_account, :id] }
  # will be translated to
  # { user_uuid: 's0meUs3r-Id-V@Lu3' }
  #
  # or
  #
  # SAD PATH (safe)
  # { user_uuid: [:user_account, :id, :non_working_method, :something_else_that_breaks] }
  # will be translated to
  # { user_uuid: nil }
  {}.tap do |obj|
    additional_instance_logs.each do |key, method_chain|
      # prevent a usecase error where someone didn't pass a method chain
      # to an instance log
      next unless method_chain.present? && method_chain.is_a?(Array)

      # call each method in the passed chain sequentially.  Each sequential
      # method call is performed on the result of the previous method call
      # The first method is called on `self`, which is the object context
      # from which we are logging, thus performing this method chain at
      # the instance level, with all of it's available context.
      obj[key] = method_chain.inject(self) do |result, meth|
        # we need to allow for silent failures if a method is not defined.
        # `.try` would not work for private methods, such as `current_user`,
        # so we use `.respond_to?(<method>, true)` where `true` indicates
        # a check against both public and private methods.  This is
        # logically equivalent to using `.try` for each method, however
        # `.send` is required to fully access the instance context.
        result.send(meth) if result.respond_to?(meth, true)
      end
    end
  end
end