flume 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6a38d4970d9c2883c1ae6611901fb8cb19df0d71
4
+ data.tar.gz: 482ef5efbe2401d919f95f8e4780ef8f6111fa74
5
+ SHA512:
6
+ metadata.gz: e1ff7e21fecf1eaf1747ad89bdc63747b425f88b549d5c0549bf4162e49fb3ab989f5b3aeef4f8472c952caa3c34e23d0cc273ec5cb315e3b973be9d768d05d8
7
+ data.tar.gz: b172999e740555a080e73c80f0e90de64ae3365b95d5c14588f8790b3575b28e06e1ea4b06f8c36e4ea36f9e287480aed6ec7c809b91b4de132615c0f60a45f6
data/.gitignore ADDED
@@ -0,0 +1,24 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
23
+ .DS_Store
24
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in flume.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Casey O'Hara
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Flume
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'flume'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install flume
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it ( https://github.com/[my-github-username]/flume/fork )
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/bin/flume ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $: << File.expand_path(File.dirname(__FILE__) + "/../lib")
4
+ require 'rubygems'
5
+ require 'flume'
6
+ require "flume/cli"
7
+
8
+ Flume::CLI.start(ARGV)
9
+
data/flume.gemspec ADDED
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'flume/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "flume"
8
+ spec.version = Flume::VERSION
9
+ spec.authors = ["Casey O'Hara"]
10
+ spec.email = ["cohara@printreleaf.com"]
11
+ spec.summary = "Redis logger"
12
+ spec.description = "A Redis logger for Ruby/Rails"
13
+ spec.homepage = "https://github.com/printreleaf/flume"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "redis"
22
+ spec.add_dependency "laissez", "~> 0.0.2"
23
+ spec.add_dependency "thor", "~> 0.19.1"
24
+
25
+ spec.add_development_dependency "bundler", "~> 1.6"
26
+ spec.add_development_dependency "rake"
27
+ spec.add_development_dependency "rspec", "~> 2.14"
28
+ spec.add_development_dependency "mock_redis", "~> 0.13.2"
29
+ spec.add_development_dependency "timecop", "~> 0.7.1"
30
+ end
31
+
data/lib/flume/cli.rb ADDED
@@ -0,0 +1,21 @@
1
+ module Flume
2
+ class CLI < Thor
3
+
4
+ desc "tail LIST", "display the last part of a log"
5
+ option :f, :type => :boolean, :default => false
6
+ option :number, :type => :numeric, :default => 80, :aliases => :n
7
+ def tail(list)
8
+ puts options
9
+ logger = Flume.logger :list => list
10
+ puts logger.tail(options[:number])
11
+
12
+ if options[:f]
13
+ trap(:INT) { puts; exit }
14
+ logger.tailf do |line|
15
+ puts line
16
+ end
17
+ end
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,83 @@
1
+ module Flume
2
+ class LogDevice
3
+ lazy_accessor :redis
4
+ lazy_accessor :cap
5
+ lazy_accessor :step
6
+ lazy_accessor :cycle
7
+ lazy_accessor :list
8
+
9
+ def initialize(*args, &block)
10
+ options = args.last.is_a?(Hash) ? args.pop : {}
11
+
12
+ @config = OpenStruct.new(options)
13
+ block.call(@config) if block
14
+
15
+ @redis = @config[:redis] || proc { Redis.new }
16
+ @cap = @config[:cap] || (2 ** 16)
17
+ @step = @config[:step] || 0
18
+ @cycle = @config[:cycle] || (2 ** 8)
19
+ @list = @config[:list] || 'flume:log'
20
+ end
21
+
22
+
23
+ def channel
24
+ "flume:#{list}"
25
+ end
26
+
27
+
28
+ def write(message)
29
+ begin
30
+ redis.lpush(list, message)
31
+ rescue Object => e
32
+ error = "#{ e.message } (#{ e.class })\n#{ Array(e.backtrace).join(10.chr) }"
33
+ STDERR.puts(error)
34
+ STDERR.puts(message)
35
+ end
36
+ ensure
37
+ redis.publish(channel, message)
38
+
39
+ if (step % cycle).zero?
40
+ truncate(cap) rescue nil
41
+ end
42
+
43
+ self.step = (step + 1) % cycle
44
+ end
45
+
46
+
47
+ def close
48
+ redis.quit rescue nil
49
+ end
50
+
51
+
52
+ def tail(n = 80)
53
+ redis.lrange(list, 0, n - 1).reverse
54
+ end
55
+
56
+
57
+ def tailf(&block)
58
+ begin
59
+ redis.subscribe(channel) do |on|
60
+ on.message do |channel, message|
61
+ block.call(message)
62
+ end
63
+ end
64
+ rescue Redis::BaseConnectionError => error
65
+ puts "#{error}, retrying in 1s"
66
+ sleep 1
67
+ retry
68
+ end
69
+ end
70
+
71
+
72
+ def truncate(n)
73
+ redis.ltrim(list, 0, n - 1)
74
+ end
75
+
76
+
77
+ def size
78
+ redis.llen(list)
79
+ end
80
+
81
+ end
82
+ end
83
+
@@ -0,0 +1,20 @@
1
+ module Flume
2
+ class Logger < ::Logger
3
+ extend Forwardable
4
+
5
+ attr_reader :logdev
6
+ def_delegators :logdev, :redis, :redis=
7
+ def_delegators :logdev, :list, :list=
8
+ def_delegators :logdev, :cap, :cap=
9
+ def_delegators :logdev, :step, :step=
10
+ def_delegators :logdev, :cycle, :cycle=
11
+ def_delegators :logdev, :truncate, :size
12
+ def_delegators :logdev, :tail, :tailf
13
+
14
+ def initialize(*args, &block)
15
+ super(STDERR)
16
+ @logdev = LogDevice.new(*args, &block)
17
+ end
18
+ end
19
+ end
20
+
@@ -0,0 +1,3 @@
1
+ module Flume
2
+ VERSION = "0.0.2"
3
+ end
data/lib/flume.rb ADDED
@@ -0,0 +1,24 @@
1
+ require 'forwardable'
2
+ require 'logger'
3
+ require 'ostruct'
4
+
5
+ require 'thor'
6
+ require 'redis'
7
+ require 'laissez'
8
+
9
+ require "flume/version"
10
+ require "flume/log_device"
11
+ require "flume/logger"
12
+
13
+ module Flume
14
+ def self.logger(*args, &block)
15
+ logger = Logger.new(*args, &block)
16
+
17
+ if defined?(::ActiveSupport::TaggedLogging)
18
+ logger = ::ActiveSupport::TaggedLogging.new(logger)
19
+ end
20
+
21
+ return logger
22
+ end
23
+ end
24
+
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ describe Flume do
4
+ before do
5
+ clear_redis!
6
+ $redis.stub(:publish)
7
+ Timecop.freeze(Time.local(2014))
8
+ end
9
+
10
+ after do
11
+ Timecop.return
12
+ end
13
+
14
+ it "writes to Redis" do
15
+ logger = Flume.logger :list => "flume:test:log" do |config|
16
+ config.redis = $redis
17
+ config.cap = proc { 1 > 0 ? 1024 : 2048 }
18
+ end
19
+
20
+ logger.unknown "An unknown message that should always be logged."
21
+ logger.fatal "An unhandleable error that results in a program crash."
22
+ logger.error "A handleable error condition."
23
+ logger.warn "A warning."
24
+ logger.info "Generic (useful) information about system operation."
25
+ logger.debug "Low-level information for developers."
26
+
27
+ logs = logger.tail
28
+ expect(logs[0]).to match /A, \[2014-01-01T00:00:00.000000 #\d+\] ANY -- : An unknown message that should always be logged./
29
+ expect(logs[1]).to match /F, \[2014-01-01T00:00:00.000000 #\d+\] FATAL -- : An unhandleable error that results in a program crash\./
30
+ expect(logs[2]).to match /E, \[2014-01-01T00:00:00.000000 #\d+\] ERROR -- : A handleable error condition\./
31
+ expect(logs[3]).to match /W, \[2014-01-01T00:00:00.000000 #\d+\] WARN -- : A warning\./
32
+ expect(logs[4]).to match /I, \[2014-01-01T00:00:00.000000 #\d+\] INFO -- : Generic \(useful\) information about system operation\./
33
+ expect(logs[5]).to match /D, \[2014-01-01T00:00:00.000000 #\d+\] DEBUG -- : Low-level information for developers\./
34
+
35
+ logs = logger.tail(3)
36
+ expect(logs[0]).to match /W, \[2014-01-01T00:00:00.000000 #\d+\] WARN -- : A warning\./
37
+ expect(logs[1]).to match /I, \[2014-01-01T00:00:00.000000 #\d+\] INFO -- : Generic \(useful\) information about system operation\./
38
+ expect(logs[2]).to match /D, \[2014-01-01T00:00:00.000000 #\d+\] DEBUG -- : Low-level information for developers\./
39
+
40
+ expect(logger.redis).to eql($redis)
41
+ expect(logger.list).to eql("flume:test:log")
42
+ expect(logger.cap).to eql(1024)
43
+ expect(logger.size).to eql(6)
44
+
45
+ logger.truncate(3)
46
+ expect(logger.size).to eql(3)
47
+ end
48
+ end
49
+
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ describe Flume, '.logger' do
4
+ it "news up a configured logger and returns it" do
5
+ configuration = lambda {}
6
+ flume_logger = double
7
+ expect(Flume::Logger).to receive(:new).
8
+ with({ list: "flume:test:log" }, &configuration).
9
+ and_return(flume_logger)
10
+ logger = Flume.logger(list: "flume:test:log", &configuration)
11
+ expect(logger).to eql flume_logger
12
+ end
13
+
14
+ it "wraps it in tagged logging if it exists" do
15
+ flume_logger = double
16
+ tagged_logging = double
17
+ wrapped_logger = double
18
+
19
+ Flume::Logger.stub(:new) { flume_logger }
20
+ stub_const("ActiveSupport::TaggedLogging", tagged_logging)
21
+
22
+ tagged_logging.stub(:new).
23
+ with(flume_logger).
24
+ and_return(wrapped_logger)
25
+
26
+ logger = Flume.logger
27
+ expect(logger).to eql wrapped_logger
28
+ end
29
+ end
30
+
@@ -0,0 +1,151 @@
1
+ require 'spec_helper'
2
+
3
+ describe Flume::LogDevice, ".new" do
4
+ # Sentinel values
5
+ let(:redis) { double }
6
+ let(:cap) { double }
7
+ let(:step) { double }
8
+ let(:cycle) { double }
9
+ let(:list) { double }
10
+
11
+ it "has reasonable defaults" do
12
+ Redis.stub(:new) { redis }
13
+ logdev = Flume::LogDevice.new
14
+ expect(logdev.redis).to eql(redis)
15
+ expect(logdev.cap).to eql(65536)
16
+ expect(logdev.step).to eql(0)
17
+ expect(logdev.cycle).to eql(256)
18
+ expect(logdev.list).to eql("flume:log")
19
+ end
20
+
21
+ it "can be configured with a hash" do
22
+ logdev = Flume::LogDevice.new(
23
+ :redis => redis,
24
+ :cap => cap,
25
+ :step => step,
26
+ :cycle => cycle,
27
+ :list => list
28
+ )
29
+
30
+ expect(logdev.redis).to eql(redis)
31
+ expect(logdev.cap).to eql(cap)
32
+ expect(logdev.step).to eql(step)
33
+ expect(logdev.cycle).to eql(cycle)
34
+ expect(logdev.list).to eql(list)
35
+ end
36
+
37
+ it "can be configured with a block" do
38
+ logdev = Flume::LogDevice.new do |config|
39
+ config.redis = redis
40
+ config.cap = cap
41
+ config.step = step
42
+ config.cycle = cycle
43
+ config.list = list
44
+ end
45
+
46
+ expect(logdev.redis).to eql(redis)
47
+ expect(logdev.cap).to eql(cap)
48
+ expect(logdev.step).to eql(step)
49
+ expect(logdev.cycle).to eql(cycle)
50
+ expect(logdev.list).to eql(list)
51
+ end
52
+
53
+ it "can be configured with both a hash and a block" do
54
+ logdev = Flume::LogDevice.new redis: redis, cap: cap do |config|
55
+ config.step = step
56
+ config.cycle = cycle
57
+ config.list = list
58
+ end
59
+
60
+ expect(logdev.redis).to eql(redis)
61
+ expect(logdev.cap).to eql(cap)
62
+ expect(logdev.step).to eql(step)
63
+ expect(logdev.cycle).to eql(cycle)
64
+ expect(logdev.list).to eql(list)
65
+ end
66
+ end
67
+
68
+ describe Flume::LogDevice, "#channel" do
69
+ it "returns its pubsub channel" do
70
+ logdev = Flume::LogDevice.new list: "my:list"
71
+ expect(logdev.channel).to eql "flume:my:list"
72
+ end
73
+ end
74
+
75
+ describe Flume::LogDevice, "#write" do
76
+ it "pushes the message onto the redis list" do
77
+ redis = double.as_null_object
78
+ logdev = Flume::LogDevice.new(redis: redis, list: "my:list")
79
+ expect(redis).to receive(:lpush).with("my:list", "hello world")
80
+ logdev.write("hello world")
81
+ end
82
+
83
+ it "auto-truncates the list" do
84
+ redis = double.as_null_object
85
+ logdev = Flume::LogDevice.new(redis: redis, list: "my:list", cap: 12, cycle: 4)
86
+ expect(redis).to receive(:ltrim).with("my:list", 0, 11).exactly(8).times
87
+ 32.times do
88
+ logdev.write("hello world")
89
+ end
90
+ end
91
+
92
+ it "publishes the message to its channel" do
93
+ redis = double.as_null_object
94
+ logdev = Flume::LogDevice.new(redis: redis, list: "my:list")
95
+ expect(redis).to receive(:publish).with("flume:my:list", "my message")
96
+ logdev.write("my message")
97
+ end
98
+
99
+ context "when there is an error writing to redis" do
100
+ it "prints the error and the message" do
101
+ redis = double.as_null_object
102
+ redis.stub(:lpush) { raise StandardError }
103
+ logdev = Flume::LogDevice.new(redis: redis)
104
+ expect(STDERR).to receive(:puts).with(/StandardError \(StandardError\)/).once
105
+ expect(STDERR).to receive(:puts).with("this will raise").once
106
+ logdev.write("this will raise")
107
+ end
108
+ end
109
+ end
110
+
111
+ describe Flume::LogDevice, "#close" do
112
+ it "quits redis" do
113
+ redis = double
114
+ logdev = Flume::LogDevice.new(redis: redis)
115
+ expect(redis).to receive(:quit)
116
+ logdev.close
117
+ end
118
+ end
119
+
120
+ describe Flume::LogDevice, "#tail(n)" do
121
+ it "returns the last n items" do
122
+ redis = double
123
+ logdev = Flume::LogDevice.new(redis: redis, list: "my:list")
124
+ redis.stub(:lrange).
125
+ with("my:list", 0, 599).
126
+ and_return(["item1", "item2", "item3"])
127
+ expect(logdev.tail(600)).to eql ["item3", "item2", "item1"]
128
+ end
129
+ end
130
+
131
+ describe Flume::LogDevice, "#truncate(n)" do
132
+ it "truncates the list" do
133
+ redis = double
134
+ logdev = Flume::LogDevice.new(redis: redis, list: "my:list")
135
+ expect(redis).to receive(:ltrim).with("my:list", 0, 99)
136
+ logdev.truncate(100)
137
+ end
138
+ end
139
+
140
+ describe Flume::LogDevice, "#size" do
141
+ it "returns the size of the list" do
142
+ redis = double
143
+ logdev = Flume::LogDevice.new(redis: redis, list: "my:list")
144
+ redis.stub(:llen).
145
+ with("my:list").
146
+ and_return(123456)
147
+ expect(logdev.size).to eql 123456
148
+ end
149
+ end
150
+
151
+
@@ -0,0 +1,77 @@
1
+ require 'spec_helper'
2
+
3
+ describe Flume::Logger do
4
+ let(:logger) { Flume::Logger.new }
5
+ let(:logdev) { double }
6
+ let(:sentinel) { double }
7
+
8
+ before do
9
+ logger.stub(:logdev) { logdev }
10
+ end
11
+
12
+ it "delegates #redis to its logdev" do
13
+ logdev.stub(:redis => sentinel)
14
+ expect(logger.redis).to eql sentinel
15
+ end
16
+
17
+ it "delegates #redis= to its logdev" do
18
+ expect(logdev).to receive(:redis=).with(sentinel)
19
+ logger.redis = sentinel
20
+ end
21
+
22
+ it "delegates #list to its logdev" do
23
+ logdev.stub(:list => sentinel)
24
+ expect(logger.list).to eql sentinel
25
+ end
26
+
27
+ it "delegates #list= to its logdev" do
28
+ expect(logdev).to receive(:list=).with(sentinel)
29
+ logger.list = sentinel
30
+ end
31
+
32
+ it "delegates #cap to its logdev" do
33
+ logdev.stub(:cap => sentinel)
34
+ expect(logger.cap).to eql sentinel
35
+ end
36
+
37
+ it "delegates #cap= to its logdev" do
38
+ expect(logdev).to receive(:cap=).with(sentinel)
39
+ logger.cap = sentinel
40
+ end
41
+
42
+ it "delegates #step to its logdev" do
43
+ logdev.stub(:step => sentinel)
44
+ expect(logger.step).to eql sentinel
45
+ end
46
+
47
+ it "delegates #step= to its logdev" do
48
+ expect(logdev).to receive(:step=).with(sentinel)
49
+ logger.step = sentinel
50
+ end
51
+
52
+ it "delegates #cycle to its logdev" do
53
+ logdev.stub(:cycle => sentinel)
54
+ expect(logger.cycle).to eql sentinel
55
+ end
56
+
57
+ it "delegates #cycle= to its logdev" do
58
+ expect(logdev).to receive(:cycle=).with(sentinel)
59
+ logger.cycle = sentinel
60
+ end
61
+
62
+ it "delegates #tail to its logdev" do
63
+ logdev.stub(:tail => sentinel)
64
+ expect(logger.tail).to eql sentinel
65
+ end
66
+
67
+ it "delegates #truncate to its logdev" do
68
+ logdev.stub(:truncate => sentinel)
69
+ expect(logger.truncate).to eql sentinel
70
+ end
71
+
72
+ it "delegates #size to its logdev" do
73
+ logdev.stub(:size => sentinel)
74
+ expect(logger.size).to eql sentinel
75
+ end
76
+ end
77
+
@@ -0,0 +1,31 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+ #
8
+
9
+ require "flume"
10
+ require 'mock_redis'
11
+ require 'timecop'
12
+
13
+ $redis = MockRedis.new
14
+
15
+ def clear_redis!
16
+ keys = $redis.keys('*')
17
+ $redis.del(*keys) if keys.any?
18
+ end
19
+
20
+ RSpec.configure do |config|
21
+ config.treat_symbols_as_metadata_keys_with_true_values = true
22
+ config.run_all_when_everything_filtered = true
23
+ config.filter_run :focus
24
+
25
+ # Run specs in random order to surface order dependencies. If you find an
26
+ # order dependency and want to debug it, you can fix the order by providing
27
+ # the seed, which is printed after each run.
28
+ # --seed 1234
29
+ config.order = 'random'
30
+ end
31
+
metadata ADDED
@@ -0,0 +1,179 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: flume
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Casey O'Hara
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-07-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: redis
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: laissez
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.0.2
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.0.2
41
+ - !ruby/object:Gem::Dependency
42
+ name: thor
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.19.1
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.19.1
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.6'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.6'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '2.14'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '2.14'
97
+ - !ruby/object:Gem::Dependency
98
+ name: mock_redis
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 0.13.2
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 0.13.2
111
+ - !ruby/object:Gem::Dependency
112
+ name: timecop
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 0.7.1
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 0.7.1
125
+ description: A Redis logger for Ruby/Rails
126
+ email:
127
+ - cohara@printreleaf.com
128
+ executables:
129
+ - flume
130
+ extensions: []
131
+ extra_rdoc_files: []
132
+ files:
133
+ - ".gitignore"
134
+ - Gemfile
135
+ - LICENSE.txt
136
+ - README.md
137
+ - Rakefile
138
+ - bin/flume
139
+ - flume.gemspec
140
+ - lib/flume.rb
141
+ - lib/flume/cli.rb
142
+ - lib/flume/log_device.rb
143
+ - lib/flume/logger.rb
144
+ - lib/flume/version.rb
145
+ - spec/integration/flume_spec.rb
146
+ - spec/lib/flume_spec.rb
147
+ - spec/lib/log_device_spec.rb
148
+ - spec/lib/logger_spec.rb
149
+ - spec/spec_helper.rb
150
+ homepage: https://github.com/printreleaf/flume
151
+ licenses:
152
+ - MIT
153
+ metadata: {}
154
+ post_install_message:
155
+ rdoc_options: []
156
+ require_paths:
157
+ - lib
158
+ required_ruby_version: !ruby/object:Gem::Requirement
159
+ requirements:
160
+ - - ">="
161
+ - !ruby/object:Gem::Version
162
+ version: '0'
163
+ required_rubygems_version: !ruby/object:Gem::Requirement
164
+ requirements:
165
+ - - ">="
166
+ - !ruby/object:Gem::Version
167
+ version: '0'
168
+ requirements: []
169
+ rubyforge_project:
170
+ rubygems_version: 2.2.2
171
+ signing_key:
172
+ specification_version: 4
173
+ summary: Redis logger
174
+ test_files:
175
+ - spec/integration/flume_spec.rb
176
+ - spec/lib/flume_spec.rb
177
+ - spec/lib/log_device_spec.rb
178
+ - spec/lib/logger_spec.rb
179
+ - spec/spec_helper.rb