# TraceLocation
TraceLocation helps you get tracing the source location of codes, and helps you can get reading the huge open souce libraries in Ruby.
## Installation
Add this line to your application's Gemfile:
```ruby
gem 'trace_location'
```
And then execute:
$ bundle
Or install it yourself as:
$ gem install trace_location
## Usage
You just surround the code which you want to track the process.
### Example 01. Track the validation process of Active Record
```
% bin/rails c
irb(main):001:0> book = Book.new(title: "My Book Title")
irb(main):002:0> TraceLocation.trace(ignore: /active_support/) { book.validate }
Created at /path/to/sampleapp/log/trace_location-2019060401061559579741.md
=> true
```
Then you can get a markdown file like this:
--
Generated by [trace_location](https://github.com/yhirano55/trace_location) at 2019-06-04 01:35:41 +0900
activerecord-5.2.3/lib/active_record/validations.rb:65
##### ActiveRecord::Validations#valid?
```ruby
def valid?(context = nil)
context ||= default_validation_context
output = super(context)
errors.empty? && output
end
# called from (irb):2
```
activerecord-5.2.3/lib/active_record/validations.rb:75
##### ActiveRecord::Validations#default_validation_context
```ruby
def default_validation_context
new_record? ? :create : :update
end
# called from activerecord-5.2.3/lib/active_record/validations.rb:66
```
activerecord-5.2.3/lib/active_record/persistence.rb:231
##### ActiveRecord::Persistence#new_record?
```ruby
def new_record?
sync_with_transaction_state
@new_record
end
# called from activerecord-5.2.3/lib/active_record/validations.rb:76
```
activerecord-5.2.3/lib/active_record/transactions.rb:490
##### ActiveRecord::Transactions#sync_with_transaction_state
```ruby
def sync_with_transaction_state
update_attributes_from_transaction_state(@transaction_state)
end
# called from activerecord-5.2.3/lib/active_record/persistence.rb:232
```
activerecord-5.2.3/lib/active_record/transactions.rb:494
##### ActiveRecord::Transactions#update_attributes_from_transaction_state
```ruby
def update_attributes_from_transaction_state(transaction_state)
if transaction_state && transaction_state.finalized?
restore_transaction_record_state(transaction_state.fully_rolledback?) if transaction_state.rolledback?
force_clear_transaction_record_state if transaction_state.fully_committed?
clear_transaction_record_state if transaction_state.fully_completed?
end
end
# called from activerecord-5.2.3/lib/active_record/transactions.rb:491
```
activemodel-5.2.3/lib/active_model/validations.rb:336
##### ActiveModel::Validations#valid?
```ruby
def valid?(context = nil)
current_context, self.validation_context = validation_context, context
errors.clear
run_validations!
ensure
self.validation_context = current_context
end
# called from activerecord-5.2.3/lib/active_record/validations.rb:67
```
activemodel-5.2.3/lib/active_model/validations.rb:303
##### ActiveModel::Validations#errors
```ruby
def errors
@errors ||= Errors.new(self)
end
# called from activemodel-5.2.3/lib/active_model/validations.rb:338
```
activemodel-5.2.3/lib/active_model/errors.rb:74
##### ActiveModel::Errors#initialize
```ruby
def initialize(base)
@base = base
@messages = apply_default_array({})
@details = apply_default_array({})
end
# called from activemodel-5.2.3/lib/active_model/validations.rb:304
```
activemodel-5.2.3/lib/active_model/errors.rb:470
##### ActiveModel::Errors#apply_default_array
```ruby
def apply_default_array(hash)
hash.default_proc = proc { |h, key| h[key] = [] }
hash
end
# called from activemodel-5.2.3/lib/active_model/errors.rb:76
```
activemodel-5.2.3/lib/active_model/errors.rb:470
##### ActiveModel::Errors#apply_default_array
```ruby
def apply_default_array(hash)
hash.default_proc = proc { |h, key| h[key] = [] }
hash
end
# called from activemodel-5.2.3/lib/active_model/errors.rb:77
```
activemodel-5.2.3/lib/active_model/errors.rb:115
##### ActiveModel::Errors#clear
```ruby
def clear
messages.clear
details.clear
end
# called from activemodel-5.2.3/lib/active_model/validations.rb:338
```
activemodel-5.2.3/lib/active_model/validations/callbacks.rb:117
##### ActiveModel::Validations::Callbacks#run_validations!
```ruby
def run_validations!
_run_validation_callbacks { super }
end
# called from activemodel-5.2.3/lib/active_model/validations.rb:339
```
activemodel-5.2.3/lib/active_model/validations.rb:408
##### ActiveModel::Validations#run_validations!
```ruby
def run_validations!
_run_validate_callbacks
errors.empty?
end
# called from activemodel-5.2.3/lib/active_model/validations/callbacks.rb:118
```
activemodel-5.2.3/lib/active_model/validations.rb:303
##### ActiveModel::Validations#errors
```ruby
def errors
@errors ||= Errors.new(self)
end
# called from activemodel-5.2.3/lib/active_model/validations.rb:410
```
activemodel-5.2.3/lib/active_model/errors.rb:209
##### ActiveModel::Errors#empty?
```ruby
def empty?
size.zero?
end
# called from activemodel-5.2.3/lib/active_model/validations.rb:410
```
activemodel-5.2.3/lib/active_model/errors.rb:179
##### ActiveModel::Errors#size
```ruby
def size
values.flatten.size
end
# called from activemodel-5.2.3/lib/active_model/errors.rb:210
```
activemodel-5.2.3/lib/active_model/errors.rb:188
##### ActiveModel::Errors#values
```ruby
def values
messages.select do |key, value|
!value.empty?
end.values
end
# called from activemodel-5.2.3/lib/active_model/errors.rb:180
```
activemodel-5.2.3/lib/active_model/validations.rb:303
##### ActiveModel::Validations#errors
```ruby
def errors
@errors ||= Errors.new(self)
end
# called from activerecord-5.2.3/lib/active_record/validations.rb:68
```
activemodel-5.2.3/lib/active_model/errors.rb:209
##### ActiveModel::Errors#empty?
```ruby
def empty?
size.zero?
end
# called from activerecord-5.2.3/lib/active_record/validations.rb:68
```
activemodel-5.2.3/lib/active_model/errors.rb:179
##### ActiveModel::Errors#size
```ruby
def size
values.flatten.size
end
# called from activemodel-5.2.3/lib/active_model/errors.rb:210
```
activemodel-5.2.3/lib/active_model/errors.rb:188
##### ActiveModel::Errors#values
```ruby
def values
messages.select do |key, value|
!value.empty?
end.values
end
# called from activemodel-5.2.3/lib/active_model/errors.rb:180
```
### Example 02. Track the lifecycle of Rails application
```
% bin/rails c
irb(main):001:0> env = Rack::MockRequest.env_for('http://localhost:3000/books')
irb(main):002:0> TraceLocation.trace(format: :log) { status, headers, body = Rails.application.call(env) }
Created at /path/to/sampleapp/log/trace_location-2019050602051557077971.log
=> true
```
Then you can get a log like this:
```
Logged by TraceLocation gem at 2019-05-06 02:39:31 +0900
https://github.com/yhirano55/trace_location
[Tracing events] C: Call, R: Return
C railties-5.2.3/lib/rails.rb:39 [Rails.application]
R railties-5.2.3/lib/rails.rb:41 [Rails.application]
C railties-5.2.3/lib/rails/engine.rb:522 [Rails::Engine#call]
C railties-5.2.3/lib/rails/application.rb:607 [Rails::Application#build_request]
C railties-5.2.3/lib/rails/engine.rb:705 [Rails::Engine#build_request]
C railties-5.2.3/lib/rails/application.rb:247 [Rails::Application#env_config]
C railties-5.2.3/lib/rails/engine.rb:528 [Rails::Engine#env_config]
R railties-5.2.3/lib/rails/engine.rb:530 [Rails::Engine#env_config]
C railties-5.2.3/lib/rails/application.rb:372 [Rails::Application#config]
R railties-5.2.3/lib/rails/application.rb:374 [Rails::Application#config]
C railties-5.2.3/lib/rails/application.rb:372 [Rails::Application#config]
R railties-5.2.3/lib/rails/application.rb:374 [Rails::Application#config]
C railties-5.2.3/lib/rails/application.rb:394 [Rails::Application#secrets]
R railties-5.2.3/lib/rails/application.rb:414 [Rails::Application#secrets]
C activesupport-5.2.3/lib/active_support/ordered_options.rb:41 [ActiveSupport::OrderedOptions#method_missing]
C activesupport-5.2.3/lib/active_support/ordered_options.rb:37 [ActiveSupport::OrderedOptions#[]]
R activesupport-5.2.3/lib/active_support/ordered_options.rb:39 [ActiveSupport::OrderedOptions#[]]
R activesupport-5.2.3/lib/active_support/ordered_options.rb:54 [ActiveSupport::OrderedOptions#method_missing]
C railties-5.2.3/lib/rails/application.rb:428 [Rails::Application#secret_key_base]
C railties-5.2.3/lib/rails.rb:72 [Rails.env]
R railties-5.2.3/lib/rails.rb:74 [Rails.env]
C activesupport-5.2.3/lib/active_support/string_inquirer.rb:26 [ActiveSupport::StringInquirer#method_missing]
R activesupport-5.2.3/lib/active_support/string_inquirer.rb:32 [ActiveSupport::StringInquirer#method_missing]
C railties-5.2.3/lib/rails/application.rb:394 [Rails::Application#secrets]
R railties-5.2.3/lib/rails/application.rb:414 [Rails::Application#secrets]
C activesupport-5.2.3/lib/active_support/ordered_options.rb:41 [ActiveSupport::OrderedOptions#method_missing]
C activesupport-5.2.3/lib/active_support/ordered_options.rb:37 [ActiveSupport::OrderedOptions#[]]
R activesupport-5.2.3/lib/active_support/ordered_options.rb:39 [ActiveSupport::OrderedOptions#[]]
R activesupport-5.2.3/lib/active_support/ordered_options.rb:54 [ActiveSupport::OrderedOptions#method_missing]
R railties-5.2.3/lib/rails/application.rb:436 [Rails::Application#secret_key_base]
..................
(an omission)
..................
```
## License
[MIT License](https://opensource.org/licenses/MIT)