commit 4c47068a62d6f958a868e5ecf5fe8fbe188c26af
parent 640b43ae702e7057b7d5a69ea78a1fd4b2aeeb62
Author: Jacob R. Edwards <jacob@jacobedwards.org>
Date: Sat, 25 Mar 2023 10:07:41 -0700
Update server logging functions
Separate log levels and subjects, allowing for much more flexibility
and replace the aps_log() function with aps_logfmt().
The log entry format is also changed, and while it takes a lot more
printf(3) statements, it's more readable.
Diffstat:
6 files changed, 90 insertions(+), 53 deletions(-)
diff --git a/aps/aps.c b/aps/aps.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2021, 2022 Jacob R. Edwards
+ * Copyright 2021-2023 Jacob R. Edwards
*
* ap -- audio player
*
@@ -95,7 +95,7 @@ aps_close(struct aps *aps)
int
aps_drop(struct aps *aps, int fd)
{
- aps_log(aps, INFO, fd, "dropping client");
+ aps_log(aps, fd, INFO, logsubjects[LogConn], "dropping client");
--aps->nfds;
aps->pfds[fd].fd = -1;
buffree(aps->clients[fd].response);
@@ -128,9 +128,9 @@ aps_accept(struct aps *aps)
while ((s = accept4(aps->con->sock, NULL, NULL, 0)) >= 0) {
if (aps_addfd(aps, s))
- aps_log(aps, ERROR, s, "unable to add client");
+ aps_log(aps, s, ERROR, logsubjects[LogConn], "unable to add client");
else
- aps_log(aps, INFO, s, "client added");
+ aps_log(aps, s, INFO, logsubjects[LogConn], "client added");
}
return errno != EWOULDBLOCK;
@@ -242,7 +242,7 @@ aps_command(struct aps *aps, int fd)
if (buf == NULL)
return 0;
- aps_logfmt(aps, COMMAND, fd, "input '%s'", buf);
+ aps_log(aps, fd, DEBUG, logsubjects[LogCommand], "raw '%s'", buf);
argv = split(buf, NULL);
if (argv == NULL) {
@@ -273,7 +273,7 @@ void
aps_errordrop(struct aps *aps, int fd, char *why)
{
/* One could send(2) the error aswell. */
- aps_log(aps, ERROR, fd, why);
+ aps_log(aps, fd, ERROR, logsubjects[LogConn], why);
aps_drop(aps, fd);
}
@@ -313,6 +313,6 @@ aps_unname(struct aps *aps)
{
if (unlink(aps->con->path) == 0)
return 0;
- aps_logfmt(aps, WARN, 0, "%s: unable to remove socket", aps->con->path);
+ aps_log(aps, 0, WARN, NULL, "%s: unable to remove socket", aps->con->path);
return 1;
}
diff --git a/aps/buf.c b/aps/buf.c
@@ -1,3 +1,21 @@
+/* Copyright 2021-2023 Jacob R. Edwards
+ *
+ * ap -- audio player
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
#include <sys/socket.h>
#include <ctype.h>
@@ -47,6 +65,6 @@ aps_bufstatus(struct aps *aps, int fd, char *error)
bufappend(buf, "\n", 1);
aps->pfds[fd].events = POLLOUT;
- aps_logfmt(aps, COMMAND, fd, "error: %s", error);
+ aps_log(aps, fd, INFO, logsubjects[LogCommand], "error: %s", error);
return 0;
}
diff --git a/aps/log.c b/aps/log.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2021, 2022 Jacob R. Edwards
+ * Copyright 2021-2023 Jacob R. Edwards
*
* ap -- audio player
*
@@ -26,60 +26,67 @@
#include <string.h>
#include "aps.h"
+#include "bug.h"
#include "log.h"
#include "util.h"
static struct {
- char *str;
- int level;
-} binds[] = {
+ char *s;
+ int i;
+} levels[] = {
+ { "debug", DEBUG },
{ "info", INFO },
{ "warn", WARN },
{ "error", ERROR },
- { "fatal", FATAL },
- { "command", COMMAND },
- { "queue", QUEUE }
+ { "fatal", FATAL }
};
-char *
-levelstr(int level)
+int
+strlevel(char *s)
{
int i;
- for (i = 0; i < LEN(binds); ++i)
- if (level == binds[i].level)
- return binds[i].str;
- return NULL;
+ for (i = 0; i < LEN(levels); ++i)
+ if (strcmp(levels[i].s, s) == 0)
+ return levels[i].i;
+ return -1;
}
-int
-strlevel(char *str)
+char *
+levelstr(int level)
{
int i;
- for (i = 0; i < LEN(binds); ++i)
- if (strcmp(str, binds[i].str) == 0)
- return binds[i].level;
- return -1;
+ for (i = 0; i < LEN(levels); ++i)
+ if (levels[i].i == level)
+ return levels[i].s;
+ return NULL;
}
void
-aps_logfmt(struct aps *aps, int level, int fd, char *fmt, ...)
+aps_log(struct aps *aps, int fd, int level, char *subject, char *fmt, ...)
{
va_list ap;
+ char *p;
if (fmt == NULL || (aps && !(level & aps->loglevel)))
return;
- fprintf(stderr, "aps(%d) %s: ", fd, levelstr(level));
+ fprintf(stderr, "aps: ");
+
+ if (fd)
+ fprintf(stderr, "client %d ", fd);
+
+ if (subject)
+ fprintf(stderr, "%s ", subject);
+
+ if (!(p = levelstr(level)))
+ bug("invalid log level");
+ fprintf(stderr, "%s", p);
+
+ fprintf(stderr, ": ");
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
fputs("\n", stderr);
}
-
-void
-aps_log(struct aps *aps, int level, int fd, char *msg)
-{
- aps_logfmt(aps, level, fd, "%s", msg);
-}
diff --git a/aps/log.h b/aps/log.h
@@ -1,13 +1,25 @@
-enum {
- INFO = 1 << 0,
- WARN = 1 << 1,
- ERROR = 1 << 2,
- FATAL = 1 << 3,
- COMMAND = 1 << 4,
- QUEUE = 1 << 5
+enum loglevel {
+ DEBUG = 1 << 0,
+ INFO = DEBUG << 1,
+ WARN = INFO << 1,
+ ERROR = WARN << 1,
+ FATAL = ERROR << 1
+};
+
+enum logsubject {
+ LogGeneral,
+ LogCommand,
+ LogConn,
+ LogQueue,
+ LogLast,
+};
+
+static char *logsubjects[LogLast] = {
+ [LogCommand] = "command",
+ [LogConn] = "connection",
+ [LogQueue] = "queue"
};
-char *levelstr(int);
int strlevel(char *);
-void aps_logfmt(struct aps *, int, int, char *, ...);
-void aps_log(struct aps *, int, int, char *);
+char *levelstr(int);
+void aps_log(struct aps *, int, int, char *, char *, ...);
diff --git a/aps/main.c b/aps/main.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2021, 2022 Jacob R. Edwards
+ * Copyright 2021-2023 Jacob R. Edwards
*
* ap -- audio player
*
@@ -44,14 +44,14 @@ static struct aps *aps;
void
die(char *s)
{
- aps_logfmt(NULL, FATAL, 0, "%s: %s", s, errstr);
+ aps_log(NULL, 0, FATAL, NULL, "%s: %s", s, errstr);
exit(1);
}
void
sigclose(int sig)
{
- aps_log(aps, FATAL, 0, "close signal");
+ aps_log(aps, 0, FATAL, NULL, "close signal");
aps->close = 1;
}
diff --git a/aps/queue.c b/aps/queue.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2021, 2022 Jacob R. Edwards
+ * Copyright 2021-2023 Jacob R. Edwards
*
* ap -- audio player
*
@@ -30,7 +30,7 @@ void
queue_set(struct aps *aps, struct item *item)
{
aps->queue = item;
- aps_logfmt(aps, QUEUE, 0, "set '%s'", item ? item->path : "");
+ aps_log(aps, 0, INFO, logsubjects[LogQueue], "set '%s'", item ? item->path : "");
if (aps->player->state != OFF && aps->player->state != STOPPED) {
pstop(aps->player);
@@ -43,11 +43,11 @@ queue_add(struct aps *aps, struct item *at, char *s)
{
struct item *item;
- aps_logfmt(aps, QUEUE, 0, "add '%s'", s);
+ aps_log(aps, 0, INFO, logsubjects[LogQueue], "add '%s'", s);
item = item_new(s);
if (item == NULL) {
- aps_log(aps, ERROR, 0, "unable to create queue item");
+ aps_log(aps, 0, ERROR, logsubjects[LogQueue], "unable to create queue item");
return NULL;
}
@@ -66,7 +66,7 @@ queue_remove(struct aps *aps, struct item *item)
if (item == NULL)
return NULL;
- aps_logfmt(aps, QUEUE, 0, "remove '%s'", item->path);
+ aps_log(aps, 0, INFO, logsubjects[LogQueue], "remove '%s'", item->path);
next = item->next;
if (next == item)