commit 655168cabde97c037a9a5ee53567ebbc77b6a83c
parent c1aa3a5588a7df832adf47be570e86d1a05ac6dd
Author: Jacob R. Edwards <jacob@jacobedwards.org>
Date: Sun, 1 Oct 2023 14:15:11 -0700
Update logging system
Use syslog(3) as a backend to all logging operations, but keep the
same interface as before.
The log command now does nothing, and may either be added back in
a different way or removed entirely in the future.
Diffstat:
8 files changed, 89 insertions(+), 67 deletions(-)
diff --git a/aps/aps.c b/aps/aps.c
@@ -43,8 +43,8 @@
struct aps *
aps_open(char *path, char **player)
{
- struct aps *aps;
int i;
+ struct aps *aps;
aps = calloc(1, sizeof(*aps));
if (aps == NULL)
diff --git a/aps/aps.h b/aps/aps.h
@@ -10,7 +10,7 @@ struct client {
struct aps {
int close;
- int loglevel;
+ int logmask;
int nfds;
int timeout;
struct apcon *con;
diff --git a/aps/command.c b/aps/command.c
@@ -32,7 +32,6 @@
#include "bug.h"
#include "command.h"
#include "find.h"
-#include "log.h"
#include "queue.h"
#include "util.h"
@@ -229,18 +228,7 @@ com_status(struct aps *aps, int fd, int argc, char **argv)
char *
com_log(struct aps *aps, int fd, int argc, char **argv)
{
- int level, mask, flip, i;
-
- level = 0;
- flip = (argc && strcmp(argv[0], "!") == 0);
- for (i = flip; i < argc; ++i) {
- if ((mask = strlevel(argv[i])) < 0)
- return "invalid log level";
- level |= mask;
- }
-
- aps->loglevel = (flip ? ~level : level);
- return NULL;
+ return "Command not currently implemented";
}
char *
diff --git a/aps/command.h b/aps/command.h
@@ -4,20 +4,20 @@ struct command {
};
char *com_add(struct aps *, int, int, char **);
-char *com_remove(struct aps *, int, int, char **);
+char *com_close(struct aps *, int, int, char **);
+char *com_commands(struct aps *, int, int, char **);
char *com_list(struct aps *, int, int, char **);
-char *com_seek(struct aps *, int, int, char **);
-char *com_play(struct aps *, int, int, char **);
-char *com_pause(struct aps *, int, int, char **);
-char *com_stop(struct aps *, int, int, char **);
-char *com_toggle(struct aps *, int, int, char **);
+char *com_log(struct aps *, int, int, char **);
char *com_name(struct aps *, int, int, char **);
char *com_next(struct aps *, int, int, char **);
+char *com_pause(struct aps *, int, int, char **);
+char *com_play(struct aps *, int, int, char **);
+char *com_player(struct aps *, int, int, char **);
char *com_previous(struct aps *, int, int, char **);
+char *com_remove(struct aps *, int, int, char **);
+char *com_seek(struct aps *, int, int, char **);
char *com_status(struct aps *, int, int, char **);
-char *com_log(struct aps *, int, int, char **);
-char *com_player(struct aps *, int, int, char **);
-char *com_truncate(struct aps *, int, int, char **);
+char *com_stop(struct aps *, int, int, char **);
char *com_terminate(struct aps *, int, int, char **);
-char *com_commands(struct aps *, int, int, char **);
-char *com_close(struct aps *, int, int, char **);
+char *com_toggle(struct aps *, int, int, char **);
+char *com_truncate(struct aps *, int, int, char **);
diff --git a/aps/log.c b/aps/log.c
@@ -17,8 +17,18 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+/* Taken from OpenBSD /usr/include/syslog.h */
+#ifndef LOG_MASK
+#define LOG_MASK(pri) (1 << (pri)) /* mask for one priority */
+#endif
+
+#ifndef LOG_UPTO
+#define LOG_UPTO(pri) ((1 << ((pri)+1)) - 1) /* all priorities through pri */
+#endif
+
#include <sys/socket.h>
+#include <errno.h>
#include <limits.h>
#include <poll.h>
#include <stdarg.h>
@@ -39,11 +49,12 @@ static struct {
{ "info", INFO },
{ "warn", WARN },
{ "error", ERROR },
- { "fatal", FATAL }
+ { "fatal", FATAL },
+ { "none", 0 }
};
int
-strlevel(char *s)
+logstrlevel(char *s)
{
int i;
@@ -54,7 +65,7 @@ strlevel(char *s)
}
char *
-levelstr(int level)
+loglevelstr(int level)
{
int i;
@@ -64,34 +75,59 @@ levelstr(int level)
return NULL;
}
+int
+logmask(int level)
+{
+ return LOG_UPTO(level);
+}
+
+void
+newbuflen(int size, int *len, int newlen, char *msg)
+{
+ if (newlen < 0)
+ bug(msg);
+ if (*len + newlen >= size)
+ bug(msg);
+ *len += newlen;
+}
+
void
aps_log(struct aps *aps, int fd, int level, char *subject, char *fmt, ...)
{
char *p;
- char tb[20];
- time_t now;
- va_list ap;
+ char buf[256];
+ int len;
+ va_list ap, apc;
- if (fmt == NULL || (aps && !(level & aps->loglevel)))
+ if (fmt == NULL || (aps && !(LOG_MASK(level) & aps->logmask)))
return;
- now = time(NULL);
- strftime(tb, sizeof(tb), "%F %T", localtime(&now));
- fprintf(stderr, "aps at %s ", tb);
+ len = 0;
- if (fd)
- fprintf(stderr, "client %d ", fd);
+ if (fd) {
+ newbuflen(sizeof(buf), &len, snprintf(buf, sizeof(buf),
+ "client %d ", fd), "aps_log client");
+ }
- if (subject)
- fprintf(stderr, "%s ", subject);
+ if (subject) {
+ assert(strchr(subject, '%') == NULL, "subject had % in it");
+ newbuflen(sizeof(buf), &len, snprintf(buf + len, sizeof(buf) - len,
+ "%.16s ", subject), "aps_log subject");
+ }
- if (!(p = levelstr(level)))
+ if (!(p = loglevelstr(level)))
bug("invalid log level");
- fprintf(stderr, "%s", p);
- fprintf(stderr, ": ");
+ newbuflen(sizeof(buf), &len, snprintf(buf + len, sizeof(buf) - len,
+ "%s: %s", p, fmt), "aps_log level and user format");
+
va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
+ va_copy(apc, ap);
+ vsyslog(level, buf, ap);
va_end(ap);
- fputs("\n", stderr);
+
+ /* LOG_PERROR is non-standard */
+ buf[sizeof(buf) > len ? len : (len - 1)] = '\n';
+ vfprintf(stderr, buf, apc);
+ va_end(apc);
}
diff --git a/aps/log.h b/aps/log.h
@@ -1,9 +1,11 @@
+#include <syslog.h>
+
enum loglevel {
- DEBUG = 1 << 0,
- INFO = DEBUG << 1,
- WARN = INFO << 1,
- ERROR = WARN << 1,
- FATAL = ERROR << 1
+ DEBUG = LOG_DEBUG,
+ INFO = LOG_INFO,
+ WARN = LOG_WARNING,
+ ERROR = LOG_ERR,
+ FATAL = LOG_CRIT
};
enum logsubject {
@@ -11,17 +13,17 @@ enum logsubject {
LogCommand,
LogConn,
LogPlayer,
- LogQueue,
- LogLast,
+ LogQueue
};
-static char *logsubjects[LogLast] = {
+static char *logsubjects[] = {
[LogCommand] = "command",
[LogConn] = "connection",
[LogPlayer] = "player",
[LogQueue] = "queue"
};
-int strlevel(char *);
-char *levelstr(int);
+int logstrlevel(char *);
+char *loglevelstr(int);
+int logmask(int);
void aps_log(struct aps *, int, int, char *, char *, ...);
diff --git a/aps/main.c b/aps/main.c
@@ -133,10 +133,14 @@ main(int argc, char *argv[])
die("pledge");
#endif
+ openlog("aps", LOG_PID, LOG_DAEMON);
+
aps = aps_open(name, player);
if (aps == NULL)
die("unable to setup server");
+ aps->logmask = logmask(ERROR);
+
aps->coms = commands;
aps->ncoms = LEN(commands);
@@ -161,5 +165,7 @@ main(int argc, char *argv[])
error = aps->close;
aps_close(aps);
+ closelog();
+
return error;
}
diff --git a/man/aps.1 b/man/aps.1
@@ -66,18 +66,8 @@ List items in the queue. If
.Ar pattern
is present, only list items which match the pattern (see
.Sx Patterns ) .
-.It Cm log Oo Ar "" "!" Oc Oo Ar level ... Oc
-Only log entries of the given log levels, or only log entries that
-are not the given log levels if the negation operator is provided
-.Sq ( "!" ) .
-This command is likely to change significantly in the future.
-.It Cm name
-Returns the name of the current item in the queue. Equivalent to
-.Do
-.Sx list
-0
-.Dc .
-May be removed in the future.
+.It Cm log
+Currently does nothing. May be removed in the future.
.It Cm next
Play the next item in the queue.
.It Cm pause