diff options
| author | David Lamparter <equinox@diac24.net> | 2020-04-28 09:30:59 +0200 | 
|---|---|---|
| committer | David Lamparter <equinox@diac24.net> | 2021-02-01 17:28:09 +0100 | 
| commit | 131879fb926798bfefd80b0e2cba266919c5be1d (patch) | |
| tree | d3969846271acbdc3f2cdb9161f813b1353f4988 | |
| parent | 60a3efec2458d9a1531f8204d0e4a91729d3fc00 (diff) | |
lib/xref: add xrefs on zlog_* calls
This allows extracting a list of all log messages including their ECs
and autogenerated unique IDs for them.
Signed-off-by: David Lamparter <equinox@diac24.net>
| -rw-r--r-- | lib/clippy.c | 3 | ||||
| -rw-r--r-- | lib/log.h | 10 | ||||
| -rw-r--r-- | lib/xref.h | 2 | ||||
| -rw-r--r-- | lib/zlog.c | 22 | ||||
| -rw-r--r-- | lib/zlog.h | 79 | 
5 files changed, 93 insertions, 23 deletions
diff --git a/lib/clippy.c b/lib/clippy.c index 2e09c24c66..15cd9d7a4b 100644 --- a/lib/clippy.c +++ b/lib/clippy.c @@ -107,7 +107,8 @@ int main(int argc, char **argv)  #include "log.h"  #include "zassert.h" -void vzlog(int prio, const char *format, va_list args) +void vzlogx(const struct xref_logmsg *xref, int prio, +	    const char *format, va_list args)  {  	vfprintf(stderr, format, args);  	fputs("\n", stderr); @@ -62,16 +62,6 @@ struct message {  	const char *str;  }; -/* For logs which have error codes associated with them */ -#define flog_err(ferr_id, format, ...)                                        \ -	zlog_err("[EC %u] " format, ferr_id, ##__VA_ARGS__) -#define flog_err_sys(ferr_id, format, ...)                                     \ -	flog_err(ferr_id, format, ##__VA_ARGS__) -#define flog_warn(ferr_id, format, ...)                                        \ -	zlog_warn("[EC %u] " format, ferr_id, ##__VA_ARGS__) -#define flog(priority, ferr_id, format, ...)                                   \ -	zlog(priority, "[EC %u] " format, ferr_id, ##__VA_ARGS__) -  extern void zlog_thread_info(int log_level);  #define ZLOG_FILTERS_MAX 100      /* Max # of filters at once */ diff --git a/lib/xref.h b/lib/xref.h index aac4a754d2..9b5bcffc01 100644 --- a/lib/xref.h +++ b/lib/xref.h @@ -27,6 +27,8 @@ enum xref_type {  	XREFT_NONE = 0,  	XREFT_THREADSCHED = 0x100, + +	XREFT_LOGMSG = 0x200,  };  /* struct xref is the "const" part;  struct xrefdata is the writable part. */ diff --git a/lib/zlog.c b/lib/zlog.c index e77feec5f2..51509e24f4 100644 --- a/lib/zlog.c +++ b/lib/zlog.c @@ -94,6 +94,7 @@ struct zlog_msg {  	const char *fmt;  	va_list args; +	const struct xref_logmsg *xref;  	char *stackbuf;  	size_t stackbufsz; @@ -349,12 +350,14 @@ void zlog_tls_buffer_flush(void)  } -static void vzlog_notls(int prio, const char *fmt, va_list ap) +static void vzlog_notls(const struct xref_logmsg *xref, int prio, +			const char *fmt, va_list ap)  {  	struct zlog_target *zt;  	struct zlog_msg stackmsg = {  		.prio = prio & LOG_PRIMASK,  		.fmt = fmt, +		.xref = xref,  	}, *msg = &stackmsg;  	char stackbuf[512]; @@ -379,8 +382,8 @@ static void vzlog_notls(int prio, const char *fmt, va_list ap)  		XFREE(MTYPE_LOG_MESSAGE, msg->text);  } -static void vzlog_tls(struct zlog_tls *zlog_tls, int prio, -		      const char *fmt, va_list ap) +static void vzlog_tls(struct zlog_tls *zlog_tls, const struct xref_logmsg *xref, +		      int prio, const char *fmt, va_list ap)  {  	struct zlog_target *zt;  	struct zlog_msg *msg; @@ -413,6 +416,7 @@ static void vzlog_tls(struct zlog_tls *zlog_tls, int prio,  	msg->stackbufsz = TLS_LOG_BUF_SIZE - zlog_tls->bufpos - 1;  	msg->fmt = fmt;  	msg->prio = prio & LOG_PRIMASK; +	msg->xref = xref;  	if (msg->prio < LOG_INFO)  		immediate = true; @@ -447,7 +451,8 @@ static void vzlog_tls(struct zlog_tls *zlog_tls, int prio,  		XFREE(MTYPE_LOG_MESSAGE, msg->text);  } -void vzlog(int prio, const char *fmt, va_list ap) +void vzlogx(const struct xref_logmsg *xref, int prio, +	    const char *fmt, va_list ap)  {  	struct zlog_tls *zlog_tls = zlog_tls_get(); @@ -480,9 +485,9 @@ void vzlog(int prio, const char *fmt, va_list ap)  #endif  	if (zlog_tls) -		vzlog_tls(zlog_tls, prio, fmt, ap); +		vzlog_tls(zlog_tls, xref, prio, fmt, ap);  	else -		vzlog_notls(prio, fmt, ap); +		vzlog_notls(xref, prio, fmt, ap);  }  void zlog_sigsafe(const char *text, size_t len) @@ -516,6 +521,11 @@ int zlog_msg_prio(struct zlog_msg *msg)  	return msg->prio;  } +const struct xref_logmsg *zlog_msg_xref(struct zlog_msg *msg) +{ +	return msg->xref; +} +  const char *zlog_msg_text(struct zlog_msg *msg, size_t *textlen)  {  	if (!msg->text) { diff --git a/lib/zlog.h b/lib/zlog.h index 1c5013746b..bdf59fa68e 100644 --- a/lib/zlog.h +++ b/lib/zlog.h @@ -38,6 +38,20 @@ extern char zlog_prefix[];  extern size_t zlog_prefixsz;  extern int zlog_tmpdirfd; +struct xref_logmsg { +	struct xref xref; + +	const char *fmtstring; +	uint32_t priority; +	uint32_t ec; +}; + +struct xrefdata_logmsg { +	struct xrefdata xrefdata; + +	/* nothing more here right now */ +}; +  /* These functions are set up to write to stdout/stderr without explicit   * initialization and/or before config load.  There is no need to call e.g.   * fprintf(stderr, ...) just because it's "too early" at startup.  Depending @@ -45,7 +59,9 @@ extern int zlog_tmpdirfd;   * determine wether something is a log message or something else.   */ -extern void vzlog(int prio, const char *fmt, va_list ap); +extern void vzlogx(const struct xref_logmsg *xref, int prio, +		   const char *fmt, va_list ap); +#define vzlog(prio, ...) vzlogx(NULL, prio, __VA_ARGS__)  PRINTFRR(2, 3)  static inline void zlog(int prio, const char *fmt, ...) @@ -57,11 +73,61 @@ static inline void zlog(int prio, const char *fmt, ...)  	va_end(ap);  } -#define zlog_err(...)    zlog(LOG_ERR, __VA_ARGS__) -#define zlog_warn(...)   zlog(LOG_WARNING, __VA_ARGS__) -#define zlog_info(...)   zlog(LOG_INFO, __VA_ARGS__) -#define zlog_notice(...) zlog(LOG_NOTICE, __VA_ARGS__) -#define zlog_debug(...)  zlog(LOG_DEBUG, __VA_ARGS__) +PRINTFRR(2, 3) +static inline void zlog_ref(const struct xref_logmsg *xref, +			    const char *fmt, ...) +{ +	va_list ap; + +	va_start(ap, fmt); +	vzlogx(xref, xref->priority, fmt, ap); +	va_end(ap); +} + +#define _zlog_ref(prio, msg, ...) do {                                         \ +		static struct xrefdata _xrefdata = {                           \ +			.hashstr = (msg),                                      \ +			.hashu32 = { (prio), 0 },                              \ +		};                                                             \ +		static const struct xref_logmsg _xref __attribute__((used)) = {\ +			.xref = XREF_INIT(XREFT_LOGMSG, &_xrefdata, __func__), \ +			.fmtstring = (msg),                                    \ +			.priority = (prio),                                    \ +		};                                                             \ +		XREF_LINK(_xref.xref);                                         \ +		zlog_ref(&_xref, (msg), ## __VA_ARGS__);                       \ +	} while (0) + +#define zlog_err(...)    _zlog_ref(LOG_ERR, __VA_ARGS__) +#define zlog_warn(...)   _zlog_ref(LOG_WARNING, __VA_ARGS__) +#define zlog_info(...)   _zlog_ref(LOG_INFO, __VA_ARGS__) +#define zlog_notice(...) _zlog_ref(LOG_NOTICE, __VA_ARGS__) +#define zlog_debug(...)  _zlog_ref(LOG_DEBUG, __VA_ARGS__) + +#define _zlog_ecref(ec_, prio, msg, ...) do {                                  \ +		static struct xrefdata _xrefdata = {                           \ +			.hashstr = (msg),                                      \ +			.hashu32 = { (prio), (ec_) },                          \ +		};                                                             \ +		static const struct xref_logmsg _xref __attribute__((used)) = {\ +			.xref = XREF_INIT(XREFT_LOGMSG, &_xrefdata, __func__), \ +			.fmtstring = (msg),                                    \ +			.priority = (prio),                                    \ +			.ec = (ec_),                                           \ +		};                                                             \ +		XREF_LINK(_xref.xref);                                         \ +		zlog_ref(&_xref, "[EC %u] " msg, ec_, ## __VA_ARGS__);         \ +	} while (0) + +#define flog_err(ferr_id, format, ...)                                         \ +	_zlog_ecref(ferr_id, LOG_ERR, format, ## __VA_ARGS__) +#define flog_warn(ferr_id, format, ...)                                        \ +	_zlog_ecref(ferr_id, LOG_WARNING, format, ## __VA_ARGS__) + +#define flog_err_sys(ferr_id, format, ...)                                     \ +	flog_err(ferr_id, format, ##__VA_ARGS__) +#define flog(priority, ferr_id, format, ...)                                   \ +	zlog(priority, "[EC %u] " format, ferr_id, ##__VA_ARGS__)  extern void zlog_sigsafe(const char *text, size_t len); @@ -83,6 +149,7 @@ extern void zlog_sigsafe(const char *text, size_t len);  struct zlog_msg;  extern int zlog_msg_prio(struct zlog_msg *msg); +extern const struct xref_logmsg *zlog_msg_xref(struct zlog_msg *msg);  /* pass NULL as textlen if you don't need it. */  extern const char *zlog_msg_text(struct zlog_msg *msg, size_t *textlen);  | 
