pushyd 0.5.3 → 0.6.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 +4 -4
- data/Gemfile.lock +6 -6
- data/bin/pushyd +8 -6
- data/lib/pushyd/constants.rb +11 -5
- data/lib/pushyd/daemon.rb +1 -1
- data/lib/pushyd/endpoint.rb +11 -31
- data/lib/pushyd/proxy.rb +12 -13
- data/lib/pushyd/shouter.rb +6 -7
- data/lib/pushyd.rb +6 -2
- data/lib/shared/conf.rb +199 -0
- data/lib/{pushyd/formatter.rb → shared/logger_formatter.rb} +5 -5
- data/lib/shared/logger_helper.rb +78 -0
- data/pushyd.gemspec +2 -2
- metadata +7 -6
- data/lib/pushyd/conf.rb +0 -140
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5f089c97e7a6a3ef7b973c85d0ed46441095cd65
|
4
|
+
data.tar.gz: d663be735567c62e089e4037969bff5dc303c502
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b9bebfd5975a91d43c6bc0bd8cf8f1d3382571712483d7d75abe87ea1da1fb6e9c97f4fb43a111f6b31ced941f26406be20f5f94e918a97ee4f96e9e5cec51e1
|
7
|
+
data.tar.gz: 7e16e42759376aa51ef81fb3df3910dc35726d9241761446e1e16e83a91ec8b0c14c4e09d43ec8666d1335b718891633c6834d61063fdec28d0b033344fecc2e
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
pushyd (0.
|
4
|
+
pushyd (0.6.0)
|
5
5
|
bunny (~> 2.3)
|
6
6
|
chamber (~> 2.9)
|
7
7
|
daemons
|
@@ -23,10 +23,10 @@ GEM
|
|
23
23
|
thor (~> 0.19.1)
|
24
24
|
daemons (1.2.3)
|
25
25
|
diff-lcs (1.2.5)
|
26
|
-
domain_name (0.5.
|
26
|
+
domain_name (0.5.20160615)
|
27
27
|
unf (>= 0.0.5, < 1.0.0)
|
28
28
|
hashie (3.4.4)
|
29
|
-
http (2.0.
|
29
|
+
http (2.0.2)
|
30
30
|
addressable (~> 2.3)
|
31
31
|
http-cookie (~> 1.0)
|
32
32
|
http-form_data (~> 1.0.1)
|
@@ -61,8 +61,8 @@ GEM
|
|
61
61
|
diff-lcs (>= 1.2.0, < 2.0)
|
62
62
|
rspec-support (~> 3.4.0)
|
63
63
|
rspec-support (3.4.1)
|
64
|
-
rubocop (0.
|
65
|
-
parser (>= 2.3.1.
|
64
|
+
rubocop (0.41.1)
|
65
|
+
parser (>= 2.3.1.1, < 3.0)
|
66
66
|
powerpack (~> 0.1)
|
67
67
|
rainbow (>= 1.99.1, < 3.0)
|
68
68
|
ruby-progressbar (~> 1.7)
|
@@ -73,7 +73,7 @@ GEM
|
|
73
73
|
unf (0.1.4)
|
74
74
|
unf_ext
|
75
75
|
unf_ext (0.0.7.2)
|
76
|
-
unicode-display_width (1.0
|
76
|
+
unicode-display_width (1.1.0)
|
77
77
|
|
78
78
|
PLATFORMS
|
79
79
|
ruby
|
data/bin/pushyd
CHANGED
@@ -5,10 +5,11 @@ begin
|
|
5
5
|
require "rubygems"
|
6
6
|
require "optparse"
|
7
7
|
require 'daemons'
|
8
|
-
require_relative "../lib/
|
8
|
+
require_relative "../lib/shared/conf"
|
9
9
|
rescue LoadError => e
|
10
10
|
raise "EXITING: some basic libs were not found (#{e.message})"
|
11
11
|
end
|
12
|
+
include Shared
|
12
13
|
|
13
14
|
|
14
15
|
# Handle configuration
|
@@ -48,10 +49,11 @@ end
|
|
48
49
|
|
49
50
|
# Display final configuration, quit if config dump requested
|
50
51
|
puts "--- #{Conf.app_name} #{Conf.app_ver}"
|
51
|
-
puts "Environment
|
52
|
-
puts "Config files
|
53
|
-
puts "Started at
|
54
|
-
puts "Loging to file
|
52
|
+
puts "Environment \t #{Conf.app_env}"
|
53
|
+
puts "Config files \t #{Conf.files}"
|
54
|
+
puts "Started at \t #{Conf.app_started}"
|
55
|
+
puts "Loging to file \t #{Conf[:log][:file]}" if Conf[:log].is_a? Enumerable
|
56
|
+
puts "Process name \t #{Conf.gen_process_name}"
|
55
57
|
puts
|
56
58
|
puts Conf.dump
|
57
59
|
|
@@ -61,7 +63,7 @@ run_options = {
|
|
61
63
|
:backtrace => true,
|
62
64
|
:multiple => false
|
63
65
|
}
|
64
|
-
Daemons.run_proc(
|
66
|
+
Daemons.run_proc(Conf.gen_process_name, run_options) do
|
65
67
|
# Load code
|
66
68
|
puts "--- load code"
|
67
69
|
require_relative "../lib/pushyd"
|
data/lib/pushyd/constants.rb
CHANGED
@@ -9,9 +9,15 @@ PROXY_USE_ACK = false
|
|
9
9
|
|
10
10
|
# Constants: logger
|
11
11
|
LOG_ROTATION = "daily"
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
|
13
|
+
LOG_HEADER_TIME = "%Y-%m-%d %H:%M:%S"
|
14
|
+
LOG_HEADER_FORMAT = "%s \t%d\t%-8s %-15s "
|
15
|
+
LOG_MESSAGE_TRIM = 200
|
16
|
+
LOG_MESSAGE_TEXT = "%s%s"
|
17
|
+
LOG_MESSAGE_ARRAY = "%s %s"
|
18
|
+
LOG_MESSAGE_HASH = "%s %-20s %s\n"
|
19
|
+
|
20
|
+
# Constants: logger app-specific prefix
|
21
|
+
LOG_PREFIX_FORMAT = nil
|
22
|
+
|
17
23
|
|
data/lib/pushyd/daemon.rb
CHANGED
@@ -18,7 +18,7 @@ module PushyDaemon
|
|
18
18
|
loop do
|
19
19
|
end
|
20
20
|
|
21
|
-
rescue EndpointConnectionError => e
|
21
|
+
rescue EndpointConnectionError, ShouterInterrupted => e
|
22
22
|
abort "EXITING #{e.class}: #{e.message}"
|
23
23
|
rescue Errno::EACCES, StandardError => e
|
24
24
|
abort "EXITING #{e.class}: #{e.message} \n #{e.backtrace.to_yaml}"
|
data/lib/pushyd/endpoint.rb
CHANGED
@@ -8,20 +8,15 @@ module PushyDaemon
|
|
8
8
|
class EndpointSubscribeError < StandardError; end
|
9
9
|
|
10
10
|
class Endpoint
|
11
|
+
include Shared::LoggerHelper
|
12
|
+
attr_reader :logger
|
11
13
|
|
12
14
|
def initialize
|
13
15
|
# Prepare logger
|
14
16
|
init_logger Conf[:logs]
|
15
17
|
|
16
18
|
# Done
|
17
|
-
|
18
|
-
# loop do
|
19
|
-
# info "info"
|
20
|
-
# info ["info1", "info2", "info3"]
|
21
|
-
# error "error"
|
22
|
-
# debug "debug"
|
23
|
-
# sleep 1
|
24
|
-
# end
|
19
|
+
log_info "endpoint initialized"
|
25
20
|
end
|
26
21
|
|
27
22
|
protected
|
@@ -38,7 +33,7 @@ module PushyDaemon
|
|
38
33
|
|
39
34
|
# Prepare logger (may be NIL > won't output anything)
|
40
35
|
@logger = Logger.new(logfile, LOG_ROTATION)
|
41
|
-
@logger.formatter =
|
36
|
+
@logger.formatter = Shared::LoggerFormatter
|
42
37
|
|
43
38
|
# Set progname
|
44
39
|
@logger.progname = me.split('::').last
|
@@ -63,29 +58,18 @@ module PushyDaemon
|
|
63
58
|
end
|
64
59
|
end
|
65
60
|
|
66
|
-
def debug messages
|
67
|
-
@logger.debug messages
|
68
|
-
end
|
69
|
-
def info message, lines = []
|
70
|
-
@logger.info message
|
71
|
-
debug_lines lines
|
72
|
-
end
|
73
|
-
def error messages
|
74
|
-
@logger.error messages
|
75
|
-
end
|
76
|
-
|
77
61
|
def log_message msg_way, msg_exchange, msg_key, msg_body = [], msg_attrs = {}
|
78
62
|
# Message header
|
79
|
-
|
63
|
+
info sprintf("%3s %-15s %s", msg_way, msg_exchange, msg_key)
|
80
64
|
|
81
65
|
# Body lines
|
82
66
|
if msg_body.is_a?(Enumerable) && !msg_body.empty?
|
83
67
|
body_json = JSON.pretty_generate(msg_body)
|
84
|
-
|
68
|
+
log_debug nil, body_json.lines
|
85
69
|
end
|
86
70
|
|
87
71
|
# Attributes lines
|
88
|
-
|
72
|
+
log_debug nil, msg_attrs if msg_attrs
|
89
73
|
end
|
90
74
|
|
91
75
|
# Start connexion to RabbitMQ
|
@@ -164,15 +148,11 @@ module PushyDaemon
|
|
164
148
|
def handle_message rule, delivery_info, metadata, payload
|
165
149
|
end
|
166
150
|
|
167
|
-
|
168
|
-
|
169
|
-
def debug_lines lines, prefix = ''
|
170
|
-
if lines.is_a? Array
|
171
|
-
@logger.debug lines.map{ |line| sprintf(LOG_FORMAT_ARRAY, prefix, line) }
|
172
|
-
elsif lines.is_a? Hash
|
173
|
-
@logger.debug lines.map{ |key, value| sprintf(LOG_FORMAT_HASH, prefix, key, value) }
|
174
|
-
end
|
151
|
+
def identifier len
|
152
|
+
rand(36**len).to_s(36)
|
175
153
|
end
|
176
154
|
|
155
|
+
private
|
156
|
+
|
177
157
|
end
|
178
158
|
end
|
data/lib/pushyd/proxy.rb
CHANGED
@@ -19,14 +19,14 @@ module PushyDaemon
|
|
19
19
|
|
20
20
|
# Start connexion to RabbitMQ and create channel
|
21
21
|
@channel = connect_channel Conf.bus
|
22
|
-
|
22
|
+
log_info "channel connected"
|
23
23
|
|
24
24
|
# Check config
|
25
25
|
config_rules = Conf[:rules]
|
26
26
|
if config_rules.nil? || !config_rules.is_a?(Hash)
|
27
|
-
|
27
|
+
log_error "prepare: empty [rules] section"
|
28
28
|
else
|
29
|
-
|
29
|
+
log_info "found rules: #{config_rules.keys.join(', ')}"
|
30
30
|
|
31
31
|
# Subsribe for each and every rule/route
|
32
32
|
config_rules.each do |name, rule|
|
@@ -36,12 +36,11 @@ module PushyDaemon
|
|
36
36
|
end
|
37
37
|
|
38
38
|
# Send config table to logs
|
39
|
-
|
40
|
-
|
41
|
-
rescue Bunny::TCPConnectionFailedForAllHosts => e
|
42
|
-
error "ERROR: cannot connect to RabbitMQ hosts (#{e.inspect})"
|
39
|
+
log_info "proxy initialized", @table.to_s.lines
|
43
40
|
end
|
44
41
|
|
42
|
+
protected
|
43
|
+
|
45
44
|
private
|
46
45
|
|
47
46
|
# Handle the reception of a message on a queue
|
@@ -79,21 +78,21 @@ module PushyDaemon
|
|
79
78
|
def propagate relay_url, post_body
|
80
79
|
# Nothing more to do if no relay
|
81
80
|
return if relay_url.nil? || relay_url.empty?
|
82
|
-
|
81
|
+
|
82
|
+
# Generate a unique identifier
|
83
|
+
id = identifier(6)
|
83
84
|
|
84
85
|
# Log message details
|
85
86
|
log_message WAY_PROP, id, relay_url, post_body
|
86
87
|
|
87
88
|
# Push message to URL
|
88
89
|
response = RestClient.post relay_url.to_s, JSON.pretty_generate(post_body), :content_type => :json
|
89
|
-
|
90
|
+
log_info "#{id}: #{response.body}"
|
90
91
|
|
91
92
|
rescue StandardError => e
|
92
|
-
|
93
|
+
log_error "propagate: #{e.message}"
|
93
94
|
end
|
94
95
|
|
95
|
-
private
|
96
|
-
|
97
96
|
def parse payload, content_type #, fields = []
|
98
97
|
# Force encoding (pftop...)
|
99
98
|
utf8payload = payload.to_s.force_encoding('UTF-8')
|
@@ -110,7 +109,7 @@ module PushyDaemon
|
|
110
109
|
|
111
110
|
# Handle body parse errors
|
112
111
|
rescue Encoding::UndefinedConversionError => e
|
113
|
-
|
112
|
+
log_error "parse: JSON PARSE ERROR: #{e.inspect}"
|
114
113
|
return {}
|
115
114
|
end
|
116
115
|
|
data/lib/pushyd/shouter.rb
CHANGED
@@ -17,7 +17,7 @@ module PushyDaemon
|
|
17
17
|
# Check config
|
18
18
|
config_shout = Conf[:shout]
|
19
19
|
unless config_shout && config_shout.any? && config_shout.is_a?(Enumerable)
|
20
|
-
|
20
|
+
log_error "prepare: empty [shout] section"
|
21
21
|
return
|
22
22
|
end
|
23
23
|
|
@@ -28,7 +28,7 @@ module PushyDaemon
|
|
28
28
|
|
29
29
|
# Start connexion to RabbitMQ and create channel
|
30
30
|
@channel = connect_channel Conf.bus
|
31
|
-
|
31
|
+
log_info "channel connected"
|
32
32
|
|
33
33
|
# Create exchange
|
34
34
|
fail PushyDaemon::EndpointTopicContext unless @topic
|
@@ -36,10 +36,7 @@ module PushyDaemon
|
|
36
36
|
|
37
37
|
# Send shouter info to logs
|
38
38
|
shouter_info = { topic: @topic, period: @period, keys: @keys }
|
39
|
-
|
40
|
-
|
41
|
-
rescue Bunny::TCPConnectionFailedForAllHosts => e
|
42
|
-
error "ERROR: cannot connect to RabbitMQ hosts (#{e.inspect})"
|
39
|
+
log_info "shouter initialized", shouter_info
|
43
40
|
end
|
44
41
|
|
45
42
|
def shout
|
@@ -60,9 +57,11 @@ module PushyDaemon
|
|
60
57
|
fail PushyDaemon::ShouterPreconditionFailed, "#{e.class} (#{e.inspect})"
|
61
58
|
rescue Interrupt => e
|
62
59
|
@channel.close
|
63
|
-
fail PushyDaemon::ShouterInterrupted,
|
60
|
+
fail PushyDaemon::ShouterInterrupted, e.class
|
64
61
|
end
|
65
62
|
|
63
|
+
protected
|
64
|
+
|
66
65
|
private
|
67
66
|
|
68
67
|
def channel_shout keys, body = {}
|
data/lib/pushyd.rb
CHANGED
@@ -6,10 +6,14 @@ require "json"
|
|
6
6
|
#require "singleton"
|
7
7
|
require "newrelic_rpm"
|
8
8
|
|
9
|
+
|
10
|
+
# Shared libs
|
11
|
+
require_relative "shared/logger_formatter"
|
12
|
+
require_relative "shared/logger_helper"
|
13
|
+
require_relative "shared/conf"
|
14
|
+
|
9
15
|
# Project libs
|
10
|
-
require_relative "pushyd/conf"
|
11
16
|
require_relative "pushyd/constants"
|
12
|
-
require_relative "pushyd/formatter"
|
13
17
|
require_relative "pushyd/endpoint"
|
14
18
|
require_relative "pushyd/proxy"
|
15
19
|
require_relative "pushyd/shouter"
|
data/lib/shared/conf.rb
ADDED
@@ -0,0 +1,199 @@
|
|
1
|
+
# FIXME: files named with hyphens will not be found by Chamber for now
|
2
|
+
require "chamber"
|
3
|
+
|
4
|
+
module Shared
|
5
|
+
class ConfigMissingParameter < StandardError; end
|
6
|
+
class ConfigOtherError < StandardError; end
|
7
|
+
class ConfigParseError < StandardError; end
|
8
|
+
class ConfigMultipleGemspec < StandardError; end
|
9
|
+
class ConfigMissingGemspec < StandardError; end
|
10
|
+
|
11
|
+
class Conf
|
12
|
+
extend Chamber
|
13
|
+
|
14
|
+
class << self
|
15
|
+
attr_accessor :app_env
|
16
|
+
attr_reader :app_root
|
17
|
+
attr_reader :app_libs
|
18
|
+
attr_reader :app_name
|
19
|
+
attr_reader :app_ver
|
20
|
+
attr_reader :app_started
|
21
|
+
attr_reader :app_spec
|
22
|
+
attr_reader :files
|
23
|
+
attr_reader :host
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.init app_root
|
28
|
+
# Permanent flags
|
29
|
+
@initialized = true
|
30
|
+
@app_started = Time.now
|
31
|
+
|
32
|
+
# Default values
|
33
|
+
@files ||= []
|
34
|
+
@app_name ||= "app_name"
|
35
|
+
@app_env ||= "production"
|
36
|
+
@host ||= `hostname`.to_s.chomp.split(".").first
|
37
|
+
|
38
|
+
# Store and clean app_root
|
39
|
+
@app_root = File.expand_path(app_root)
|
40
|
+
|
41
|
+
# Try to find any gemspec file
|
42
|
+
matches = Dir["#{@app_root}/*.gemspec"]
|
43
|
+
fail ConfigMissingGemspec, "gemspec file not found: #{gemspec_path}" if matches.size < 1
|
44
|
+
fail ConfigMultipleGemspec, "gemspec file not found: #{gemspec_path}" if matches.size > 1
|
45
|
+
|
46
|
+
# Load Gemspec (just the only match)
|
47
|
+
@spec = Gem::Specification::load(matches.first)
|
48
|
+
@app_name = @spec.name
|
49
|
+
@app_ver = @spec.version
|
50
|
+
fail ConfigMissingParameter, "gemspec: missing name" unless @app_name
|
51
|
+
fail ConfigMissingParameter, "gemspec: missing version" unless @app_ver
|
52
|
+
|
53
|
+
# Now we know app_name, initalize app_libs
|
54
|
+
@app_libs = File.expand_path( @app_root + "/lib/#{@app_name}/" )
|
55
|
+
|
56
|
+
# Add other config files
|
57
|
+
add_default_config
|
58
|
+
add_etc_config
|
59
|
+
|
60
|
+
# Return something
|
61
|
+
return @app_name
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.prepare args = {}
|
65
|
+
ensure_init
|
66
|
+
|
67
|
+
# Add extra config file
|
68
|
+
add_extra_config args[:config]
|
69
|
+
|
70
|
+
# Load configuration files
|
71
|
+
load_files
|
72
|
+
|
73
|
+
# Set Rack env
|
74
|
+
ENV["RACK_ENV"] = @app_env.to_s
|
75
|
+
|
76
|
+
# Init New Relic
|
77
|
+
prepare_newrelic self[:newrelic], self.at(:logs, :newrelic)
|
78
|
+
|
79
|
+
# Try to access any key to force parsing of the files
|
80
|
+
self[:dummy]
|
81
|
+
|
82
|
+
rescue Psych::SyntaxError => e
|
83
|
+
fail ConfigParseError, e.message
|
84
|
+
rescue StandardError => e
|
85
|
+
fail ConfigOtherError, "#{e.message} \n #{e.backtrace.to_yaml}"
|
86
|
+
end
|
87
|
+
|
88
|
+
# Reload files
|
89
|
+
def self.reload!
|
90
|
+
ensure_init
|
91
|
+
load_files
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.dump
|
95
|
+
ensure_init
|
96
|
+
to_hash.to_yaml(indent: 4, useheader: true, useversion: false )
|
97
|
+
end
|
98
|
+
|
99
|
+
# Direct access to any depth
|
100
|
+
def self.at *path
|
101
|
+
ensure_init
|
102
|
+
path.reduce(Conf) { |m, key| m && m[key.to_s] }
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.newrelic_enabled?
|
106
|
+
ensure_init
|
107
|
+
!!self[:newrelic]
|
108
|
+
end
|
109
|
+
|
110
|
+
# Defaults generators
|
111
|
+
def self.gen_pidfile
|
112
|
+
ensure_init
|
113
|
+
"/tmp/#{@app_name}-#{@host}-#{Process.pid}.pid"
|
114
|
+
end
|
115
|
+
def self.gen_process_name
|
116
|
+
ensure_init
|
117
|
+
"#{@app_name}/#{@app_env}/#{Process.pid}"
|
118
|
+
end
|
119
|
+
def self.gen_config_etc
|
120
|
+
ensure_init
|
121
|
+
"/etc/#{@app_name}.yml"
|
122
|
+
end
|
123
|
+
def self.gen_config_sample
|
124
|
+
ensure_init
|
125
|
+
"#{@app_root}/#{@app_name}.sample.yml"
|
126
|
+
end
|
127
|
+
def self.gen_config_message
|
128
|
+
config_etc = gen_config_etc
|
129
|
+
config_sample = gen_config_sample
|
130
|
+
return "
|
131
|
+
A default configuration is available here: #{config_sample}.
|
132
|
+
You should copy it to the default location: #{config_etc}.
|
133
|
+
sudo cp #{config_sample} #{config_etc}
|
134
|
+
"
|
135
|
+
end
|
136
|
+
|
137
|
+
protected
|
138
|
+
|
139
|
+
def self.load_files
|
140
|
+
load files: @files, namespaces: { environment: @app_env }
|
141
|
+
end
|
142
|
+
|
143
|
+
def self.add_default_config
|
144
|
+
@files << "#{@app_root}/defaults.yml" if @app_root
|
145
|
+
end
|
146
|
+
|
147
|
+
def self.add_etc_config
|
148
|
+
@files << File.expand_path("/etc/#{@app_name}.yml") if @app_name
|
149
|
+
end
|
150
|
+
|
151
|
+
def self.add_extra_config path
|
152
|
+
@files << File.expand_path(path) if path
|
153
|
+
end
|
154
|
+
|
155
|
+
def self.prepare_newrelic section, logfile
|
156
|
+
# Disable NewRelic if no config present
|
157
|
+
unless section.is_a?(Hash) && section[:licence]
|
158
|
+
ENV["NEWRELIC_AGENT_ENABLED"] = "false"
|
159
|
+
return
|
160
|
+
end
|
161
|
+
|
162
|
+
# Enable GC profiler
|
163
|
+
GC::Profiler.enable
|
164
|
+
|
165
|
+
# Enable module
|
166
|
+
ENV["NEWRELIC_AGENT_ENABLED"] = "true"
|
167
|
+
ENV["NEW_RELIC_MONITOR_MODE"] = "true"
|
168
|
+
|
169
|
+
# License
|
170
|
+
ENV["NEW_RELIC_LICENSE_KEY"] = section[:licence].to_s
|
171
|
+
|
172
|
+
# Build NewRelic app_name if not provided as-is
|
173
|
+
if section[:app_name]
|
174
|
+
ENV["NEW_RELIC_APP_NAME"] = section[:app_name].to_s
|
175
|
+
else
|
176
|
+
stack = []
|
177
|
+
stack << (section[:prefix] || @app_name)
|
178
|
+
stack << section[:platform] if section[:platform]
|
179
|
+
stack << @app_env
|
180
|
+
text = stack.join('-')
|
181
|
+
ENV["NEW_RELIC_APP_NAME"] = "#{text}-#{host};#{text}"
|
182
|
+
end
|
183
|
+
|
184
|
+
# Logfile
|
185
|
+
ENV["NEW_RELIC_LOG"] = logfile.to_s if logfile
|
186
|
+
end
|
187
|
+
|
188
|
+
private
|
189
|
+
|
190
|
+
def self.ensure_init
|
191
|
+
# Skip is already done
|
192
|
+
return if @initialized
|
193
|
+
|
194
|
+
# Go through init if not already done
|
195
|
+
self.init
|
196
|
+
end
|
197
|
+
|
198
|
+
end
|
199
|
+
end
|
@@ -1,12 +1,12 @@
|
|
1
|
-
module
|
2
|
-
class
|
1
|
+
module Shared
|
2
|
+
class LoggerFormatter
|
3
3
|
|
4
4
|
def self.call severity, datetime, progname, payload
|
5
5
|
# Build common values
|
6
|
-
timestamp = datetime.strftime(
|
6
|
+
timestamp = datetime.strftime(LOG_HEADER_TIME)
|
7
7
|
|
8
8
|
# Build header
|
9
|
-
header = sprintf
|
9
|
+
header = sprintf LOG_HEADER_FORMAT,
|
10
10
|
timestamp,
|
11
11
|
Process.pid,
|
12
12
|
severity,
|
@@ -24,7 +24,7 @@ module PushyDaemon
|
|
24
24
|
protected
|
25
25
|
|
26
26
|
def self.trimmed line
|
27
|
-
line.to_s.rstrip[0..
|
27
|
+
line.to_s.rstrip[0..LOG_MESSAGE_TRIM].force_encoding(Encoding::UTF_8)
|
28
28
|
end
|
29
29
|
|
30
30
|
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require "logger"
|
2
|
+
|
3
|
+
module Shared
|
4
|
+
module LoggerHelper
|
5
|
+
|
6
|
+
protected
|
7
|
+
|
8
|
+
def log_info message, details = nil
|
9
|
+
build_messages Logger::INFO, message, details
|
10
|
+
end
|
11
|
+
|
12
|
+
def log_error message, details = nil
|
13
|
+
build_messages Logger::ERROR, message, details
|
14
|
+
end
|
15
|
+
|
16
|
+
def log_debug message, details = nil
|
17
|
+
build_messages Logger::DEBUG, message, details
|
18
|
+
end
|
19
|
+
|
20
|
+
alias info log_info
|
21
|
+
alias error log_error
|
22
|
+
alias debug log_debug
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
# Builds prefix if LOG_PREFIX_FORMAT defined and caller has log_prefix method to provide values
|
27
|
+
def build_prefix
|
28
|
+
# Skip if no values from user class
|
29
|
+
return unless respond_to?(:log_prefix, true)
|
30
|
+
values = log_prefix
|
31
|
+
|
32
|
+
# Skip if no format defined
|
33
|
+
return unless defined?('LOG_PREFIX_FORMAT')
|
34
|
+
return unless LOG_PREFIX_FORMAT.is_a? String
|
35
|
+
|
36
|
+
# Build prefix string
|
37
|
+
LOG_PREFIX_FORMAT % values.map(&:to_s)
|
38
|
+
end
|
39
|
+
|
40
|
+
def build_messages severity, message, details = nil
|
41
|
+
messages = []
|
42
|
+
# messages << "/---------------------------------------"
|
43
|
+
# messages << "severity: #{severity}"
|
44
|
+
# messages << "message: #{message.class}"
|
45
|
+
# messages << "details: #{details.class} #{details.inspect}"
|
46
|
+
# messages << "ARRAY(#{details.count})" if details.is_a? Array
|
47
|
+
# messages << "HASH(#{details.count})" if details.is_a? Hash
|
48
|
+
|
49
|
+
prefix = build_prefix
|
50
|
+
|
51
|
+
# Add main message
|
52
|
+
messages << sprintf(LOG_MESSAGE_TEXT, prefix, message) if message
|
53
|
+
|
54
|
+
# Add details from array
|
55
|
+
details.each do |line|
|
56
|
+
messages << sprintf(LOG_MESSAGE_ARRAY, prefix, line)
|
57
|
+
end if details.is_a? Array
|
58
|
+
|
59
|
+
# Add details from hash
|
60
|
+
details.each do |key, value|
|
61
|
+
messages << sprintf(LOG_MESSAGE_HASH, prefix, key, value)
|
62
|
+
end if details.is_a? Hash
|
63
|
+
|
64
|
+
# Return all that stuff
|
65
|
+
# messages << "\\---------------------------------------"
|
66
|
+
logger.add severity, messages
|
67
|
+
end
|
68
|
+
|
69
|
+
# def debug_lines lines, prefix = ''
|
70
|
+
# if lines.is_a? Array
|
71
|
+
# logger.debug lines.map{ |line| sprintf(LOG_MESSAGE_ARRAY, prefix, line) }
|
72
|
+
# elsif lines.is_a? Hash
|
73
|
+
# logger.debug lines.map{ |key, value| sprintf(LOG_MESSAGE_HASH, prefix, key, value) }
|
74
|
+
# end
|
75
|
+
# end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
data/pushyd.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
Gem::Specification.new do |spec|
|
3
3
|
# Project version
|
4
|
-
spec.version = "0.
|
4
|
+
spec.version = "0.6.0"
|
5
5
|
|
6
6
|
# Project description
|
7
7
|
spec.name = "pushyd"
|
@@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.files = `git ls-files -z`.split("\x0")
|
18
18
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
19
|
spec.require_paths = ["lib"]
|
20
|
-
spec.required_ruby_version = ">= 2.
|
20
|
+
spec.required_ruby_version = ">= 2.2.3"
|
21
21
|
|
22
22
|
# Development dependencies
|
23
23
|
spec.add_development_dependency "bundler", "~> 1.6"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pushyd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bruno MEDICI
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-06-
|
11
|
+
date: 2016-06-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -195,13 +195,14 @@ files:
|
|
195
195
|
- bin/pushyd
|
196
196
|
- defaults.yml
|
197
197
|
- lib/pushyd.rb
|
198
|
-
- lib/pushyd/conf.rb
|
199
198
|
- lib/pushyd/constants.rb
|
200
199
|
- lib/pushyd/daemon.rb
|
201
200
|
- lib/pushyd/endpoint.rb
|
202
|
-
- lib/pushyd/formatter.rb
|
203
201
|
- lib/pushyd/proxy.rb
|
204
202
|
- lib/pushyd/shouter.rb
|
203
|
+
- lib/shared/conf.rb
|
204
|
+
- lib/shared/logger_formatter.rb
|
205
|
+
- lib/shared/logger_helper.rb
|
205
206
|
- pushyd.gemspec
|
206
207
|
homepage: http://github.com/bmedici/pushyd
|
207
208
|
licenses:
|
@@ -215,7 +216,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
215
216
|
requirements:
|
216
217
|
- - ">="
|
217
218
|
- !ruby/object:Gem::Version
|
218
|
-
version:
|
219
|
+
version: 2.2.3
|
219
220
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
220
221
|
requirements:
|
221
222
|
- - ">="
|
@@ -223,7 +224,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
223
224
|
version: '0'
|
224
225
|
requirements: []
|
225
226
|
rubyforge_project:
|
226
|
-
rubygems_version: 2.5.1
|
227
|
+
rubygems_version: 2.4.5.1
|
227
228
|
signing_key:
|
228
229
|
specification_version: 4
|
229
230
|
summary: A nice proxy listenning to a RabbitMQ bus, repeating selected messages in
|
data/lib/pushyd/conf.rb
DELETED
@@ -1,140 +0,0 @@
|
|
1
|
-
require "chamber"
|
2
|
-
|
3
|
-
# FIXME: files named with hyphens will not be found by Chamber for now
|
4
|
-
class ConfigMissingParameter < StandardError; end
|
5
|
-
class ConfigOtherError < StandardError; end
|
6
|
-
class ConfigParseError < StandardError; end
|
7
|
-
class ConfigMultipleGemspec < StandardError; end
|
8
|
-
class ConfigMissingGemspec < StandardError; end
|
9
|
-
|
10
|
-
class Conf
|
11
|
-
extend Chamber
|
12
|
-
|
13
|
-
class << self
|
14
|
-
attr_accessor :app_env
|
15
|
-
|
16
|
-
attr_reader :app_root
|
17
|
-
attr_reader :app_libs
|
18
|
-
|
19
|
-
attr_reader :app_name
|
20
|
-
attr_reader :app_ver
|
21
|
-
attr_reader :app_started
|
22
|
-
|
23
|
-
attr_reader :spec
|
24
|
-
attr_reader :files
|
25
|
-
attr_reader :host
|
26
|
-
end
|
27
|
-
|
28
|
-
def self.init app_root = nil
|
29
|
-
# Defaults, hostname
|
30
|
-
@files = []
|
31
|
-
@app_env = "production"
|
32
|
-
@app_started = Time.now
|
33
|
-
@host = `hostname`.to_s.chomp.split(".").first
|
34
|
-
|
35
|
-
# Grab app root
|
36
|
-
@app_root = File.expand_path( File.dirname(__FILE__) + "/../../")
|
37
|
-
@app_libs = File.expand_path( File.dirname(__FILE__) )
|
38
|
-
|
39
|
-
# Try to find any gemspec file
|
40
|
-
matches = Dir["#{@app_root}/*.gemspec"]
|
41
|
-
fail ConfigMissingGemspec, "gemspec file not found: #{gemspec_path}" if matches.size < 1
|
42
|
-
fail ConfigMultipleGemspec, "gemspec file not found: #{gemspec_path}" if matches.size > 1
|
43
|
-
|
44
|
-
# Load Gemspec (just the only match)
|
45
|
-
@spec = Gem::Specification::load(matches.first)
|
46
|
-
@app_name = @spec.name
|
47
|
-
@app_ver = @spec.version
|
48
|
-
fail ConfigMissingParameter, "gemspec: missing name" unless @app_name
|
49
|
-
fail ConfigMissingParameter, "gemspec: missing version" unless @app_ver
|
50
|
-
|
51
|
-
# Add config files
|
52
|
-
add_default_config
|
53
|
-
add_etc_config
|
54
|
-
end
|
55
|
-
|
56
|
-
def self.prepare args = {}
|
57
|
-
# Add extra config file
|
58
|
-
add_extra_config args[:config]
|
59
|
-
|
60
|
-
# Load configuration files
|
61
|
-
load_files
|
62
|
-
|
63
|
-
# Init New Relic
|
64
|
-
prepare_newrelic self[:newrelic], self.at(:logs, :newrelic)
|
65
|
-
|
66
|
-
# Try to access any key to force parsing of the files
|
67
|
-
self[:dummy]
|
68
|
-
|
69
|
-
rescue Psych::SyntaxError => e
|
70
|
-
fail ConfigParseError, e.message
|
71
|
-
rescue StandardError => e
|
72
|
-
fail ConfigOtherError, "#{e.message} \n #{e.backtrace.to_yaml}"
|
73
|
-
end
|
74
|
-
|
75
|
-
def self.reload!
|
76
|
-
load_files
|
77
|
-
end
|
78
|
-
|
79
|
-
def self.dump
|
80
|
-
to_hash.to_yaml(indent: 4, useheader: true, useversion: false )
|
81
|
-
end
|
82
|
-
|
83
|
-
# Direct access to any depth
|
84
|
-
def self.at *path
|
85
|
-
path.reduce(Conf) { |m, key| m && m[key.to_s] }
|
86
|
-
end
|
87
|
-
|
88
|
-
def self.newrelic_enabled?
|
89
|
-
!!self[:newrelic]
|
90
|
-
end
|
91
|
-
|
92
|
-
protected
|
93
|
-
|
94
|
-
def self.load_files
|
95
|
-
load files: @files, namespaces: { environment: @app_env }
|
96
|
-
end
|
97
|
-
|
98
|
-
def self.add_default_config
|
99
|
-
@files << "#{@app_root}/defaults.yml" if @app_root
|
100
|
-
end
|
101
|
-
|
102
|
-
def self.add_etc_config
|
103
|
-
@files << File.expand_path("/etc/#{@app_name}.yml") if @app_name
|
104
|
-
end
|
105
|
-
|
106
|
-
def self.add_extra_config path
|
107
|
-
@files << File.expand_path(path) if path
|
108
|
-
end
|
109
|
-
|
110
|
-
def self.get_pidfile
|
111
|
-
self[:pidfile] || "/tmp/#{@app_name}-#{@host}-#{self[:port]}.pid"
|
112
|
-
end
|
113
|
-
|
114
|
-
def self.prepare_newrelic section, logfile
|
115
|
-
# Disable NewRelic if no config present
|
116
|
-
unless section.is_a?(Hash) && section[:licence]
|
117
|
-
ENV["NEWRELIC_AGENT_ENABLED"] = "false"
|
118
|
-
return
|
119
|
-
end
|
120
|
-
|
121
|
-
# Enable GC profiler
|
122
|
-
GC::Profiler.enable
|
123
|
-
|
124
|
-
# Enable module
|
125
|
-
ENV["NEWRELIC_AGENT_ENABLED"] = "true"
|
126
|
-
ENV["NEW_RELIC_MONITOR_MODE"] = "true"
|
127
|
-
|
128
|
-
# License
|
129
|
-
ENV["NEW_RELIC_LICENSE_KEY"] = section[:licence].to_s
|
130
|
-
|
131
|
-
# Appname
|
132
|
-
platform = section[:platform] || self.host
|
133
|
-
section[:app_name] ||= "#{@app_name}-#{platform}-#{@app_env}"
|
134
|
-
ENV["NEW_RELIC_APP_NAME"] = section[:app_name].to_s
|
135
|
-
|
136
|
-
# Logfile
|
137
|
-
ENV["NEW_RELIC_LOG"] = logfile.to_s if logfile
|
138
|
-
end
|
139
|
-
|
140
|
-
end
|