Class: OneApm::TransactionSample::Segment

Inherits:
Object
  • Object
show all
Includes:
Coerce
Defined in:
lib/one_apm/transaction/segment.rb

Direct Known Subclasses

CompositeSegment, SummarySegment

Constant Summary collapse

OA_UNKNOWN_SEGMENT_NAME =
'<unknown>'.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Coerce

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

Constructor Details

#initialize(timestamp, metric_name, segment_id = nil) ⇒ Segment

Returns a new instance of Segment.

[View source]

20
21
22
23
24
# File 'lib/one_apm/transaction/segment.rb', line 20

def initialize(timestamp, metric_name, segment_id=nil)
  @entry_timestamp = timestamp
  @metric_name     = metric_name || OA_UNKNOWN_SEGMENT_NAME
  @segment_id      = segment_id  || object_id
end

Instance Attribute Details

#entry_timestampObject (readonly)

Returns the value of attribute entry_timestamp.


6
7
8
# File 'lib/one_apm/transaction/segment.rb', line 6

def 
  @entry_timestamp
end

#exit_timestampObject (readonly)

The exit timestamp will be relative except for the outermost sample which will have a timestamp.


9
10
11
# File 'lib/one_apm/transaction/segment.rb', line 9

def exit_timestamp
  @exit_timestamp
end

#metric_nameObject

Returns the value of attribute metric_name.


16
17
18
# File 'lib/one_apm/transaction/segment.rb', line 16

def metric_name
  @metric_name
end

#parent_segmentObject

Returns the value of attribute parent_segment.


10
11
12
# File 'lib/one_apm/transaction/segment.rb', line 10

def parent_segment
  @parent_segment
end

#segment_idObject (readonly)

This is only used from developer mode and rpm_site. No new clients should be added.


14
15
16
# File 'lib/one_apm/transaction/segment.rb', line 14

def segment_id
  @segment_id
end

Instance Method Details

#[](key) ⇒ Object

[View source]

119
120
121
# File 'lib/one_apm/transaction/segment.rb', line 119

def [](key)
  params[key]
end

#[]=(key, value) ⇒ Object

[View source]

113
114
115
116
117
# File 'lib/one_apm/transaction/segment.rb', line 113

def []=(key, value)
  # only create a parameters field if a parameter is set; this will save
  # bandwidth etc as most segments have no parameters
  params[key] = value
end

#add_called_segment(s) ⇒ Object

[View source]

32
33
34
35
36
# File 'lib/one_apm/transaction/segment.rb', line 32

def add_called_segment(s)
  @called_segments ||= []
  @called_segments << s
  s.parent_segment = self
end

#called_segmentsObject

[View source]

87
88
89
# File 'lib/one_apm/transaction/segment.rb', line 87

def called_segments
  @called_segments || []
end

#called_segments=(segments) ⇒ Object

[View source]

184
185
186
# File 'lib/one_apm/transaction/segment.rb', line 184

def called_segments=(segments)
  @called_segments = segments
end

#count_segmentsObject

[View source]

107
108
109
110
111
# File 'lib/one_apm/transaction/segment.rb', line 107

def count_segments
  count = 1
  called_segments.each { | seg | count  += seg.count_segments }
  count
end

#durationObject

return the total duration of this segment

[View source]

92
93
94
# File 'lib/one_apm/transaction/segment.rb', line 92

def duration
  (@exit_timestamp - @entry_timestamp).to_f
end

#each_segment(&block) ⇒ Object

call the provided block for this segment and each of the called segments

[View source]

133
134
135
136
137
138
139
140
141
# File 'lib/one_apm/transaction/segment.rb', line 133

def each_segment(&block)
  block.call self

  if @called_segments
    @called_segments.each do |segment|
      segment.each_segment(&block)
    end
  end
end

#each_segment_with_nest_tracking(&block) ⇒ Object

call the provided block for this segment and each of the called segments while keeping track of nested segments

[View source]

145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/one_apm/transaction/segment.rb', line 145

def each_segment_with_nest_tracking(&block)
  summary = block.call self
  summary.current_nest_count += 1 if summary

  if @called_segments
    @called_segments.each do |segment|
      segment.each_segment_with_nest_tracking(&block)
    end
  end

  summary.current_nest_count -= 1 if summary
end

#end_trace(timestamp) ⇒ Object

sets the final timestamp on a segment to indicate the exit point of the segment

[View source]

28
29
30
# File 'lib/one_apm/transaction/segment.rb', line 28

def end_trace(timestamp)
  @exit_timestamp = timestamp
end

#exclusive_durationObject

return the duration of this segment without including the time in the called segments

[View source]

98
99
100
101
102
103
104
105
# File 'lib/one_apm/transaction/segment.rb', line 98

def exclusive_duration
  d = duration

  called_segments.each do |segment|
    d -= segment.duration
  end
  d
end

#explain_sqlObject

[View source]

168
169
170
171
172
173
174
175
176
177
178
# File 'lib/one_apm/transaction/segment.rb', line 168

def explain_sql
  return params[:explain_plan] if params.key?(:explain_plan)

  statement = params[:sql]
  return nil unless statement.respond_to?(:config) &&
                    statement.respond_to?(:explainer)

  OneApm::Agent::Database.explain_sql(statement,
                                        statement.config,
                                        &statement.explainer)
end

#find_segment(id) ⇒ Object

This is only for use by developer mode

[View source]

159
160
161
162
163
164
165
166
# File 'lib/one_apm/transaction/segment.rb', line 159

def find_segment(id)
  return self if segment_id == id
  called_segments.each do |segment|
    found = segment.find_segment(id)
    return found if found
  end
  nil
end

#obfuscated_sqlObject

[View source]

180
181
182
# File 'lib/one_apm/transaction/segment.rb', line 180

def obfuscated_sql
  OneApm::Agent::Database.obfuscate_sql(params[:sql])
end

#paramsObject

[View source]

123
124
125
# File 'lib/one_apm/transaction/segment.rb', line 123

def params
  @params ||= {}
end

#params=(p) ⇒ Object

[View source]

127
128
129
# File 'lib/one_apm/transaction/segment.rb', line 127

def params=(p)
  @params = p
end

#path_stringObject

[View source]

53
54
55
# File 'lib/one_apm/transaction/segment.rb', line 53

def path_string
  "#{metric_name}[#{called_segments.collect {|segment| segment.path_string }.join('')}]"
end

#to_arrayObject

[View source]

44
45
46
47
48
49
50
51
# File 'lib/one_apm/transaction/segment.rb', line 44

def to_array
  [ OneApm::Helper.time_to_millis(@entry_timestamp),
    OneApm::Helper.time_to_millis(@exit_timestamp),
    string(@metric_name),
    (@params || {}) ] +
    [ (@called_segments ? @called_segments.map{|s| s.to_array} : []) ] #+
    # [ '', '' ]
end

#to_debug_str(depth) ⇒ Object

[View source]

66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/one_apm/transaction/segment.rb', line 66

def to_debug_str(depth)
  tab = "  " * depth
  s = tab.clone
  s << ">> #{'%3i ms' % (@entry_timestamp*1000)} [#{self.class.name.split("::").last}] #{metric_name} \n"
  unless params.empty?
    params.each do |k,v|
      s << "#{tab}    -#{'%-16s' % k}: #{v.to_s[0..80]}\n"
    end
  end
  called_segments.each do |cs|
    s << cs.to_debug_str(depth + 1)
  end
  s << tab + "<< "
  s << case @exit_timestamp
       when nil then ' n/a'
       when Numeric then '%3i ms' % (@exit_timestamp*1000)
       else @exit_timestamp.to_s
       end
  s << " #{metric_name}\n"
end

#to_sObject

[View source]

38
39
40
# File 'lib/one_apm/transaction/segment.rb', line 38

def to_s
  to_debug_str(0)
end

#to_s_compactObject

[View source]

57
58
59
60
61
62
63
64
# File 'lib/one_apm/transaction/segment.rb', line 57

def to_s_compact
  str = ""
  str << metric_name
  if called_segments.any?
    str << "{#{called_segments.map { | cs | cs.to_s_compact }.join(",")}}"
  end
  str
end