summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@diac24.net>2020-04-28 09:30:59 +0200
committerDavid Lamparter <equinox@diac24.net>2021-02-01 17:28:09 +0100
commit131879fb926798bfefd80b0e2cba266919c5be1d (patch)
treed3969846271acbdc3f2cdb9161f813b1353f4988
parent60a3efec2458d9a1531f8204d0e4a91729d3fc00 (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.c3
-rw-r--r--lib/log.h10
-rw-r--r--lib/xref.h2
-rw-r--r--lib/zlog.c22
-rw-r--r--lib/zlog.h79
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);
diff --git a/lib/log.h b/lib/log.h
index 3d2f0ed829..7147253644 100644
--- a/lib/log.h
+++ b/lib/log.h
@@ -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);