17
17
#define DEFAULT_LOG_FMT "ABDhmsvRti"
18
18
#define UDP 0
19
19
#define TCP 1
20
- #define RECONNECT_INTERVAL 500000
20
+ #define RECONNECT_INTERVAL 120000000
21
21
#define MIN_CONNECTIONS 1
22
22
#define MAX_CONNECTIONS 5
23
23
#define SEND_BUFFER 1048576
24
24
25
25
module AP_MODULE_DECLARE_DATA log_gelf_module ;
26
26
27
- static int verbose = 0 ;
27
+ static int verbose = 1 ;
28
28
static char errbuf [1024 ];
29
29
30
30
typedef struct {
@@ -35,26 +35,26 @@ typedef struct {
35
35
} log_item ;
36
36
37
37
typedef struct {
38
- apr_socket_t * s ; /* Actual GELF connection */
39
- apr_sockaddr_t * sa ; /* GELF Address */
38
+ apr_socket_t * s ; /* Actual GELF connection */
39
+ apr_sockaddr_t * sa ; /* GELF Address */
40
40
} gelf_connection ;
41
41
42
42
typedef struct {
43
- int enabled ;
44
- int port ; /* GELF port */
45
- int protocol ; /* 0=UDP 1=TCP */
46
- const char * server ; /* Hostname/IP of Graylog server */
47
- const char * source ; /* Source field */
48
- const char * facility ; /* Facility field */
49
- const char * tag ; /* Optional tag field */
50
- const char * fields ; /* String with fields of interest */
51
- const char * cookie ; /* Log this cookie */
52
- log_item * * parsed_fields ; /* Link fields to extractor function */
53
- apr_pool_t * parse_pool ; /* memory pool for option parsing */
54
- apr_reslist_t * connection_pool ;
55
- int nmin ;
56
- int nkeep ;
57
- int nmax ;
43
+ int enabled ;
44
+ int port ; /* GELF port */
45
+ int protocol ; /* 0=UDP 1=TCP */
46
+ const char * server ; /* Hostname/IP of Graylog server */
47
+ const char * source ; /* Source field */
48
+ const char * facility ; /* Facility field */
49
+ const char * tag ; /* Optional tag field */
50
+ const char * fields ; /* String with fields of interest */
51
+ const char * cookie ; /* Log this cookie */
52
+ log_item * * parsed_fields ; /* Link fields to extractor function */
53
+ apr_pool_t * parse_pool ; /* memory pool for option parsing */
54
+ apr_reslist_t * connection_pool ; /* Connection pool, with min, max and ttl settings */
55
+ int nmin ;
56
+ int nkeep ;
57
+ int nmax ;
58
58
apr_interval_time_t ttl ;
59
59
} gelf_config ;
60
60
@@ -66,7 +66,7 @@ static void *create_gelf_configuration(apr_pool_t *pool, server_rec *server) {
66
66
config -> source = "localhost" ;
67
67
config -> facility = "apache-gelf" ;
68
68
config -> fields = DEFAULT_LOG_FMT ;
69
- /* connection pool settings */
69
+ /* connection pool settings */
70
70
config -> nmin = MIN_CONNECTIONS ;
71
71
config -> nkeep = MIN_CONNECTIONS ;
72
72
config -> nmax = MAX_CONNECTIONS ;
@@ -197,34 +197,34 @@ static const command_rec log_gelf_directives[] = {
197
197
static gelf_connection * log_gelf_connection_acquire (request_rec * r ) {
198
198
gelf_config * config = ap_get_module_config (r -> server -> module_config , & log_gelf_module ) ;
199
199
apr_status_t rv ;
200
- gelf_connection * con ;
201
-
200
+ gelf_connection * con ;
201
+
202
202
rv = apr_reslist_acquire (config -> connection_pool , (void * * )& con );
203
- if ( rv != APR_SUCCESS ) {
203
+ if (rv != APR_SUCCESS || ! con ) {
204
204
ap_log_rerror (APLOG_MARK , APLOG_ERR , 0 , r ,
205
205
"mod_log_gelf: Failed to acquire GELF connection from pool %s" ,
206
206
apr_strerror (rv , errbuf , sizeof (errbuf )));
207
207
return NULL ;
208
208
}
209
-
209
+
210
210
return con ;
211
211
}
212
212
213
213
static apr_status_t log_gelf_connection_release (request_rec * r , gelf_connection * con ) {
214
- gelf_config * config = ap_get_module_config (r -> server -> module_config , & log_gelf_module );
215
- apr_status_t rv ;
216
- rv = apr_reslist_release (config -> connection_pool , con );
217
- if (rv != APR_SUCCESS ) {
218
- ap_log_rerror (APLOG_MARK , APLOG_ERR , 0 , r , "mod_log_gelf: Can not release GELF socket." );
219
- }
220
-
221
- return rv ;
214
+ gelf_config * config = ap_get_module_config (r -> server -> module_config , & log_gelf_module );
215
+ apr_status_t rv ;
216
+ rv = apr_reslist_release (config -> connection_pool , con );
217
+ if (rv != APR_SUCCESS ) {
218
+ ap_log_rerror (APLOG_MARK , APLOG_ERR , 0 , r , "mod_log_gelf: Can not release GELF socket." );
219
+ }
220
+
221
+ return rv ;
222
222
}
223
223
224
224
static apr_status_t log_gelf_get_gelf_connection (gelf_connection * gc , gelf_config * config , apr_pool_t * pool ) {
225
225
apr_status_t rv ;
226
226
int proto = NULL ;
227
- int type = NULL ;
227
+ int type = NULL ;
228
228
229
229
if (config -> protocol == TCP ) {
230
230
proto = APR_PROTO_TCP ;
@@ -298,20 +298,20 @@ static apr_status_t log_gelf_get_gelf_connection(gelf_connection *gc, gelf_confi
298
298
static apr_status_t gelf_pool_construct (void * * rs , void * params , apr_pool_t * pool ) {
299
299
gelf_config * config = (gelf_config * )params ;
300
300
apr_status_t rv ;
301
-
302
- if (config -> enabled < 1 ) {
303
- /* module disabled, no socket needed */
304
- return APR_SUCCESS ;
305
- }
306
-
301
+
302
+ if (config -> enabled < 1 ) {
303
+ /* module disabled, no socket needed */
304
+ return APR_SUCCESS ;
305
+ }
306
+
307
307
if (verbose > 0 ) {
308
308
ap_log_perror (APLOG_MARK , APLOG_CRIT , 0 , pool , "mod_log_gelf: Creating new socket for pool: %s:%d" ,
309
309
config -> server , config -> port );
310
310
}
311
311
312
- gelf_connection * con ;
313
- con = apr_palloc (pool , sizeof (gelf_connection ));
314
- rv = log_gelf_get_gelf_connection (con , config , pool );
312
+ gelf_connection * con ;
313
+ con = apr_palloc (pool , sizeof (gelf_connection ));
314
+ rv = log_gelf_get_gelf_connection (con , config , pool );
315
315
if (rv != APR_SUCCESS ) {
316
316
return APR_EGENERAL ;
317
317
}
@@ -326,18 +326,21 @@ static apr_status_t gelf_pool_construct(void** rs, void* params, apr_pool_t* poo
326
326
}
327
327
328
328
static apr_status_t gelf_pool_destruct (void * resource , void * params , apr_pool_t * pool ) {
329
- if (resource ) {
330
- gelf_connection * con = (gelf_connection * )resource ;
331
- apr_socket_close (con -> s );
332
- }
329
+ if (resource ) {
330
+ if (verbose > 0 ) {
331
+ ap_log_perror (APLOG_MARK , APLOG_CRIT , 0 , pool , "mod_log_gelf: Removing socket from pool" );
332
+ }
333
+ gelf_connection * con = (gelf_connection * )resource ;
334
+ apr_socket_close (con -> s );
335
+ }
333
336
return APR_SUCCESS ;
334
337
}
335
338
336
339
/* Registered hooks */
337
340
static int log_gelf_post_config (apr_pool_t * p , apr_pool_t * plog , apr_pool_t * ptemp , server_rec * server ) {
338
341
gelf_config * config = ap_get_module_config (server -> module_config , & log_gelf_module );
339
342
340
- /* initialize resource list to keep track of socket pool */
343
+ /* initialize resource list to keep track of socket pool */
341
344
if ( apr_reslist_create (& config -> connection_pool ,
342
345
config -> nmin ,
343
346
config -> nkeep ,
@@ -347,8 +350,8 @@ static int log_gelf_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *pte
347
350
gelf_pool_destruct ,
348
351
config , p ) != APR_SUCCESS ) {
349
352
ap_log_error (APLOG_MARK , APLOG_CRIT , 0 , server , "mod_log_gelf: Failed to initialize resource pool, disabling GELF logging." );
350
- config -> enabled = 0 ;
351
- return OK ;
353
+ config -> enabled = 0 ;
354
+ return OK ;
352
355
}
353
356
apr_pool_cleanup_register (p , config -> connection_pool ,
354
357
(void * )apr_reslist_destroy , apr_pool_cleanup_null );
@@ -394,7 +397,7 @@ static int log_gelf_transaction(request_rec *request) {
394
397
"mod_log_gelf: Module is disbaled, not sending log data!" );
395
398
return OK ;
396
399
}
397
-
400
+
398
401
/* skip logging if endpoint is not configured properly */
399
402
if (!config -> server || !config -> port ) {
400
403
log_error (APLOG_MARK , APLOG_ERR , 0 , request -> server ,
@@ -532,14 +535,14 @@ void log_gelf_send_message_udp(const transferData* payload, request_rec *request
532
535
} else {
533
536
log_error (APLOG_MARK , APLOG_ERR , 0 , request -> server ,
534
537
"mod_log_gelf: Got empty log message, not sending anything." );
535
- return ;
538
+ return ;
536
539
}
537
540
538
- /* acquire a free socket, send message, release socket */
541
+ /* acquire a free socket, send message, release socket */
539
542
gelf_connection * con = log_gelf_connection_acquire (request );
540
- if (!con ) {
541
- return ;
542
- }
543
+ if (!con ) {
544
+ return ;
545
+ }
543
546
544
547
if (verbose > 0 ) {
545
548
log_error (APLOG_MARK , APLOG_ERR , 0 , request -> server ,
@@ -553,7 +556,7 @@ void log_gelf_send_message_udp(const transferData* payload, request_rec *request
553
556
payload -> size , apr_strerror (rv , errbuf , sizeof (errbuf )));
554
557
}
555
558
556
- log_gelf_connection_release (request , con );
559
+ log_gelf_connection_release (request , con );
557
560
}
558
561
559
562
void log_gelf_send_message_tcp (const transferData * payload , request_rec * request ) {
@@ -573,11 +576,11 @@ void log_gelf_send_message_tcp(const transferData* payload, request_rec *request
573
576
/* copy payload and append '\0' */
574
577
const char * gelf_payload = apr_pstrmemdup (request -> pool , payload -> data , payload -> size );
575
578
576
- /* acquire a free socket, send message, release socket */
579
+ /* acquire a free socket, send message, release socket */
577
580
gelf_connection * con = log_gelf_connection_acquire (request );
578
- if (!con ) {
579
- return ;
580
- }
581
+ if (!con || ! con -> s ) {
582
+ return ;
583
+ }
581
584
582
585
if (verbose > 0 ) {
583
586
log_error (APLOG_MARK , APLOG_ERR , 0 , request -> server ,
@@ -589,16 +592,26 @@ void log_gelf_send_message_tcp(const transferData* payload, request_rec *request
589
592
log_error (APLOG_MARK , APLOG_ERR , 0 , request -> server ,
590
593
"mod_log_gelf: Error writing to socket %d bytes. Error %s" ,
591
594
payload -> size , apr_strerror (rv , errbuf , sizeof (errbuf )));
592
- apr_reslist_invalidate (config -> connection_pool , con ) ;
595
+ apr_reslist_invalidate (config -> connection_pool , con ) ;
593
596
}
594
-
595
- log_gelf_connection_release (request , con );
597
+
598
+ log_gelf_connection_release (request , con );
596
599
}
597
600
598
601
double log_gelf_get_timestamp () {
599
602
return ((double ) (apr_time_now () / 1000 )) / 1000.0 ;
600
603
}
601
604
605
+ static void log_gelf_sig_pipe (int sig ){
606
+ apr_pool_t * pool = NULL ;
607
+ apr_pool_create (& pool , NULL );
608
+
609
+ if (verbose > 0 ) {
610
+ ap_log_perror (APLOG_MARK , APLOG_ERR , 0 , pool ,
611
+ "mod_log_gelf: Got signal SIGPIPE. Most likely GELF server went away." );
612
+ }
613
+ }
614
+
602
615
static void log_gelf_child_init (apr_pool_t * p , server_rec * server ) {
603
616
apr_status_t rv ;
604
617
gelf_config * config = ap_get_module_config (server -> module_config , & log_gelf_module );
@@ -614,6 +627,8 @@ static void log_gelf_child_init(apr_pool_t *p, server_rec *server) {
614
627
gelf_config * config = create_gelf_configuration (p , server );
615
628
ap_set_module_config (server -> module_config , & log_gelf_module , config );
616
629
}
630
+
631
+ apr_signal (SIGPIPE , log_gelf_sig_pipe );
617
632
}
618
633
619
634
static void register_hooks (apr_pool_t * p ) {
0 commit comments