Class: NewRelic::TransactionSample

Inherits:
Object
  • Object
show all
Includes:
Coerce, TransactionAnalysis
Defined in:
lib/new_relic/transaction_sample.rb,
lib/new_relic/transaction_sample/segment.rb,
lib/new_relic/transaction_sample/fake_segment.rb,
lib/new_relic/transaction_sample/summary_segment.rb,
lib/new_relic/transaction_sample/composite_segment.rb

Defined Under Namespace

Classes: CompositeSegment, FakeSegment, Segment, SummarySegment

Constant Summary collapse

@@start_time =
Time.now

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Coerce

#float, #int, #int_or_nil, #log_failure, #string

Methods included from TransactionAnalysis

#breakdown_data, #database_time, #render_time, #sql_segments

Constructor Details

#initialize(time = Time.now.to_f, sample_id = nil) ⇒ TransactionSample

Returns a new instance of TransactionSample.



26
27
28
29
30
31
32
33
34
35
# File 'lib/new_relic/transaction_sample.rb', line 26

def initialize(time = Time.now.to_f, sample_id = nil)
  @sample_id = sample_id || object_id
  @start_time = time
  @params = { :segment_count => -1, :request_params => {} }
  @segment_count = -1
  @root_segment = create_segment 0.0, "ROOT"

  @guid = generate_guid
  NewRelic::Agent::TransactionState.get.request_guid = @guid
end

Instance Attribute Details

#finishedObject

Returns the value of attribute finished.



18
19
20
# File 'lib/new_relic/transaction_sample.rb', line 18

def finished
  @finished
end

#force_persistObject

Returns the value of attribute force_persist.



18
19
20
# File 'lib/new_relic/transaction_sample.rb', line 18

def force_persist
  @force_persist
end

#guidObject

Returns the value of attribute guid.



18
19
20
# File 'lib/new_relic/transaction_sample.rb', line 18

def guid
  @guid
end

#paramsObject

Returns the value of attribute params.



18
19
20
# File 'lib/new_relic/transaction_sample.rb', line 18

def params
  @params
end

#profileObject

Returns the value of attribute profile.



18
19
20
# File 'lib/new_relic/transaction_sample.rb', line 18

def profile
  @profile
end

#root_segmentObject

Returns the value of attribute root_segment.



18
19
20
# File 'lib/new_relic/transaction_sample.rb', line 18

def root_segment
  @root_segment
end

#sample_idObject (readonly)

Returns the value of attribute sample_id.



20
21
22
# File 'lib/new_relic/transaction_sample.rb', line 20

def sample_id
  @sample_id
end

#thresholdObject

Returns the value of attribute threshold.



18
19
20
# File 'lib/new_relic/transaction_sample.rb', line 18

def threshold
  @threshold
end

#xray_session_idObject

Returns the value of attribute xray_session_id.



18
19
20
# File 'lib/new_relic/transaction_sample.rb', line 18

def xray_session_id
  @xray_session_id
end

Instance Method Details

#count_segmentsObject



37
38
39
# File 'lib/new_relic/transaction_sample.rb', line 37

def count_segments
  @segment_count
end

#create_segment(relative_timestamp, metric_name = nil, segment_id = nil) ⇒ Object

relative_timestamp is seconds since the start of the transaction

Raises:

  • (TypeError)


105
106
107
108
109
110
# File 'lib/new_relic/transaction_sample.rb', line 105

def create_segment(relative_timestamp, metric_name=nil, segment_id = nil)
  raise TypeError.new("Frozen Transaction Sample") if finished
  @params[:segment_count] += 1
  @segment_count += 1
  NewRelic::TransactionSample::Segment.new(relative_timestamp, metric_name, segment_id)
end

#durationObject



112
113
114
# File 'lib/new_relic/transaction_sample.rb', line 112

def duration
  root_segment.duration
end

#each_segment(&block) ⇒ Object

Iterates recursively over each segment in the entire transaction sample tree



118
119
120
# File 'lib/new_relic/transaction_sample.rb', line 118

def each_segment(&block)
  @root_segment.each_segment(&block)
end

#each_segment_with_nest_tracking(&block) ⇒ Object

Iterates recursively over each segment in the entire transaction sample tree while keeping track of nested segments



124
125
126
# File 'lib/new_relic/transaction_sample.rb', line 124

def each_segment_with_nest_tracking(&block)
  @root_segment.each_segment_with_nest_tracking(&block)
end

#ensure_segment_count_set(count) ⇒ Object

makes sure that the parameter cache for segment count is set to the correct value



43
44
45
# File 'lib/new_relic/transaction_sample.rb', line 43

def ensure_segment_count_set(count)
  params[:segment_count] ||= count
end

#find_segment(id) ⇒ Object

Searches the tree recursively for the segment with the given id. note that this is an internal id, not an ActiveRecord id



134
135
136
# File 'lib/new_relic/transaction_sample.rb', line 134

def find_segment(id)
  @root_segment.find_segment(id)
end

#force_persist_sample?Boolean

Returns:

  • (Boolean)


205
206
207
208
# File 'lib/new_relic/transaction_sample.rb', line 205

def force_persist_sample?
  NewRelic::Agent::TransactionState.get.request_token &&
    self.duration > NewRelic::Agent::TransactionState.get.transaction.apdex_t
end

#forced?Boolean

Returns:

  • (Boolean)


100
101
102
# File 'lib/new_relic/transaction_sample.rb', line 100

def forced?
  !!@force_persist || !int_or_nil(xray_session_id).nil?
end

#omit_segments_with(regex) ⇒ Object

return a new transaction sample that treats segments with the given regular expression in their name as if they were never called at all. This allows us to strip out segments from traces captured in development environment that would not normally show up in production (like Rails/Application Code Loading)



165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/new_relic/transaction_sample.rb', line 165

def omit_segments_with(regex)
  regex = Regexp.new(regex)

  sample = TransactionSample.new(@start_time, sample_id)

  sample.params = params.dup
  sample.params[:segment_count] = 0

  delta = build_segment_with_omissions(sample, 0.0, @root_segment, sample.root_segment, regex)
  sample.root_segment.end_trace(@root_segment.exit_timestamp - delta)
  sample.profile = self.profile
  sample
end

#path_stringObject



88
89
90
# File 'lib/new_relic/transaction_sample.rb', line 88

def path_string
  @root_segment.path_string
end

#prepare_to_send(options = {}) ⇒ Object

Return a new transaction sample that can be sent to the New Relic service. This involves potentially one or more of the following options

:explain_sql : run EXPLAIN on all queries whose response times equal the value for this key
    (for example :explain_sql => 2.0 would explain everything over 2 seconds.  0.0 would explain everything.)
:keep_backtraces : keep backtraces, significantly increasing size of trace (off by default)
:record_sql => [ :raw | :obfuscated] : copy over the sql, obfuscating if necessary


187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/new_relic/transaction_sample.rb', line 187

def prepare_to_send(options={})
  sample = TransactionSample.new(@start_time, sample_id)

  sample.params.merge! self.params
  sample.guid = self.guid
  sample.force_persist = self.force_persist if self.force_persist
  sample.xray_session_id = self.xray_session_id

  build_segment_for_transfer(sample, @root_segment, sample.root_segment, options)

  sample.root_segment.end_trace(@root_segment.exit_timestamp)
  sample
end

#set_custom_param(name, value) ⇒ Object



56
57
58
59
# File 'lib/new_relic/transaction_sample.rb', line 56

def set_custom_param(name, value)
  @params[:custom_params] ||= {}
  @params[:custom_params][name] = value
end

#start_timeObject



84
85
86
# File 'lib/new_relic/transaction_sample.rb', line 84

def start_time
  Time.at(@start_time)
end

#timestampObject

offset from start of app



48
49
50
# File 'lib/new_relic/transaction_sample.rb', line 48

def timestamp
  @start_time - @@start_time.to_f
end

#to_arrayObject



63
64
65
66
67
68
# File 'lib/new_relic/transaction_sample.rb', line 63

def to_array
  [ float(@start_time),
    @params[:request_params],
    @params[:custom_params],
    @root_segment.to_array ]
end

#to_collector_array(encoder) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/new_relic/transaction_sample.rb', line 70

def to_collector_array(encoder)
  trace_tree = encoder.encode(self.to_array)
  [ Helper.time_to_millis(@start_time),
    Helper.time_to_millis(duration),
    string(transaction_name),
    string(@params[:uri]),
    trace_tree,
    string(@guid),
    nil,
    forced?,
    int_or_nil(xray_session_id)
  ]
end

#to_jsonObject



52
53
54
# File 'lib/new_relic/transaction_sample.rb', line 52

def to_json
  JSON.dump(self.to_array)
end

#to_sObject



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/new_relic/transaction_sample.rb', line 138

def to_s
  s = "Transaction Sample collected at #{start_time}\n"
  s << "  {\n"
  s << "  Path: #{params[:path]} \n"

  params.each do |k,v|
    next if k == :path
    s << "  #{k}: " <<
    case v
      when Enumerable then v.map(&:to_s).sort.join("; ")
      when String then v
      when Float then '%6.3s' % v
      when Fixnum then v.to_s
      when nil then ''
    else
      raise "unexpected value type for #{k}: '#{v}' (#{v.class})"
    end << "\n"
  end
  s << "  }\n\n"
  s <<  @root_segment.to_debug_str(0)
end

#to_s_compactObject



128
129
130
# File 'lib/new_relic/transaction_sample.rb', line 128

def to_s_compact
  @root_segment.to_s_compact
end

#transaction_nameObject



92
93
94
# File 'lib/new_relic/transaction_sample.rb', line 92

def transaction_name
  @params[:path]
end

#transaction_name=(new_name) ⇒ Object



96
97
98
# File 'lib/new_relic/transaction_sample.rb', line 96

def transaction_name=(new_name)
  @params[:path] = new_name
end