]> git.proxmox.com Git - mirror_frr.git/commitdiff
lib/xref: add xrefs on zlog_* calls
authorDavid Lamparter <equinox@diac24.net>
Tue, 28 Apr 2020 07:30:59 +0000 (09:30 +0200)
committerDavid Lamparter <equinox@diac24.net>
Mon, 1 Feb 2021 16:28:09 +0000 (17:28 +0100)
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>
lib/clippy.c
lib/log.h
lib/xref.h
lib/zlog.c
lib/zlog.h

index 2e09c24c66f8531bc149bb7fbdd1fb9e4e9faef0..15cd9d7a4b743cdbe421b543239db036083e0b77 100644 (file)
@@ -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);
index 3d2f0ed829a7cd69ce5ae158d2239cfed73fbdcd..714725364451770b50f05984c76ab5d57c5f5e35 100644 (file)
--- 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 */
index aac4a754d2a407a6003db3cd5ccb246eefad17e0..9b5bcffc018326ffa1e0680a01db27fe88edfd1b 100644 (file)
@@ -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. */
index e77feec5f2c7962cb540d283ba487376d881f2ff..51509e24f4d4429615d500f005f4df9d3e096190 100644 (file)
@@ -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) {
index 1c5013746b60f470a878f8a75e91de756467a042..bdf59fa68eb7d760360226e3251b8f4d3f718c80 100644 (file)
@@ -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);