redis_syslog 0.0.2 → 0.0.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2b412edcf43c1d2b439f46717d4c5af955225202
4
- data.tar.gz: feff4048fc2c079a933cd3c42e588f57c8b7365e
3
+ metadata.gz: afb4ce6ef888935609d8323c018383c5bba18948
4
+ data.tar.gz: e33283b271eda2685cfc61e4518fcfa7dd782b0f
5
5
  SHA512:
6
- metadata.gz: 2a0c832ecc5d42bb1b3630a836e0b87df7d16b1018cbb1dd0855c317418f1cec4f982d3e763d7c609b11de5930a194489992a4a11c0e004f871371f22862f545
7
- data.tar.gz: 9473eedef0f8ee10ecb0971a7024bf9c5a19b06ccbb6f400e8db7c4d56808101df35b5bd327474509f759bcc5c31f228f1c3fe80103bfeb7b80fdb1bdc3b6e99
6
+ metadata.gz: a7c2811eb787f44dd9531c34ebd60834b923cef06be335673e047f380468aca8ef5ddb3b3f6a4da35e6d7aab3addc137457b534203accfdaffbd06bd12fb5313
7
+ data.tar.gz: 2803508c6873e78f71b86aeaea24fda32e2eeabacd89266448d7dea35b60b858631b3280ab2188f3ccce7667f1acb372166ad4d842d7dc9b78117c1dbbbe16e5
data/README.md CHANGED
@@ -17,23 +17,44 @@ gem 'redis_syslog'
17
17
  @redis = Redis.new
18
18
 
19
19
  #Create an instance of RedisSyslog
20
- @logger = RedisSyslog.new redisrb: @redis, namespace: "com.fittr.periodic"
20
+ @logger = RedisSyslog.new @redis
21
21
  ```
22
22
 
23
23
  3. Profit
24
24
  ```ruby
25
- #Write a new entry
26
- @logger.write "This is my message"
25
+ #Write a new entry to the com.bar.sobriety namespace log
26
+ @logger.write "com.bar.sobriety", "Ordered a beer"
27
+ @logger.write "com.bar.sobriety", "Hiccup!"
27
28
 
28
- #Get last 1 entry
29
- @logger.last_n_entries(1) #[{:time=>TimeClass, :message => "This is my message"]
29
+ #Get last 2 entries
30
+ puts @logger.tail "com.bar.sobriety", 2
31
+ >[{:index => 1, :timestamp=>2014-1027 18:48:28 -0400, :message => "Hiccup!"},
32
+ {:index => 0, :timestamp=>2014-1027 18:48:28 -0400, :message => "Ordered a beer"}]
30
33
 
31
- #Delete all entries
32
- @logger.delete!
34
+ #View all namespaces used
35
+ puts @logger.namespaces ["com.bar.sobriety"]
36
+
37
+ #Drop this namespace
38
+ @logger.delete "com.bar.sobriety"
39
+
40
+ #Delete all data including indexes
41
+ @logger.drop_all
33
42
  ```
34
43
 
35
- That's it. That's the entire API.
44
+ There are no limits on the number of logs (namespaces) you can have.
45
+
46
+ How is it stored?
36
47
  ------------
37
- How is it stored? Simple. Each namespace uses the one key with a redis sorted set. The key follows this format.
48
+ Each namespace (i.e. each log name) uses the one key with a redis sorted set. `` redis_syslog://#{namespace} ``<br />
49
+ Then, we have one index key which contains an unsorted set of keys. `` redis_syslog://namespaces ``
50
+
51
+ For each entry in the sorted set of some namespace, we follow the simple protocol.
52
+ ```ruby
53
+ ###########################################################################
54
+ #index - Number that should be monotonically increasing for each entry
55
+ #timestamp - A time in seconds from unix epoch
56
+ #message - Your message
57
+ ###########################################################################
58
+ @encoded_message = "#{index}\n#{timestamp}\n#{message}"
59
+ ```
38
60
 
39
- `` redis_syslog://#{namespace} ``
data/lib/redis_syslog.rb CHANGED
@@ -1,40 +1,87 @@
1
1
  require "redis_syslog/version"
2
2
 
3
+ module RedisSyslog::MessageEncoder
4
+ #Encode a message with a timestamp fit for inserting into a redis set. This must include the index itself because
5
+ #a non-unique message could end up getting ignored by redis because it's technically a duplicate if the timestamp
6
+ #happened to be the same.
7
+ #We're encoding to INDEX\nTIMESTAMP\nMESSAGE
8
+ def self.encode(index:, timestamp:, message:)
9
+ "#{index}\n#{timestamp}\n#{message}"
10
+ end
11
+
12
+ def self.decode(data)
13
+ info = data.split("\n")
14
+ index = info.shift.to_i
15
+ timestamp = info.shift.to_i
16
+
17
+ #Retrieve by inverting the rest
18
+ message = data.gsub(self.encode(index: index, timestamp: timestamp, message:""), "")
19
+
20
+ return {index: index, timestamp: timestamp, message: message}
21
+ end
22
+ end
23
+
3
24
  class RedisSyslog::RedisSyslog
4
25
  PREFIX = "redis_syslog://"
26
+ NAMESPACES_LIST_KEY = "redis_syslog://namespaces" #A list of used namespaces
5
27
 
6
- def self.list_used_namespaces
7
- #Return a list of used namespaces
28
+ #First N characters of key are magic random characters because we are using a sorted set
29
+ #to store these lists and redis will not allow two duplicate entries (even with different scores)
30
+ RANDOM_WORD_PREFIX_CHARACTER_COUNT = 8
31
+
32
+ #List currently used namespaces
33
+ def namespaces
34
+ return @redis.smembers NAMESPACES_LIST_KEY
8
35
  end
9
36
 
10
- def initialize(redisrb:, namespace:)
11
- @redis = redisrb
12
- @namespace = namespace
37
+ def initialize(redis)
38
+ @redis = redis
13
39
  end
14
40
 
15
41
  #This is the actual list key
16
- def _key
17
- return "#{PREFIX}#{@namespace}"
42
+ def _key_for_namespace namespace
43
+ return "#{PREFIX}#{namespace}"
44
+ end
45
+
46
+ def delete namespace
47
+ @redis.del _key_for_namespace(namespace)
48
+ @redis.srem NAMESPACES_LIST_KEY, namespace
18
49
  end
19
50
 
20
- def delete!
21
- @redis.del _key
51
+ def drop_all
52
+ self.namespaces.each do |namespace|
53
+ self.delete namespace
54
+ end
55
+
56
+ #For good measure
57
+ @redis.del NAMESPACES_LIST_KEY
22
58
  end
23
59
 
24
- def last_n_entries n
60
+ def tail namespace, n=1
25
61
  raise "n cannot be 0" unless n > 0
26
62
  #Return the last N entries of this log
27
- results = @redis.zrevrange _key, 0, n-1, :with_scores => true
28
- results = results.map{|e| {:time => Time.at(e[1]), :message => e[0][8..-1]} }
63
+ results = @redis.zrevrange _key_for_namespace(namespace), 0, n-1
64
+
65
+ results.map! do |result|
66
+ result = RedisSyslog::MessageEncoder.decode result
67
+ result[:timestamp] = Time.at(result[:timestamp].to_i)
68
+ result
69
+ end
70
+
71
+ results
29
72
  end
30
73
 
31
- def write message
32
- @redis.zadd _key, Time.now.to_i, "#{[*('A'..'Z')].sample(8).join}#{message}"
74
+ def write namespace, message
75
+ index = @redis.zcard(_key_for_namespace(namespace))
76
+ encoded_message = RedisSyslog::MessageEncoder.encode index: @redis.zcard(_key_for_namespace(namespace)), timestamp: Time.now.to_i, message: message
77
+
78
+ @redis.zadd _key_for_namespace(namespace), index, encoded_message
79
+ @redis.sadd NAMESPACES_LIST_KEY, namespace
33
80
  end
34
81
  end
35
82
 
36
83
  module RedisSyslog
37
- def self.new(redisrb:, namespace:)
38
- return RedisSyslog.new redisrb: redisrb, namespace: namespace
84
+ def self.new(redis)
85
+ return RedisSyslog.new redis
39
86
  end
40
87
  end
@@ -1,3 +1,3 @@
1
1
  module RedisSyslog
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis_syslog
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Seo Townsend