diff --git a/src/descrambler.h b/src/descrambler.h index 9bd2cda7..36c7a52d 100755 --- a/src/descrambler.h +++ b/src/descrambler.h @@ -71,7 +71,7 @@ typedef struct th_descrambler_runtime { time_t dr_ecm_key_time; time_t dr_last_err; sbuf_t dr_buf; - loglimiter_t dr_loglimit_key; + tvhlog_limit_t dr_loglimit_key; } th_descrambler_runtime_t; typedef void (*descrambler_section_callback_t) diff --git a/src/descrambler/descrambler.c b/src/descrambler/descrambler.c index 448f03ed..f6ad5ce9 100755 --- a/src/descrambler/descrambler.c +++ b/src/descrambler/descrambler.c @@ -359,7 +359,8 @@ descrambler_descramble ( service_t *t, ki = tsb[3]; if ((ki & 0x80) != 0x00) { if (key_valid(dr, ki) == 0) { - limitedlog(&dr->dr_loglimit_key, "descrambler", + if (tvhlog_limit(&dr->dr_loglimit_key, 10)) + tvhwarn("descrambler", "%s %s", ((mpegts_service_t *)t)->s_dvb_svcname, (ki & 0x40) ? "odd stream key is not valid" : "even stream key is not valid"); diff --git a/src/input/mpegts.h b/src/input/mpegts.h index c3b1225c..e0be22c0 100644 --- a/src/input/mpegts.h +++ b/src/input/mpegts.h @@ -197,8 +197,7 @@ struct mpegts_table int8_t mt_cc; - time_t mt_last_perr; // last printer error - size_t mt_errors; // total number of table errors + tvhlog_limit_t mt_err_log; mpegts_psi_section_t mt_sect; diff --git a/src/input/mpegts/mpegts_table.c b/src/input/mpegts/mpegts_table.c index 34e9639c..e7dedb37 100644 --- a/src/input/mpegts/mpegts_table.c +++ b/src/input/mpegts/mpegts_table.c @@ -62,13 +62,10 @@ mpegts_table_dispatch if (tid == 0x72) { /* stuffing section */ if (len != r - 3) { - mt->mt_errors++; - if (mt->mt_last_perr + 10 < dispatch_clock) { + if (tvhlog_limit(&mt->mt_err_log, 10)) tvhwarn(mt->mt_name, "stuffing found with trailing data " "(len %i, total %zi, errors %zi)", - len, r, mt->mt_errors); - mt->mt_last_perr = dispatch_clock; - } + len, r, mt->mt_err_log.count); } dvb_table_reset(mt); return; @@ -77,12 +74,9 @@ mpegts_table_dispatch /* It seems some hardware (or is it the dvb API?) does not honour the DMX_CHECK_CRC flag, so we check it again */ if(chkcrc && tvh_crc32(sec, r, 0xffffffff)) { - mt->mt_errors++; - if (mt->mt_last_perr + 10 < dispatch_clock) { + if (tvhlog_limit(&mt->mt_err_log, 10)) tvhwarn(mt->mt_name, "invalid checksum (len %zi, errors %zi)", - r, mt->mt_errors); - mt->mt_last_perr = dispatch_clock; - } + r, mt->mt_err_log.count); return; } diff --git a/src/input/mpegts/tsdemux.c b/src/input/mpegts/tsdemux.c index 114e5a14..57883dad 100644 --- a/src/input/mpegts/tsdemux.c +++ b/src/input/mpegts/tsdemux.c @@ -69,11 +69,11 @@ ts_recv_packet0 if(tsb[3] & 0x10) { cc = tsb[3] & 0xf; if(st->es_cc != -1 && cc != st->es_cc) { - /* Let the hardware to stabilize */ - if (t->s_start_time + 1 < dispatch_clock) - /* Incorrect CC */ - limitedlog(&st->es_loglimit_cc, "TS", service_component_nicename(st), - "Continuity counter error"); + /* Let the hardware to stabilize and don't flood the log */ + if (t->s_start_time + 1 < dispatch_clock && + tvhlog_limit(&st->es_cc_log, 10)) + tvhwarn("TS", "%s Continuity counter error (total %zi)", + service_component_nicename(st), st->es_cc_log.count); avgstat_add(&t->s_cc_errors, 1, dispatch_clock); avgstat_add(&st->es_cc_errors, 1, dispatch_clock); @@ -192,8 +192,9 @@ ts_recv_packet1 if(error) { /* Transport Error Indicator */ - limitedlog(&t->s_loglimit_tei, "TS", service_nicename((service_t*)t), - "Transport error indicator"); + if (tvhlog_limit(&t->s_tei_log, 10)) + tvhwarn("TS", "%s Transport error indicator (total %zi)", + service_nicename((service_t*)t), t->s_tei_log.count); } pid = (tsb[1] & 0x1f) << 8 | tsb[2]; diff --git a/src/main.c b/src/main.c index ea84a2d6..26779506 100644 --- a/src/main.c +++ b/src/main.c @@ -164,7 +164,6 @@ const tvh_caps_t tvheadend_capabilities[] = { { NULL, NULL } }; -time_t dispatch_clock; pthread_mutex_t global_lock; pthread_mutex_t ffmpeg_lock; pthread_mutex_t fork_lock; @@ -986,31 +985,6 @@ scopedunlock(pthread_mutex_t **mtxp) } -void -limitedlog(loglimiter_t *ll, const char *sys, const char *o, const char *event) -{ - time_t now; - char buf[64]; - time(&now); - - ll->events++; - if(ll->last == now) - return; // Duplicate event - - if(ll->last <= now - 10) { - // Too old, reset duplicate counter - ll->events = 0; - buf[0] = 0; - } else { - snprintf(buf, sizeof(buf), ", %d duplicate log lines suppressed", - ll->events); - } - - tvhlog(LOG_WARNING, sys, "%s: %s%s", o, event, buf); - ll->last = now; -} - - /** * */ diff --git a/src/parsers/parsers.c b/src/parsers/parsers.c index c542f28d..6ce2268e 100644 --- a/src/parsers/parsers.c +++ b/src/parsers/parsers.c @@ -851,8 +851,9 @@ parse_pes_header(service_t *t, elementary_stream_t *st, err: st->es_curdts = PTS_UNSET; st->es_curpts = PTS_UNSET; - limitedlog(&st->es_loglimit_pes, "TS", service_component_nicename(st), - "Corrupted PES header"); + if (tvhlog_limit(&st->es_pes_log, 10)) + tvhwarn("TS", "%s Corrupted PES header (errors %zi)", + service_component_nicename(st), st->es_pes_log.count); return -1; } diff --git a/src/service.c b/src/service.c index ba3c0076..a9fdc1f0 100644 --- a/src/service.c +++ b/src/service.c @@ -259,6 +259,9 @@ stream_clean(elementary_stream_t *st) free(st->es_section); st->es_section = NULL; + + tvhlog_limit_reset(&st->es_cc_log); + tvhlog_limit_reset(&st->es_pes_log); } /** @@ -320,6 +323,7 @@ service_stop(service_t *t) stream_clean(st); t->s_status = SERVICE_IDLE; + tvhlog_limit_reset(&t->s_tei_log); pthread_mutex_unlock(&t->s_stream_mutex); } diff --git a/src/service.h b/src/service.h index 59646477..d1419803 100644 --- a/src/service.h +++ b/src/service.h @@ -115,8 +115,8 @@ typedef struct elementary_stream { /* Error log limiters */ - loglimiter_t es_loglimit_cc; - loglimiter_t es_loglimit_pes; + tvhlog_limit_t es_cc_log; + tvhlog_limit_t es_pes_log; char *es_nicename; @@ -434,9 +434,7 @@ typedef struct service { */ streaming_pad_t s_streaming_pad; - - loglimiter_t s_loglimit_tei; - + tvhlog_limit_t s_tei_log; int64_t s_current_pts; diff --git a/src/tvheadend.h b/src/tvheadend.h index 0b557f51..5f586f02 100644 --- a/src/tvheadend.h +++ b/src/tvheadend.h @@ -195,18 +195,6 @@ LIST_HEAD(dvr_autorec_entry_list, dvr_autorec_entry); TAILQ_HEAD(th_pktref_queue, th_pktref); LIST_HEAD(streaming_target_list, streaming_target); -/** - * Log limiter - */ -typedef struct loglimter { - time_t last; - int events; -} loglimiter_t; - -void limitedlog(loglimiter_t *ll, const char *sys, - const char *o, const char *event); - - /** * Device connection types */ @@ -572,7 +560,6 @@ int sri_to_rate(int sri); int rate_to_sri(int rate); -extern time_t dispatch_clock; extern struct service_list all_transports; extern void scopedunlock(pthread_mutex_t **mtxp); diff --git a/src/tvhlog.c b/src/tvhlog.c index 6f38f96b..04f79d65 100644 --- a/src/tvhlog.c +++ b/src/tvhlog.c @@ -25,6 +25,8 @@ #include "webui/webui.h" +time_t dispatch_clock; + int tvhlog_run; int tvhlog_level; int tvhlog_options; diff --git a/src/tvhlog.h b/src/tvhlog.h index f9c2d325..90c19d63 100644 --- a/src/tvhlog.h +++ b/src/tvhlog.h @@ -30,6 +30,14 @@ #include "htsmsg.h" +typedef struct { + time_t last; + size_t count; +} tvhlog_limit_t; + +/* Globals */ +extern time_t dispatch_clock; + /* Config */ extern int tvhlog_level; extern htsmsg_t *tvhlog_debug; @@ -57,6 +65,11 @@ void _tvhlog_hexdump ( const char *file, int line, int notify, int severity, const char *subsys, const uint8_t *data, ssize_t len ); +static inline void tvhlog_limit_reset ( tvhlog_limit_t *limit ) + { limit->last = 0; limit->count = 0; } +static inline int tvhlog_limit ( tvhlog_limit_t *limit, uint32_t delay ) + { time_t t = dispatch_clock; int res = limit->last + delay < t; + limit->count++; limit->last = t; return res; } /* Options */