elasticelmah 0.0.1

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 (3) hide show
  1. data/lib/elasticelmah.rb +131 -0
  2. data/tests/elasticelmah_tests.rb +129 -0
  3. metadata +113 -0
@@ -0,0 +1,131 @@
1
+ require 'elasticsearch'
2
+ require 'log4r'
3
+ require 'time'
4
+ module ElasticElmah
5
+
6
+ class Outputter < Log4r::Outputter
7
+ attr_reader :log
8
+ def initialize(_name, hash={})
9
+ super(_name, hash)
10
+ @index = "logs"
11
+
12
+ @index = hash[:index] if hash.has_key?(:index)
13
+ @closed = false
14
+ @initialized = false
15
+ @client = Elasticsearch::Client.new #log: true
16
+ end
17
+
18
+ def time_now
19
+ Time.now.utc
20
+ end
21
+ def time_stamp
22
+ time_now.strftime('%Y-%m-%dT%H:%M:%S.%7N%:z') #"0001-01-01T00:00:00.0 00 000 0+01:00"
23
+ end
24
+
25
+ def closed?
26
+ @closed
27
+ end
28
+
29
+ def close
30
+ @closed = true
31
+ @level = OFF
32
+ OutputterFactory.create_methods(self)
33
+ Logger.log_internal {"Outputter '#{@name}' closed and set to OFF"}
34
+ end
35
+
36
+ def serialize(l)
37
+ # attr_reader :level, :tracer, :data, :name, :fullname
38
+ # [level] The integer level of the log event. Use LNAMES[level]
39
+ # to get the actual level name.
40
+ # [tracer] The execution stack returned by <tt>caller</tt> at the
41
+ # log event. It is nil if the invoked Logger's trace is false.
42
+ # [data] The object that was passed into the logging method.
43
+ # [name] The name of the logger that was invoked.
44
+ # [fullname] The fully qualified name of the logger that was invoked.
45
+ return {
46
+ loggerName:l.name,
47
+ level: Log4r::LNAMES[l.level],
48
+ message: l.data != nil && l.data.respond_to?(:message) ? l.data.message : l.data,
49
+ threadName:"",
50
+ timeStamp:time_stamp,
51
+ locationInfo:{
52
+ className:"?",
53
+ fileName:"?",
54
+ lineNumber:"?",
55
+ methodName:"?"
56
+ },
57
+ userName:"",
58
+ properties:{},
59
+ exceptionString: l.tracer!=nil ? l.tracer.join("\n") : "",
60
+ domain:"",
61
+ identity:""
62
+ }
63
+ end
64
+
65
+ #######
66
+ private
67
+ #######
68
+ def create_index
69
+ @client.indices.create(index: @index, body: {
70
+ settings: {
71
+ index: { number_of_shards: 1, number_of_replicas: 0 }
72
+ },
73
+ mappings:{
74
+ "LoggingEvent" => logging_event_mappings
75
+ }
76
+ })
77
+ #@client.indices.put_mapping(index: @index, type: 'LoggingEvent', body: logging_event_mappings)
78
+ end
79
+ def logging_event_mappings
80
+ {
81
+ _source: {
82
+ enabled: true,
83
+ compress: false
84
+ },
85
+ _ttl: {
86
+ enabled: true,
87
+ default: "24d"
88
+ },
89
+ _timestamp: {
90
+ enabled: true,
91
+ path: "timeStamp",
92
+ store: true
93
+ },
94
+ properties: {
95
+ timeStamp: {
96
+ type: "date"
97
+ },
98
+ message:{type: "string"},
99
+ exceptionString:{type: "string"},
100
+ domain:{type: "string"},
101
+ identity:{type: "string"},
102
+ userName: {type: "string"},
103
+ locationInfo:{
104
+ type: "object",
105
+ properties: {
106
+ className:{type: "string"},
107
+ fileName:{type: "string"},
108
+ lineNumber:{type: "string"},
109
+ methodName:{type: "string"}
110
+ }
111
+ },
112
+ threadName:{type: "string"},
113
+ loggerName:{type: "string"},
114
+ level:{type:"string"},
115
+ properties:{ type: "object", store: "yes" }
116
+ }
117
+ }
118
+ end
119
+
120
+ # perform the write
121
+ def canonical_log(logevent)
122
+ if !@initialized
123
+ @initialized= true
124
+ if !@client.indices.exists(index: @index)
125
+ create_index
126
+ end
127
+ end
128
+ @client.index index: @index, type: 'LoggingEvent', body: serialize(logevent)
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,129 @@
1
+ $:.unshift File.join(File.dirname(__FILE__),'..','lib')
2
+
3
+ require 'elasticelmah'
4
+ require 'test/unit'
5
+ require 'securerandom'
6
+ class OutputterWithFakedElastic < ElasticElmah::Outputter
7
+ attr_reader :written
8
+ def initialize(_name, hash={})
9
+ super(_name, hash)
10
+ @written = []
11
+ end
12
+
13
+ private
14
+ def canonical_log(logevent)
15
+ @written.push(logevent)
16
+ end
17
+ end
18
+
19
+ class OutputterWithFakedElasticAndTimestamp < OutputterWithFakedElastic
20
+ def initialize(_name, hash={})
21
+ super(_name, hash)
22
+ @written = []
23
+ end
24
+ def time_now
25
+ Time.new(2008,6,21, 12,30,0, "+01:00")
26
+ end
27
+ end
28
+
29
+ class TestElasticElmahOutputterForReal < Test::Unit::TestCase
30
+ def setup
31
+ Log4r::Logger.root.level = Log4r::INFO
32
+ @logger = Log4r::Logger.new 'testout_for_real'
33
+ @index = SecureRandom.uuid
34
+ @outp = ElasticElmah::Outputter.new 'outp_for_real',{index: @index}
35
+ @logger.add('outp_for_real')
36
+ @client = Elasticsearch::Client.new# log: true
37
+ end
38
+ def teardown
39
+ @client.indices.delete(index: @index)
40
+ end
41
+
42
+ def test_generated_from_logging_event_data
43
+ @logger.error('some_error')
44
+ @client.indices.flush(index: @index )
45
+ result = @client.search index: @index
46
+ assert_equal 1, result["hits"]["hits"].length
47
+ hits = result["hits"]["hits"]
48
+ assert_equal 'some_error', hits[0]["_source"]["message"]
49
+ end
50
+ end
51
+
52
+
53
+ class TestElasticElmahOutputter < Test::Unit::TestCase
54
+ def setup
55
+ Log4r::Logger.root.level = Log4r::INFO
56
+ @logger = Log4r::Logger.new 'testoutp'
57
+
58
+ @outp = OutputterWithFakedElasticAndTimestamp.new 'outp1'
59
+ @logger.add('outp1')
60
+ end
61
+
62
+ def test_generated_from_logging_event_data
63
+ @logger.error('some_error')
64
+ assert_equal([{:loggerName=>"testoutp",
65
+ :level=>"ERROR",
66
+ :message=>"some_error",
67
+ :threadName=>"",
68
+ :timeStamp=>"2008-06-21T12:30:00.0000000+01:00",
69
+ :locationInfo=>
70
+ {:className=>"?", :fileName=>"?", :lineNumber=>"?", :methodName=>"?"},
71
+ :userName=>"",
72
+ :properties=>{},
73
+ :exceptionString=>"",
74
+ :domain=>"",
75
+ :identity=>""}],
76
+ @outp.written.map do |written| @outp.serialize(written) end)
77
+ end
78
+ end
79
+
80
+ class FakeLogger
81
+ attr_reader :name, :fullname
82
+ def initialize(name,fullname)
83
+ @name = name
84
+ @fullname = fullname
85
+ end
86
+ end
87
+
88
+ class TestElasticElmahSerializer < Test::Unit::TestCase
89
+ def setup
90
+ @outp = OutputterWithFakedElasticAndTimestamp.new 'outp2'
91
+ end
92
+
93
+
94
+ def test_will_serialize_exception_string
95
+ logger = FakeLogger.new('logger_1', 'fullname_of_logger_1')
96
+ tracer = caller
97
+ data = Exception.new("Message")
98
+ l = Log4r::LogEvent.new(Log4r::INFO, logger, tracer, data)
99
+ s = @outp.serialize(l)
100
+ assert_equal("Message",s[:message])
101
+ assert_equal(caller.join("\n"),s[:exceptionString])
102
+ end
103
+
104
+ def test_will_serialize_exception_without_exception_string
105
+ expected = {
106
+ loggerName:"logger_1",
107
+ level:"INFO",
108
+ message:"Message",
109
+ threadName:"",
110
+ timeStamp:"2008-06-21T12:30:00.0000000+01:00",
111
+ locationInfo:{
112
+ className:"?",
113
+ fileName:"?",
114
+ lineNumber:"?",
115
+ methodName:"?"
116
+ },
117
+ userName:"",
118
+ properties:{},
119
+ exceptionString:"",
120
+ domain:"",
121
+ identity:""
122
+ }
123
+ logger = FakeLogger.new('logger_1', 'fullname_of_logger_1')
124
+ tracer = nil
125
+ data = Exception.new("Message")
126
+ l = Log4r::LogEvent.new(Log4r::INFO, logger, tracer, data)
127
+ assert_equal(expected, @outp.serialize(l))
128
+ end
129
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: elasticelmah
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Oskar Gewalli
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-02-18 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: elasticsearch
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: log4r
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rake
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: bundler
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ description: ! 'An appender for log4r that appends to elastic search
79
+
80
+ '
81
+ email: ''
82
+ executables: []
83
+ extensions: []
84
+ extra_rdoc_files: []
85
+ files:
86
+ - lib/elasticelmah.rb
87
+ - tests/elasticelmah_tests.rb
88
+ homepage:
89
+ licenses: []
90
+ post_install_message:
91
+ rdoc_options: []
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ! '>='
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ none: false
102
+ requirements:
103
+ - - ! '>='
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ requirements: []
107
+ rubyforge_project:
108
+ rubygems_version: 1.8.24
109
+ signing_key:
110
+ specification_version: 3
111
+ summary: ElasticSearch log4r appender
112
+ test_files:
113
+ - tests/elasticelmah_tests.rb