passenger 3.0.8 → 3.0.9
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of passenger might be problematic. Click here for more details.
- data/NEWS +9 -0
- data/bin/passenger-install-nginx-module +1 -1
- data/build/basics.rb +0 -1
- data/build/cxx_tests.rb +5 -0
- data/build/rpm.rb +1 -1
- data/doc/Users guide Apache.html +1 -1
- data/doc/Users guide Nginx.html +1 -1
- data/ext/apache2/Configuration.cpp +12 -0
- data/ext/apache2/Configuration.hpp +12 -1
- data/ext/apache2/Hooks.cpp +2 -0
- data/ext/common/AgentsStarter.cpp +4 -0
- data/ext/common/AgentsStarter.h +2 -0
- data/ext/common/AgentsStarter.hpp +4 -0
- data/ext/common/Constants.h +1 -1
- data/ext/common/Logging.h +481 -261
- data/ext/common/LoggingAgent/LoggingServer.h +10 -4
- data/ext/common/LoggingAgent/Main.cpp +7 -2
- data/ext/common/LoggingAgent/RemoteSender.h +25 -3
- data/ext/common/MessageChannel.h +18 -227
- data/ext/common/MessageClient.h +95 -92
- data/ext/common/Utils/IOUtils.cpp +114 -1
- data/ext/common/Utils/IOUtils.h +57 -1
- data/ext/common/Utils/MessageIO.h +576 -0
- data/ext/nginx/Configuration.c +35 -0
- data/ext/nginx/Configuration.h +2 -0
- data/ext/nginx/ContentHandler.c +17 -6
- data/ext/nginx/ngx_http_passenger_module.c +8 -0
- data/lib/phusion_passenger.rb +2 -2
- data/lib/phusion_passenger/analytics_logger.rb +174 -117
- data/lib/phusion_passenger/app_process.rb +14 -2
- data/test/cxx/CxxTestMain.cpp +14 -19
- data/test/cxx/IOUtilsTest.cpp +68 -18
- data/test/cxx/LoggingTest.cpp +20 -24
- data/test/cxx/MessageChannelTest.cpp +1 -1
- data/test/cxx/MessageIOTest.cpp +310 -0
- data/test/cxx/TestSupport.cpp +47 -0
- data/test/cxx/TestSupport.h +8 -0
- data/test/ruby/analytics_logger_spec.rb +20 -28
- data/test/tut/tut.h +2 -0
- metadata +11 -11
- data/build/rdoctask.rb +0 -209
- data/test/cxx/HttpStatusExtractorTest.cpp +0 -198
data/ext/nginx/Configuration.c
CHANGED
@@ -57,6 +57,11 @@ static ngx_path_init_t ngx_http_proxy_temp_path = {
|
|
57
57
|
};
|
58
58
|
|
59
59
|
|
60
|
+
static int
|
61
|
+
ngx_str_equals(ngx_str_t *str, const char *value) {
|
62
|
+
return ngx_memn2cmp(str->data, (u_char *) value, str->len, strlen(value)) == 0;
|
63
|
+
}
|
64
|
+
|
60
65
|
void *
|
61
66
|
passenger_create_main_conf(ngx_conf_t *cf)
|
62
67
|
{
|
@@ -92,6 +97,10 @@ passenger_create_main_conf(ngx_conf_t *cf)
|
|
92
97
|
conf->union_station_gateway_port = (ngx_uint_t) NGX_CONF_UNSET;
|
93
98
|
conf->union_station_gateway_cert.data = NULL;
|
94
99
|
conf->union_station_gateway_cert.len = 0;
|
100
|
+
conf->union_station_proxy_address.data = NULL;
|
101
|
+
conf->union_station_proxy_address.len = 0;
|
102
|
+
conf->union_station_proxy_type.data = NULL;
|
103
|
+
conf->union_station_proxy_type.len = 0;
|
95
104
|
|
96
105
|
conf->prestart_uris = ngx_array_create(cf->pool, 1, sizeof(ngx_str_t));
|
97
106
|
if (conf->prestart_uris == NULL) {
|
@@ -234,6 +243,18 @@ passenger_init_main_conf(ngx_conf_t *cf, void *conf_pointer)
|
|
234
243
|
conf->union_station_gateway_cert.data = (u_char *) "";
|
235
244
|
}
|
236
245
|
|
246
|
+
if (conf->union_station_proxy_address.len == 0) {
|
247
|
+
conf->union_station_proxy_address.data = (u_char *) "";
|
248
|
+
}
|
249
|
+
|
250
|
+
if (conf->union_station_proxy_type.len == 0) {
|
251
|
+
conf->union_station_proxy_type.data = (u_char *) "";
|
252
|
+
|
253
|
+
} else if (!ngx_str_equals(&conf->union_station_proxy_type, "http")
|
254
|
+
&& !ngx_str_equals(&conf->union_station_proxy_type, "socks5")) {
|
255
|
+
return "union_station_proxy_type may only be 'http' or 'socks5'.";
|
256
|
+
}
|
257
|
+
|
237
258
|
return NGX_CONF_OK;
|
238
259
|
}
|
239
260
|
|
@@ -1145,6 +1166,20 @@ const ngx_command_t passenger_commands[] = {
|
|
1145
1166
|
offsetof(passenger_main_conf_t, union_station_gateway_cert),
|
1146
1167
|
NULL },
|
1147
1168
|
|
1169
|
+
{ ngx_string("union_station_proxy_address"),
|
1170
|
+
NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE1,
|
1171
|
+
ngx_conf_set_str_slot,
|
1172
|
+
NGX_HTTP_MAIN_CONF_OFFSET,
|
1173
|
+
offsetof(passenger_main_conf_t, union_station_proxy_address),
|
1174
|
+
NULL },
|
1175
|
+
|
1176
|
+
{ ngx_string("union_station_proxy_type"),
|
1177
|
+
NGX_HTTP_MAIN_CONF | NGX_CONF_TAKE1,
|
1178
|
+
ngx_conf_set_str_slot,
|
1179
|
+
NGX_HTTP_MAIN_CONF_OFFSET,
|
1180
|
+
offsetof(passenger_main_conf_t, union_station_proxy_type),
|
1181
|
+
NULL },
|
1182
|
+
|
1148
1183
|
{ ngx_string("union_station_filter"),
|
1149
1184
|
NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_HTTP_LIF_CONF | NGX_CONF_TAKE1,
|
1150
1185
|
union_station_filter,
|
data/ext/nginx/Configuration.h
CHANGED
@@ -80,6 +80,8 @@ typedef struct {
|
|
80
80
|
ngx_str_t union_station_gateway_address;
|
81
81
|
ngx_uint_t union_station_gateway_port;
|
82
82
|
ngx_str_t union_station_gateway_cert;
|
83
|
+
ngx_str_t union_station_proxy_address;
|
84
|
+
ngx_str_t union_station_proxy_type;
|
83
85
|
ngx_array_t *prestart_uris;
|
84
86
|
} passenger_main_conf_t;
|
85
87
|
|
data/ext/nginx/ContentHandler.c
CHANGED
@@ -336,6 +336,7 @@ create_request(ngx_http_request_t *r)
|
|
336
336
|
ngx_table_elt_t *header;
|
337
337
|
ngx_http_script_code_pt code;
|
338
338
|
ngx_http_script_engine_t e, le;
|
339
|
+
ngx_http_core_srv_conf_t *cscf;
|
339
340
|
passenger_loc_conf_t *slcf;
|
340
341
|
passenger_main_conf_t *main_conf;
|
341
342
|
passenger_context_t *context;
|
@@ -344,6 +345,7 @@ create_request(ngx_http_request_t *r)
|
|
344
345
|
ngx_http_ssl_srv_conf_t *ssl_conf;
|
345
346
|
#endif
|
346
347
|
|
348
|
+
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
|
347
349
|
slcf = ngx_http_get_module_loc_conf(r, ngx_http_passenger_module);
|
348
350
|
main_conf = &passenger_main_conf;
|
349
351
|
context = ngx_http_get_module_ctx(r, ngx_http_passenger_module);
|
@@ -415,11 +417,15 @@ create_request(ngx_http_request_t *r)
|
|
415
417
|
}
|
416
418
|
|
417
419
|
/* SERVER_NAME; must be equal to HTTP_HOST without the port part */
|
418
|
-
|
419
|
-
|
420
|
-
|
420
|
+
if (r->headers_in.host != NULL) {
|
421
|
+
tmp = memchr(r->headers_in.host->value.data, ':', r->headers_in.host->value.len);
|
422
|
+
if (tmp == NULL) {
|
423
|
+
server_name_len = r->headers_in.host->value.len;
|
424
|
+
} else {
|
425
|
+
server_name_len = (int) ((const u_char *) tmp - r->headers_in.host->value.data);
|
426
|
+
}
|
421
427
|
} else {
|
422
|
-
server_name_len =
|
428
|
+
server_name_len = cscf->server_name.len;
|
423
429
|
}
|
424
430
|
len += sizeof("SERVER_NAME") + server_name_len + 1;
|
425
431
|
|
@@ -650,8 +656,13 @@ create_request(ngx_http_request_t *r)
|
|
650
656
|
|
651
657
|
/* SERVER_NAME */
|
652
658
|
b->last = ngx_copy(b->last, "SERVER_NAME", sizeof("SERVER_NAME"));
|
653
|
-
|
654
|
-
|
659
|
+
if (r->headers_in.host != NULL) {
|
660
|
+
b->last = ngx_copy(b->last, r->headers_in.host->value.data,
|
661
|
+
server_name_len);
|
662
|
+
} else {
|
663
|
+
b->last = ngx_copy(b->last, cscf->server_name.data,
|
664
|
+
server_name_len);
|
665
|
+
}
|
655
666
|
b->last = ngx_copy(b->last, "", 1);
|
656
667
|
|
657
668
|
/* Various other HTTP headers. */
|
@@ -239,6 +239,8 @@ start_helper_server(ngx_cycle_t *cycle) {
|
|
239
239
|
char *analytics_log_permissions;
|
240
240
|
char *union_station_gateway_address;
|
241
241
|
char *union_station_gateway_cert;
|
242
|
+
char *union_station_proxy_address;
|
243
|
+
char *union_station_proxy_type;
|
242
244
|
char *error_message = NULL;
|
243
245
|
|
244
246
|
core_conf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
|
@@ -256,6 +258,8 @@ start_helper_server(ngx_cycle_t *cycle) {
|
|
256
258
|
analytics_log_permissions = ngx_str_null_terminate(&passenger_main_conf.analytics_log_permissions);
|
257
259
|
union_station_gateway_address = ngx_str_null_terminate(&passenger_main_conf.union_station_gateway_address);
|
258
260
|
union_station_gateway_cert = ngx_str_null_terminate(&passenger_main_conf.union_station_gateway_cert);
|
261
|
+
union_station_proxy_address = ngx_str_null_terminate(&passenger_main_conf.union_station_proxy_address);
|
262
|
+
union_station_proxy_type = ngx_str_null_terminate(&passenger_main_conf.union_station_proxy_type);
|
259
263
|
|
260
264
|
prestart_uris = (ngx_str_t *) passenger_main_conf.prestart_uris->elts;
|
261
265
|
prestart_uris_ary = calloc(sizeof(char *), passenger_main_conf.prestart_uris->nelts);
|
@@ -284,6 +288,8 @@ start_helper_server(ngx_cycle_t *cycle) {
|
|
284
288
|
union_station_gateway_address,
|
285
289
|
passenger_main_conf.union_station_gateway_port,
|
286
290
|
union_station_gateway_cert,
|
291
|
+
union_station_proxy_address,
|
292
|
+
union_station_proxy_type,
|
287
293
|
(const char **) prestart_uris_ary, passenger_main_conf.prestart_uris->nelts,
|
288
294
|
starting_helper_server_after_fork,
|
289
295
|
cycle,
|
@@ -355,6 +361,8 @@ cleanup:
|
|
355
361
|
free(analytics_log_permissions);
|
356
362
|
free(union_station_gateway_address);
|
357
363
|
free(union_station_gateway_cert);
|
364
|
+
free(union_station_proxy_address);
|
365
|
+
free(union_station_proxy_type);
|
358
366
|
free(error_message);
|
359
367
|
if (prestart_uris_ary != NULL) {
|
360
368
|
for (i = 0; i < passenger_main_conf.prestart_uris->nelts; i++) {
|
data/lib/phusion_passenger.rb
CHANGED
@@ -25,9 +25,9 @@ module PhusionPassenger
|
|
25
25
|
###### Version numbers ######
|
26
26
|
|
27
27
|
# Phusion Passenger version number. Don't forget to edit ext/common/Constants.h too.
|
28
|
-
VERSION_STRING = '3.0.
|
28
|
+
VERSION_STRING = '3.0.9'
|
29
29
|
|
30
|
-
PREFERRED_NGINX_VERSION = '1.0.
|
30
|
+
PREFERRED_NGINX_VERSION = '1.0.6'
|
31
31
|
PREFERRED_PCRE_VERSION = '8.12'
|
32
32
|
STANDALONE_INTERFACE_VERSION = 1
|
33
33
|
|
@@ -24,7 +24,7 @@
|
|
24
24
|
require 'thread'
|
25
25
|
require 'phusion_passenger/utils'
|
26
26
|
require 'phusion_passenger/debug_logging'
|
27
|
-
require 'phusion_passenger/
|
27
|
+
require 'phusion_passenger/message_channel'
|
28
28
|
|
29
29
|
module PhusionPassenger
|
30
30
|
|
@@ -38,24 +38,33 @@ class AnalyticsLogger
|
|
38
38
|
class Log
|
39
39
|
attr_reader :txn_id
|
40
40
|
|
41
|
-
def initialize(
|
42
|
-
if
|
43
|
-
@
|
41
|
+
def initialize(connection = nil, txn_id = nil)
|
42
|
+
if connection
|
43
|
+
@connection = connection
|
44
44
|
@txn_id = txn_id
|
45
|
-
|
45
|
+
connection.ref
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
49
|
def null?
|
50
|
-
return !@
|
50
|
+
return !@connection
|
51
51
|
end
|
52
52
|
|
53
53
|
def message(text)
|
54
|
-
@
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
54
|
+
@connection.synchronize do
|
55
|
+
return if !@connection.connected?
|
56
|
+
begin
|
57
|
+
@connection.channel.write("log", @txn_id,
|
58
|
+
AnalyticsLogger.timestamp_string)
|
59
|
+
@connection.channel.write_scalar(text)
|
60
|
+
rescue SystemCallError, IOError => e
|
61
|
+
@connection.disconnect
|
62
|
+
DebugLogging.warn("Error communicating with the logging agent: #{e.message}")
|
63
|
+
rescue Exception => e
|
64
|
+
@connection.disconnect
|
65
|
+
raise e
|
66
|
+
end
|
67
|
+
end if @connection
|
59
68
|
end
|
60
69
|
|
61
70
|
def begin_measure(name, extra_info = nil)
|
@@ -107,30 +116,39 @@ class AnalyticsLogger
|
|
107
116
|
end
|
108
117
|
|
109
118
|
def close(flush_to_disk = false)
|
110
|
-
@
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
raise "Expected logging server to respond with 'ok', but got #{result.inspect} instead"
|
117
|
-
end
|
118
|
-
if flush_to_disk
|
119
|
-
@shared_data.client.write("flush")
|
120
|
-
result = @shared_data.client.read
|
119
|
+
@connection.synchronize do
|
120
|
+
begin
|
121
|
+
# We need an ACK here. See abstract_request_handler.rb finalize_request.
|
122
|
+
@connection.channel.write("closeTransaction", @txn_id,
|
123
|
+
AnalyticsLogger.timestamp_string, true)
|
124
|
+
result = @connection.channel.read
|
121
125
|
if result != ["ok"]
|
122
|
-
raise "
|
126
|
+
raise "Expected logging agent to respond with 'ok', but got #{result.inspect} instead"
|
127
|
+
end
|
128
|
+
if flush_to_disk
|
129
|
+
@connection.channel.write("flush")
|
130
|
+
result = @connection.channel.read
|
131
|
+
if result != ["ok"]
|
132
|
+
raise "Invalid logging agent response #{result.inspect} to the 'flush' command"
|
133
|
+
end
|
123
134
|
end
|
135
|
+
rescue SystemCallError, IOError => e
|
136
|
+
@connection.disconnect
|
137
|
+
DebugLogging.warn("Error communicating with the logging agent: #{e.message}")
|
138
|
+
rescue Exception => e
|
139
|
+
@connection.disconnect
|
140
|
+
raise e
|
141
|
+
ensure
|
142
|
+
@connection.unref
|
143
|
+
@connection = nil
|
124
144
|
end
|
125
|
-
|
126
|
-
@shared_data = nil
|
127
|
-
end if @shared_data
|
145
|
+
end if @connection
|
128
146
|
end
|
129
147
|
|
130
148
|
def closed?
|
131
|
-
if @
|
132
|
-
@
|
133
|
-
return !@
|
149
|
+
if @connection
|
150
|
+
@connection.synchronize do
|
151
|
+
return !@connection.connected?
|
134
152
|
end
|
135
153
|
else
|
136
154
|
return nil
|
@@ -170,10 +188,10 @@ class AnalyticsLogger
|
|
170
188
|
@random_dev = File.open("/dev/urandom")
|
171
189
|
|
172
190
|
# This mutex protects the following instance variables, but
|
173
|
-
# not the contents of @
|
191
|
+
# not the contents of @connection.
|
174
192
|
@mutex = Mutex.new
|
175
193
|
|
176
|
-
@
|
194
|
+
@connection = Connection.new(nil)
|
177
195
|
if @server_address && local_socket_address?(@server_address)
|
178
196
|
@max_connect_tries = 10
|
179
197
|
else
|
@@ -185,20 +203,20 @@ class AnalyticsLogger
|
|
185
203
|
|
186
204
|
def clear_connection
|
187
205
|
@mutex.synchronize do
|
188
|
-
@
|
206
|
+
@connection.synchronize do
|
189
207
|
@random_dev = File.open("/dev/urandom") if @random_dev.closed?
|
190
|
-
@
|
191
|
-
@
|
208
|
+
@connection.unref
|
209
|
+
@connection = Connection.new(nil)
|
192
210
|
end
|
193
211
|
end
|
194
212
|
end
|
195
213
|
|
196
214
|
def close
|
197
215
|
@mutex.synchronize do
|
198
|
-
@
|
216
|
+
@connection.synchronize do
|
199
217
|
@random_dev.close
|
200
|
-
@
|
201
|
-
@
|
218
|
+
@connection.unref
|
219
|
+
@connection = nil
|
202
220
|
end
|
203
221
|
end
|
204
222
|
end
|
@@ -212,44 +230,53 @@ class AnalyticsLogger
|
|
212
230
|
|
213
231
|
txn_id = (AnalyticsLogger.current_time.to_i / 60).to_s(36)
|
214
232
|
txn_id << "-#{random_token(11)}"
|
233
|
+
|
215
234
|
Lock.new(@mutex).synchronize do |lock|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
235
|
+
if current_time < @next_reconnect_time
|
236
|
+
return Log.new
|
237
|
+
end
|
238
|
+
|
239
|
+
Lock.new(@connection.mutex).synchronize do |connection_lock|
|
240
|
+
if !@connection.connected?
|
220
241
|
begin
|
221
|
-
connect
|
222
|
-
@
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
if result != ["ok"]
|
230
|
-
raise "Expected logging server to respond with 'ok', but got #{result.inspect} instead"
|
231
|
-
end
|
232
|
-
return Log.new(@shared_data, txn_id)
|
233
|
-
rescue Errno::ENOENT, *NETWORK_ERRORS
|
234
|
-
try_count += 1
|
235
|
-
disconnect(true)
|
236
|
-
shared_data_lock.reset(@shared_data.mutex, false)
|
237
|
-
lock.unlock
|
238
|
-
sleep RETRY_SLEEP if try_count < @max_connect_tries
|
239
|
-
lock.lock
|
240
|
-
shared_data_lock.lock
|
242
|
+
connect
|
243
|
+
connection_lock.reset(@connection.mutex)
|
244
|
+
rescue SystemCallError, IOError
|
245
|
+
@connection.disconnect
|
246
|
+
DebugLogging.warn("Cannot connect to the logging agent at #{@server_address}; " +
|
247
|
+
"retrying in #{@reconnect_timeout} second(s).")
|
248
|
+
@next_reconnect_time = current_time + @reconnect_timeout
|
249
|
+
return Log.new
|
241
250
|
rescue Exception => e
|
242
|
-
disconnect
|
251
|
+
@connection.disconnect
|
243
252
|
raise e
|
244
253
|
end
|
245
254
|
end
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
255
|
+
|
256
|
+
begin
|
257
|
+
@connection.channel.write("openTransaction",
|
258
|
+
txn_id, group_name, "", category,
|
259
|
+
AnalyticsLogger.timestamp_string,
|
260
|
+
union_station_key,
|
261
|
+
true,
|
262
|
+
true)
|
263
|
+
result = @connection.channel.read
|
264
|
+
if result != ["ok"]
|
265
|
+
raise "Expected logging server to respond with 'ok', but got #{result.inspect} instead"
|
266
|
+
end
|
267
|
+
return Log.new(@connection, txn_id)
|
268
|
+
rescue SystemCallError, IOError
|
269
|
+
@connection.disconnect
|
270
|
+
DebugLogging.warn("The logging agent at #{@server_address}" <<
|
271
|
+
" closed the connection; will reconnect in " <<
|
272
|
+
"#{@reconnect_timeout} second(s).")
|
273
|
+
@next_reconnect_time = current_time + @reconnect_timeout
|
274
|
+
return Log.new
|
275
|
+
rescue Exception => e
|
276
|
+
@connection.disconnect
|
277
|
+
raise e
|
278
|
+
end
|
250
279
|
end
|
251
|
-
return Log.new
|
252
|
-
end
|
253
280
|
end
|
254
281
|
end
|
255
282
|
|
@@ -261,38 +288,46 @@ class AnalyticsLogger
|
|
261
288
|
end
|
262
289
|
|
263
290
|
Lock.new(@mutex).synchronize do |lock|
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
291
|
+
if current_time < @next_reconnect_time
|
292
|
+
return Log.new
|
293
|
+
end
|
294
|
+
|
295
|
+
Lock.new(@connection.mutex).synchronize do |connection_lock|
|
296
|
+
if !@connection.connected?
|
268
297
|
begin
|
269
|
-
connect
|
270
|
-
@
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
try_count += 1
|
278
|
-
disconnect(true)
|
279
|
-
shared_data_lock.reset(@shared_data.mutex, false)
|
280
|
-
lock.unlock
|
281
|
-
sleep RETRY_SLEEP if try_count < @max_connect_tries
|
282
|
-
lock.lock
|
283
|
-
shared_data_lock.lock
|
298
|
+
connect
|
299
|
+
connection_lock.reset(@connection.mutex)
|
300
|
+
rescue SystemCallError, IOError
|
301
|
+
@connection.disconnect
|
302
|
+
DebugLogging.warn("Cannot connect to the logging agent at #{@server_address}; " +
|
303
|
+
"retrying in #{@reconnect_timeout} second(s).")
|
304
|
+
@next_reconnect_time = current_time + @reconnect_timeout
|
305
|
+
return Log.new
|
284
306
|
rescue Exception => e
|
285
|
-
disconnect
|
307
|
+
@connection.disconnect
|
286
308
|
raise e
|
287
309
|
end
|
288
310
|
end
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
311
|
+
|
312
|
+
begin
|
313
|
+
@connection.channel.write("openTransaction",
|
314
|
+
txn_id, group_name, "", category,
|
315
|
+
AnalyticsLogger.timestamp_string,
|
316
|
+
union_station_key,
|
317
|
+
true)
|
318
|
+
return Log.new(@connection, txn_id)
|
319
|
+
rescue SystemCallError, IOError
|
320
|
+
@connection.disconnect
|
321
|
+
DebugLogging.warn("The logging agent at #{@server_address}" <<
|
322
|
+
" closed the connection; will reconnect in " <<
|
323
|
+
"#{@reconnect_timeout} second(s).")
|
324
|
+
@next_reconnect_time = current_time + @reconnect_timeout
|
325
|
+
return Log.new
|
326
|
+
rescue Exception => e
|
327
|
+
@connection.disconnect
|
328
|
+
raise e
|
329
|
+
end
|
293
330
|
end
|
294
|
-
return Log.new
|
295
|
-
end
|
296
331
|
end
|
297
332
|
end
|
298
333
|
|
@@ -337,18 +372,23 @@ private
|
|
337
372
|
end
|
338
373
|
end
|
339
374
|
|
340
|
-
class
|
375
|
+
class Connection
|
341
376
|
attr_reader :mutex
|
342
|
-
attr_accessor :
|
377
|
+
attr_accessor :channel
|
343
378
|
|
344
|
-
def initialize
|
379
|
+
def initialize(io)
|
345
380
|
@mutex = Mutex.new
|
346
381
|
@refcount = 1
|
382
|
+
@channel = MessageChannel.new(io) if io
|
383
|
+
end
|
384
|
+
|
385
|
+
def connected?
|
386
|
+
return !!@channel
|
347
387
|
end
|
348
388
|
|
349
|
-
def disconnect
|
350
|
-
|
351
|
-
@
|
389
|
+
def disconnect
|
390
|
+
@channel.close if @channel
|
391
|
+
@channel = nil
|
352
392
|
end
|
353
393
|
|
354
394
|
def ref
|
@@ -369,29 +409,46 @@ private
|
|
369
409
|
end
|
370
410
|
end
|
371
411
|
|
372
|
-
def connected?
|
373
|
-
return @shared_data.client && @shared_data.client.connected?
|
374
|
-
end
|
375
|
-
|
376
412
|
def connect
|
377
|
-
|
378
|
-
|
379
|
-
|
413
|
+
socket = connect_to_server(@server_address)
|
414
|
+
channel = MessageChannel.new(socket)
|
415
|
+
|
416
|
+
result = channel.read
|
417
|
+
if result.nil?
|
418
|
+
raise EOFError
|
419
|
+
elsif result.size != 2 || result[0] != "version"
|
420
|
+
raise IOError, "The logging agent didn't sent a valid version identifier"
|
421
|
+
elsif result[1] != "1"
|
422
|
+
raise IOError, "Unsupported logging agent protocol version #{result[1]}"
|
423
|
+
end
|
424
|
+
|
425
|
+
channel.write_scalar(@username)
|
426
|
+
channel.write_scalar(@password)
|
427
|
+
|
428
|
+
result = channel.read
|
429
|
+
if result.nil?
|
430
|
+
raise EOFError
|
431
|
+
elsif result[0] != "ok"
|
432
|
+
raise SecurityError, result[0]
|
433
|
+
end
|
434
|
+
|
435
|
+
channel.write("init", @node_name)
|
436
|
+
args = channel.read
|
380
437
|
if !args
|
381
|
-
raise Errno::ECONNREFUSED, "Cannot connect to logging
|
438
|
+
raise Errno::ECONNREFUSED, "Cannot connect to logging agent"
|
382
439
|
elsif args.size != 1
|
383
|
-
raise IOError, "Logging
|
440
|
+
raise IOError, "Logging agent returned an invalid reply for the 'init' command"
|
384
441
|
elsif args[0] == "server shutting down"
|
385
|
-
raise Errno::ECONNREFUSED, "Cannot connect to logging
|
442
|
+
raise Errno::ECONNREFUSED, "Cannot connect to logging agent"
|
386
443
|
elsif args[0] != "ok"
|
387
|
-
raise IOError, "Logging
|
444
|
+
raise IOError, "Logging agent returned an invalid reply for the 'init' command"
|
388
445
|
end
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
446
|
+
|
447
|
+
@connection.unref
|
448
|
+
@connection = Connection.new(socket)
|
449
|
+
rescue Exception => e
|
450
|
+
socket.close if socket && !socket.closed?
|
451
|
+
raise e
|
395
452
|
end
|
396
453
|
|
397
454
|
def random_token(length)
|