s3_log 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,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MDMwNzBmNzcyYWQ1MDAyZDRkNGMzMmMxYjQ3YzczZDI3NDQ1MjdiNQ==
5
+ data.tar.gz: !binary |-
6
+ ZjEyZGI2Y2NhMzNjYTJlODUyYjZmZGI3NTBlYTM2MjM1NDhhMzI3NQ==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ OTFlNDY4ZmE2Y2M0MTY0ZDhkNjljNDY3Mzk0NmUxNWIzMTQ3ZWM1ZTY5ZTU3
10
+ M2IxMDEwZWRmZTk2YmMzNTdlMDcyYTZlZmVjMDI1ZWUxMTZmODQ2YzZlNzRj
11
+ OWQzYjA2NzI3MzlkOTAyYjc0MjI1NDRkODY1ZGVjZjU5NGJlYjY=
12
+ data.tar.gz: !binary |-
13
+ MWZkNjY1Mjg0NDRiYzVhYzZhMjhjNDdhMGVmYjU4NWM3MDJmNzE5ZmVkMWY2
14
+ OTBkODJiOTVjZTNjM2M4ODFiNTE1MTU4ZGUyMWM0YTU3YjYyMmJiNWI1MDRl
15
+ NjI4MDM0ZWQ4MTVlN2JhNzQ1ZDQwOTkyZTlkN2E5ZWQyZTcxOWE=
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ /.bundle
2
+ /log/*.log
3
+ /tmp
4
+ *~
5
+ *.swp
6
+ /pkg
7
+ /bin
8
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/HISTORY.md ADDED
@@ -0,0 +1,4 @@
1
+ ## History ##
2
+
3
+ * 0.0.2 - Renamed to S3Log to avoid conflict with an existing gem
4
+ * 0.0.1 - Initial release
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Dennis Walters
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,57 @@
1
+ ## S3Logger ##
2
+
3
+ Naively log events to a file on S3
4
+
5
+ ## Gem Setup ##
6
+
7
+ ```ruby
8
+ gem install s3_logger
9
+
10
+ # Gemfile
11
+ gem 's3_logger'
12
+ ```
13
+
14
+ ## Configuration ##
15
+
16
+ S3Logger requires an AWS access key id, AWS secret access key, and a S3 bucket (preferably created in advance) name to function. It can be configured (in a Rails initializer or what have you) like so:
17
+
18
+ ```ruby
19
+ S3Logger.configure(
20
+ access_key_id: 'YOUR AWS ACCESS KEY ID',
21
+ secret_access_key: 'YOUR AWS SECRET ACCESS KEY',
22
+ bucket: 'YOUR S3 BUCKET'
23
+ )
24
+ ```
25
+
26
+ ## Usage ##
27
+
28
+ Basically, logging an event is a matter of using S3Logger.write to write content to a given file location on S3. The file does not have to exist prior to writing, and a write always appends to an existing file.
29
+
30
+ ```ruby
31
+ S3Logger.write('path/to/file', 'Some content')
32
+ ```
33
+
34
+ ## Caveats ##
35
+
36
+ There is no locking in this process, and an existing file will always be read and appended rather than blindly replaced. That being the case, near-simultaneous writes are won by the most recent write, and you would do well to do one of the following to avoid data loss:
37
+
38
+ * Ensure that only one process writes to a given file at a time
39
+ * Use a new file path for each write (ie models/user/1/TIMESTAMP.log rather than models/user/1.log)
40
+
41
+ ## Formal Documentation ##
42
+
43
+ The actual library docs can be read
44
+ [over on rubydoc](http://rubydoc.info/gems/s3_logger/frames).
45
+
46
+ ## Contributing ##
47
+
48
+ Do you use git-flow? I sure do. Please base anything you do off of
49
+ [the develop branch](https://github.com/ess/s3_logger/tree/develop).
50
+
51
+ 1. Fork it.
52
+ 2. Perform some BDD magic. Seriously. Be testing.
53
+ 3. Submit a pull request.
54
+
55
+ ## License ##
56
+
57
+ MIT License. Copyright 2015 Dennis Walters
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler::GemHelper.install_tasks
4
+ require "bundler/gem_tasks"
@@ -0,0 +1,15 @@
1
+ module S3Log
2
+ class Error < StandardError ; end
3
+
4
+ class InvalidConfigError < Error
5
+ def initialize(missing)
6
+ super("Missing configuration keys (#{missing.join(', ')})")
7
+ end
8
+ end
9
+
10
+ class Unconfigured < Error
11
+ def initialize(garbage = nil)
12
+ super("You must first run S3Logger.configure")
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,3 @@
1
+ module S3Log
2
+ VERSION = '0.0.2'
3
+ end
data/lib/s3_log.rb ADDED
@@ -0,0 +1,63 @@
1
+ require 'fog/aws/storage'
2
+ require 's3_log/exceptions'
3
+
4
+ module S3Log
5
+ RequiredOptions = [:access_key_id, :secret_access_key, :bucket]
6
+
7
+ def self.storage
8
+ @storage
9
+ end
10
+
11
+ def self.bucket
12
+ @bucket
13
+ end
14
+
15
+ def self.configured?
16
+ storage && bucket
17
+ end
18
+
19
+ def self.configure(options = {})
20
+ missing = RequiredOptions - options.keys
21
+ raise InvalidConfigError.new(missing) unless missing.empty?
22
+
23
+ clear_configuration
24
+
25
+ @storage = Fog::Storage::AWS.new(
26
+ aws_access_key_id: options[:access_key_id],
27
+ aws_secret_access_key: options[:secret_access_key]
28
+ )
29
+
30
+ @bucket = @storage.directories.create(
31
+ key: options[:bucket],
32
+ public: false
33
+ )
34
+ self
35
+ end
36
+
37
+ def self.write(path, content)
38
+ unless storage && bucket
39
+ raise Unconfigured
40
+ end
41
+
42
+ bucket.files.create(
43
+ key: path,
44
+ body: read(path).split("\n").push(content).join("\n"),
45
+ public: false
46
+ )
47
+
48
+ self
49
+ end
50
+
51
+ def self.read(path)
52
+ unless storage && bucket
53
+ raise Unconfigured
54
+ end
55
+
56
+ file = bucket.files.get(path)
57
+ file.nil? ? '' : file.body.to_s
58
+ end
59
+
60
+ def self.clear_configuration
61
+ @bucket = @storage = nil
62
+ end
63
+ end
data/s3_log.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/s3_log/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Dennis Walters"]
6
+ gem.email = ["dennis@elevatorup.com"]
7
+ gem.summary = %q{Log misc events to Amazon S3}
8
+ gem.description = <<-EOD
9
+ Log misc events to Amazon S3
10
+ EOD
11
+ gem.homepage = "http://github.com/ess/s3_log"
12
+ gem.license = 'MIT'
13
+
14
+ gem.files = `git ls-files`.split($\)
15
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
16
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
17
+ gem.name = "s3_log"
18
+ gem.require_paths = ["lib"]
19
+ gem.version = S3Log::VERSION
20
+
21
+ gem.add_dependency 'fog-aws', '~> 0.1.1'
22
+ gem.add_development_dependency 'rspec', '~> 3.2.0'
23
+ end
@@ -0,0 +1,131 @@
1
+ require 'spec_helper'
2
+ require 's3_log'
3
+
4
+ describe S3Log do
5
+ let(:access_key_id) {'ACCESS_KEY_ID'}
6
+ let(:secret_access_key) {'SECRET_ACCESS_KEY'}
7
+ let(:bucket) {'bucket'}
8
+ let(:path) {'path/to/a/file'}
9
+ let(:content) {'line 1'}
10
+
11
+ before(:each) do
12
+ Fog::Mock.reset
13
+ Fog.mock!
14
+ end
15
+
16
+ describe '.configure' do
17
+ let(:good_options) {{
18
+ access_key_id: access_key_id,
19
+ secret_access_key: secret_access_key,
20
+ bucket: bucket
21
+ }}
22
+
23
+ it 'requires an aws access key id' do
24
+ expect{described_class.configure(good_options)}.
25
+ not_to raise_error
26
+
27
+ good_options.delete(:access_key_id)
28
+
29
+ expect{described_class.configure(good_options)}.
30
+ to raise_error(S3Log::InvalidConfigError)
31
+ end
32
+
33
+ it 'requires an aws secret access key' do
34
+ expect{described_class.configure(good_options)}.
35
+ not_to raise_error
36
+
37
+ good_options.delete(:secret_access_key)
38
+
39
+ expect{described_class.configure(good_options)}.
40
+ to raise_error(S3Log::InvalidConfigError)
41
+
42
+ end
43
+
44
+ it 'requires a bucket name' do
45
+ expect{described_class.configure(good_options)}.
46
+ not_to raise_error
47
+
48
+ good_options.delete(:bucket)
49
+
50
+ expect{described_class.configure(good_options)}.
51
+ to raise_error(S3Log::InvalidConfigError)
52
+ end
53
+ end
54
+
55
+ describe '.read' do
56
+ before(:each) do
57
+ described_class.configure(
58
+ access_key_id: 'ACCESS_KEY_ID',
59
+ secret_access_key: 'SECRET_ACCESS_KEY',
60
+ bucket: 'bucket'
61
+ )
62
+ end
63
+
64
+ it 'requires that the module be configured' do
65
+ described_class.clear_configuration
66
+ expect {described_class.read(path)}.
67
+ to raise_error(described_class::Unconfigured)
68
+ end
69
+
70
+ it 'is a string' do
71
+ expect(described_class.read(path)).to be_a(String)
72
+ end
73
+
74
+ context 'for a non-existent path' do
75
+ it 'is an empty string' do
76
+ expect(described_class.read(path)).to eql('')
77
+ end
78
+ end
79
+
80
+ context 'for an existing path' do
81
+ it 'is the content of the file' do
82
+ described_class.write(path, content)
83
+ expect(described_class.read(path)).to eql(content)
84
+ end
85
+ end
86
+ end
87
+
88
+ describe '.write' do
89
+ before(:each) do
90
+ described_class.configure(
91
+ access_key_id: 'ACCESS_KEY_ID',
92
+ secret_access_key: 'SECRET_ACCESS_KEY',
93
+ bucket: 'bucket'
94
+ )
95
+ end
96
+
97
+ it 'requires that the module be configured' do
98
+ described_class.clear_configuration
99
+ expect {described_class.write(path, content)}.
100
+ to raise_error(described_class::Unconfigured)
101
+ end
102
+
103
+ it 'reads the file' do
104
+ expect(described_class).
105
+ to receive(:read).with(path).and_call_original
106
+
107
+ described_class.write(path, content)
108
+ end
109
+
110
+ it 'creates the file on s3' do
111
+ expect(described_class.read(path)).to eql('')
112
+
113
+ described_class.write(path, content)
114
+
115
+ expect(described_class.read(path)).to eql(content)
116
+ end
117
+
118
+ it 'appends to an exsiting s3 file' do
119
+ more_content = 'more content'
120
+ described_class.write(path, content)
121
+ expect(described_class.read(path)).to eql(content)
122
+
123
+ described_class.write(path, "more content")
124
+ expect(described_class.read(path)).to eql("#{content}\n#{more_content}")
125
+ end
126
+
127
+ it 'returns the logger itself' do
128
+ expect(described_class.write(path, content)).to eql(described_class)
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,9 @@
1
+ require 'rspec'
2
+ require 'rspec/mocks'
3
+ require 'rspec/expectations'
4
+
5
+ $:.unshift File.join(File.dirname(__FILE__), '..')
6
+
7
+ RSpec.configure do |config|
8
+ config.mock_framework = :rspec
9
+ end
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: s3_log
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Dennis Walters
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-03-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: fog-aws
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 0.1.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 0.1.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 3.2.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: 3.2.0
41
+ description: ! ' Log misc events to Amazon S3
42
+
43
+ '
44
+ email:
45
+ - dennis@elevatorup.com
46
+ executables: []
47
+ extensions: []
48
+ extra_rdoc_files: []
49
+ files:
50
+ - .gitignore
51
+ - Gemfile
52
+ - HISTORY.md
53
+ - LICENSE
54
+ - README.md
55
+ - Rakefile
56
+ - lib/s3_log.rb
57
+ - lib/s3_log/exceptions.rb
58
+ - lib/s3_log/version.rb
59
+ - s3_log.gemspec
60
+ - spec/s3_log_spec.rb
61
+ - spec/spec_helper.rb
62
+ homepage: http://github.com/ess/s3_log
63
+ licenses:
64
+ - MIT
65
+ metadata: {}
66
+ post_install_message:
67
+ rdoc_options: []
68
+ require_paths:
69
+ - lib
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ! '>='
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ! '>='
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ requirements: []
81
+ rubyforge_project:
82
+ rubygems_version: 2.4.5
83
+ signing_key:
84
+ specification_version: 4
85
+ summary: Log misc events to Amazon S3
86
+ test_files:
87
+ - spec/s3_log_spec.rb
88
+ - spec/spec_helper.rb