tingyun_rpm 1.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.DS_Store +0 -0
- data/.gitignore +14 -0
- data/.travis.yml +4 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +3 -0
- data/Guardfile +25 -0
- data/LICENSE.txt +22 -0
- data/README.md +41 -0
- data/cert/cacert.pem +0 -0
- data/lib/ting_yun/agent/agent.rb +128 -0
- data/lib/ting_yun/agent/class_methods.rb +21 -0
- data/lib/ting_yun/agent/collector/base_sampler.rb +2 -0
- data/lib/ting_yun/agent/collector/error_collector/error_trace_array.rb +88 -0
- data/lib/ting_yun/agent/collector/error_collector/noticed_error.rb +129 -0
- data/lib/ting_yun/agent/collector/error_collector.rb +165 -0
- data/lib/ting_yun/agent/collector/middle_ware_collector/cpu_sampler.rb +68 -0
- data/lib/ting_yun/agent/collector/middle_ware_collector/memory_sampler.rb +139 -0
- data/lib/ting_yun/agent/collector/middle_ware_collector/middle_ware.rb +13 -0
- data/lib/ting_yun/agent/collector/middle_ware_collector/sampler.rb +59 -0
- data/lib/ting_yun/agent/collector/middle_ware_collector.rb +80 -0
- data/lib/ting_yun/agent/collector/sql_sampler.rb +299 -0
- data/lib/ting_yun/agent/collector/stats_engine/metric_stats.rb +170 -0
- data/lib/ting_yun/agent/collector/stats_engine/stats_hash.rb +172 -0
- data/lib/ting_yun/agent/collector/stats_engine.rb +28 -0
- data/lib/ting_yun/agent/collector/transaction_sampler/slowest_sample_buffer.rb +25 -0
- data/lib/ting_yun/agent/collector/transaction_sampler/transaction_sample_buffer_base.rb +96 -0
- data/lib/ting_yun/agent/collector/transaction_sampler.rb +226 -0
- data/lib/ting_yun/agent/container_data_manager.rb +94 -0
- data/lib/ting_yun/agent/cross_app/cross_app_monitor.rb +131 -0
- data/lib/ting_yun/agent/cross_app/cross_app_tracing.rb +202 -0
- data/lib/ting_yun/agent/cross_app/inbound_request_monitor.rb +22 -0
- data/lib/ting_yun/agent/database.rb +410 -0
- data/lib/ting_yun/agent/datastore/metric_helper.rb +82 -0
- data/lib/ting_yun/agent/datastore/mongo.rb +44 -0
- data/lib/ting_yun/agent/datastore.rb +33 -0
- data/lib/ting_yun/agent/dispatcher.rb +39 -0
- data/lib/ting_yun/agent/event/event_listener.rb +47 -0
- data/lib/ting_yun/agent/event/event_loop.rb +194 -0
- data/lib/ting_yun/agent/instance_methods/connect.rb +164 -0
- data/lib/ting_yun/agent/instance_methods/container_data_manager.rb +137 -0
- data/lib/ting_yun/agent/instance_methods/handle_errors.rb +71 -0
- data/lib/ting_yun/agent/instance_methods/start.rb +219 -0
- data/lib/ting_yun/agent/instance_methods/start_worker_thread.rb +51 -0
- data/lib/ting_yun/agent/instance_methods.rb +39 -0
- data/lib/ting_yun/agent/method_tracer.rb +256 -0
- data/lib/ting_yun/agent/method_tracer_helpers.rb +85 -0
- data/lib/ting_yun/agent/threading/agent_thread.rb +49 -0
- data/lib/ting_yun/agent/transaction/attributes.rb +22 -0
- data/lib/ting_yun/agent/transaction/request_attributes.rb +126 -0
- data/lib/ting_yun/agent/transaction/trace.rb +125 -0
- data/lib/ting_yun/agent/transaction/trace_node.rb +110 -0
- data/lib/ting_yun/agent/transaction/traced_method_stack.rb +80 -0
- data/lib/ting_yun/agent/transaction/transaction_metrics.rb +51 -0
- data/lib/ting_yun/agent/transaction/transaction_sample_builder.rb +63 -0
- data/lib/ting_yun/agent/transaction/transaction_state.rb +112 -0
- data/lib/ting_yun/agent/transaction.rb +522 -0
- data/lib/ting_yun/agent.rb +207 -0
- data/lib/ting_yun/configuration/default_source.rb +638 -0
- data/lib/ting_yun/configuration/dotted_hash.rb +46 -0
- data/lib/ting_yun/configuration/environment_source.rb +116 -0
- data/lib/ting_yun/configuration/manager.rb +232 -0
- data/lib/ting_yun/configuration/manual_source.rb +14 -0
- data/lib/ting_yun/configuration/server_source.rb +88 -0
- data/lib/ting_yun/configuration/yaml_source.rb +136 -0
- data/lib/ting_yun/configuration.rb +9 -0
- data/lib/ting_yun/environment_report.rb +123 -0
- data/lib/ting_yun/frameworks/class_methods.rb +47 -0
- data/lib/ting_yun/frameworks/external.rb +15 -0
- data/lib/ting_yun/frameworks/instance_methods.rb +120 -0
- data/lib/ting_yun/frameworks/instrumentation.rb +67 -0
- data/lib/ting_yun/frameworks/rails.rb +63 -0
- data/lib/ting_yun/frameworks/rails3.rb +26 -0
- data/lib/ting_yun/frameworks/rails4.rb +14 -0
- data/lib/ting_yun/frameworks/ruby.rb +17 -0
- data/lib/ting_yun/frameworks/sinatra.rb +10 -0
- data/lib/ting_yun/frameworks.rb +34 -0
- data/lib/ting_yun/http/generic_request.rb +8 -0
- data/lib/ting_yun/http/net_http_request.rb +46 -0
- data/lib/ting_yun/instrumentation/active_record.rb +103 -0
- data/lib/ting_yun/instrumentation/middleware_proxy.rb +77 -0
- data/lib/ting_yun/instrumentation/middleware_tracing.rb +84 -0
- data/lib/ting_yun/instrumentation/mongo.rb +103 -0
- data/lib/ting_yun/instrumentation/mongo2.rb +37 -0
- data/lib/ting_yun/instrumentation/mongo_command_log_subscriber.rb +97 -0
- data/lib/ting_yun/instrumentation/moped.rb +95 -0
- data/lib/ting_yun/instrumentation/net.rb +59 -0
- data/lib/ting_yun/instrumentation/rack.rb +109 -0
- data/lib/ting_yun/instrumentation/rails3/action_controller.rb +63 -0
- data/lib/ting_yun/instrumentation/rails3/action_view.rb +115 -0
- data/lib/ting_yun/instrumentation/rails4/action_controller_subscriber.rb +124 -0
- data/lib/ting_yun/instrumentation/rails4/action_view_subscriber.rb +118 -0
- data/lib/ting_yun/instrumentation/rails4/active_record_subscriber.rb +124 -0
- data/lib/ting_yun/instrumentation/rails_middleware.rb +38 -0
- data/lib/ting_yun/instrumentation/redis.rb +70 -0
- data/lib/ting_yun/instrumentation/support/active_record_helper.rb +178 -0
- data/lib/ting_yun/instrumentation/support/controller_instrumentation.rb +54 -0
- data/lib/ting_yun/instrumentation/support/database.rb +38 -0
- data/lib/ting_yun/instrumentation/support/event_formatter.rb +19 -0
- data/lib/ting_yun/instrumentation/support/evented_subscriber.rb +97 -0
- data/lib/ting_yun/instrumentation/support/external_error.rb +52 -0
- data/lib/ting_yun/instrumentation/support/metric_translator.rb +84 -0
- data/lib/ting_yun/instrumentation/support/mongo_formatter.rb +49 -0
- data/lib/ting_yun/instrumentation/support/parameter_filtering.rb +21 -0
- data/lib/ting_yun/instrumentation/support/queue_time.rb +76 -0
- data/lib/ting_yun/instrumentation/support/transaction_namer.rb +68 -0
- data/lib/ting_yun/instrumentation/thrift.rb +329 -0
- data/lib/ting_yun/logger/agent_logger.rb +196 -0
- data/lib/ting_yun/logger/log_once.rb +38 -0
- data/lib/ting_yun/logger/memory_logger.rb +56 -0
- data/lib/ting_yun/logger/null_logger.rb +31 -0
- data/lib/ting_yun/logger/startup_logger.rb +13 -0
- data/lib/ting_yun/logger.rb +8 -0
- data/lib/ting_yun/metrics/metric_data.rb +86 -0
- data/lib/ting_yun/metrics/metric_spec.rb +89 -0
- data/lib/ting_yun/metrics/stats.rb +158 -0
- data/lib/ting_yun/metrics.rb +12 -0
- data/lib/ting_yun/support/coerce.rb +86 -0
- data/lib/ting_yun/support/collector.rb +29 -0
- data/lib/ting_yun/support/exception.rb +79 -0
- data/lib/ting_yun/support/hash_extensions.rb +25 -0
- data/lib/ting_yun/support/helper.rb +54 -0
- data/lib/ting_yun/support/hostname.rb +13 -0
- data/lib/ting_yun/support/http_clients/uri_util.rb +49 -0
- data/lib/ting_yun/support/language_support.rb +155 -0
- data/lib/ting_yun/support/library_detection.rb +129 -0
- data/lib/ting_yun/support/local_environment.rb +185 -0
- data/lib/ting_yun/support/path.rb +13 -0
- data/lib/ting_yun/support/serialize/encodes.rb +61 -0
- data/lib/ting_yun/support/serialize/encoding_normalizer.rb +84 -0
- data/lib/ting_yun/support/serialize/json_marshaller.rb +73 -0
- data/lib/ting_yun/support/serialize/json_wrapper.rb +78 -0
- data/lib/ting_yun/support/serialize/marshaller.rb +69 -0
- data/lib/ting_yun/support/serialize/ok_json.rb +651 -0
- data/lib/ting_yun/support/system_info.rb +206 -0
- data/lib/ting_yun/support/timer_lib.rb +29 -0
- data/lib/ting_yun/support/version_number.rb +70 -0
- data/lib/ting_yun/ting_yun_service/connection.rb +118 -0
- data/lib/ting_yun/ting_yun_service/http.rb +41 -0
- data/lib/ting_yun/ting_yun_service/request.rb +90 -0
- data/lib/ting_yun/ting_yun_service/ssl.rb +45 -0
- data/lib/ting_yun/ting_yun_service/upload_service.rb +149 -0
- data/lib/ting_yun/ting_yun_service.rb +124 -0
- data/lib/ting_yun/version.rb +17 -0
- data/lib/tingyun_rpm.rb +47 -0
- data/tingyun_rpm.gemspec +60 -0
- metadata +415 -0
@@ -0,0 +1,116 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# This file is distributed under Ting Yun's license terms.
|
3
|
+
|
4
|
+
require 'ting_yun/configuration/dotted_hash'
|
5
|
+
|
6
|
+
|
7
|
+
module TingYun
|
8
|
+
module Configuration
|
9
|
+
class EnvironmentSource < DottedHash
|
10
|
+
SUPPORTED_PREFIXES = /^ting_yun_|^tingyun_/i
|
11
|
+
SPECIAL_CASE_KEYS = [
|
12
|
+
'TING_YUN_ENV',
|
13
|
+
'TING_YUN_LOG' # read by set_log_file
|
14
|
+
]
|
15
|
+
|
16
|
+
attr_accessor :alias_map, :type_map
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
set_config_file
|
20
|
+
set_log_file
|
21
|
+
|
22
|
+
@alias_map = {}
|
23
|
+
@type_map = {}
|
24
|
+
|
25
|
+
DEFAULTS.each do |config_setting, value|
|
26
|
+
self.type_map[config_setting] = value[:type]
|
27
|
+
set_aliases(config_setting, value)
|
28
|
+
end
|
29
|
+
|
30
|
+
set_values_from_ting_yun_environment_variables
|
31
|
+
end
|
32
|
+
|
33
|
+
def set_aliases(config_setting, value)
|
34
|
+
set_dotted_alias(config_setting)
|
35
|
+
|
36
|
+
return unless value[:aliases]
|
37
|
+
value[:aliases].each do |alise|
|
38
|
+
self.alias_map[alise] = config_setting
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def set_dotted_alias(original_config_setting)
|
43
|
+
config_setting = original_config_setting.to_s
|
44
|
+
|
45
|
+
|
46
|
+
if config_setting.include? '.'
|
47
|
+
config_alias = config_setting.gsub(/\./, '_').to_sym
|
48
|
+
self.alias_map[config_alias] = original_config_setting
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def set_config_file
|
53
|
+
self[:config_path] = ENV['NRCONFIG'] if ENV['NRCONFIG']
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
def set_log_file
|
58
|
+
if ENV['TING_YUN_LOG']
|
59
|
+
if ENV['TING_YUN_LOG'].upcase == 'STDOUT'
|
60
|
+
self[:log_file_path] = self[:log_file_name] = 'STDOUT'
|
61
|
+
else
|
62
|
+
self[:log_file_path] = File.dirname(ENV['TING_YUN_LOG'])
|
63
|
+
self[:log_file_name] = File.basename(ENV['TING_YUN_LOG'])
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def set_values_from_ting_yun_environment_variables
|
69
|
+
env_var_keys = collect_ting_yun_environment_variable_keys
|
70
|
+
env_var_keys.each do |key|
|
71
|
+
next if SPECIAL_CASE_KEYS.include?(key.upcase)
|
72
|
+
set_value_from_environment_variable(key)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def set_value_from_environment_variable(key)
|
77
|
+
config_key = convert_environment_key_to_config_key(key)
|
78
|
+
set_key_by_type(config_key, key)
|
79
|
+
end
|
80
|
+
|
81
|
+
def set_key_by_type(config_key, environment_key)
|
82
|
+
value = ENV[environment_key]
|
83
|
+
type = self.type_map[config_key]
|
84
|
+
|
85
|
+
if type == String
|
86
|
+
self[config_key] = value
|
87
|
+
elsif type == Fixnum
|
88
|
+
self[config_key] = value.to_i
|
89
|
+
elsif type == Float
|
90
|
+
self[config_key] = value.to_f
|
91
|
+
elsif type == Symbol
|
92
|
+
self[config_key] = value.to_sym
|
93
|
+
elsif type == TingYun::Configuration::Boolean
|
94
|
+
if value =~ /false|off|no/i
|
95
|
+
self[config_key] = false
|
96
|
+
elsif value != nil
|
97
|
+
self[config_key] = true
|
98
|
+
end
|
99
|
+
else
|
100
|
+
# TingYun::Agent.logger.info("#{environment_key} does not have a corresponding configuration setting (#{config_key} does not exist).")
|
101
|
+
self[config_key] = value
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
def convert_environment_key_to_config_key(key)
|
107
|
+
stripped_key = key.gsub(SUPPORTED_PREFIXES, '').downcase.to_sym
|
108
|
+
self.alias_map[stripped_key] || stripped_key
|
109
|
+
end
|
110
|
+
|
111
|
+
def collect_ting_yun_environment_variable_keys
|
112
|
+
ENV.keys.select { |key| key.match(SUPPORTED_PREFIXES) }
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,232 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# This file is distributed under Ting Yun's license terms.
|
3
|
+
require 'ting_yun/configuration/default_source'
|
4
|
+
require 'ting_yun/configuration/environment_source'
|
5
|
+
require 'ting_yun/configuration/yaml_source'
|
6
|
+
require 'ting_yun/configuration/server_source'
|
7
|
+
require 'ting_yun/configuration/manual_source'
|
8
|
+
|
9
|
+
|
10
|
+
module TingYun
|
11
|
+
module Configuration
|
12
|
+
class Manager
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
reset_to_defaults
|
16
|
+
end
|
17
|
+
|
18
|
+
def [](key)
|
19
|
+
@cache[key]
|
20
|
+
end
|
21
|
+
|
22
|
+
def has_key?(key)
|
23
|
+
@cache.has_key?(key)
|
24
|
+
end
|
25
|
+
|
26
|
+
def keys
|
27
|
+
@cache.keys
|
28
|
+
end
|
29
|
+
|
30
|
+
def app_names
|
31
|
+
if TingYun::Agent.config[:'nbs.auto_app_naming']
|
32
|
+
begin
|
33
|
+
[::TingYun::Frameworks.framework.root.split('/').last]
|
34
|
+
rescue Exception => e
|
35
|
+
get_name
|
36
|
+
end
|
37
|
+
else
|
38
|
+
get_name
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
def get_name
|
44
|
+
case TingYun::Agent.config[:app_name]
|
45
|
+
when Array then
|
46
|
+
TingYun::Agent.config[:app_name]
|
47
|
+
when String then
|
48
|
+
TingYun::Agent.config[:app_name].split(';')
|
49
|
+
else
|
50
|
+
[]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def reset_to_defaults
|
55
|
+
@default_source = DefaultSource.new
|
56
|
+
@environment_source = EnvironmentSource.new
|
57
|
+
@yaml_source = nil
|
58
|
+
@server_source = nil
|
59
|
+
@manual_source = nil
|
60
|
+
# @callbacks = Hash.new {|hash,key| hash[key] =[]}#存放需要merge本地和服务端配置的info'
|
61
|
+
|
62
|
+
@configs_for_testing = []
|
63
|
+
|
64
|
+
reset_cache
|
65
|
+
end
|
66
|
+
|
67
|
+
def reset_cache
|
68
|
+
@cache = Hash.new { |hash, key| hash[key] = self.fetch(key) }
|
69
|
+
end
|
70
|
+
|
71
|
+
def fetch(key)
|
72
|
+
config_stack.each do |config|
|
73
|
+
next unless config
|
74
|
+
accessor = key.to_sym
|
75
|
+
|
76
|
+
if config.has_key?(accessor)
|
77
|
+
return evaluated = evaluate_procs(config[accessor]) #if it's proc
|
78
|
+
end
|
79
|
+
end
|
80
|
+
nil
|
81
|
+
end
|
82
|
+
|
83
|
+
def evaluate_procs(value)
|
84
|
+
if value.respond_to?(:call)
|
85
|
+
instance_eval(&value)
|
86
|
+
else
|
87
|
+
value
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def add_config_for_testing(source, level=0)
|
92
|
+
raise 'Invalid config type for testing' unless [Hash, DottedHash].include?(source.class)
|
93
|
+
@configs_for_testing << [source.freeze, level]
|
94
|
+
reset_cache
|
95
|
+
log_config(:add, source)
|
96
|
+
end
|
97
|
+
|
98
|
+
def remove_config_type(sym)
|
99
|
+
source = case sym
|
100
|
+
when :environment then @environment_source
|
101
|
+
when :server then @server_source
|
102
|
+
when :manual then @manual_source
|
103
|
+
when :yaml then @yaml_source
|
104
|
+
when :default then @default_source
|
105
|
+
end
|
106
|
+
remove_config(source)
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
def remove_config(source)
|
111
|
+
case source
|
112
|
+
when YamlSource then @yaml_source = nil
|
113
|
+
when DefaultSource then @default_source = nil
|
114
|
+
when EnvironmentSource then @environment_source = nil
|
115
|
+
when ManualSource then @manual_source = nil
|
116
|
+
when ServerSource then @server_source = nil
|
117
|
+
else
|
118
|
+
@configs_for_testing.delete_if { |src, lvl| src == source }
|
119
|
+
end
|
120
|
+
|
121
|
+
reset_cache
|
122
|
+
|
123
|
+
#invoke_callbacks(:remove,source)
|
124
|
+
|
125
|
+
log_config(:remove, source)
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
def replace_or_add_config(source)
|
130
|
+
source.freeze
|
131
|
+
|
132
|
+
was_finished = finished_configuring?
|
133
|
+
|
134
|
+
case source
|
135
|
+
when YamlSource then @yaml_source = source
|
136
|
+
when DefaultSource then @default_source = source
|
137
|
+
when EnvironmentSource then @environment_source = source
|
138
|
+
when ServerSource then @server_source = source
|
139
|
+
when ManualSource then @manual_source = source
|
140
|
+
else
|
141
|
+
TingYun::Agent.logger.warn("Invalid config format; config will be ignored: #{source}")
|
142
|
+
end
|
143
|
+
reset_cache
|
144
|
+
|
145
|
+
log_config(:add, source)
|
146
|
+
|
147
|
+
notify_finished_configuring if !was_finished && finished_configuring?
|
148
|
+
end
|
149
|
+
|
150
|
+
def notify_finished_configuring
|
151
|
+
TingYun::Agent.instance.events.notify(:finished_configuring)
|
152
|
+
end
|
153
|
+
|
154
|
+
def finished_configuring?
|
155
|
+
!@server_source.nil?
|
156
|
+
end
|
157
|
+
|
158
|
+
|
159
|
+
def source(key)
|
160
|
+
config_stack.each do |config|
|
161
|
+
if config.respond_to?(key.to_sym) || config.has_key?(key.to_sym)
|
162
|
+
return config
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def log_config(direction, source)
|
168
|
+
# Just generating this log message (specifically calling
|
169
|
+
# flattened.inspect) is expensive enough that we don't want to do it
|
170
|
+
# unless we're actually going to be logging the message based on our
|
171
|
+
# current log level.
|
172
|
+
::TingYun::Agent.logger.debug do
|
173
|
+
"Updating config (#{direction}) from #{source.class}. Results: #{flattened.inspect}"
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def flattened
|
178
|
+
config_stack.reverse.inject({}) do |flat, layer|
|
179
|
+
thawed_layer = layer.to_hash.dup
|
180
|
+
thawed_layer.each do |k, v|
|
181
|
+
begin
|
182
|
+
thawed_layer[k] = instance_eval(&v) if v.respond_to?(:call)
|
183
|
+
rescue => e
|
184
|
+
::TingYun::Agent.logger.debug("#{e.class.name} : #{e.message} - when accessing config key #{k}")
|
185
|
+
thawed_layer[k] = nil
|
186
|
+
end
|
187
|
+
thawed_layer.delete(:config)
|
188
|
+
end
|
189
|
+
flat.merge(thawed_layer.to_hash)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def config_classes_for_testing
|
194
|
+
config_stack.map(&:class)
|
195
|
+
end
|
196
|
+
|
197
|
+
|
198
|
+
|
199
|
+
|
200
|
+
def to_collector_hash
|
201
|
+
DottedHash.new(flattened).to_hash.delete_if do |k, v|
|
202
|
+
default = DEFAULTS[k]
|
203
|
+
if default
|
204
|
+
default[:exclude_from_reported_settings]
|
205
|
+
else
|
206
|
+
# In our tests, we add totally bogus configs, because testing.
|
207
|
+
# In those cases, there will be no default. So we'll just let
|
208
|
+
# them through.
|
209
|
+
false
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
private
|
215
|
+
|
216
|
+
def config_stack
|
217
|
+
stack = [@environment_source, @server_source, @manual_source, @yaml_source, @default_source]
|
218
|
+
|
219
|
+
stack.compact!
|
220
|
+
@configs_for_testing.each do |config, at_start|
|
221
|
+
if at_start
|
222
|
+
stack.insert(0, config)
|
223
|
+
else
|
224
|
+
stack.push(config)
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
stack
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# This file is distributed under Ting Yun's license terms.
|
3
|
+
|
4
|
+
require 'ting_yun/configuration/dotted_hash'
|
5
|
+
|
6
|
+
module TingYun
|
7
|
+
module Configuration
|
8
|
+
class ManualSource < DottedHash
|
9
|
+
def initialize(hash)
|
10
|
+
super(hash, true)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# This file is distributed under Ting Yun's license terms.
|
3
|
+
|
4
|
+
require 'ting_yun/configuration/dotted_hash'
|
5
|
+
|
6
|
+
module TingYun
|
7
|
+
module Configuration
|
8
|
+
class ServerSource < DottedHash
|
9
|
+
# These keys appear *outside* of the agent_config hash in the connect
|
10
|
+
# response, but should still be merged in as config settings to the
|
11
|
+
# main agent configuration.
|
12
|
+
TOP_LEVEL_KEYS = [
|
13
|
+
"applicationId",
|
14
|
+
"tingyunIdSecret",
|
15
|
+
"enabled",
|
16
|
+
"appSessionKey",
|
17
|
+
"dataSentInterval",
|
18
|
+
"apdex_t",
|
19
|
+
"config"
|
20
|
+
]
|
21
|
+
|
22
|
+
def self.add_top_level_keys_for_testing(add_array)
|
23
|
+
TOP_LEVEL_KEYS.concat add_array
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.remove_top_level_keys_for_testing(remove_arry)
|
27
|
+
remove_arry.each{|i| TOP_LEVEL_KEYS.delete(i)}
|
28
|
+
end
|
29
|
+
|
30
|
+
def initialize(connect_reply)
|
31
|
+
merged_settings = {}
|
32
|
+
|
33
|
+
merge_top_level_keys(merged_settings, connect_reply)
|
34
|
+
merge_agent_config_hash(merged_settings, connect_reply)
|
35
|
+
filter_keys(merged_settings)
|
36
|
+
# apply_feature_gates(merged_settings, connect_reply, existing_config)
|
37
|
+
|
38
|
+
# The value under this key is a hash mapping transaction name strings
|
39
|
+
# to apdex_t values. We don't want the nested hash to be flattened
|
40
|
+
# as part of the call to super below, so it skips going through
|
41
|
+
# merged_settings.
|
42
|
+
# self[:web_transactions_apdex] = connect_reply['web_transactions_apdex']
|
43
|
+
|
44
|
+
# This causes keys in merged_settings to be symbolized and flattened
|
45
|
+
super(merged_settings)
|
46
|
+
end
|
47
|
+
|
48
|
+
def merge_top_level_keys(merged_settings, connect_reply)
|
49
|
+
TOP_LEVEL_KEYS.each do |key_name|
|
50
|
+
if connect_reply[key_name]
|
51
|
+
merged_settings[key_name] = connect_reply[key_name]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def merge_agent_config_hash(merged_settings, connect_reply)
|
57
|
+
if connect_reply['config']
|
58
|
+
merged_settings.merge!(connect_reply['config'])
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def fix_transaction_threshold(merged_settings)
|
63
|
+
# when value is "apdex_f" remove the config and defer to default
|
64
|
+
if merged_settings['transaction_tracer.transaction_threshold'] =~ /apdex_f/i
|
65
|
+
merged_settings.delete('transaction_tracer.transaction_threshold')
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def filter_keys(merged_settings)
|
70
|
+
merged_settings.delete_if do |key, _|
|
71
|
+
setting_spec = DEFAULTS[key.to_sym]
|
72
|
+
if setting_spec
|
73
|
+
if setting_spec[:allowed_from_server]
|
74
|
+
false # it's allowed, so don't delete it
|
75
|
+
else
|
76
|
+
TingYun::Agent.logger.warn("Ignoring server-sent config for '#{key}' - this setting cannot be set from the server")
|
77
|
+
true # delete it
|
78
|
+
end
|
79
|
+
else
|
80
|
+
TingYun::Agent.logger.debug("Ignoring unrecognized config key from server: '#{key}'")
|
81
|
+
true
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'ting_yun/configuration/dotted_hash'
|
3
|
+
require 'ting_yun/support/language_support'
|
4
|
+
require 'erb'
|
5
|
+
|
6
|
+
module TingYun
|
7
|
+
module Configuration
|
8
|
+
class YamlSource < DottedHash
|
9
|
+
attr_accessor :file_path, :failures
|
10
|
+
|
11
|
+
def initialize(path, env)
|
12
|
+
config = {}
|
13
|
+
@failures = []
|
14
|
+
|
15
|
+
begin
|
16
|
+
@file_path = vaildate_config_file_path(path)
|
17
|
+
return unless @file_path
|
18
|
+
|
19
|
+
::TingYun::Agent.logger.info("Reading configuration from #{path} (#{Dir.pwd})")
|
20
|
+
|
21
|
+
raw_file = File.read(@file_path)
|
22
|
+
erb_file = process_erb(raw_file)
|
23
|
+
config = process_yaml(erb_file, env, config, @file_path)
|
24
|
+
rescue ScriptError, StandardError => e
|
25
|
+
log_failure("Failed to read or parse configuration file at #{path}", e)
|
26
|
+
end
|
27
|
+
booleanify_values(config, 'nbs.agent_enabled', 'enabled')
|
28
|
+
super(config, true)
|
29
|
+
end
|
30
|
+
|
31
|
+
def failed?
|
32
|
+
!@failures.empty?
|
33
|
+
end
|
34
|
+
|
35
|
+
protected
|
36
|
+
|
37
|
+
def vaildate_config_file_path(path)
|
38
|
+
expanded_path = File.expand_path(path)
|
39
|
+
|
40
|
+
if path.empty? || !File.exist?(expanded_path)
|
41
|
+
warn_missing_config_file(expanded_path)
|
42
|
+
return
|
43
|
+
end
|
44
|
+
expanded_path
|
45
|
+
end
|
46
|
+
|
47
|
+
def warn_missing_config_file(path)
|
48
|
+
based_on = 'unknown'
|
49
|
+
source = ::TingYun::Agent.config.source(:config_path)
|
50
|
+
candidate_paths = [path]
|
51
|
+
|
52
|
+
case source
|
53
|
+
when DefaultSource
|
54
|
+
based_on = "default"
|
55
|
+
candidate_paths = TingYun::Agent.config[:config_search_paths].map do |p|
|
56
|
+
File.expand_path(p)
|
57
|
+
end
|
58
|
+
when EnvironmentSource
|
59
|
+
based_on = "environment_source"
|
60
|
+
when ManualSource
|
61
|
+
based_on = 'API call'
|
62
|
+
end
|
63
|
+
|
64
|
+
TingYun::Agent.logger.warn(
|
65
|
+
"No configuration file found. Working directory = #{Dir.pwd}",
|
66
|
+
"Looked in these locations (based on #{based_on}): #{candidate_paths.join(", ")}"
|
67
|
+
)
|
68
|
+
end
|
69
|
+
|
70
|
+
def process_erb(file)
|
71
|
+
begin
|
72
|
+
# Exclude lines that are commented out so failing Ruby code in an
|
73
|
+
# ERB template commented at the YML level is fine. Leave the line,
|
74
|
+
# though, so ERB line numbers remain correct.
|
75
|
+
file.gsub!(/^\s*#.*$/, '#')
|
76
|
+
|
77
|
+
# Next two are for populating the tingyun.yml via erb binding, necessary
|
78
|
+
# when using the default tingyun.yml file
|
79
|
+
generated_for_user = ''
|
80
|
+
license_key = ''
|
81
|
+
|
82
|
+
ERB.new(file).result(binding)
|
83
|
+
rescue ScriptError, StandardError => e
|
84
|
+
log_failure("Failed ERB processing configuration file. This is typically caused by a Ruby error in <% %> templating blocks in your tingyun.yml file.", e)
|
85
|
+
nil
|
86
|
+
ensure
|
87
|
+
# Avoid warnings by using these again
|
88
|
+
generated_for_user = nil
|
89
|
+
license_key = nil
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def process_yaml(file, env, config, path)
|
94
|
+
if file
|
95
|
+
confighash = with_yaml_engine { YAML.load(file) }
|
96
|
+
unless confighash.key?(env)
|
97
|
+
log_failure("Config file at #{path} doesn't include a '#{env}' section!")
|
98
|
+
end
|
99
|
+
|
100
|
+
config = confighash[env] || {}
|
101
|
+
end
|
102
|
+
config
|
103
|
+
end
|
104
|
+
|
105
|
+
def with_yaml_engine
|
106
|
+
return yield unless TingYun::Support::LanguageSupport.needs_syck?
|
107
|
+
|
108
|
+
yamler = ::YAML::ENGINE.yamler
|
109
|
+
::YAML::ENGINE.yamler = 'syck'
|
110
|
+
result = yield
|
111
|
+
::YAML::ENGINE.yamler = yamler
|
112
|
+
result
|
113
|
+
end
|
114
|
+
|
115
|
+
def booleanify_values(config, *keys)
|
116
|
+
# auto means defer ro default
|
117
|
+
keys.each do |option|
|
118
|
+
if config[option] == 'auto'
|
119
|
+
config.delete(option)
|
120
|
+
elsif !config[option].nil? && !is_boolean?(config[option])
|
121
|
+
config[option] = !!(config[option] =~ /yes|on|true/i)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def is_boolean?(value)
|
127
|
+
value == !!value
|
128
|
+
end
|
129
|
+
|
130
|
+
def log_failure(*messages)
|
131
|
+
::TingYun::Agent.logger.error(*messages)
|
132
|
+
@failures << messages
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|