Class: Kotoshu::Metrics::Collector

Inherits:
Object
  • Object
show all
Defined in:
lib/kotoshu/metrics_collector.rb

Overview

Thread-safe metrics collector.

Tracks performance metrics for spellchecking operations:

  • Lookup counts and timing

  • Cache hit/miss rates

  • Suggestion generation stats

Examples:

collector = Kotoshu::Metrics::Collector.new
collector.record_lookup("hello", result: true, time: 0.5)
collector.stats
# => { lookups: 1, correct_lookups: 1, avg_lookup_time: 0.5, ... }

Instance Method Summary collapse

Constructor Details

#initializeCollector

Initialize a new collector.



19
20
21
22
# File 'lib/kotoshu/metrics_collector.rb', line 19

def initialize
  @mutex = Mutex.new
  reset
end

Instance Method Details

#record_cache(cache_type, hit:) ⇒ Object

Record a cache operation.

Parameters:

  • cache_type (String)

    Type of cache (lookup, suggestion)

  • hit (Boolean)

    True if cache hit



43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/kotoshu/metrics_collector.rb', line 43

def record_cache(cache_type, hit:)
  @mutex.synchronize do
    key = "#{cache_type}_cache_hits".to_sym
    miss_key = "#{cache_type}_cache_misses".to_sym

    if hit
      @metrics[key] += 1
    else
      @metrics[miss_key] += 1
    end
  end
end

#record_lookup(_word, result:, time:) ⇒ Object

Record a lookup operation.

Parameters:

  • word (String)

    The word being looked up

  • result (Boolean)

    The lookup result

  • time (Float)

    Time taken in milliseconds



29
30
31
32
33
34
35
36
37
# File 'lib/kotoshu/metrics_collector.rb', line 29

def record_lookup(_word, result:, time:)
  @mutex.synchronize do
    @metrics[:lookups] += 1
    @metrics[:correct_lookups] += 1 if result
    @metrics[:misspelled_lookups] += 1 unless result

    @metrics[:lookup_times] << time
  end
end

#record_suggestions(_word, count:, time:) ⇒ Object

Record suggestion generation.

Parameters:

  • word (String)

    The input word

  • count (Integer)

    Number of suggestions generated

  • time (Float)

    Time taken in milliseconds



61
62
63
64
65
66
67
68
# File 'lib/kotoshu/metrics_collector.rb', line 61

def record_suggestions(_word, count:, time:)
  @mutex.synchronize do
    @metrics[:suggestion_requests] += 1
    @metrics[:suggestions_generated] += count

    @metrics[:suggestion_times] << time
  end
end

#resetObject

Reset all metrics.



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/kotoshu/metrics_collector.rb', line 80

def reset
  @mutex.synchronize do
    @metrics = {
      lookups: 0,
      correct_lookups: 0,
      misspelled_lookups: 0,
      lookup_times: [],

      lookup_cache_hits: 0,
      lookup_cache_misses: 0,
      suggestion_cache_hits: 0,
      suggestion_cache_misses: 0,

      suggestion_requests: 0,
      suggestions_generated: 0,
      suggestion_times: [],

      started_at: Time.now
    }
  end
end

#statsHash

Get current metrics statistics.

Returns:

  • (Hash)

    Current statistics with computed averages



73
74
75
76
77
# File 'lib/kotoshu/metrics_collector.rb', line 73

def stats
  @mutex.synchronize do
    calculate_stats
  end
end

#to_prometheusString

Export metrics in Prometheus exposition format.

Returns:

  • (String)

    Prometheus format



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/kotoshu/metrics_collector.rb', line 126

def to_prometheus
  s = stats

  lines = []
  lines << "# HELP kotoshu_lookups Total number of word lookups"
  lines << "# TYPE kotoshu_lookups counter"
  lines << "kotoshu_lookups #{s[:lookups]}"

  lines << "# HELP kotoshu_correct_lookups Number of correct word lookups"
  lines << "# TYPE kotoshu_correct_lookups counter"
  lines << "kotoshu_correct_lookups #{s[:correct_lookups]}"

  lines << "# HELP kotoshu_misspelled_lookups Number of misspelled word lookups"
  lines << "# TYPE kotoshu_misspelled_lookups counter"
  lines << "kotoshu_misspelled_lookups #{s[:misspelled_lookups]}"

  lines << "# HELP kotoshu_avg_lookup_time Average lookup time in milliseconds"
  lines << "# TYPE kotoshu_avg_lookup_time gauge"
  lines << "kotoshu_avg_lookup_time #{s[:avg_lookup_time]}"

  lines << "# HELP kotoshu_lookup_cache_hits Number of lookup cache hits"
  lines << "# TYPE kotoshu_lookup_cache_hits counter"
  lines << "kotoshu_lookup_cache_hits #{s[:lookup_cache_hits]}"

  lines << "# HELP kotoshu_lookup_cache_misses Number of lookup cache misses"
  lines << "# TYPE kotoshu_lookup_cache_misses counter"
  lines << "kotoshu_lookup_cache_misses #{s[:lookup_cache_misses]}"

  lines << "# HELP kotoshu_suggestion_requests Number of suggestion requests"
  lines << "# TYPE kotoshu_suggestion_requests counter"
  lines << "kotoshu_suggestion_requests #{s[:suggestion_requests]}"

  lines << "# HELP kotoshu_suggestions_generated Total number of suggestions generated"
  lines << "# TYPE kotoshu_suggestions_generated counter"
  lines << "kotoshu_suggestions_generated #{s[:suggestions_generated]}"

  lines << "# HELP kotoshu_avg_suggestion_time Average suggestion generation time in milliseconds"
  lines << "# TYPE kotoshu_avg_suggestion_time gauge"
  lines << "kotoshu_avg_suggestion_time #{s[:avg_suggestion_time]}"

  lines.join("\n")
end

#to_statsdString

Export metrics in StatsD format.

Returns:

  • (String)

    StatsD protocol lines



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/kotoshu/metrics_collector.rb', line 105

def to_statsd
  s = stats
  prefix = "kotoshu"

  lines = []
  lines << "#{prefix}.lookups:#{s[:lookups]}|c"
  lines << "#{prefix}.correct_lookups:#{s[:correct_lookups]}|c"
  lines << "#{prefix}.misspelled_lookups:#{s[:misspelled_lookups]}|c"
  lines << "#{prefix}.avg_lookup_time:#{s[:avg_lookup_time]}|ms"
  lines << "#{prefix}.lookup_cache_hits:#{s[:lookup_cache_hits]}|c"
  lines << "#{prefix}.lookup_cache_misses:#{s[:lookup_cache_misses]}|c"
  lines << "#{prefix}.suggestion_requests:#{s[:suggestion_requests]}|c"
  lines << "#{prefix}.suggestions_generated:#{s[:suggestions_generated]}|c"
  lines << "#{prefix}.avg_suggestion_time:#{s[:avg_suggestion_time]}|ms"

  lines.join("\n")
end