log4r-sequel 0.0.1 → 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.
- checksums.yaml +4 -4
- data/.travis.yml +6 -0
- data/README.md +42 -4
- data/VERSION +1 -1
- data/example/log2postgres.rb +2 -2
- data/example/log2sqlite.rb +1 -4
- data/example/log4r-postgres.yaml +1 -1
- data/example/log4r-sqlite.yaml +1 -1
- data/lib/log4r/outputter/sequeloutputter.rb +15 -23
- data/test/functional/test_postgres.rb +63 -0
- data/test/functional/test_sqlite.rb +18 -2
- data/test/log4r-postgres_test.yaml +42 -0
- data/test/log4r-sqlite_test.yaml +4 -15
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4e2df9143f88d2565644c34dd200a0c66a4d49f5
|
4
|
+
data.tar.gz: c76ec6079a80db159faac195d8890e8757794e25
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6fbd50621319256bad2e8c8ca51a88e3df425c02da1abdcdfb525f0fa98474b0743aafa60427a081c4f43d503e4ad02b51abc63f27105c0cfa0655866acd3551
|
7
|
+
data.tar.gz: bc46f2fd5e8ef4a268f6ff5151e8f70ca21f03656ec7c720a51d556757ab2a1c8e2298661f669bc72772e66999c8c3f58116f1aa0bf051a1e0bc7cba98f1ba30
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,21 @@
|
|
1
1
|
# log4r-sequel
|
2
2
|
Log4r outputter to a Sequel database handle
|
3
3
|
|
4
|
+
- [usage](#usage)
|
5
|
+
- [pre-built gem installation (stable)](#pre-built-gem-installation-stable)
|
6
|
+
- [from-source installation (latest)](#from-source-installation-latest)
|
7
|
+
- [demo](#demo)
|
8
|
+
- [supported databases](#supported-databases)
|
9
|
+
- [TODO](#todo)
|
10
|
+
|
11
|
+
the de-facto standard library for logging in Ruby, [log4r](https://github.com/colbygk/log4r) works very well for a wide array of logging targets:
|
12
|
+
* STDOUT / STDERR
|
13
|
+
* file
|
14
|
+
* email
|
15
|
+
* syslog
|
16
|
+
|
17
|
+
and so on, but didn't have a way to output directly to a database - enter `log4r-sequel`
|
18
|
+
|
4
19
|
## usage
|
5
20
|
|
6
21
|
### pre-built gem installation (stable)
|
@@ -33,13 +48,36 @@ irb(main):001:0> require 'log4r/outputter/sequeloutputter'
|
|
33
48
|
=> true
|
34
49
|
```
|
35
50
|
|
51
|
+
### demo
|
52
|
+
|
53
|
+
```
|
54
|
+
$ ruby example/log2postgres.rb
|
55
|
+
2016/08/27 17:08.1472342938 | bar | DEBUG | this is a debug message
|
56
|
+
2016/08/27 17:08.1472342938 | bar | INFO | this is an info message
|
57
|
+
2016/08/27 17:08.1472342938 | bar | WARN | this is a warning
|
58
|
+
2016/08/27 17:08.1472342938 | bar | ERROR | this is an error
|
59
|
+
2016/08/27 17:08.1472342938 | bar | FATAL | this is a fatal
|
60
|
+
$ sqlite3 example/log.sqlite
|
61
|
+
SQLite version 3.8.10.2 2015-05-20 18:17:19
|
62
|
+
Enter ".help" for usage hints.
|
63
|
+
sqlite> select * from logs;
|
64
|
+
1|2016/08/27 17:10.1472343022|foo|DEBUG|this is a debug message
|
65
|
+
2|2016/08/27 17:10.1472343022|foo|INFO|this is an info message
|
66
|
+
3|2016/08/27 17:10.1472343022|foo|WARN|this is a warning
|
67
|
+
4|2016/08/27 17:10.1472343022|foo|ERROR|this is an error
|
68
|
+
5|2016/08/27 17:10.1472343022|foo|FATAL|this is a fatal
|
69
|
+
sqlite>
|
70
|
+
```
|
71
|
+
|
36
72
|
## supported databases
|
37
73
|
* sqlite3
|
38
74
|
* Postgres
|
39
|
-
|
75
|
+
|
40
76
|
## TODO
|
41
|
-
* allow database name to be semi-dynamically generated - via YAML config, not just by passing the hash directly
|
42
77
|
* tests
|
43
78
|
* unit tests
|
44
|
-
|
45
|
-
|
79
|
+
|
80
|
+
|
81
|
+
## notes
|
82
|
+
* `:database`, `:table`, and `:file` options are passed through `Time.now.strftime(%s)`
|
83
|
+
* sqlite filenames cannot contain underscores (`the scheme sqlite does not accept registry part`)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.2
|
data/example/log2postgres.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
$LOAD_PATH << sprintf('%s/../lib', File.dirname(__FILE__))
|
2
|
-
|
3
|
-
#require 'log4r-sequel'
|
4
2
|
require 'log4r/outputter/sequeloutputter'
|
5
3
|
|
4
|
+
require 'pg'
|
5
|
+
|
6
6
|
file = sprintf('%s/log4r-postgres.yaml', File.dirname(__FILE__))
|
7
7
|
Log4r::YamlConfigurator.load_yaml_file(file)
|
8
8
|
|
data/example/log2sqlite.rb
CHANGED
@@ -1,11 +1,8 @@
|
|
1
1
|
$LOAD_PATH << sprintf('%s/../lib', File.dirname(__FILE__))
|
2
|
+
require 'log4r/outputter/sequeloutputter'
|
2
3
|
|
3
4
|
require 'sqlite3'
|
4
5
|
|
5
|
-
#require 'log4r-sequel'
|
6
|
-
require 'log4r/outputter/sequeloutputter'
|
7
|
-
require 'log4r/yamlconfigurator'
|
8
|
-
|
9
6
|
## instantiate a logger following the log4r pattern
|
10
7
|
file = sprintf('%s/log4r-sqlite.yaml', File.dirname(__FILE__))
|
11
8
|
Log4r::YamlConfigurator.load_yaml_file(file)
|
data/example/log4r-postgres.yaml
CHANGED
data/example/log4r-sqlite.yaml
CHANGED
@@ -24,7 +24,7 @@ log4r_config:
|
|
24
24
|
pattern: '%d!@#$%C!@#$%l!@#$%m' # date|level|event/class fullname|message
|
25
25
|
# log4r-sequel settings
|
26
26
|
engine: sqlite
|
27
|
-
file: log.sqlite
|
27
|
+
file: log-%Y-%m-%d-%H-%M-%s.sqlite
|
28
28
|
table: logs
|
29
29
|
delimiter: '!@#$' # this is used to determine columns needed based on log4 configuration
|
30
30
|
map:
|
@@ -3,21 +3,9 @@ require 'log4r/yamlconfigurator'
|
|
3
3
|
require 'sequel'
|
4
4
|
require 'yaml'
|
5
5
|
|
6
|
-
# TODO should we move this to ../logger.rb
|
7
|
-
# TODO .. or should we remove this entirely? it was implemented to let us call connect/configure, but since we do that in initiliaze now, maybe we just pull it
|
8
6
|
class Log4r::Logger
|
9
|
-
# +method+ String or Symbol representing the name of the method in the Log4r::Outputter::SequelOutputter class you want to use
|
10
|
-
# +parameters+ arbitrary data type to be passed to :methods
|
11
|
-
def sequel(method, parameters = { })
|
12
|
-
# TODO support methods that take more than one parameter
|
13
|
-
self.outputters.each do |op|
|
14
|
-
next unless op.is_a?(SequelOutputter)
|
15
|
-
return op.send(method.to_sym, parameters)
|
16
|
-
end
|
17
|
-
end
|
18
7
|
|
19
8
|
# no parameters, returns the first Log4r::Outputter::Sequel object
|
20
|
-
# TODO is there ever a case where there would be more than one?
|
21
9
|
def get_outputter
|
22
10
|
self.outputters.each do |op|
|
23
11
|
next unless op.is_a?(SequelOutputter)
|
@@ -57,16 +45,21 @@ class SequelOutputter < Log4r::Outputter
|
|
57
45
|
@engine = config[:engine].to_sym
|
58
46
|
|
59
47
|
# error checking on table/column settings
|
60
|
-
@table
|
61
|
-
@map
|
48
|
+
@table = Time.now.strftime(config[:table]).to_sym
|
49
|
+
@map = config[:map]
|
62
50
|
@delimiter = config[:delimiter]
|
63
|
-
|
64
|
-
|
51
|
+
|
52
|
+
{
|
53
|
+
:delimiter => @delimiter,
|
54
|
+
:map => @map,
|
55
|
+
:table => @table,
|
56
|
+
}.each_pair do |key, value|
|
57
|
+
raise Log4r::ConfigError.new(sprintf('required key[%s] missing from configuration', key)) if value.nil?
|
65
58
|
end
|
66
59
|
|
67
60
|
if @engine.eql?(:postgres)
|
68
|
-
@database = config[:database]
|
69
|
-
@file =
|
61
|
+
@database = Time.now.strftime(config[:database])
|
62
|
+
@file = @table # this is technically the.. table, but maintaining interface cleanliness
|
70
63
|
server = config[:server]
|
71
64
|
port = config[:port]
|
72
65
|
username = config[:username]
|
@@ -74,7 +67,7 @@ class SequelOutputter < Log4r::Outputter
|
|
74
67
|
@dbh = Sequel.connect(sprintf('postgres://%s:%s@%s:%s/%s', username, password, server, port, @database))
|
75
68
|
elsif @engine.eql?(:sqlite)
|
76
69
|
@database = nil # sqlite has one DB per file
|
77
|
-
@file = config[:file]
|
70
|
+
@file = Time.now.strftime(config[:file])
|
78
71
|
@dbh = Sequel.connect(sprintf('sqlite://%s', @file))
|
79
72
|
else
|
80
73
|
raise Log4r::ConfigError.new(sprintf('unable to use engine[%s], allowed[%s]', @engine, KNOWN_ENGINES))
|
@@ -90,7 +83,7 @@ class SequelOutputter < Log4r::Outputter
|
|
90
83
|
|
91
84
|
@dbh = dbh
|
92
85
|
|
93
|
-
# idempotently create table
|
86
|
+
# idempotently create database/table
|
94
87
|
initialize_db
|
95
88
|
end
|
96
89
|
|
@@ -103,9 +96,8 @@ class SequelOutputter < Log4r::Outputter
|
|
103
96
|
|
104
97
|
def write(data)
|
105
98
|
raise StandardError.new(sprintf('%s is not connected, run %s.connect(yaml_file)', self.class, self.class)) unless connected?
|
106
|
-
|
107
|
-
|
108
|
-
hash = Hash.new
|
99
|
+
tokens = data.chomp.split(@delimiter)
|
100
|
+
hash = Hash.new
|
109
101
|
|
110
102
|
tokens.each_with_index do |token, i|
|
111
103
|
hash[@map[i].to_sym] = token
|
@@ -0,0 +1,63 @@
|
|
1
|
+
$LOAD_PATH << sprintf('%s/../../lib', File.dirname(__FILE__))
|
2
|
+
require 'log4r/outputter/sequeloutputter'
|
3
|
+
|
4
|
+
require 'test/unit'
|
5
|
+
|
6
|
+
class TestPostgres < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def setup
|
9
|
+
@good_config = sprintf('%s/../log4r-postgres_test.yaml', File.expand_path(File.dirname(__FILE__)))
|
10
|
+
@table = Time.now.strftime('logs-%Y/%m/%d-%H:%M').to_sym
|
11
|
+
|
12
|
+
begin
|
13
|
+
require 'pg'
|
14
|
+
rescue LoadError
|
15
|
+
omit('[pg] not installed/configured')
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
def teardown; end
|
21
|
+
|
22
|
+
def test_happy_yaml
|
23
|
+
file = @good_config
|
24
|
+
Log4r::YamlConfigurator.load_yaml_file(file)
|
25
|
+
|
26
|
+
logger = nil
|
27
|
+
|
28
|
+
assert_nothing_raised do
|
29
|
+
logger = Log4r::Logger.get('test')
|
30
|
+
end
|
31
|
+
|
32
|
+
assert_not_nil(logger)
|
33
|
+
assert_equal(0, logger.get_outputter.dbh[@table].count)
|
34
|
+
|
35
|
+
assert_nothing_raised do
|
36
|
+
logger.debug('this is a debug message')
|
37
|
+
logger.info('this is an info message')
|
38
|
+
logger.warn('this is a warning')
|
39
|
+
logger.error('this is an error')
|
40
|
+
logger.fatal('this is a fatal')
|
41
|
+
end
|
42
|
+
|
43
|
+
assert_not_equal(0, logger.get_outputter.dbh[@table].count)
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_sad_yaml
|
48
|
+
# TODO pass in bad configs as hashes
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_happy_hash
|
52
|
+
logger = nil
|
53
|
+
|
54
|
+
assert_nothing_raised do
|
55
|
+
#logger = Logger::Log4r.new()
|
56
|
+
p 'DBGZ' if nil?
|
57
|
+
end
|
58
|
+
|
59
|
+
#assert_equal(0, logger.get_outputter.dbh[@table].count)
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
$LOAD_PATH << sprintf('%s/../../lib', File.dirname(__FILE__))
|
2
2
|
require 'log4r/outputter/sequeloutputter'
|
3
3
|
|
4
|
-
|
5
4
|
require 'test/unit'
|
6
5
|
|
7
6
|
class TestSqlite < Test::Unit::TestCase
|
@@ -9,6 +8,12 @@ class TestSqlite < Test::Unit::TestCase
|
|
9
8
|
def setup
|
10
9
|
@good_config = sprintf('%s/../log4r-sqlite_test.yaml', File.expand_path(File.dirname(__FILE__)))
|
11
10
|
@table = :logs
|
11
|
+
|
12
|
+
begin
|
13
|
+
require 'sqlite3'
|
14
|
+
rescue LoadError
|
15
|
+
omit('[sqlite3] not installed/configured')
|
16
|
+
end
|
12
17
|
end
|
13
18
|
|
14
19
|
def teardown
|
@@ -41,9 +46,20 @@ class TestSqlite < Test::Unit::TestCase
|
|
41
46
|
|
42
47
|
end
|
43
48
|
|
44
|
-
def
|
49
|
+
def test_sad_yaml
|
45
50
|
# TODO pass in bad configs as hashes
|
46
51
|
end
|
47
52
|
|
53
|
+
def test_happy_hash
|
54
|
+
logger = nil
|
55
|
+
|
56
|
+
assert_nothing_raised do
|
57
|
+
#logger = Logger::Log4r.new()
|
58
|
+
end
|
59
|
+
|
60
|
+
#assert_equal(0, logger.get_outputter.dbh[@table].count)
|
61
|
+
|
62
|
+
|
63
|
+
end
|
48
64
|
|
49
65
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
---
|
2
|
+
log4r_config:
|
3
|
+
loggers:
|
4
|
+
- name: 'test'
|
5
|
+
outputters:
|
6
|
+
- sequel
|
7
|
+
- stdout
|
8
|
+
outputters:
|
9
|
+
# not needed, but feedback is useful
|
10
|
+
- type: StdoutOutputter
|
11
|
+
name: stdout
|
12
|
+
formatter:
|
13
|
+
type: PatternFormatter
|
14
|
+
date_pattern: '%Y/%m/%d %H:%M.%s'
|
15
|
+
pattern: '%d | %C | %l | %m'
|
16
|
+
|
17
|
+
- type: SequelOutputter
|
18
|
+
# traditional Log4r settings
|
19
|
+
name: sequel
|
20
|
+
level: DEBUG
|
21
|
+
formatter:
|
22
|
+
type: PatternFormatter
|
23
|
+
date_pattern: '%Y/%m/%d %H:%M.%s'
|
24
|
+
pattern: '%d!@#$%l!@#$%C!@#$%c!@#$%h!@#$%p!@#$%m'
|
25
|
+
|
26
|
+
# log4r-sequel settings
|
27
|
+
engine: postgres
|
28
|
+
server: localhost
|
29
|
+
port: 5432
|
30
|
+
database: logs
|
31
|
+
table: logs-%Y/%m/%d-%H:%M
|
32
|
+
username: postgres
|
33
|
+
password: postgres
|
34
|
+
delimiter: '!@#$'
|
35
|
+
map:
|
36
|
+
0: 'date'
|
37
|
+
1: 'level'
|
38
|
+
2: 'class'
|
39
|
+
3: 'relative_class'
|
40
|
+
4: 'thread'
|
41
|
+
5: 'pid'
|
42
|
+
6: 'message'
|
data/test/log4r-sqlite_test.yaml
CHANGED
@@ -21,26 +21,15 @@ log4r_config:
|
|
21
21
|
formatter:
|
22
22
|
type: PatternFormatter
|
23
23
|
date_pattern: '%Y/%m/%d %H:%M.%s'
|
24
|
-
pattern: '%d!@#$%C!@#$%l!@#$%m'
|
24
|
+
pattern: '%d!@#$%C!@#$%l!@#$%m'
|
25
|
+
|
25
26
|
# log4r-sequel settings
|
26
27
|
engine: sqlite
|
27
|
-
file: log.sqlite
|
28
|
+
file: log-%Y-%m-%d-%H-%M.sqlite # underscores are apparently 'invalid'
|
28
29
|
table: logs
|
29
|
-
delimiter: '!@#$'
|
30
|
+
delimiter: '!@#$'
|
30
31
|
map:
|
31
32
|
0: 'date'
|
32
33
|
1: 'level'
|
33
34
|
2: 'class'
|
34
35
|
3: 'message'
|
35
|
-
|
36
|
-
# truncated map from http://log4r.rubyforge.org/rdoc/Log4r/PatternFormatter.html
|
37
|
-
# %c - event short name
|
38
|
-
# %C - event fullname
|
39
|
-
# %d - date
|
40
|
-
# %g - Global Diagnostic Context (GDC)
|
41
|
-
# %t - trace
|
42
|
-
# %m - message
|
43
|
-
# %h - thread name
|
44
|
-
# %p - process ID aka PID
|
45
|
-
# %M - formatted message
|
46
|
-
# %l - Level in string form
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: log4r-sequel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Conor Horan-Kates
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-09-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: log4r
|
@@ -143,7 +143,9 @@ files:
|
|
143
143
|
- example/log4r-postgres.yaml
|
144
144
|
- example/log4r-sqlite.yaml
|
145
145
|
- lib/log4r/outputter/sequeloutputter.rb
|
146
|
+
- test/functional/test_postgres.rb
|
146
147
|
- test/functional/test_sqlite.rb
|
148
|
+
- test/log4r-postgres_test.yaml
|
147
149
|
- test/log4r-sqlite_test.yaml
|
148
150
|
homepage: http://github.com/chorankates/log4r-sequel
|
149
151
|
licenses:
|