changeset 1047:d7764d6cdab8

irccd: add support for formatted logs
author David Demelier <markand@malikania.fr>
date Sun, 20 Jun 2021 09:53:12 +0200
parents 8fc354b3e198
children 4b53eb6fff73
files irccd/conf.y irccd/lex.l lib/irccd/log.c lib/irccd/log.h man/irccd.conf.5
diffstat 5 files changed, 85 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/irccd/conf.y	Sun Jun 20 09:13:56 2021 +0200
+++ b/irccd/conf.y	Sun Jun 20 09:53:12 2021 +0200
@@ -160,6 +160,7 @@
 %token T_IDENT
 %token T_LOCATION
 %token T_LOGS
+%token T_LOG_TEMPLATE
 %token T_OPTIONS
 %token T_ORIGINS
 %token T_PASSWORD
@@ -180,7 +181,7 @@
 %token T_WITH
 
 %type <ival> log_verbosity
-%type <sval> plugin_location
+%type <sval> plugin_location log_template
 %type <plugin> plugin_params plugin_params_opt
 %type <rule> rule_params rule_params_opt
 %type <server> server_params
@@ -265,28 +266,45 @@
 	}
 	;
 
+log_template
+	: T_LOG_TEMPLATE T_STRING
+	{
+		$$ = $2;
+	}
+	|
+	{
+		$$ = NULL;
+	}
+	;
+
 logs
-	: T_LOGS log_verbosity
+	: T_LOGS log_verbosity log_template
 	{
 		irc_log_set_verbose($2);
+		irc_log_set_template($3);
+		free($3);
 	}
-	| T_LOGS log_verbosity T_TO T_LOG_TYPE
+	| T_LOGS log_verbosity log_template T_TO T_LOG_TYPE
 	{
 		irc_log_set_verbose($2);
+		irc_log_set_template($3);
 
-		if (strcmp($4, "console") == 0)
+		if (strcmp($5, "console") == 0)
 			irc_log_to_console();
-		else if (strcmp($4, "syslog") == 0)
+		else if (strcmp($5, "syslog") == 0)
 			irc_log_to_syslog();
 		else
 			errx(1, "missing log file path");
 
-		free($4);
+		free($3);
+		free($5);
 	}
-	| T_LOGS log_verbosity T_TO T_LOG_TYPE T_STRING
+	| T_LOGS log_verbosity log_template T_TO T_LOG_TYPE T_STRING
 	{
-		irc_log_to_file($4);
-		free($4);
+		irc_log_to_file($6);
+		irc_log_set_template($3);
+		free($3);
+		free($6);
 	}
 	;
 
--- a/irccd/lex.l	Sun Jun 20 09:13:56 2021 +0200
+++ b/irccd/lex.l	Sun Jun 20 09:53:12 2021 +0200
@@ -43,6 +43,7 @@
 hostname        hostname
 ident           ident
 location        location
+log_template    template
 log_type        console|syslog|file
 log_verbosity   quiet|verbose
 logs            logs
@@ -93,6 +94,7 @@
 {hostname}              return T_HOSTNAME;
 {ident}                 return T_IDENT;
 {location}              return T_LOCATION;
+{log_template}          return T_LOG_TEMPLATE;
 {logs}                  return T_LOGS;
 {options}               return T_OPTIONS;
 {origins}               return T_ORIGINS;
--- a/lib/irccd/log.c	Sun Jun 20 09:13:56 2021 +0200
+++ b/lib/irccd/log.c	Sun Jun 20 09:53:12 2021 +0200
@@ -24,6 +24,7 @@
 #include <syslog.h>
 
 #include "log.h"
+#include "subst.h"
 
 enum level {
 	LEVEL_INFO,
@@ -33,19 +34,18 @@
 
 static FILE *out, *err;
 static int verbosity;
+static char tmpl[512] = "#{message}";
 
 static void
-handler_files(enum level level, const char *fmt, va_list ap)
+handler_files(enum level level, const char *line)
 {
 	switch (level) {
 	case LEVEL_WARN:
-		vfprintf(err, fmt, ap);
-		putc('\n', err);
+		fprintf(err, "%s\n", line);
 		fflush(err);
 		break;
 	default:
-		vfprintf(out, fmt, ap);
-		putc('\n', out);
+		fprintf(out, "%s\n", line);
 		fflush(out);
 		break;
 	}
@@ -57,10 +57,12 @@
 	/* Out and err are the same. */
 	if (out)
 		fclose(out);
+
+	out = err = NULL;
 }
 
 static void
-handler_syslog(enum level level, const char *fmt, va_list ap)
+handler_syslog(enum level level, const char *line)
 {
 	static const int table[] = {
 		[LEVEL_INFO] = LOG_INFO,
@@ -68,8 +70,7 @@
 		[LEVEL_DEBUG] = LOG_DEBUG
 	};
 
-	/* TODO: add compatibility shim for vsyslog. */
-	vsyslog(table[level], fmt, ap);
+	syslog(table[level], "%s", line);
 }
 
 static void
@@ -78,9 +79,32 @@
 	closelog();
 }
 
-static void (*handler)(enum level, const char *, va_list);
+static void (*handler)(enum level, const char *);
 static void (*finalizer)(void);
 
+static void
+wrap(enum level level, const char *fmt, va_list ap)
+{
+	char formatted[1024] = {0}, line[1024] = {0};
+	struct irc_subst_keyword kw[] = {
+		{ "message", line }
+	};
+	struct irc_subst subst = {
+		.time = time(NULL),
+		.flags = IRC_SUBST_DATE |
+		         IRC_SUBST_KEYWORDS |
+		         IRC_SUBST_ENV |
+		         IRC_SUBST_SHELL |
+		         IRC_SUBST_SHELL_ATTRS,
+		.keywords = kw,
+		.keywordsz = 1
+	};
+
+	vsnprintf(line, sizeof (line), fmt, ap);
+	irc_subst(formatted, sizeof (formatted), tmpl, &subst);
+	handler(level, formatted);
+}
+
 void
 irc_log_to_syslog(void)
 {
@@ -132,6 +156,12 @@
 }
 
 void
+irc_log_set_template(const char *fmt)
+{
+	strlcpy(tmpl, fmt, sizeof (tmpl));
+}
+
+void
 irc_log_info(const char *fmt, ...)
 {
 	assert(fmt);
@@ -141,7 +171,7 @@
 	va_start(ap, fmt);
 
 	if (verbosity && handler)
-		handler(LEVEL_INFO, fmt, ap);
+		wrap(LEVEL_INFO, fmt, ap);
 
 	va_end(ap);
 }
@@ -156,7 +186,7 @@
 	va_start(ap, fmt);
 
 	if (handler)
-		handler(LEVEL_WARN, fmt, ap);
+		wrap(LEVEL_WARN, fmt, ap);
 
 	va_end(ap);
 }
@@ -172,7 +202,7 @@
 	va_start(ap, fmt);
 
 	if (handler)
-		handler(LEVEL_DEBUG, fmt, ap);
+		wrap(LEVEL_DEBUG, fmt, ap);
 
 	va_end(ap);
 #else
--- a/lib/irccd/log.h	Sun Jun 20 09:13:56 2021 +0200
+++ b/lib/irccd/log.h	Sun Jun 20 09:53:12 2021 +0200
@@ -39,6 +39,9 @@
 irc_log_set_verbose(int);
 
 void
+irc_log_set_template(const char *);
+
+void
 irc_log_info(const char *, ...);
 
 void
--- a/man/irccd.conf.5	Sun Jun 20 09:13:56 2021 +0200
+++ b/man/irccd.conf.5	Sun Jun 20 09:53:12 2021 +0200
@@ -89,13 +89,13 @@
 .Ss logs
 This section can let you configure how irccd should log the messages.
 .Bl -tag
-.It Ar logs [verbose|quiet] to console
+.It Ar logs [verbose|quiet] [template string] to console
 Use the standard output and error to log content. This the default.
-.It Ar logs [verbose|quiet] to syslog
+.It Ar logs [verbose|quiet] [template string] to syslog
 Use the
 .Xr syslog 3
 daemon to log information.
-.It Ar logs [verbose|quiet] to file path
+.It Ar logs [verbose|quiet] [template string] to file path
 Use
 .Pa path
 to logs every entries.
@@ -106,6 +106,14 @@
 argument controls either if verbose logging should be enabled or not. Only
 informative messages are affected by this setting. Warnings and debugging
 messages are stored independently from this setting.
+.Pp
+The option
+.Ar template
+can be used to format the output log entries using
+.Ar string
+as template. See
+.Xr irccd-templates 7
+for more details.
 .\" transport
 .Ss transport
 Enable transport to interract with the