portertech-sensu-logger 1.4.0
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 +7 -0
- data/LICENSE.txt +20 -0
- data/README.md +28 -0
- data/lib/sensu/logger/constants.rb +5 -0
- data/lib/sensu/logger/stream.rb +183 -0
- data/lib/sensu/logger.rb +33 -0
- data/sensu-logger.gemspec +24 -0
- metadata +119 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: cc5c7a9853eb75e4fb3b4beb6f3b0775a145249be10b9f9413d4306605151550
|
4
|
+
data.tar.gz: 1ec6bc4130a889ba91211d2b9ba532ddcb001bfbc87234a130894666a799c9c6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8bf2d89c6eea8153f4886ead8f922c60e4350158f62beda089e2d1149c01c1eca05f5bcd649404fb28acf83dba0d11272723bf46d6992c4e6882e0023f8935bb
|
7
|
+
data.tar.gz: d97842c82f53ceb9ff6392cc09451e2f33f8b9f1c40d2644b1aafbd4e5f15c6d424c02b8c9ee85b05a2edf120ccd3e62368cb83f3823e2563c9446f116790c2e
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2016 Heavy Water Operations, LLC.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# Sensu::Logger
|
2
|
+
|
3
|
+
[](https://travis-ci.org/sensu/sensu-logger)
|
4
|
+

|
5
|
+

|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'sensu-logger'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
## Usage
|
18
|
+
|
19
|
+
Documentation can be found [here](http://rubydoc.info/github/sensu/sensu-logger/Sensu/Logger).
|
20
|
+
|
21
|
+
## Contributing
|
22
|
+
|
23
|
+
0. By contributing to this project you agree to abide by the [code of conduct](https://sensuapp.org/conduct).
|
24
|
+
1. [Fork it](https://github.com/sensu/sensu-logger/fork)
|
25
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
26
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
27
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
28
|
+
5. Create a new Pull Request
|
@@ -0,0 +1,183 @@
|
|
1
|
+
require "sensu/json"
|
2
|
+
require "eventmachine"
|
3
|
+
require "sensu/logger/constants"
|
4
|
+
|
5
|
+
module Sensu
|
6
|
+
module Logger
|
7
|
+
class Stream
|
8
|
+
# @!attribute [rw] level
|
9
|
+
# @return level [Symbol] current log level.
|
10
|
+
attr_accessor :level
|
11
|
+
|
12
|
+
# Initialize a log stream, redirect STDERR to STDOUT, create log
|
13
|
+
# level methods, and setup the reactor log event writer.
|
14
|
+
def initialize
|
15
|
+
@stream = []
|
16
|
+
@stream_callbacks = []
|
17
|
+
@level = :info
|
18
|
+
STDOUT.sync = true
|
19
|
+
STDERR.reopen(STDOUT)
|
20
|
+
self.class.create_level_methods
|
21
|
+
setup_writer
|
22
|
+
end
|
23
|
+
|
24
|
+
# Create a method for each of the log levels, they call add() to
|
25
|
+
# add log events to the log stream.
|
26
|
+
def self.create_level_methods
|
27
|
+
LEVELS.each do |level|
|
28
|
+
define_method(level) do |*args|
|
29
|
+
add(level, *args)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Check to see if a log level is currently being filtered.
|
35
|
+
#
|
36
|
+
# @param level [Symbol] log event level.
|
37
|
+
# @return [TrueClass, FalseClass]
|
38
|
+
def level_filtered?(level)
|
39
|
+
LEVELS.index(level) < LEVELS.index(@level)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Add a log event to the log stream.
|
43
|
+
#
|
44
|
+
# @param level [Symbol] log event level.
|
45
|
+
# @param args [Array] to pass to create_log_event().
|
46
|
+
# @return [TrueClass, FalseClass] if the log event was added.
|
47
|
+
def add(level, *args)
|
48
|
+
unless level_filtered?(level)
|
49
|
+
event = create_log_event(level, *args)
|
50
|
+
if EM.reactor_running?
|
51
|
+
schedule_write(event)
|
52
|
+
else
|
53
|
+
safe_write(event)
|
54
|
+
end
|
55
|
+
true
|
56
|
+
else
|
57
|
+
false
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Reopen the log stream output, write log events to a file.
|
62
|
+
#
|
63
|
+
# @param target [IO, String] IO stream or file path.
|
64
|
+
def reopen(target)
|
65
|
+
@reopen = target
|
66
|
+
case target
|
67
|
+
when IO
|
68
|
+
STDOUT.reopen(target)
|
69
|
+
STDOUT.sync = true
|
70
|
+
STDERR.reopen(STDOUT)
|
71
|
+
when String
|
72
|
+
if File.writable?(target) || !File.exist?(target) && File.writable?(File.dirname(target))
|
73
|
+
STDOUT.reopen(target, "a")
|
74
|
+
STDOUT.sync = true
|
75
|
+
STDERR.reopen(STDOUT)
|
76
|
+
else
|
77
|
+
error("log file is not writable", {
|
78
|
+
:log_file => target
|
79
|
+
})
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Setup signal traps for the log stream.
|
85
|
+
# Signals:
|
86
|
+
# TRAP: toggle debug logging.
|
87
|
+
# USR2: reopen the log file.
|
88
|
+
def setup_signal_traps
|
89
|
+
if Signal.list.include?("TRAP")
|
90
|
+
Signal.trap("TRAP") do
|
91
|
+
@level = case @level
|
92
|
+
when :debug
|
93
|
+
@previous_level || :info
|
94
|
+
else
|
95
|
+
@previous_level = @level
|
96
|
+
:debug
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
if Signal.list.include?("USR2")
|
101
|
+
Signal.trap("USR2") do
|
102
|
+
if @reopen
|
103
|
+
reopen(@reopen)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
# Create a JSON log event.
|
112
|
+
#
|
113
|
+
# @param level [Symbol] log event level.
|
114
|
+
# @param message [String] log event message.
|
115
|
+
# @param data [Hash] log event data.
|
116
|
+
# @return [String] JSON log event.
|
117
|
+
def create_log_event(level, message, data=nil)
|
118
|
+
event = {}
|
119
|
+
event[:timestamp] = Time.now.strftime("%Y-%m-%dT%H:%M:%S.%6N%z")
|
120
|
+
event[:level] = level
|
121
|
+
event[:message] = message
|
122
|
+
if data.is_a?(Hash)
|
123
|
+
event.merge!(data)
|
124
|
+
end
|
125
|
+
Sensu::JSON.dump(event)
|
126
|
+
end
|
127
|
+
|
128
|
+
# Schedule a log event write, pushing the JSON log event into
|
129
|
+
# the stream.
|
130
|
+
#
|
131
|
+
# @param event [String] JSON log event.
|
132
|
+
def schedule_write(event)
|
133
|
+
EM.schedule do
|
134
|
+
@stream << event
|
135
|
+
unless @stream_callbacks.empty?
|
136
|
+
@stream_callbacks.shift.call(@stream.shift)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
# Write a JSON log event to STDOUT, which may be redirected to a
|
142
|
+
# log file. This method will take no action if the storage
|
143
|
+
# device has no space remaining.
|
144
|
+
def safe_write(event)
|
145
|
+
begin
|
146
|
+
puts event
|
147
|
+
rescue Errno::ENOSPC
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
# Register a log stream callback (a write operation).
|
152
|
+
#
|
153
|
+
# @param [Proc] callback to register, it will eventually be
|
154
|
+
# called and passed a JSON log event as a parameter.
|
155
|
+
def register_callback(&callback)
|
156
|
+
EM.schedule do
|
157
|
+
if @stream.empty?
|
158
|
+
@stream_callbacks << callback
|
159
|
+
else
|
160
|
+
callback.call(@stream.shift)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
# Setup reactor log event writer. On shutdown, remaining log
|
166
|
+
# events will be written/flushed.
|
167
|
+
def setup_writer
|
168
|
+
writer = Proc.new do |log_event|
|
169
|
+
safe_write(log_event)
|
170
|
+
EM.next_tick do
|
171
|
+
register_callback(&writer)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
register_callback(&writer)
|
175
|
+
EM.add_shutdown_hook do
|
176
|
+
@stream.size.times do
|
177
|
+
safe_write(@stream.shift)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
data/lib/sensu/logger.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require "sensu/logger/stream"
|
2
|
+
|
3
|
+
module Sensu
|
4
|
+
module Logger
|
5
|
+
class << self
|
6
|
+
# Setup a log stream.
|
7
|
+
#
|
8
|
+
# @param [Hash] options to create the log stream with.
|
9
|
+
# @option options [String] :log_level to use.
|
10
|
+
# @option options [String] :log_file to use.
|
11
|
+
# @return [Stream] instance of a log stream.
|
12
|
+
def setup(options={})
|
13
|
+
@stream = Stream.new
|
14
|
+
if options[:log_level]
|
15
|
+
@stream.level = options[:log_level]
|
16
|
+
end
|
17
|
+
if options[:log_file]
|
18
|
+
@stream.reopen(options[:log_file])
|
19
|
+
end
|
20
|
+
@stream
|
21
|
+
end
|
22
|
+
|
23
|
+
# Retrieve the current log stream or set one up if there isn't
|
24
|
+
# one. Note: We may need to add a mutex for thread safety.
|
25
|
+
#
|
26
|
+
# @param [Hash] options to pass to setup().
|
27
|
+
# @return [Stream] instance of a log stream.
|
28
|
+
def get(options={})
|
29
|
+
@stream || setup(options)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = "portertech-sensu-logger"
|
5
|
+
spec.version = "1.4.0"
|
6
|
+
spec.authors = ["Sean Porter"]
|
7
|
+
spec.email = ["portertech@gmail.com"]
|
8
|
+
spec.summary = "The Sensu logger library"
|
9
|
+
spec.description = "The Sensu logger library"
|
10
|
+
spec.homepage = "https://github.com/sensu/sensu-logger"
|
11
|
+
spec.license = "MIT"
|
12
|
+
|
13
|
+
spec.files = Dir.glob("lib/**/*") + %w[sensu-logger.gemspec README.md LICENSE.txt]
|
14
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
15
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
16
|
+
spec.require_paths = ["lib"]
|
17
|
+
|
18
|
+
spec.add_dependency("portertech-sensu-json")
|
19
|
+
spec.add_dependency("eventmachine")
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 2.4"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "rspec"
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: portertech-sensu-logger
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.4.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sean Porter
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-10-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: portertech-sensu-json
|
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: eventmachine
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.4'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.4'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
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
|
+
description: The Sensu logger library
|
84
|
+
email:
|
85
|
+
- portertech@gmail.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- LICENSE.txt
|
91
|
+
- README.md
|
92
|
+
- lib/sensu/logger.rb
|
93
|
+
- lib/sensu/logger/constants.rb
|
94
|
+
- lib/sensu/logger/stream.rb
|
95
|
+
- sensu-logger.gemspec
|
96
|
+
homepage: https://github.com/sensu/sensu-logger
|
97
|
+
licenses:
|
98
|
+
- MIT
|
99
|
+
metadata: {}
|
100
|
+
post_install_message:
|
101
|
+
rdoc_options: []
|
102
|
+
require_paths:
|
103
|
+
- lib
|
104
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - ">="
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '0'
|
114
|
+
requirements: []
|
115
|
+
rubygems_version: 3.4.10
|
116
|
+
signing_key:
|
117
|
+
specification_version: 4
|
118
|
+
summary: The Sensu logger library
|
119
|
+
test_files: []
|