class ElasticAPM::CentralConfig
@api private
def assign(update)
def assign(update) # For each updated option, store the original value, # unless already stored update.each_key do |key| @modified_options[key] ||= config.get(key.to_sym)&.value end # If the new update doesn't set a previously modified option, # revert it to the original @modified_options.each_key do |key| next if update.key?(key) update[key] = @modified_options.delete(key) end config.assign(update) end
def fetch_and_apply_config
def fetch_and_apply_config @promise = Concurrent::Promise .execute(&method(:fetch_config)) .on_success(&method(:handle_success)) .rescue(&method(:handle_error)) end
def fetch_config
def fetch_config resp = perform_request case resp.status when 200..299 resp when 300..399 resp when 400..499 raise ClientError, resp when 500..599 raise ServerError, resp end end
def handle_error(error)
def handle_error(error) error( 'Failed fetching config: %s, trying again in %d seconds', error.response.body, DEFAULT_MAX_AGE ) assign({}) schedule_next_fetch(error.response) end
def handle_success(resp)
def handle_success(resp) if resp.status == 304 info 'Received 304 Not Modified' else update = JSON.parse(resp.body.to_s) assign(update) info 'Updated config from Kibana' end schedule_next_fetch(resp) true rescue Exception => e error 'Failed to apply remote config, %s', e.inspect debug { e.backtrace.join('\n') } end
def initialize(config)
def initialize(config) @config = config @modified_options = {} @service_info = { 'service.name': config.service_name, 'service.environment': config.environment }.to_json end
def perform_request
def perform_request Http.post( config.server_url + '/agent/v1/config/', body: @service_info, headers: { etag: 1, content_type: 'application/json' } ) end
def schedule_next_fetch(resp)
def schedule_next_fetch(resp) seconds = if (cache_header = resp.headers['Cache-Control']) CacheControl.new(cache_header).max_age else DEFAULT_MAX_AGE end @scheduled_task = Concurrent::ScheduledTask .execute(seconds, &method(:fetch_and_apply_config)) end
def start
def start return unless config.central_config? fetch_and_apply_config end
def stop
def stop @scheduled_task&.cancel end