Mercurial > hg > nginx
comparison src/core/ngx_syslog.c @ 9225:1c9264603adc
Syslog: introduced ngx_syslog_send() error logging moderation.
Errors when logging to syslog are now logged at most once per second.
This ensures that persistent errors won't flood other logs, and spontaneous
errors, such as ENOBUFS as observed on BSD systems when syslogd cannot cope
with load, or EAGAIN as seen in similar situation on Linux, won't further
overload logging subsystem, leading to more errors.
Further, errors now can only trigger reconnects at most once per second.
This ensures that persistent errors, which cannot be fixed with reconnects,
don't trigger too much unneeded work.
Additionally, in case of connection errors, such as when syslogd is not
running, connection attempts are only made once per second.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Fri, 01 Mar 2024 05:42:12 +0300 |
parents | c7c8354f99fa |
children | c769217b4a5c |
comparison
equal
deleted
inserted
replaced
9224:c7c8354f99fa | 9225:1c9264603adc |
---|---|
301 if (ngx_syslog_init_peer(peer) != NGX_OK) { | 301 if (ngx_syslog_init_peer(peer) != NGX_OK) { |
302 return NGX_ERROR; | 302 return NGX_ERROR; |
303 } | 303 } |
304 } | 304 } |
305 | 305 |
306 if (ngx_time() == peer->error_log_time) { | |
307 peer->conn.log_error = NGX_ERROR_DEBUG; | |
308 } | |
309 | |
306 if (ngx_send) { | 310 if (ngx_send) { |
307 n = ngx_send(&peer->conn, buf, len); | 311 n = ngx_send(&peer->conn, buf, len); |
308 | 312 |
309 } else { | 313 } else { |
310 /* event module has not yet set ngx_io */ | 314 /* event module has not yet set ngx_io */ |
311 n = ngx_os_io.send(&peer->conn, buf, len); | 315 n = ngx_os_io.send(&peer->conn, buf, len); |
312 } | 316 } |
313 | 317 |
314 if (n == NGX_ERROR) { | 318 if (n == NGX_ERROR |
315 | 319 && peer->conn.log_error != NGX_ERROR_DEBUG) |
320 { | |
316 if (ngx_close_socket(peer->conn.fd) == -1) { | 321 if (ngx_close_socket(peer->conn.fd) == -1) { |
317 ngx_log_error(NGX_LOG_ALERT, &peer->log, ngx_socket_errno, | 322 ngx_log_error(NGX_LOG_ALERT, &peer->log, ngx_socket_errno, |
318 ngx_close_socket_n " failed"); | 323 ngx_close_socket_n " failed"); |
319 } | 324 } |
320 | 325 |
321 peer->conn.fd = (ngx_socket_t) -1; | 326 peer->conn.fd = (ngx_socket_t) -1; |
322 | 327 peer->error_log_time = ngx_time(); |
323 } else if ((size_t) n != len) { | 328 |
329 } else if ((size_t) n != len | |
330 && peer->conn.log_error != NGX_ERROR_DEBUG) | |
331 { | |
324 ngx_log_error(NGX_LOG_CRIT, &peer->log, 0, | 332 ngx_log_error(NGX_LOG_CRIT, &peer->log, 0, |
325 "send() incomplete"); | 333 "send() incomplete"); |
326 } | 334 peer->error_log_time = ngx_time(); |
335 } | |
336 | |
337 peer->conn.log_error = NGX_ERROR_ERR; | |
327 | 338 |
328 return n; | 339 return n; |
329 } | 340 } |
330 | 341 |
331 | 342 |
332 static ngx_int_t | 343 static ngx_int_t |
333 ngx_syslog_init_peer(ngx_syslog_peer_t *peer) | 344 ngx_syslog_init_peer(ngx_syslog_peer_t *peer) |
334 { | 345 { |
335 ngx_socket_t fd; | 346 ngx_socket_t fd; |
347 | |
348 if (ngx_time() == peer->connect_error_time) { | |
349 return NGX_ERROR; | |
350 } | |
336 | 351 |
337 fd = ngx_socket(peer->server.sockaddr->sa_family, SOCK_DGRAM, 0); | 352 fd = ngx_socket(peer->server.sockaddr->sa_family, SOCK_DGRAM, 0); |
338 if (fd == (ngx_socket_t) -1) { | 353 if (fd == (ngx_socket_t) -1) { |
339 ngx_log_error(NGX_LOG_ALERT, &peer->log, ngx_socket_errno, | 354 ngx_log_error(NGX_LOG_ALERT, &peer->log, ngx_socket_errno, |
340 ngx_socket_n " failed"); | 355 ngx_socket_n " failed"); |
356 peer->connect_error_time = ngx_time(); | |
341 return NGX_ERROR; | 357 return NGX_ERROR; |
342 } | 358 } |
343 | 359 |
344 if (ngx_nonblocking(fd) == -1) { | 360 if (ngx_nonblocking(fd) == -1) { |
345 ngx_log_error(NGX_LOG_ALERT, &peer->log, ngx_socket_errno, | 361 ngx_log_error(NGX_LOG_ALERT, &peer->log, ngx_socket_errno, |
353 goto failed; | 369 goto failed; |
354 } | 370 } |
355 | 371 |
356 peer->conn.fd = fd; | 372 peer->conn.fd = fd; |
357 peer->conn.log = &peer->log; | 373 peer->conn.log = &peer->log; |
374 peer->conn.log_error = NGX_ERROR_ERR; | |
358 | 375 |
359 /* UDP sockets are always ready to write */ | 376 /* UDP sockets are always ready to write */ |
360 peer->conn.write->ready = 1; | 377 peer->conn.write->ready = 1; |
361 | 378 |
362 return NGX_OK; | 379 return NGX_OK; |
363 | 380 |
364 failed: | 381 failed: |
382 | |
383 peer->connect_error_time = ngx_time(); | |
365 | 384 |
366 if (ngx_close_socket(fd) == -1) { | 385 if (ngx_close_socket(fd) == -1) { |
367 ngx_log_error(NGX_LOG_ALERT, &peer->log, ngx_socket_errno, | 386 ngx_log_error(NGX_LOG_ALERT, &peer->log, ngx_socket_errno, |
368 ngx_close_socket_n " failed"); | 387 ngx_close_socket_n " failed"); |
369 } | 388 } |