struct rcu_head head_self;
atomic_uint_fast32_t state;
+ atomic_uint_fast32_t lost_msgs;
};
static void zlog_live(struct zlog_target *zt, struct zlog_msg *msgs[],
hdr->ts_nsec = ts.tv_nsec;
hdr->pid = pid;
hdr->tid = tid;
+ hdr->lost_msgs = atomic_load_explicit(&zte->lost_msgs,
+ memory_order_relaxed);
hdr->prio = prio;
hdr->flags = 0;
hdr->textlen = textlen;
for (size_t msgpos = 0; msgpos < msgtotal; msgpos += sent) {
sent = sendmmsg(fd, mmhs + msgpos, msgtotal - msgpos, 0);
- if (sent <= 0 && (errno == EAGAIN || errno == EWOULDBLOCK))
+ if (sent <= 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
+ atomic_fetch_add_explicit(&zte->lost_msgs,
+ msgtotal - msgpos,
+ memory_order_relaxed);
break;
+ }
if (sent <= 0)
goto out_err;
}
int64_t pid;
int64_t tid;
+ /* number of lost messages due to best-effort non-blocking mode */
+ uint32_t lost_msgs;
/* syslog priority value */
uint32_t prio;
/* flags: currently unused */
struct thread *log_reader;
int log_fd;
+ uint32_t lost_msgs;
};
static bool stderr_tty;
if (ret < 0 && ERRNO_IO_RETRY(errno))
return;
+ if (stderr_stdout_same) {
+#ifdef HAVE_RL_CLEAR_VISIBLE_LINE
+ rl_clear_visible_line();
+#else
+ puts("\r");
+#endif
+ fflush(stdout);
+ }
+
if (ret <= 0) {
struct timespec ts;
buf.hdr.flags = 0;
buf.hdr.texthdrlen = 0;
buf.hdr.n_argpos = 0;
- }
+ } else {
+ int32_t lost_msgs = buf.hdr.lost_msgs - vclient->lost_msgs;
- if (stderr_stdout_same) {
-#ifdef HAVE_RL_CLEAR_VISIBLE_LINE
- rl_clear_visible_line();
-#else
- puts("\r");
-#endif
- fflush(stdout);
+ if (lost_msgs > 0) {
+ vclient->lost_msgs = buf.hdr.lost_msgs;
+ fprintf(stderr,
+ "%d log messages from %s lost (vtysh reading too slowly)\n",
+ lost_msgs, vclient->name);
+ }
}
text = buf.text + sizeof(buf.hdr.argpos[0]) * buf.hdr.n_argpos;