commit b592495: [Minor] Refactor logging function to join console and file

Vsevolod Stakhov vsevolod at rspamd.com
Sat Sep 16 16:07:04 UTC 2023


Author: Vsevolod Stakhov
Date: 2023-09-16 17:01:08 +0100
URL: https://github.com/rspamd/rspamd/commit/b59249576fb9d87008dd016cc5cfa3e06e69585e (HEAD -> master)

[Minor] Refactor logging function to join console and file

---
 src/libserver/logger/logger.c         | 200 +++++++++++++++++++++++++++++++++-
 src/libserver/logger/logger_console.c | 135 ++---------------------
 src/libserver/logger/logger_file.c    | 120 ++------------------
 src/libserver/logger/logger_private.h |  28 ++++-
 4 files changed, 243 insertions(+), 240 deletions(-)

diff --git a/src/libserver/logger/logger.c b/src/libserver/logger/logger.c
index b62048c86..9b9d302f2 100644
--- a/src/libserver/logger/logger.c
+++ b/src/libserver/logger/logger.c
@@ -1,11 +1,11 @@
-/*-
- * Copyright 2016 Vsevolod Stakhov
+/*
+ * Copyright 2023 Vsevolod Stakhov
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- *   http://www.apache.org/licenses/LICENSE-2.0
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -27,6 +27,8 @@ static rspamd_logger_t *default_logger = NULL;
 static rspamd_logger_t *emergency_logger = NULL;
 static struct rspamd_log_modules *log_modules = NULL;
 
+static const gchar lf_chr = '\n';
+
 guint rspamd_task_log_id = (guint) -1;
 RSPAMD_CONSTRUCTOR(rspamd_task_log_init)
 {
@@ -1003,4 +1005,196 @@ rspamd_get_log_severity_string(gint level_flags)
 	bitnum = ffs(level_flags) - 1;
 #endif
 	return level_strs[bitnum];
+}
+
+static inline void
+log_time(gdouble now, rspamd_logger_t *rspamd_log, gchar *timebuf,
+		 size_t len)
+{
+	time_t sec = (time_t) now;
+	gsize r;
+	struct tm tms;
+
+	rspamd_localtime(sec, &tms);
+	r = strftime(timebuf, len, "%F %H:%M:%S", &tms);
+
+	if (rspamd_log->flags & RSPAMD_LOG_FLAG_USEC) {
+		gchar usec_buf[16];
+
+		rspamd_snprintf(usec_buf, sizeof(usec_buf), "%.5f",
+						now - (gdouble) sec);
+		rspamd_snprintf(timebuf + r, len - r,
+						"%s", usec_buf + 1);
+	}
+}
+
+gsize rspamd_log_fill_iov(struct iovec *iov,
+						  double ts,
+						  const gchar *module,
+						  const gchar *id,
+						  const gchar *function,
+						  gint level_flags,
+						  const gchar *message,
+						  gsize mlen,
+						  rspamd_logger_t *logger)
+{
+	bool log_color = (logger->flags & RSPAMD_LOG_FLAG_COLOR);
+	bool log_severity = (logger->flags & RSPAMD_LOG_FLAG_SEVERITY);
+	bool log_rspamadm = (logger->flags & RSPAMD_LOG_FLAG_RSPAMADM);
+	bool log_systemd = (logger->flags & RSPAMD_LOG_FLAG_SYSTEMD);
+
+	gint r;
+
+	if (iov == NULL) {
+		if (log_rspamadm) {
+			if (logger->log_level == G_LOG_LEVEL_DEBUG) {
+				return 4;
+			}
+			else {
+				return 3; /* No time component */
+			}
+		}
+		else if (log_systemd) {
+			return 3;
+		}
+		else {
+			if (log_color) {
+				return 5;
+			}
+			else {
+				return 4;
+			}
+		}
+	}
+	else {
+		static gchar timebuf[64], modulebuf[64];
+		static gchar tmpbuf[256];
+
+		if (!log_systemd) {
+			log_time(ts, logger, timebuf, sizeof(timebuf));
+		}
+
+		if (!log_rspamadm) {
+			if (!log_systemd) {
+				if (log_color) {
+					if (level_flags & (G_LOG_LEVEL_INFO | G_LOG_LEVEL_MESSAGE)) {
+						/* White */
+						r = rspamd_snprintf(tmpbuf, sizeof(tmpbuf), "\033[0;37m");
+					}
+					else if (level_flags & G_LOG_LEVEL_WARNING) {
+						/* Magenta */
+						r = rspamd_snprintf(tmpbuf, sizeof(tmpbuf), "\033[0;32m");
+					}
+					else if (level_flags & G_LOG_LEVEL_CRITICAL) {
+						/* Red */
+						r = rspamd_snprintf(tmpbuf, sizeof(tmpbuf), "\033[1;31m");
+					}
+					else {
+						r = 0;
+					}
+				}
+				else {
+					r = 0;
+				}
+
+				if (log_severity) {
+					r += rspamd_snprintf(tmpbuf + r,
+										 sizeof(tmpbuf) - r,
+										 "%s [%s] #%P(%s) ",
+										 timebuf,
+										 rspamd_get_log_severity_string(level_flags),
+										 logger->pid,
+										 logger->process_type);
+				}
+				else {
+					r += rspamd_snprintf(tmpbuf + r,
+										 sizeof(tmpbuf) - r,
+										 "%s #%P(%s) ",
+										 timebuf,
+										 logger->pid,
+										 logger->process_type);
+				}
+			}
+			else {
+				r = 0;
+				r += rspamd_snprintf(tmpbuf + r,
+									 sizeof(tmpbuf) - r,
+									 "(%s) ",
+									 logger->process_type);
+			}
+
+			int mremain, mr;
+			char *m;
+
+			modulebuf[0] = '\0';
+			mremain = sizeof(modulebuf);
+			m = modulebuf;
+
+			if (id != NULL) {
+				guint slen = strlen(id);
+				slen = MIN(RSPAMD_LOG_ID_LEN, slen);
+				mr = rspamd_snprintf(m, mremain, "<%*.s>; ", slen,
+									 id);
+				m += mr;
+				mremain -= mr;
+			}
+			if (module != NULL) {
+				mr = rspamd_snprintf(m, mremain, "%s; ", module);
+				m += mr;
+				mremain -= mr;
+			}
+			if (function != NULL) {
+				mr = rspamd_snprintf(m, mremain, "%s: ", function);
+				m += mr;
+				mremain -= mr;
+			}
+			else {
+				mr = rspamd_snprintf(m, mremain, ": ");
+				m += mr;
+				mremain -= mr;
+			}
+
+			/* Ensure that we have a space at the end */
+			if (m > modulebuf && *(m - 1) != ' ') {
+				*(m - 1) = ' ';
+			}
+
+			/* Construct IOV for log line */
+			iov[0].iov_base = tmpbuf;
+			iov[0].iov_len = r;
+			iov[1].iov_base = modulebuf;
+			iov[1].iov_len = m - modulebuf;
+			iov[2].iov_base = (void *) message;
+			iov[2].iov_len = mlen;
+			iov[3].iov_base = (void *) &lf_chr;
+			iov[3].iov_len = 1;
+
+			if (log_color) {
+				iov[4].iov_base = "\033[0m";
+				iov[4].iov_len = sizeof("\033[0m") - 1;
+
+				return 5;
+			}
+
+			return 4;
+		}
+		else {
+			/* Rspamadm case */
+			int niov = 0;
+
+			if (logger->log_level == G_LOG_LEVEL_DEBUG) {
+				iov[niov].iov_base = (void *) timebuf;
+				iov[niov++].iov_len = strlen(timebuf);
+				iov[niov].iov_base = (void *) " ";
+				iov[niov++].iov_len = 1;
+			}
+
+			iov[niov].iov_base = (void *) message;
+			iov[niov++].iov_len = mlen;
+			iov[niov].iov_base = (void *) &lf_chr;
+			iov[niov++].iov_len = 1;
+
+			return niov;
+		}
+	}
 }
\ No newline at end of file
diff --git a/src/libserver/logger/logger_console.c b/src/libserver/logger/logger_console.c
index b5250f657..691566ab9 100644
--- a/src/libserver/logger/logger_console.c
+++ b/src/libserver/logger/logger_console.c
@@ -1,11 +1,11 @@
-/*-
- * Copyright 2020 Vsevolod Stakhov
+/*
+ * Copyright 2023 Vsevolod Stakhov
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- *   http://www.apache.org/licenses/LICENSE-2.0
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -153,13 +153,8 @@ bool rspamd_log_console_log(const gchar *module, const gchar *id,
 							gpointer arg)
 {
 	struct rspamd_console_logger_priv *priv = (struct rspamd_console_logger_priv *) arg;
-	static gchar timebuf[64], modulebuf[64];
-	gchar tmpbuf[256];
-	gchar *m;
-	struct iovec iov[6];
-	gulong r = 0, mr = 0;
-	size_t mremain;
-	gint fd, niov = 0;
+	gint fd, r;
+	double now;
 
 	if (level_flags & G_LOG_LEVEL_CRITICAL) {
 		fd = priv->crit_fd;
@@ -184,119 +179,13 @@ bool rspamd_log_console_log(const gchar *module, const gchar *id,
 	rspamd_file_lock(fd, FALSE);
 #endif
 
-	if (!(rspamd_log->flags & RSPAMD_LOG_FLAG_SYSTEMD)) {
-		log_time(rspamd_get_calendar_ticks(),
-				 rspamd_log, timebuf, sizeof(timebuf));
-	}
-
-	if (priv->log_color) {
-		if (level_flags & (G_LOG_LEVEL_INFO | G_LOG_LEVEL_MESSAGE)) {
-			/* White */
-			r = rspamd_snprintf(tmpbuf, sizeof(tmpbuf), "\033[0;37m");
-		}
-		else if (level_flags & G_LOG_LEVEL_WARNING) {
-			/* Magenta */
-			r = rspamd_snprintf(tmpbuf, sizeof(tmpbuf), "\033[0;32m");
-		}
-		else if (level_flags & G_LOG_LEVEL_CRITICAL) {
-			/* Red */
-			r = rspamd_snprintf(tmpbuf, sizeof(tmpbuf), "\033[1;31m");
-		}
-	}
-	else {
-		r = 0;
-	}
-
-	if (priv->log_rspamadm) {
-		if (rspamd_log->log_level == G_LOG_LEVEL_DEBUG) {
-			log_time(rspamd_get_calendar_ticks(),
-					 rspamd_log, timebuf, sizeof(timebuf));
-			iov[niov].iov_base = (void *) timebuf;
-			iov[niov++].iov_len = strlen(timebuf);
-			iov[niov].iov_base = (void *) " ";
-			iov[niov++].iov_len = 1;
-		}
-
-		iov[niov].iov_base = (void *) message;
-		iov[niov++].iov_len = mlen;
-		iov[niov].iov_base = (void *) &lf_chr;
-		iov[niov++].iov_len = 1;
-	}
-	else {
-		if (!(rspamd_log->flags & RSPAMD_LOG_FLAG_SYSTEMD)) {
-			if (priv->log_severity) {
-				r += rspamd_snprintf(tmpbuf + r,
-									 sizeof(tmpbuf) - r,
-									 "%s [%s] #%P(%s) ",
-									 timebuf,
-									 rspamd_get_log_severity_string(level_flags),
-									 rspamd_log->pid,
-									 rspamd_log->process_type);
-			}
-			else {
-				r += rspamd_snprintf(tmpbuf + r,
-									 sizeof(tmpbuf) - r,
-									 "%s #%P(%s) ",
-									 timebuf,
-									 rspamd_log->pid,
-									 rspamd_log->process_type);
-			}
-		}
-		else {
-			r += rspamd_snprintf(tmpbuf + r,
-								 sizeof(tmpbuf) - r,
-								 "#%P(%s) ",
-								 rspamd_log->pid,
-								 rspamd_log->process_type);
-		}
-
-		modulebuf[0] = '\0';
-		mremain = sizeof(modulebuf);
-		m = modulebuf;
-
-		if (id != NULL) {
-			guint slen = strlen(id);
-			slen = MIN(RSPAMD_LOG_ID_LEN, slen);
-			mr = rspamd_snprintf(m, mremain, "<%*.s>; ", slen,
-								 id);
-			m += mr;
-			mremain -= mr;
-		}
-		if (module != NULL) {
-			mr = rspamd_snprintf(m, mremain, "%s; ", module);
-			m += mr;
-			mremain -= mr;
-		}
-		if (function != NULL) {
-			mr = rspamd_snprintf(m, mremain, "%s: ", function);
-			m += mr;
-			mremain -= mr;
-		}
-		else {
-			mr = rspamd_snprintf(m, mremain, ": ");
-			m += mr;
-			mremain -= mr;
-		}
-
-		/* Ensure that we have a space at the end */
-		if (m > modulebuf && *(m - 1) != ' ') {
-			*(m - 1) = ' ';
-		}
-
-		iov[niov].iov_base = tmpbuf;
-		iov[niov++].iov_len = r;
-		iov[niov].iov_base = modulebuf;
-		iov[niov++].iov_len = m - modulebuf;
-		iov[niov].iov_base = (void *) message;
-		iov[niov++].iov_len = mlen;
-		iov[niov].iov_base = (void *) &lf_chr;
-		iov[niov++].iov_len = 1;
-	}
-
-	if (priv->log_color) {
-		iov[niov].iov_base = "\033[0m";
-		iov[niov++].iov_len = sizeof("\033[0m") - 1;
-	}
+	now = rspamd_get_calendar_ticks();
+	gsize niov = rspamd_log_fill_iov(NULL, now, module, id,
+									 function, level_flags, message,
+									 mlen, rspamd_log);
+	struct iovec *iov = g_alloca(sizeof(struct iovec) * niov);
+	rspamd_log_fill_iov(iov, now, module, id, function, level_flags, message,
+						mlen, rspamd_log);
 
 again:
 	r = writev(fd, iov, niov);
diff --git a/src/libserver/logger/logger_file.c b/src/libserver/logger/logger_file.c
index 91ae1956c..490cf0b65 100644
--- a/src/libserver/logger/logger_file.c
+++ b/src/libserver/logger/logger_file.c
@@ -1,11 +1,11 @@
-/*-
- * Copyright 2020 Vsevolod Stakhov
+/*
+ * Copyright 2023 Vsevolod Stakhov
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- *   http://www.apache.org/licenses/LICENSE-2.0
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -24,8 +24,6 @@
 
 #define FILE_LOG_QUARK g_quark_from_static_string("file_logger")
 
-static const gchar lf_chr = '\n';
-
 struct rspamd_file_logger_priv {
 	gint fd;
 	struct {
@@ -57,28 +55,6 @@ rspamd_log_calculate_cksum(const gchar *message, size_t mlen)
 	return rspamd_cryptobox_fast_hash(message, mlen, rspamd_hash_seed());
 }
 
-static inline void
-log_time(gdouble now, rspamd_logger_t *rspamd_log, gchar *timebuf,
-		 size_t len)
-{
-	time_t sec = (time_t) now;
-	gsize r;
-	struct tm tms;
-
-	rspamd_localtime(sec, &tms);
-	r = strftime(timebuf, len, "%F %H:%M:%S", &tms);
-
-	if (rspamd_log->flags & RSPAMD_LOG_FLAG_USEC) {
-		gchar usec_buf[16];
-
-		rspamd_snprintf(usec_buf, sizeof(usec_buf), "%.5f",
-						now - (gdouble) sec);
-		rspamd_snprintf(timebuf + r, len - r,
-						"%s", usec_buf + 1);
-	}
-}
-
-
 /*
  * Write a line to log file (unbuffered)
  */
@@ -399,15 +375,8 @@ bool rspamd_log_file_log(const gchar *module, const gchar *id,
 						 gpointer arg)
 {
 	struct rspamd_file_logger_priv *priv = (struct rspamd_file_logger_priv *) arg;
-	static gchar timebuf[64], modulebuf[64];
-	gchar tmpbuf[256];
-	gchar *m;
 	gdouble now;
-	struct iovec iov[6];
-	gulong r = 0, mr = 0;
 	guint64 cksum;
-	size_t mremain;
-	const gchar *cptype = NULL;
 	gboolean got_time = FALSE;
 
 
@@ -496,84 +465,13 @@ bool rspamd_log_file_log(const gchar *module, const gchar *id,
 		now = rspamd_get_calendar_ticks();
 	}
 
-	/* Format time */
-	if (!(rspamd_log->flags & RSPAMD_LOG_FLAG_SYSTEMD)) {
-		log_time(now, rspamd_log, timebuf, sizeof(timebuf));
-	}
-
-	cptype = rspamd_log->process_type;
-	r = 0;
-
-	if (!(rspamd_log->flags & RSPAMD_LOG_FLAG_SYSTEMD)) {
-		if (priv->log_severity) {
-			r += rspamd_snprintf(tmpbuf + r,
-								 sizeof(tmpbuf) - r,
-								 "%s [%s] #%P(%s) ",
-								 timebuf,
-								 rspamd_get_log_severity_string(level_flags),
-								 rspamd_log->pid,
-								 cptype);
-		}
-		else {
-			r += rspamd_snprintf(tmpbuf + r,
-								 sizeof(tmpbuf) - r,
-								 "%s #%P(%s) ",
-								 timebuf,
-								 rspamd_log->pid,
-								 cptype);
-		}
-	}
-	else {
-		r += rspamd_snprintf(tmpbuf + r,
-							 sizeof(tmpbuf) - r,
-							 "(%s) ",
-							 cptype);
-	}
-
-	modulebuf[0] = '\0';
-	mremain = sizeof(modulebuf);
-	m = modulebuf;
-
-	if (id != NULL) {
-		guint slen = strlen(id);
-		slen = MIN(RSPAMD_LOG_ID_LEN, slen);
-		mr = rspamd_snprintf(m, mremain, "<%*.s>; ", slen,
-							 id);
-		m += mr;
-		mremain -= mr;
-	}
-	if (module != NULL) {
-		mr = rspamd_snprintf(m, mremain, "%s; ", module);
-		m += mr;
-		mremain -= mr;
-	}
-	if (function != NULL) {
-		mr = rspamd_snprintf(m, mremain, "%s: ", function);
-		m += mr;
-		mremain -= mr;
-	}
-	else {
-		mr = rspamd_snprintf(m, mremain, ": ");
-		m += mr;
-		mremain -= mr;
-	}
-
-	/* Ensure that we have a space at the end */
-	if (m > modulebuf && *(m - 1) != ' ') {
-		*(m - 1) = ' ';
-	}
+	gsize niov = rspamd_log_fill_iov(NULL, now, module, id, function, level_flags, message,
+									 mlen, rspamd_log);
+	struct iovec *iov = g_alloca(sizeof(struct iovec) * niov);
+	rspamd_log_fill_iov(iov, now, module, id, function, level_flags, message,
+						mlen, rspamd_log);
 
-	/* Construct IOV for log line */
-	iov[0].iov_base = tmpbuf;
-	iov[0].iov_len = r;
-	iov[1].iov_base = modulebuf;
-	iov[1].iov_len = m - modulebuf;
-	iov[2].iov_base = (void *) message;
-	iov[2].iov_len = mlen;
-	iov[3].iov_base = (void *) &lf_chr;
-	iov[3].iov_len = 1;
-
-	return file_log_helper(rspamd_log, priv, iov, 4, level_flags);
+	return file_log_helper(rspamd_log, priv, iov, niov, level_flags);
 }
 
 void *
diff --git a/src/libserver/logger/logger_private.h b/src/libserver/logger/logger_private.h
index a5ce1cdc3..138f8df91 100644
--- a/src/libserver/logger/logger_private.h
+++ b/src/libserver/logger/logger_private.h
@@ -1,11 +1,11 @@
-/*-
- * Copyright 2020 Vsevolod Stakhov
+/*
+ * Copyright 2023 Vsevolod Stakhov
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- *   http://www.apache.org/licenses/LICENSE-2.0
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -102,6 +102,28 @@ bool rspamd_log_file_log(const gchar *module, const gchar *id,
 						 gpointer arg);
 bool rspamd_log_file_on_fork(rspamd_logger_t *logger, struct rspamd_config *cfg,
 							 gpointer arg, GError **err);
+
+/**
+ * Fills IOV of logger (usable for file/console logging)
+ * Warning: this function is NOT reentrant, do not call it twice from a single moment of execution
+ * @param iov if NULL just returns the number of elements required in IOV array
+ * @param module
+ * @param id
+ * @param function
+ * @param level_flags
+ * @param message
+ * @param mlen
+ * @param rspamd_log
+ * @return number of iov elements being filled
+ */
+gsize rspamd_log_fill_iov(struct iovec *iov,
+						  double ts,
+						  const gchar *module, const gchar *id,
+						  const gchar *function,
+						  gint level_flags,
+						  const gchar *message,
+						  gsize mlen,
+						  rspamd_logger_t *rspamd_log);
 /**
  * Escape log line by replacing unprintable characters to hex escapes like \xNN
  * @param src


More information about the Commits mailing list