pushyd 0.3.4 → 0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e4c0863d93fc6a8efc1323791dcab4cde429ff67
4
- data.tar.gz: ebbd792bf40400fbca51905c61611707b2013b3e
3
+ metadata.gz: da7515bbd91875e7d4d0c28edcd7b1222ddeb8a2
4
+ data.tar.gz: 633a9271a1359e036a00d94cf800ad458744f1da
5
5
  SHA512:
6
- metadata.gz: abca867f07fe275efc2ffe00c26098760a8a4ce2d8e80b240f3be1a8e068df37e4b12eec29a0d61f51a587d9c5ce045f5441916805764a6cb4d96f25c1003270
7
- data.tar.gz: da02db1407df734c58854bd123330c22da5c1ab3a200cbbf721485b4e85db3fa31ea67662f3898bff476bf2055588ff42acb4c4b08d5585155047fb4e7f27a2b
6
+ metadata.gz: faf3ee6045545e77dc262d0b1b73469ea4531bf690ec3536cd367b33a02c5a9c765b23dcc3e615636a5eca47225a485cd80b54ad052b35ec2ee6d35207225269
7
+ data.tar.gz: ad8edf30c5fa35fc447ad0e51347ad7479d24ca6533457d597701e6dbb46d8ef695f21413be049baad855314dcaeafb963a5d6a9cd97bcddda98989aba507c84
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- pushyd (0.3.4)
4
+ pushyd (0.4.0)
5
5
  bunny
6
6
  chamber
7
7
  daemons
data/bin/pushyd CHANGED
@@ -5,7 +5,6 @@ begin
5
5
  require "rubygems"
6
6
  require "optparse"
7
7
  require 'daemons'
8
- require 'logger'
9
8
  require_relative "../lib/pushyd/conf"
10
9
  rescue LoadError
11
10
  raise "EXITING: some basic libs were not found"
@@ -33,14 +32,14 @@ begin
33
32
  end.order!(ARGV)
34
33
 
35
34
  # Build Chamber-based configuration from Gemspec with initial context
36
- Conf.prepare root: APP_ROOT, gemspec: "pushyd", env: cmd_env, config: cmd_config, log: cmd_logfile
35
+ Conf.prepare root: APP_ROOT, gemspec: "pushyd", env: cmd_env, config: cmd_config, logfile: cmd_logfile
37
36
 
38
37
  rescue OptionParser::InvalidOption => e
39
- abort "EXITING: option parser: #{e.message}"
38
+ abort "EXITING: InvalidOption: #{e.message} \n #{e.backtrace.to_yaml}"
40
39
  rescue PushyDaemon::ConfigParseError => e
41
- abort "EXITING: ConfigParseError: #{e.message}"
40
+ abort "EXITING: ConfigParseError: #{e.message} \n #{e.backtrace.to_yaml}"
42
41
  rescue StandardError => e
43
- abort "EXITING: Exception: #{e.message}"
42
+ abort "EXITING: StandardError: #{e.message} \n #{e.backtrace.to_yaml}"
44
43
  end
45
44
 
46
45
  # Display final configuration
@@ -48,8 +47,7 @@ puts "--- #{Conf.name} #{Conf.version}"
48
47
  puts "YAML Parser \t #{YAML.name}"
49
48
  puts "Environment \t #{Conf.env}"
50
49
  puts "Config files \t #{Conf.files}"
51
- puts "Loging to file \t #{Conf[:log]}"
52
-
50
+ puts "Loging to file \t #{Conf.log.logfile}"
53
51
 
54
52
  # Quit if config dump requested
55
53
  if cmd_dump
@@ -65,10 +63,10 @@ run_options = {
65
63
  }
66
64
  Daemons.run_proc('pushy-daemon', run_options) do
67
65
  # Load code
68
- puts "--- loading code"
66
+ puts "--- load code"
69
67
  require_relative "../lib/pushyd"
70
68
 
71
69
  # Start daemon
72
- puts "--- starting daemon"
70
+ puts "--- start daemon"
73
71
  PushyDaemon::Daemon.run
74
72
  end
data/defaults.yml CHANGED
@@ -6,7 +6,9 @@ bus:
6
6
  user: guest
7
7
  pass: guest
8
8
 
9
- log: null
9
+ log:
10
+ file: null
11
+ level: debug
10
12
 
11
13
  shout:
12
14
  topic: pushyd
@@ -19,6 +21,13 @@ shout:
19
21
  # - updated
20
22
  # - deleted
21
23
  # - crunched
24
+
25
+ # newrelic:
26
+ # licence: ""
27
+ # platform: "bigbusiness" # app platform name
28
+ # app_name: "rftpd-bigbusiness-dev" # nickname used for naming app
29
+ # logfile: null
30
+
22
31
  # rules:
23
32
  # proxy_tests:
24
33
  # title: All proxy tests messages
@@ -26,3 +35,4 @@ shout:
26
35
  # routes: "proxy.#"
27
36
  # subscribe: false
28
37
  # #relay: http://requestb.in/1clzv7v1
38
+
data/lib/pushyd/conf.rb CHANGED
@@ -2,6 +2,7 @@ require "chamber"
2
2
 
3
3
  module PushyDaemon
4
4
  class ConfigMissingParameter < StandardError; end
5
+ class ConfigOtherError < StandardError; end
5
6
  class ConfigParseError < StandardError; end
6
7
 
7
8
  class Conf
@@ -13,6 +14,7 @@ module PushyDaemon
13
14
  attr_reader :files
14
15
  attr_reader :version
15
16
  attr_reader :env
17
+ attr_reader :host
16
18
  end
17
19
 
18
20
  def self.prepare args = {}
@@ -25,6 +27,9 @@ module PushyDaemon
25
27
  fail PushyDaemon::ConfigMissingParameter, "missing gemspec" unless args[:gemspec]
26
28
  fail PushyDaemon::ConfigMissingParameter, "gemspec file not found: #{gemspec_path}" unless File.exist?(gemspec_path)
27
29
 
30
+ # Init host if missing
31
+ @host ||= `hostname`.to_s.chomp.split(".").first
32
+
28
33
  # Load Gemspec
29
34
  @spec = Gem::Specification::load gemspec_path
30
35
  @name = @spec.name
@@ -39,23 +44,61 @@ module PushyDaemon
39
44
  # Load configuration files
40
45
  load files: @files, namespaces: { environment: @env }
41
46
 
47
+ # Override some values
48
+ self[:log] ||= {}
49
+ if args[:logfile]
50
+ self[:log][:file] = logfile
51
+ end
52
+
53
+ # Init New Relic
54
+ prepare_newrelic self[:newrelic]
55
+
42
56
  # Try to access any key to force parsing of the files
43
57
  self[:dummy]
44
58
 
45
- # Override some values
46
- self[:log] = args[:log].to_s if args[:log]
47
-
48
59
  rescue Psych::SyntaxError => e
49
60
  fail PushyDaemon::ConfigParseError, e.message
50
-
51
- rescue Exception => e
52
- fail PushyDaemon::ConfigParseError, e.message
53
-
61
+ rescue StandardError => e
62
+ fail PushyDaemon::ConfigOtherError, "#{e.message} \n #{e.backtrace.to_yaml}"
54
63
  end
55
64
 
56
65
  def self.dump
57
66
  self.to_hash.to_yaml
58
67
  end
59
68
 
69
+ def Conf.newrelic_enabled?
70
+ !!self[:newrelic]
71
+ end
72
+
73
+ protected
74
+
75
+ def self.prepare_newrelic section
76
+ unless section.is_a?(Hash)
77
+ puts "prepare_newrelic: no config"
78
+ ENV["NEWRELIC_AGENT_ENABLED"] = "false"
79
+ return
80
+ end
81
+ puts "prepare_newrelic: config ok"
82
+
83
+ # Enable GC profiler
84
+ GC::Profiler.enable
85
+
86
+ # Enable module
87
+ ENV["NEWRELIC_AGENT_ENABLED"] = "true"
88
+ ENV["NEW_RELIC_MONITOR_MODE"] = "true"
89
+
90
+ # License
91
+ ENV["NEW_RELIC_LICENSE_KEY"] = section[:licence].to_s
92
+
93
+ # Appname
94
+ platform = section[:platform] || self.host
95
+ section[:app_name] ||= "#{self.name}-#{platform}-#{self.env}"
96
+ ENV["NEW_RELIC_APP_NAME"] = section[:app_name].to_s
97
+
98
+ # Logfile
99
+ ENV["NEW_RELIC_LOG"] = section[:logfile].to_s
100
+ end
101
+
102
+
60
103
  end
61
104
  end
@@ -4,14 +4,14 @@ WAY_IN = "RECD"
4
4
  WAY_POST = "POST"
5
5
 
6
6
  # Constants: proxy
7
- PROXY_MESSAGE_MAX = 1
8
- PROXY_USE_ACK = false
7
+ PROXY_MESSAGE_MAX = 1
8
+ PROXY_USE_ACK = false
9
9
 
10
10
  # Constants: logger
11
- LOG_COL_ID = 6
11
+ LOG_ROTATION = "daily"
12
12
  LOG_TRIM_LINE = 200
13
13
  LOG_FORMAT_TIME = "%Y-%m-%d %H:%M:%S"
14
- LOG_FORMAT_MESSAGE = "%-6s"
15
- LOG_NEWLINE = "\n"
16
- LOG_INDENT = "\t"
17
- LOG_ROTATION = "daily"
14
+ LOG_FORMAT_LINE = "%s\t%-8s\t%-10s\t%s\n"
15
+ LOG_FORMAT_ARRAY = "%s\t%-8s\t%-10s\t %s\n"
16
+ LOG_FORMAT_HASH = "%s\t%-8s\t%-10s\t %-17s %s\n"
17
+
data/lib/pushyd/daemon.rb CHANGED
@@ -19,7 +19,7 @@ module PushyDaemon
19
19
  end
20
20
 
21
21
  rescue Errno::EACCES, StandardError => e
22
- abort "EXITING #{e.class}: #{e.message}"
22
+ abort "EXITING #{e.class}: #{e.message} \n #{e.backtrace.to_yaml}"
23
23
  end
24
24
 
25
25
  end
@@ -10,33 +10,70 @@ module PushyDaemon
10
10
  class Endpoint
11
11
 
12
12
  def initialize
13
- # Prepare logger (may be NIL > won't output anything)
14
- logfile = Conf[:log]
13
+ # Prepare logger
14
+ init_logger Conf[:log]
15
+
16
+ # Done
17
+ info "endpoint initialized"
18
+ # loop do
19
+ # info "info"
20
+ # info ["info1", "info2", "info3"]
21
+ # error "error"
22
+ # debug "debug"
23
+ # sleep 1
24
+ # end
25
+ end
26
+
27
+ protected
15
28
 
16
- # Create the logger
17
- @logger = PushyLogger.new(logfile, LOG_ROTATION)
18
- @logger.add Logger::INFO, "starting #{self.class.name}"
29
+ def init_logger logconf
30
+ # Extract context
31
+ logfile = logconf[:file]
32
+ loglevel = logconf[:level]
33
+ me = self.class.name
34
+
35
+ # Prepare logger (may be NIL > won't output anything)
36
+ @logger = Logger.new(logfile, LOG_ROTATION)
37
+ @logger.formatter = Formatter
38
+
39
+ # Set progname
40
+ @logger.progname = me.split('::').last
41
+
42
+ # Set expected level
43
+ @logger.level = case loglevel
44
+ when "debug"
45
+ Logger::DEBUG
46
+ when "info"
47
+ Logger::INFO
48
+ when "warn"
49
+ Logger::WARN
50
+ else
51
+ Logger::INFO
52
+ end
19
53
 
20
- # Declare we're now logging
21
- puts "#{self.class} logging to #{logfile}"
54
+ # Announce on STDOUT we're now logging to file
55
+ if logfile
56
+ puts "#{self.class} logging loglevel [#{loglevel} > #{@logger.level}] to [#{logfile}]"
57
+ else
58
+ puts "#{self.class} logging disabled"
59
+ end
22
60
  end
23
61
 
24
- protected
62
+ def error messages
63
+ @logger.error messages
64
+ end
25
65
 
26
- def error message, lines = {}
27
- @logger.add Logger::ERROR, "#{self.class}: #{message}", lines
66
+ def info messages
67
+ @logger.info messages
28
68
  end
29
69
 
30
- def info message, lines = {}
31
- @logger.add Logger::INFO, "#{self.class}: #{message}", lines
70
+ def debug messages
71
+ @logger.debug messages
32
72
  end
33
73
 
34
74
  def message params = {}
35
- # Indenting
36
- lines = []
37
-
38
75
  # Header
39
- message = sprintf(
76
+ @logger.info sprintf(
40
77
  "%3s %-15s %s",
41
78
  params[:way],
42
79
  params[:exchange],
@@ -44,24 +81,14 @@ module PushyDaemon
44
81
  )
45
82
 
46
83
  # Attributes
47
- if (params[:attrs].is_a? Hash)
48
- # lines.merge params[:attrs]
49
- params[:attrs].each do |name, value|
50
- lines << sprintf("%-15s %s", name, value)
51
- end
52
- end
84
+ @logger.debug params[:attrs] if params[:attrs].is_a?(Hash)
53
85
 
54
86
  # Body (split in lines to log them separately)
55
- if params[:body] && params[:body].is_a?(Enumerable)
87
+ if params[:body].is_a?(Enumerable) && !params[:body].empty?
56
88
  body_json = JSON.pretty_generate(params[:body])
57
- body_json.each_line do |line|
58
- lines << line.rstrip
59
- end
89
+ #puts "log? #{params[:body]} "
90
+ @logger.debug body_json.lines
60
91
  end
61
-
62
- # Send the info
63
- @logger.add Logger::INFO, message, lines
64
- # @logger.log_info message, lines
65
92
  end
66
93
 
67
94
  # Start connexion to RabbitMQ
@@ -70,11 +97,12 @@ module PushyDaemon
70
97
  busconf[:host] && busconf[:port]
71
98
 
72
99
  info "connecting to #{busconf[:host]} port #{busconf[:port]}"
73
- conn = Bunny.new host: (busconf[:host].to_s || "localhost").to_s,
100
+ conn = Bunny.new host: busconf[:host].to_s,
74
101
  port: busconf[:port].to_i,
75
102
  user: busconf[:user].to_s,
76
103
  pass: busconf[:pass].to_s,
77
- heartbeat: :server
104
+ heartbeat: :server,
105
+ logger: @logger
78
106
  conn.start
79
107
 
80
108
  # Create channel
@@ -116,7 +144,8 @@ module PushyDaemon
116
144
  info "subscribe: bind [#{rule_topic}/#{route}] \t> #{rule_queue}"
117
145
 
118
146
  # Add row to config table
119
- @table.add_row [rule_name, rule_topic, route, rule[:relay].to_s, rule[:title].to_s ]
147
+ # ["rule", "topic", "route", "relay", "queue", "description"]
148
+ @table.add_row [rule_name, rule_topic, route, rule[:relay].to_s, rule_queue, rule[:title].to_s ]
120
149
  end
121
150
 
122
151
  # Subscribe to our new queue
@@ -0,0 +1,32 @@
1
+ module PushyDaemon
2
+ class Formatter
3
+
4
+ def self.call severity, datetime, progname, messages
5
+ # Build common values
6
+ timestamp = datetime.strftime(LOG_FORMAT_TIME)
7
+
8
+ # If we have a bunch of lines, prefix them and send them together
9
+ if messages.is_a? Array
10
+ messages.map do |line|
11
+ sprintf LOG_FORMAT_ARRAY, timestamp, severity, progname, trimmed(line)
12
+ end.join
13
+
14
+ elsif messages.is_a? Hash
15
+ messages.map do |key, value|
16
+ sprintf LOG_FORMAT_HASH, timestamp, severity, progname, key, value
17
+ end.join
18
+
19
+ else
20
+ sprintf LOG_FORMAT_LINE, timestamp, severity, progname, trimmed(messages)
21
+
22
+ end
23
+ end
24
+
25
+ protected
26
+
27
+ def self.trimmed line
28
+ line.to_s.rstrip[0..LOG_TRIM_LINE].force_encoding(Encoding::UTF_8)
29
+ end
30
+
31
+ end
32
+ end
data/lib/pushyd/proxy.rb CHANGED
@@ -14,7 +14,7 @@ module PushyDaemon
14
14
  # Init ASCII table
15
15
  @table = Terminal::Table.new
16
16
  @table.title = "Propagation rules"
17
- @table.headings = ["queue binding", "topic", "route", "relay", "title"]
17
+ @table.headings = ["rule", "topic", "route", "relay", "queue", "description"]
18
18
  @table.align_column(5, :right)
19
19
 
20
20
  # Start connexion to RabbitMQ and create channel
@@ -23,21 +23,21 @@ module PushyDaemon
23
23
 
24
24
  # Check config
25
25
  config_rules = Conf[:rules]
26
- unless (config_rules.is_a? Enumerable) && !config_rules.empty?
26
+ if config_rules.nil? || !config_rules.is_a?(Hash)
27
27
  error "prepare: empty [rules] section"
28
- end
29
- info "found rules: #{config_rules.keys.join(', ')}"
30
-
31
- # Subsribe for each and every rule/route
32
- config_rules.each do |name, rule|
33
- rule[:name] = name
34
- channel_subscribe rule
35
- #abort "prepare: OK"
28
+ else
29
+ info "found rules: #{config_rules.keys.join(', ')}"
30
+
31
+ # Subsribe for each and every rule/route
32
+ config_rules.each do |name, rule|
33
+ rule[:name] = name
34
+ channel_subscribe rule
35
+ end
36
36
  end
37
37
 
38
38
  # Send config table to logs
39
- table_lines = @table.to_s.lines
40
- info "initialized with configuration:", table_lines
39
+ info "proxy initialized"
40
+ info @table.to_s.lines
41
41
 
42
42
  rescue Bunny::TCPConnectionFailedForAllHosts => e
43
43
  error "ERROR: cannot connect to RabbitMQ hosts (#{e.inspect})"
@@ -100,17 +100,15 @@ module PushyDaemon
100
100
  error "propagate: #{e.message}"
101
101
  end
102
102
 
103
+ private
103
104
 
104
105
  def parse payload, content_type #, fields = []
105
106
  # Force encoding (pftop...)
106
- utf8payload = payload.force_encoding('UTF-8')
107
+ utf8payload = payload.to_s.force_encoding('UTF-8')
107
108
 
108
109
  # Parse payload if content-type provided
109
110
  case content_type
110
111
  when "application/json"
111
- # if fields = rule[:payload_extract]
112
- # data = payload_extract(payload, fields)
113
- # data_source = "extract #{fields.inspect} #{data.keys.count}k"
114
112
  return JSON.parse utf8payload
115
113
  when "text/plain"
116
114
  return utf8payload.to_s
@@ -124,5 +122,12 @@ module PushyDaemon
124
122
  return {}
125
123
  end
126
124
 
125
+ # NewRelic instrumentation
126
+ if Conf.newrelic_enabled?
127
+ include ::NewRelic::Agent::Instrumentation::ControllerInstrumentation
128
+ add_transaction_tracer :handle_message, category: :task
129
+ add_transaction_tracer :propagate, category: :task
130
+ end
131
+
127
132
  end
128
133
  end
@@ -33,7 +33,11 @@ module PushyDaemon
33
33
  # Create exchange
34
34
  fail PushyDaemon::EndpointTopicContext unless @topic
35
35
  @exchange = @channel.topic(@topic, durable: true, persistent: true)
36
- info "initialized with parameters:", { topic: @topic, period: @period, keys: @keys }
36
+
37
+ # Send shouter info to logs
38
+ shouter_info = { topic: @topic, period: @period, keys: @keys }
39
+ info "shouter initialized"
40
+ info shouter_info
37
41
 
38
42
  rescue Bunny::TCPConnectionFailedForAllHosts => e
39
43
  error "ERROR: cannot connect to RabbitMQ hosts (#{e.inspect})"
@@ -74,7 +78,11 @@ module PushyDaemon
74
78
  routing_key = keys.unshift(exchange_name).join('.')
75
79
 
76
80
  # Announce shout
77
- message way: WAY_OUT, exchange: exchange_name, key: routing_key, body: nil, attrs: {}
81
+ message way: WAY_OUT,
82
+ exchange: exchange_name,
83
+ key: routing_key,
84
+ body: body,
85
+ attrs: {}
78
86
 
79
87
  # Publish
80
88
  @exchange.publish(body.to_json,
@@ -85,5 +93,12 @@ module PushyDaemon
85
93
  )
86
94
  end
87
95
 
96
+ # NewRelic instrumentation
97
+ if Conf.newrelic_enabled?
98
+ include ::NewRelic::Agent::Instrumentation::ControllerInstrumentation
99
+ add_transaction_tracer :channel_shout, category: :task
100
+ add_transaction_tracer :shout, category: :task
101
+ end
102
+
88
103
  end
89
104
  end
data/lib/pushyd.rb CHANGED
@@ -4,12 +4,12 @@ require "yaml"
4
4
  require "json"
5
5
  require "thread"
6
6
  require "singleton"
7
- # require "newrelic_rpm"
7
+ require "newrelic_rpm"
8
8
 
9
9
  # Project libs
10
10
  require_relative "pushyd/conf"
11
11
  require_relative "pushyd/constants"
12
- require_relative "pushyd/pushy_logger"
12
+ require_relative "pushyd/formatter"
13
13
  require_relative "pushyd/endpoint"
14
14
  require_relative "pushyd/proxy"
15
15
  require_relative "pushyd/shouter"
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.3.4"
4
+ spec.version = "0.4.0"
5
5
 
6
6
  # Project description
7
7
  spec.name = "pushyd"
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.3.4
4
+ version: 0.4.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-09 00:00:00.000000000 Z
11
+ date: 2016-06-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -198,8 +198,8 @@ files:
198
198
  - lib/pushyd/constants.rb
199
199
  - lib/pushyd/daemon.rb
200
200
  - lib/pushyd/endpoint.rb
201
+ - lib/pushyd/formatter.rb
201
202
  - lib/pushyd/proxy.rb
202
- - lib/pushyd/pushy_logger.rb
203
203
  - lib/pushyd/shouter.rb
204
204
  - pushyd.gemspec
205
205
  homepage: http://github.com/bmedici/pushyd
@@ -1,61 +0,0 @@
1
- require "logger"
2
-
3
- class PushyLogger < Logger
4
-
5
- def initialize logfile, rotation = nil
6
- # Call my parent's initializer
7
- super
8
-
9
- # And the formatter
10
- self.formatter = proc do |severity, datetime, _progname, messages|
11
- # Build common line prefix
12
- prefix = "%s %s\t" % [
13
- datetime.strftime(LOG_FORMAT_TIME),
14
- severity ]
15
-
16
- # If we have a bunch of lines, prefix them and send them together
17
- if messages.is_a? Array
18
- messages.map { |line| prefix + line + LOG_NEWLINE}.join
19
- else
20
- prefix + messages.to_s + LOG_NEWLINE
21
- end
22
- end
23
- end
24
-
25
- def add level, message, lines = {}
26
- level ||= Logger::DEBUG
27
-
28
- if lines.is_a? Hash
29
- output = build_from_hash lines
30
- elsif lines.is_a? Array
31
- output = build_from_array lines
32
- else
33
- output = []
34
- end
35
-
36
- # Prepend plain message to output
37
- output.unshift message.force_encoding(Encoding::UTF_8)
38
-
39
- # Send all this to logger
40
- super level, output
41
- end
42
-
43
- protected
44
-
45
- def trim_line line
46
- line.to_s.rstrip.strip[0..LOG_TRIM_LINE]
47
- end
48
-
49
- def build_from_array lines
50
- lines.map do |value|
51
- "#{LOG_INDENT}#{trim_line(value)}"
52
- end
53
- end
54
-
55
- def build_from_hash lines
56
- lines.map do |name, value|
57
- "#{LOG_INDENT}#{name}: #{trim_line(value)}"
58
- end
59
- end
60
-
61
- end