Methods
Included Modules
Classes and Modules
Class PhusionPassenger::AnalyticsLogger::LockClass PhusionPassenger::AnalyticsLogger::Log
Class PhusionPassenger::AnalyticsLogger::SharedData
Constants
RETRY_SLEEP | = | 0.2 |
NETWORK_ERRORS | = | [Errno::EPIPE, Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::EHOSTUNREACH, Errno::ENETDOWN, Errno::ENETUNREACH, Errno::ETIMEDOUT] |
RANDOM_CHARS | = | ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'] |
Attributes
[RW] | max_connect_tries | |
[RW] | reconnect_timeout |
Public Class methods
[ show source ]
# File lib/phusion_passenger/analytics_logger.rb, line 150 150: def initialize(logging_agent_address, username, password, node_name) 151: @server_address = logging_agent_address 152: @username = username 153: @password = password 154: if node_name && !node_name.empty? 155: @node_name = node_name 156: else 157: @node_name = `hostname`.strip 158: end 159: @random_dev = File.open("/dev/urandom") 160: 161: # This mutex protects the following instance variables, but 162: # not the contents of @shared_data. 163: @mutex = Mutex.new 164: 165: @shared_data = SharedData.new 166: if @server_address && local_socket_address?(@server_address) 167: @max_connect_tries = 10 168: else 169: @max_connect_tries = 1 170: end 171: @reconnect_timeout = 60 172: @next_reconnect_time = Time.utc(1980, 1, 1) 173: end
[ show source ]
# File lib/phusion_passenger/analytics_logger.rb, line 136 136: def self.new_from_options(options) 137: if options["analytics"] && options["logging_agent_address"] 138: return new(options["logging_agent_address"], 139: options["logging_agent_username"], 140: options["logging_agent_password_base64"].unpack('m').first, 141: options["node_name"]) 142: else 143: return nil 144: end 145: end
Public Instance methods
[ show source ]
# File lib/phusion_passenger/analytics_logger.rb, line 175 175: def clear_connection 176: @mutex.synchronize do 177: @shared_data.synchronize do 178: @random_dev = File.open("/dev/urandom") if @random_dev.closed? 179: @shared_data.unref 180: @shared_data = SharedData.new 181: end 182: end 183: end
[ show source ]
# File lib/phusion_passenger/analytics_logger.rb, line 185 185: def close 186: @mutex.synchronize do 187: @shared_data.synchronize do 188: @random_dev.close 189: @shared_data.unref 190: @shared_data = nil 191: end 192: end 193: end
[ show source ]
# File lib/phusion_passenger/analytics_logger.rb, line 245 245: def continue_transaction(txn_id, group_name, category = :requests, union_station_key = nil) 246: if !@server_address 247: return Log.new 248: elsif !txn_id || txn_id.empty? 249: raise ArgumentError, "Transaction ID may not be empty" 250: end 251: 252: Lock.new(@mutex).synchronize do |lock| 253: Lock.new(@shared_data.mutex).synchronize do |shared_data_lock| 254: try_count = 0 255: if current_time >= @next_reconnect_time 256: while try_count < @max_connect_tries 257: begin 258: connect if !connected? 259: @shared_data.client.write("openTransaction", 260: txn_id, group_name, "", category, 261: AnalyticsLogger.timestamp_string, 262: union_station_key, 263: true) 264: return Log.new(@shared_data, txn_id) 265: rescue Errno::ENOENT, *NETWORK_ERRORS 266: try_count += 1 267: disconnect(true) 268: shared_data_lock.reset(@shared_data.mutex, false) 269: lock.unlock 270: sleep RETRY_SLEEP if try_count < @max_connect_tries 271: lock.lock 272: shared_data_lock.lock 273: rescue Exception => e 274: disconnect 275: raise e 276: end 277: end 278: # Failed to connect. 279: DebugLogging.warn("Cannot connect to the logging agent (#{@server_address}); " + 280: "retrying in #{@reconnect_timeout} seconds.") 281: @next_reconnect_time = current_time + @reconnect_timeout 282: end 283: return Log.new 284: end 285: end 286: end
[ show source ]
# File lib/phusion_passenger/analytics_logger.rb, line 195 195: def new_transaction(group_name, category = :requests, union_station_key = nil) 196: if !@server_address 197: return Log.new 198: elsif !group_name || group_name.empty? 199: raise ArgumentError, "Group name may not be empty" 200: end 201: 202: txn_id = (AnalyticsLogger.current_time.to_i / 60).to_s(36) 203: txn_id << "-#{random_token(11)}" 204: Lock.new(@mutex).synchronize do |lock| 205: Lock.new(@shared_data.mutex).synchronize do |shared_data_lock| 206: try_count = 0 207: if current_time >= @next_reconnect_time 208: while try_count < @max_connect_tries 209: begin 210: connect if !connected? 211: @shared_data.client.write("openTransaction", 212: txn_id, group_name, "", category, 213: AnalyticsLogger.timestamp_string, 214: union_station_key, 215: true, 216: true) 217: result = @shared_data.client.read 218: if result != ["ok"] 219: raise "Expected logging server to respond with 'ok', but got #{result.inspect} instead" 220: end 221: return Log.new(@shared_data, txn_id) 222: rescue Errno::ENOENT, *NETWORK_ERRORS 223: try_count += 1 224: disconnect(true) 225: shared_data_lock.reset(@shared_data.mutex, false) 226: lock.unlock 227: sleep RETRY_SLEEP if try_count < @max_connect_tries 228: lock.lock 229: shared_data_lock.lock 230: rescue Exception => e 231: disconnect 232: raise e 233: end 234: end 235: # Failed to connect. 236: DebugLogging.warn("Cannot connect to the logging agent (#{@server_address}); " + 237: "retrying in #{@reconnect_timeout} seconds.") 238: @next_reconnect_time = current_time + @reconnect_timeout 239: end 240: return Log.new 241: end 242: end 243: end