Module: DulyNoted

Extended by:
DulyNoted
Includes:
Helpers
Included in:
DulyNoted
Defined in:
lib/duly_noted.rb,
lib/duly_noted/helpers.rb,
lib/duly_noted/version.rb

Overview

The DulyNoted module contains four main methods:

  • ‘track`

  • ‘update`

  • ‘query`

  • ‘count`

Defined Under Namespace

Modules: Helpers

Constant Summary collapse

VERSION =
"0.1.0"

Instance Method Summary collapse

Methods included from Helpers

#normalize, #parse_time_range

Instance Method Details

#count(metric_name, options = {}) ⇒ Object

##Count

_parameters: ‘metric_name`, `for`(required if set when created), `time_start`(optional), `time_end`(optional)_

Count will return the number of events logged in a given time range, or if no time range is given, the total count.

‘metric_name`: The name of the metric to query, ex: `page_views`, `downloads`

‘for`_(required if you set `for` when you generated the metric)_: A name space for your metric, ex: `home_page`

‘time_start`_(optional)_: The start of the time range to grab the data from.

‘time_end`_(optional)_: The end of the time range to grab the data from.

‘time_range _(optional)_: Alternatively you can specify a time range, instead of `time_start` and `time_end`.

###Usage

DulyNoted.count("page_views",
  for: "home_page",
  time_start: Time.now,
  time_end: 1.day.ago)

DulyNoted.count("page_views",
   for: "home_page",
   time_range: Time.now..1.day.ago)


211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
# File 'lib/duly_noted.rb', line 211

def count(metric_name, options={})
  parse_time_range(options)
  key = normalize(metric_name)
  keys = []
  if options[:for]
    key << ":#{options[:for]}"
  else
    keys << DulyNoted.redis.keys("#{key}*")
    keys - DulyNoted.redis.keys("#{key}*:meta")
    keys - DulyNoted.redis.keys("#{key}:*:")
    keys.flatten!
  end
  if keys.empty?
    if options[:time_start] && options[:time_end]
      return DulyNoted.redis.zcount(key, options[:time_start].to_f, options[:time_end].to_f)
    else 
      return DulyNoted.redis.zcard(key)
    end
  else
    sum = 0
    if options[:time_start] && options[:time_end]
      keys.each do |key|
        sum += DulyNoted.redis.zcount(key, options[:time_start].to_f, options[:time_end].to_f)
      end
      return sum
    else
      keys.each do |key|
        sum += DulyNoted.redis.zcard(key)
      end
      return sum
    end
  end
end

#query(metric_name, options = {}) ⇒ Object

##Query

_parameters: ‘metric_name`, `for`(required if set when created), `time_start`(optional), `time_end`(optional)_

Query will return an array of all the metadata in chronological order from a time range, or for the whole data set.

‘metric_name`: The name of the metric to query, ex: `page_views`, `downloads`

‘for`_(required if you set `for` when you generated the metric)_: A name space for your metric, ex: `home_page`

‘ref_id`: _(optional)_: The reference ID that you set when you called `track` (if you set this, the time restraints is ignored)

‘meta_fields` _(optional)_: An array of fields to retrieve from the meta hash. If not specified, the entire hash will be grabbed. Fields will be converted to strings, because redis converts all hash keys and values to strings.

‘time_start`_(optional)_: The start of the time range to grab the data from.

‘time_end`_(optional)_: The end of the time range to grab the data from.

‘time_range _(optional)_: Alternatively you can specify a time range, instead of `time_start` and `time_end`.

###Usage

DulyNoted.query("page_views",
  for: "home_page",
  time_start: 1.day.ago,
  time_end: Time.now)

DulyNoted.query("page_views",
  for: "home_page",
  time_range: 1.day.ago..Time.now)


144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/duly_noted.rb', line 144

def query(metric_name, options={})
  key = normalize(metric_name)
  parse_time_range(options)
  key << ":#{options[:for]}" if options[:for]
  if options[:ref_id]
    key << ":#{options[:ref_id]}"
    real_key = DulyNoted.redis.get key
    if options[:meta_fields]
      options[:meta_fields].collect! { |x| x.to_s }
      result = {}
      options[:meta_fields].each do |field|
        result[field] = DulyNoted.redis.hget real_key, field
      end
      results = [result]
    else
      results = [DulyNoted.redis.hgetall(real_key)]
    end
  else
    grab_results = Proc.new do |metric|
      if options[:meta_fields]
        options[:meta_fields].collect! { |x| x.to_s }
        result = {}
        options[:meta_fields].each do |field|
          result[field] = DulyNoted.redis.hget metric, field
        end
        result
      else
        DulyNoted.redis.hgetall metric
      end
    end
    if options[:time_start] && options[:time_end]
      results = DulyNoted.redis.zrangebyscore(key, options[:time_start].to_f, options[:time_end].to_f).collect(&grab_results)
    else
      results = DulyNoted.redis.zrange(key, 0, -1).collect(&grab_results)
    end
  end
  return results
end

#redisObject



257
258
259
260
261
262
263
264
265
266
267
268
# File 'lib/duly_noted.rb', line 257

def redis
  @redis ||= (
    url = URI(@redis_url || "redis://127.0.0.1:6379/0")

    Redis.new({
      :host => url.host,
      :port => url.port,
      :db => url.path[1..-1],
      :password => url.password
    })
  )
end

#redis=(url) ⇒ Object

##Redis

DulyNoted will try to connect to Redis’s default url and port if you don’t specify a Redis connection URL. You can set the url with the method

DulyNoted.redis = REDIS_URL


251
252
253
254
255
# File 'lib/duly_noted.rb', line 251

def redis=(url)
  @redis = nil
  @redis_url = url
  redis
end

#track(metric_name, options = {}) ⇒ Object

##Track

_parameters: ‘metric_name`, `for`(optional), `generated_at`(optional), `meta`(optional), `ref_id`(optional)_

‘metric_name`: The name of the metric to track, ex: `page_views`, `downloads`

‘for`_(optional)_: A name space for your metric, ex: `home_page`

‘generated_at`_(optional)_: If the metric was generated in the past but is just now being logged, you can set the time it was generated at

‘meta`_(optional)_: A hash with whatever meta data fields you might want to store, ex: `ip_address`, `file_type`

‘ref_id`_(optional)_: If you need to reference the metric later, perhaps to add more metadata later on, you can set a reference id that you can use to update the metric



74
75
76
77
78
79
80
81
# File 'lib/duly_noted.rb', line 74

def track(metric_name, options={})
  options = {:generated_at => Time.now}.merge(options)
  key = normalize(metric_name)
  key << ":#{options[:for]}" if options[:for]
  DulyNoted.redis.zadd key, options[:generated_at].to_f, "#{key}:#{options[:generated_at].to_f}:meta"
  DulyNoted.redis.set "#{key}:#{options[:ref_id]}", "#{key}:#{options[:generated_at].to_f}:meta" if options[:ref_id] # set alias key
  DulyNoted.redis.mapped_hmset "#{key}:#{options[:generated_at].to_f}:meta", options[:meta] if options[:meta] # set meta data
end

#update(metric_name, ref_id, options = {}) ⇒ Object

##Update

_parameters: ‘metric_name`, `ref_id`, `for`(required if set when created), `meta`(optional)_

The meta hash will not overwrite the old meta hash but be merged with it, with the new one overwriting conflicts.

‘metric_name`: The name of the metric to track, ex: `page_views`, `downloads`

‘ref_id`: The reference ID that you set when you called `track`

‘for`_(required if you set `for` when you generated the metric)_: A name space for your metric, ex: `home_page`

‘meta`_(optional)_: A hash with whatever meta data fields you might want to store, or update ex: `ip_address`, `file_type`, `time_left`

###Usage

DulyNoted.update("page_views",
  "a_unique_id",
  for: "home_page",
  meta: { time_on_page: 30 })


104
105
106
107
108
109
110
# File 'lib/duly_noted.rb', line 104

def update(metric_name, ref_id, options={})
  key = normalize(metric_name)
  key << ":#{options[:for]}" if options[:for]
  key << ":#{ref_id}"
  real_key = DulyNoted.redis.get key
  DulyNoted.redis.mapped_hmset real_key, options[:meta] if options[:meta] 
end