simple_events_redis 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. checksums.yaml +15 -0
  2. data/README.md +41 -0
  3. data/lib/events.rb +348 -0
  4. metadata +46 -0
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MzRlMWU0MjUxNGIxYmFiZTBiN2YzMDYyZjdkN2Q1NTA3ZDdhYzFlOQ==
5
+ data.tar.gz: !binary |-
6
+ NzFlOGMwOWVhNWZkMDdmNWFkNDA1MDJhOTYxMjAxYWI5MDViZGM1ZA==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ YzQ0ZjgyZGE0NGVhZWQwYjgxZjBjMmFiOThlYTFiZjZjZTVlZWFlZGRjOGRi
10
+ MzdjMzUwOGRkYTI5NzZiMTVjMTNmMjIyMTkwZjE5ZWRlNDk2ODVmN2IzYjM4
11
+ ZDZhYjI2NmE0MTczYjBiOWM5YTRkMDZlNWJiZmM5NjA0MGRlYzA=
12
+ data.tar.gz: !binary |-
13
+ YjdjOTBhNWRmMDNlZTQ0OTViMGNlOTQzMDViMzZkZDU5ODk4ODVkNmYyMzkx
14
+ ZjU0ODNiNDU1N2E5MDA0ODk4NGM3OWYyODliNWExYzM2M2VlMTVmMDk2NmNi
15
+ ZTA1MTdjNTI2NmMzOGNiNjNhYmJkYWI5MTk2MmRlODVhNzRhMTA=
data/README.md ADDED
@@ -0,0 +1,41 @@
1
+ # Simple tracking of custom events
2
+
3
+
4
+ Library to store custom data in lists by days in Redis.
5
+ Old data is automatically removed.
6
+ Useful for debugging and tracking different events in application.
7
+
8
+
9
+ ## Overview
10
+ Data is stored in Redis in lists with names:
11
+ <<YOUR_SITE_NAME>> : lists : <list_name> : <day> - Redis list
12
+
13
+ for example,
14
+
15
+ mysite:lists:mylist:20130407 - list for day April 04, 2013
16
+
17
+
18
+ ## Installation
19
+
20
+ It uses gem 'redis' and relies on $redis global variable to access Redis server.
21
+
22
+ in Rails application:
23
+
24
+ gem 'redis'
25
+ gem 'lists_by_days_redis'
26
+
27
+
28
+
29
+ Setup:
30
+
31
+ initializer:
32
+
33
+ ListsByDaysRedis::List::SITE_NAME = 'mysite'
34
+ ListsByDaysRedis::List::EXPIRE_DAYS = 7
35
+
36
+
37
+
38
+ ## Add new item to list
39
+
40
+
41
+
data/lib/events.rb ADDED
@@ -0,0 +1,348 @@
1
+ module SimpleEventsRedis
2
+
3
+ require 'redis'
4
+
5
+ class Events
6
+ # static data
7
+ #PROCESSES = ['effects']
8
+ SITE_NAME = ''
9
+
10
+ EXPIRE_DAYS = 7
11
+
12
+
13
+ @@redis = nil
14
+
15
+ # redis object to access Redis server
16
+ def self.redis
17
+ return @@redis unless @redis.nil?
18
+
19
+ # init by global object
20
+ unless $redis.nil?
21
+ @@redis = $redis
22
+ return @@redis
23
+ end
24
+
25
+
26
+ # default
27
+ @@redis = Redis.new(:host => 'localhost', :port => 6379)
28
+
29
+ @@redis
30
+ end
31
+
32
+ # methods for any log_type add_<<ANY_LOG_TYPE>>
33
+ def self.method_missing(method_name, *args, &block)
34
+ if method_name.to_s =~ /^log_(.+)$/
35
+ self.log($1, *args)
36
+ else
37
+ super
38
+ end
39
+ end
40
+
41
+
42
+ # logging
43
+
44
+ def self.log(log_name, data={})
45
+ t = Time.now.utc.to_i
46
+ rkey = self.redis_key_log log_name
47
+
48
+ #
49
+ hash = {:created=>t}
50
+ if data.is_a?(Hash)
51
+ data.each_pair { |k,v| hash["#{k}"] = v }
52
+ elsif data.is_a?(String)
53
+ hash["msg"] = data
54
+ else
55
+ hash["msg"] = "#{data.inspect}"
56
+ end
57
+
58
+ #
59
+ require 'json'
60
+ s = JSON.generate(hash)
61
+
62
+ redis.rpush rkey, s
63
+ redis.expireat rkey, t+EXPIRE_DAYS*24*60*60
64
+
65
+ return true
66
+ end
67
+
68
+
69
+ def self.log_event(log_name, event_name, msg, data={})
70
+ data['event'] = event_name
71
+ data['msg'] = msg
72
+ return self.log log_name, data
73
+ end
74
+
75
+ #
76
+ def self.debug(event_name, msg, data={})
77
+ data['event'] = event_name
78
+ data['msg'] = msg
79
+ return self.log 'debug', data
80
+ end
81
+
82
+
83
+
84
+ def self.get_logs(log_name, n_days_back=-1, filter={})
85
+ all_keys = redis.keys(self.redis_key_log_prefix + "#{log_name}:" +'*')
86
+
87
+ return [] if all_keys.nil?
88
+
89
+ require 'json'
90
+
91
+ tnow = Time.now.utc.to_i
92
+ rows = []
93
+ all_keys.each do |rkey|
94
+ day = self.parse_date rkey
95
+
96
+ # if cannot parse key
97
+ next if day.nil?
98
+
99
+ # if not too old day
100
+ if n_days_back>0
101
+ next if tnow - day.to_i > n_days_back * (60*60*24)
102
+ end
103
+
104
+ # get all items from the list
105
+ values = redis.lrange rkey, 0, 100000
106
+
107
+ values.each do |v|
108
+ #r = Marshal.load v
109
+ r = JSON.parse(v)
110
+
111
+ # filter
112
+ is_good = true
113
+
114
+ unless filter.nil? && filter.is_a?(Hash)
115
+ filter.each_pair do |field_name, field_value|
116
+ if r[field_name].nil?
117
+ is_good = false
118
+ break
119
+ end
120
+ if r[field_name] != field_value
121
+ is_good = false
122
+ break
123
+ end
124
+ end
125
+ end
126
+
127
+ # add to result
128
+ if is_good
129
+ rows << r
130
+ end
131
+ end
132
+
133
+ end
134
+
135
+ rows
136
+ end
137
+
138
+
139
+
140
+
141
+
142
+ # status
143
+ def self.status_set(event_name)
144
+ redis.hset self.redis_key_status, event_name, Time.now.utc.to_i
145
+
146
+ return true
147
+ end
148
+
149
+ def self.get_status(event_name, v_def=nil)
150
+ v = redis.hget self.redis_key_status, event_name
151
+ v ||= v_def
152
+ v
153
+ end
154
+
155
+ def self.get_statuses(pattern='*')
156
+ # event_names like 'name*'
157
+
158
+ rows = []
159
+
160
+ all_values = redis.hgetall self.redis_key_status
161
+
162
+ all_values.each do |event, v|
163
+ rows << {:site=>SITE_NAME, :event=>event, :v=>v}
164
+ end
165
+
166
+ rows
167
+ end
168
+
169
+
170
+
171
+ # counters
172
+
173
+ def self.stat_add(event_name, n=1)
174
+ redis.hincrby self.redis_key_stat, event_name, n
175
+
176
+ return true
177
+ end
178
+
179
+ def self.stat_add_perf(event_name, duration_secs, n=1)
180
+ redis.hincrby self.redis_key_stat, event_name+'_time', (duration_secs*1000).floor
181
+ redis.hincrby self.redis_key_stat, event_name+'_n', 1
182
+
183
+ return 1
184
+ end
185
+
186
+
187
+ def self.get_stats(n_days_back=1)
188
+ rows = []
189
+
190
+ self.stat_walk(n_days_back, 0) do |key, day|
191
+ all_values = redis.hgetall key
192
+
193
+ all_values.each do |event, v|
194
+ rows << {:site=>SITE_NAME, :created=>day.to_i, :event=>event, :amount=>v.to_i}
195
+ end
196
+ end
197
+
198
+ rows
199
+ end
200
+
201
+
202
+
203
+
204
+ # helper methods
205
+
206
+ def self.redis_key_prefix
207
+ "#{SITE_NAME=='' ? '' : SITE_NAME+':'}"
208
+ end
209
+
210
+ def self.key_day(d=nil)
211
+ d ||= DateTime.now.new_offset(0)
212
+
213
+ d.strftime("%Y%m%d")
214
+ end
215
+
216
+
217
+ # redis keys for log
218
+ def self.redis_key_log_prefix
219
+ self.redis_key_prefix + "log:"
220
+ end
221
+
222
+ def self.redis_key_log(name)
223
+ self.redis_key_log_prefix + "#{name}:" + self.key_day
224
+ end
225
+
226
+
227
+ # redis keys for status
228
+
229
+ def self.redis_key_status
230
+ self.redis_key_prefix + 'status'
231
+ end
232
+
233
+
234
+ # redis keys for stat
235
+
236
+ def self.redis_key_stat_prefix
237
+ self.redis_key_prefix + 'stat:'
238
+ end
239
+
240
+ def self.redis_key_stat
241
+ self.redis_key_stat_prefix + self.key_day
242
+ end
243
+
244
+
245
+ #
246
+ def self.parse_date(s)
247
+ # parse key
248
+ mm = s.scan(/(\d\d\d\d)(\d\d)(\d\d)$/i)
249
+
250
+ return nil if mm.nil? || mm[0].nil?
251
+
252
+ y, m, d = mm[0].map{|v| v.to_i}
253
+
254
+ Time.utc(y,m,d)
255
+ end
256
+
257
+
258
+
259
+ # clear data
260
+
261
+ def self.clear_logs_all
262
+ keys = redis.keys self.redis_key_log_prefix + '*'
263
+ return if keys.empty?
264
+ redis.del keys
265
+ end
266
+
267
+ def self.clear_logs(name)
268
+ keys = redis.keys self.redis_key_log_prefix+"#{name}:*"
269
+ return if keys.empty?
270
+ redis.del keys
271
+ end
272
+
273
+ # TODO:
274
+ def self.clear_logs_old(name)
275
+
276
+ end
277
+
278
+
279
+ # clear status
280
+
281
+ def self.clear_status_all
282
+ rkey = self.redis_key_status
283
+
284
+ redis.del rkey
285
+ end
286
+
287
+
288
+
289
+ # clear stats
290
+
291
+ def self.clear_stats_all
292
+ keys = redis.keys self.redis_key_stat_prefix+"*"
293
+ return if keys.empty?
294
+ redis.del keys
295
+ end
296
+
297
+
298
+ # clear data older than n_days_back
299
+ def self.clear_stats_old(n_days_back=1)
300
+ rows = []
301
+
302
+ # all days older than N days
303
+ self.stat_walk(-1, n_days_back) do |key, day|
304
+ redis.del key
305
+ end
306
+
307
+ rows
308
+ end
309
+
310
+
311
+ def self.stat_walk(n_days_back_from, n_days_back_to)
312
+
313
+ tnow = Time.now.utc_to_i
314
+
315
+ key_prefix = self.redis_key_stat_prefix
316
+ keys = redis.keys key_prefix + "*"
317
+
318
+ keys.each do |key|
319
+ # parse key
320
+ mm = key.scan(/#{key_prefix}:(\d+)$/i)
321
+
322
+ next if mm.nil? || mm[0].nil?
323
+
324
+ day = self.parse_date(mm[0][0])
325
+
326
+ next if day.nil?
327
+
328
+ # too old
329
+ if n_days_back_from>=0
330
+ next if tnow - day.to_i > n_days_back_from * (60*60*24)
331
+ end
332
+
333
+ # too fresh
334
+ if n_days_back_to>=0
335
+ next if tnow - day.to_i < n_days_back_to * (60*60*24)
336
+ end
337
+
338
+ # do the work
339
+ yield(key, day)
340
+
341
+ end
342
+ end
343
+
344
+ end
345
+
346
+
347
+ end
348
+
metadata ADDED
@@ -0,0 +1,46 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: simple_events_redis
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - ! 'Max Ivak '
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-04-09 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: ''
14
+ email:
15
+ - maxivak@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/events.rb
21
+ - README.md
22
+ homepage: https://github.com/maxivak/simple_events_redis/
23
+ licenses: []
24
+ metadata: {}
25
+ post_install_message:
26
+ rdoc_options: []
27
+ require_paths:
28
+ - lib
29
+ required_ruby_version: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ required_rubygems_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ requirements: []
40
+ rubyforge_project:
41
+ rubygems_version: 2.0.3
42
+ signing_key:
43
+ specification_version: 4
44
+ summary: ! 'Library to track events: counters of events, logging, state monitoring.
45
+ Data is stored in Redis'
46
+ test_files: []