back to topotato report
topotato coverage report
Current view: top level - lib - zlog.h (source / functions) Hit Total Coverage
Test: test_pim_basic2.py::PIMTopo2Test Lines: 6 12 50.0 %
Date: 2023-02-24 18:39:36 Functions: 1 2 50.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2015-19  David Lamparter, for NetDEF, Inc.
       3             :  *
       4             :  * Permission to use, copy, modify, and distribute this software for any
       5             :  * purpose with or without fee is hereby granted, provided that the above
       6             :  * copyright notice and this permission notice appear in all copies.
       7             :  *
       8             :  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
       9             :  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      10             :  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
      11             :  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
      12             :  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
      13             :  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      14             :  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      15             :  */
      16             : 
      17             : #ifndef _FRR_ZLOG_H
      18             : #define _FRR_ZLOG_H
      19             : 
      20             : #include <stdarg.h>
      21             : #include <stdbool.h>
      22             : #include <stdint.h>
      23             : #include <string.h>
      24             : #include <syslog.h>
      25             : #include <unistd.h>
      26             : #include <sys/uio.h>
      27             : 
      28             : #include <assert.h>
      29             : 
      30             : #include "atomlist.h"
      31             : #include "frrcu.h"
      32             : #include "memory.h"
      33             : #include "hook.h"
      34             : #include "printfrr.h"
      35             : 
      36             : #ifdef __cplusplus
      37             : extern "C" {
      38             : #endif
      39             : 
      40             : DECLARE_MGROUP(LOG);
      41             : 
      42             : extern char zlog_prefix[];
      43             : extern size_t zlog_prefixsz;
      44             : extern int zlog_tmpdirfd;
      45             : extern int zlog_instance;
      46             : extern const char *zlog_progname;
      47             : 
      48             : struct xref_logmsg {
      49             :         struct xref xref;
      50             : 
      51             :         const char *fmtstring;
      52             :         uint32_t priority;
      53             :         uint32_t ec;
      54             :         const char *args;
      55             : };
      56             : 
      57             : /* whether flag was added in config mode or enable mode */
      58             : #define LOGMSG_FLAG_EPHEMERAL   (1 << 0)
      59             : #define LOGMSG_FLAG_PERSISTENT  (1 << 1)
      60             : 
      61             : struct xrefdata_logmsg {
      62             :         struct xrefdata xrefdata;
      63             : 
      64             :         uint8_t fl_print_bt;
      65             : };
      66             : 
      67             : /* These functions are set up to write to stdout/stderr without explicit
      68             :  * initialization and/or before config load.  There is no need to call e.g.
      69             :  * fprintf(stderr, ...) just because it's "too early" at startup.  Depending
      70             :  * on context, it may still be the right thing to use fprintf though -- try to
      71             :  * determine whether something is a log message or something else.
      72             :  */
      73             : 
      74             : extern void vzlogx(const struct xref_logmsg *xref, int prio, const char *fmt,
      75             :                    va_list ap) PRINTFRR(3, 0);
      76             : #define vzlog(prio, ...) vzlogx(NULL, prio, __VA_ARGS__)
      77             : 
      78             : PRINTFRR(2, 3)
      79           0 : static inline void zlog(int prio, const char *fmt, ...)
      80             : {
      81           0 :         va_list ap;
      82             : 
      83           0 :         va_start(ap, fmt);
      84           0 :         vzlog(prio, fmt, ap);
      85           0 :         va_end(ap);
      86           0 : }
      87             : 
      88             : PRINTFRR(2, 3)
      89         345 : static inline void zlog_ref(const struct xref_logmsg *xref,
      90             :                             const char *fmt, ...)
      91             : {
      92         345 :         va_list ap;
      93             : 
      94         345 :         va_start(ap, fmt);
      95         345 :         vzlogx(xref, xref->priority, fmt, ap);
      96         345 :         va_end(ap);
      97         345 : }
      98             : 
      99             : #define _zlog_ecref(ec_, prio, msg, ...)                                       \
     100             :         do {                                                                   \
     101             :                 static struct xrefdata_logmsg _xrefdata = {                    \
     102             :                         .xrefdata =                                            \
     103             :                                 {                                              \
     104             :                                         .xref = NULL,                          \
     105             :                                         .uid = {},                             \
     106             :                                         .hashstr = (msg),                      \
     107             :                                         .hashu32 = {(prio), (ec_)},            \
     108             :                                 },                                             \
     109             :                 };                                                             \
     110             :                 static const struct xref_logmsg _xref __attribute__(           \
     111             :                         (used)) = {                                            \
     112             :                         .xref = XREF_INIT(XREFT_LOGMSG, &_xrefdata.xrefdata,   \
     113             :                                           __func__),                           \
     114             :                         .fmtstring = (msg),                                    \
     115             :                         .priority = (prio),                                    \
     116             :                         .ec = (ec_),                                           \
     117             :                         .args = (#__VA_ARGS__),                                \
     118             :                 };                                                             \
     119             :                 XREF_LINK(_xref.xref);                                         \
     120             :                 zlog_ref(&_xref, (msg), ##__VA_ARGS__);                        \
     121             :         } while (0)
     122             : 
     123             : #define zlog_err(...)    _zlog_ecref(0, LOG_ERR, __VA_ARGS__)
     124             : #define zlog_warn(...)   _zlog_ecref(0, LOG_WARNING, __VA_ARGS__)
     125             : #define zlog_info(...)   _zlog_ecref(0, LOG_INFO, __VA_ARGS__)
     126             : #define zlog_notice(...) _zlog_ecref(0, LOG_NOTICE, __VA_ARGS__)
     127             : #define zlog_debug(...)  _zlog_ecref(0, LOG_DEBUG, __VA_ARGS__)
     128             : 
     129             : #define flog_err(ferr_id, format, ...)                                         \
     130             :         _zlog_ecref(ferr_id, LOG_ERR, format, ## __VA_ARGS__)
     131             : #define flog_warn(ferr_id, format, ...)                                        \
     132             :         _zlog_ecref(ferr_id, LOG_WARNING, format, ## __VA_ARGS__)
     133             : 
     134             : #define flog_err_sys(ferr_id, format, ...)                                     \
     135             :         _zlog_ecref(ferr_id, LOG_ERR, format, ## __VA_ARGS__)
     136             : 
     137             : extern void zlog_sigsafe(const char *text, size_t len);
     138             : 
     139             : /* extra priority value to disable a target without deleting it */
     140             : #define ZLOG_DISABLED   (LOG_EMERG-1)
     141             : 
     142             : /* zlog_msg encapsulates a particular logging call from somewhere in the code.
     143             :  * The same struct is passed around to all zlog_targets.
     144             :  *
     145             :  * This is used to defer formatting the log message until it is actually
     146             :  * requested by one of the targets.  If none of the targets needs the message
     147             :  * formatted, the formatting call is avoided entirely.
     148             :  *
     149             :  * This struct is opaque / private to the core zlog code.  Logging targets
     150             :  * should use zlog_msg_* functions to get text / timestamps / ... for a
     151             :  * message.
     152             :  */
     153             : 
     154             : struct zlog_msg;
     155             : 
     156             : extern int zlog_msg_prio(struct zlog_msg *msg);
     157             : extern const struct xref_logmsg *zlog_msg_xref(struct zlog_msg *msg);
     158             : 
     159             : /* text is NOT \0 terminated; instead there is a \n after textlen since the
     160             :  * logging targets would jump extra hoops otherwise for a single byte.  (the
     161             :  * \n is not included in textlen)
     162             :  *
     163             :  * calling this with NULL textlen is likely wrong.
     164             :  * use  "%.*s", (int)textlen, text  when passing to printf-like functions
     165             :  */
     166             : extern const char *zlog_msg_text(struct zlog_msg *msg, size_t *textlen);
     167             : 
     168             : extern void zlog_msg_args(struct zlog_msg *msg, size_t *hdrlen,
     169             :                           size_t *n_argpos, const struct fmt_outpos **argpos);
     170             : 
     171             : /* timestamp formatting control flags */
     172             : 
     173             : /* sub-second digit count */
     174             : #define ZLOG_TS_PREC            0xfU
     175             : 
     176             : /* 8601:   0000-00-00T00:00:00Z      (if used with ZLOG_TS_UTC)
     177             :  *         0000-00-00T00:00:00+00:00 (otherwise)
     178             :  * Legacy: 0000/00/00 00:00:00       (no TZ indicated!)
     179             :  */
     180             : #define ZLOG_TS_ISO8601         (1 << 8)
     181             : #define ZLOG_TS_LEGACY          (1 << 9)
     182             : 
     183             : /* default is local time zone */
     184             : #define ZLOG_TS_UTC             (1 << 10)
     185             : 
     186             : struct timespec;
     187             : 
     188             : extern size_t zlog_msg_ts(struct zlog_msg *msg, struct fbuf *out,
     189             :                           uint32_t flags);
     190             : extern void zlog_msg_tsraw(struct zlog_msg *msg, struct timespec *ts);
     191             : 
     192             : /* "mmm dd hh:mm:ss" for RFC3164 syslog.  Only ZLOG_TS_UTC for flags. */
     193             : extern size_t zlog_msg_ts_3164(struct zlog_msg *msg, struct fbuf *out,
     194             :                                uint32_t flags);
     195             : 
     196             : /* currently just returns the current PID/TID since we never write another
     197             :  * thread's messages
     198             :  */
     199             : extern void zlog_msg_pid(struct zlog_msg *msg, intmax_t *pid, intmax_t *tid);
     200             : 
     201             : /* This list & struct implements the actual logging targets.  It is accessed
     202             :  * lock-free from all threads, and thus MUST only be changed atomically, i.e.
     203             :  * RCU.
     204             :  *
     205             :  * Since there's no atomic replace, the replacement action is an add followed
     206             :  * by a delete.  This means that during logging config changes, log messages
     207             :  * may be duplicated in the log target that is being changed.  The old entry
     208             :  * being changed MUST also at the very least not crash or do other stupid
     209             :  * things.
     210             :  *
     211             :  * This list and struct are NOT related to config.  Logging config is kept
     212             :  * separately, and results in creating appropriate zlog_target(s) to realize
     213             :  * the config.  Log targets may also be created from varying sources, e.g.
     214             :  * command line options, or VTY commands ("log monitor").
     215             :  *
     216             :  * struct zlog_target is intended to be embedded into a larger structure that
     217             :  * contains additional field for the specific logging target, e.g. an fd or
     218             :  * additional options.  It MUST be the first field in that larger struct.
     219             :  */
     220             : 
     221             : PREDECL_ATOMLIST(zlog_targets);
     222             : struct zlog_target {
     223             :         struct zlog_targets_item head;
     224             : 
     225             :         int prio_min;
     226             : 
     227             :         void (*logfn)(struct zlog_target *zt, struct zlog_msg *msg[],
     228             :                       size_t nmsgs);
     229             : 
     230             :         /* for crash handlers, set to NULL if log target can't write crash logs
     231             :          * without possibly deadlocking (AS-Safe)
     232             :          *
     233             :          * text is not \0 terminated & split up into lines (e.g. no \n)
     234             :          */
     235             :         void (*logfn_sigsafe)(struct zlog_target *zt, const char *text,
     236             :                               size_t len);
     237             : 
     238             :         struct rcu_head rcu_head;
     239             : };
     240             : 
     241             : /* make a copy for RCUpdating.  oldzt may be NULL to allocate a fresh one. */
     242             : extern struct zlog_target *zlog_target_clone(struct memtype *mt,
     243             :                                              struct zlog_target *oldzt,
     244             :                                              size_t size);
     245             : 
     246             : /* update the zlog_targets list;  both oldzt and newzt may be NULL.  You
     247             :  * still need to zlog_target_free() the old target afterwards if it wasn't
     248             :  * NULL.
     249             :  *
     250             :  * Returns oldzt so you can zlog_target_free(zlog_target_replace(old, new));
     251             :  * (Some log targets may need extra cleanup inbetween, but remember the old
     252             :  * target MUST remain functional until the end of the current RCU cycle.)
     253             :  */
     254             : extern struct zlog_target *zlog_target_replace(struct zlog_target *oldzt,
     255             :                                                struct zlog_target *newzt);
     256             : 
     257             : /* Mostly for symmetry for zlog_target_clone(), just rcu_free() internally. */
     258             : #define zlog_target_free(mt, zt) \
     259             :         rcu_free(mt, zt, rcu_head)
     260             : 
     261             : extern void zlog_init(const char *progname, const char *protoname,
     262             :                       unsigned short instance, uid_t uid, gid_t gid);
     263             : DECLARE_HOOK(zlog_init, (const char *progname, const char *protoname,
     264             :                          unsigned short instance, uid_t uid, gid_t gid),
     265             :                         (progname, protoname, instance, uid, gid));
     266             : 
     267             : extern void zlog_fini(void);
     268             : DECLARE_KOOH(zlog_fini, (), ());
     269             : 
     270             : extern void zlog_set_prefix_ec(bool enable);
     271             : extern bool zlog_get_prefix_ec(void);
     272             : extern void zlog_set_prefix_xid(bool enable);
     273             : extern bool zlog_get_prefix_xid(void);
     274             : 
     275             : /* for tools & test programs, i.e. anything not a daemon.
     276             :  * (no cleanup needed at exit)
     277             :  */
     278             : extern void zlog_aux_init(const char *prefix, int prio_min);
     279             : DECLARE_HOOK(zlog_aux_init, (const char *prefix, int prio_min),
     280             :                             (prefix, prio_min));
     281             : 
     282             : extern void zlog_startup_end(void);
     283             : 
     284             : extern void zlog_tls_buffer_init(void);
     285             : extern void zlog_tls_buffer_flush(void);
     286             : extern void zlog_tls_buffer_fini(void);
     287             : 
     288             : /* Enable or disable 'immediate' output - default is to buffer messages. */
     289             : extern void zlog_set_immediate(bool set_p);
     290             : 
     291             : extern const char *zlog_priority_str(int priority);
     292             : 
     293             : #ifdef __cplusplus
     294             : }
     295             : #endif
     296             : 
     297             : #endif /* _FRR_ZLOG_H */

Generated by: LCOV version v1.16-topotato