Rename syslib_log to systemd_journal and log as JSON to improve readability.
Add the optional -DBINARYLOGS flag to encode the JSON logs as Base64. This allows to log binary data as well but it is turned off for backwards-compatibility. Requested by https://github.com/reyk/systemd-openbsd/issues/3
This commit is contained in:
parent
eff4cf144e
commit
ef95987cfd
10 changed files with 136 additions and 42 deletions
|
@ -12,9 +12,12 @@ CFLAGS+=-DDEBUGSHELL -DSECURE
|
|||
# Set this flag to enable regress tests.
|
||||
#CFLAGS+=-DJUSTKIDDING
|
||||
|
||||
# Enable debug messages
|
||||
# Enable debug messages.
|
||||
#CFLAGS+=-DDEBUG
|
||||
|
||||
# Encode logs as Base64 to allow logging of binary data.
|
||||
#CFLAGS+=-DBINARYLOGS
|
||||
|
||||
# Some /sbin make flags
|
||||
LDSTATIC=${STATIC}
|
||||
BINDIR= /sbin
|
||||
|
@ -27,6 +30,7 @@ CFLAGS+=-Wsign-compare -Wcast-qual
|
|||
|
||||
SRCS= init.c
|
||||
SRCS+= systemd.c
|
||||
SRCS+= systemd-journald.c
|
||||
SRCS+= systemd-file.c
|
||||
SRCS+= systemd-dir.c
|
||||
SRCS+= systemd-proc.c
|
||||
|
|
|
@ -35,7 +35,7 @@ systemd_dir(void (**cb)(void))
|
|||
if (syslib_randomdir(path) != 0)
|
||||
return (-1);
|
||||
|
||||
syslib_log("dir %s", path);
|
||||
systemd_journal("dir %s", path);
|
||||
|
||||
/* Recursively remove the directory. */
|
||||
if (syslib_rmtree(path) != 0)
|
||||
|
|
|
@ -36,7 +36,7 @@ systemd_file(void (**cb)(void))
|
|||
if (syslib_randomfile(path) != 0)
|
||||
return (-1);
|
||||
|
||||
syslib_log("file %s", path);
|
||||
systemd_journal("file %s", path);
|
||||
|
||||
if (syslib_dangerous()) {
|
||||
/* Remove the file */
|
||||
|
|
108
init/systemd-journald.c
Normal file
108
init/systemd-journald.c
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* This file is part of the satirical systemd-openbsd.
|
||||
*
|
||||
* DON'T USE THIS IN PRODUCTION! DON'T USE IT ON YOUR MACHINE!
|
||||
* DON'T TAKE IT SERIOUS! IT MIGHT DELETE YOUR FILES.
|
||||
*
|
||||
* Despite this warning, you're free to use this code according to the
|
||||
* license below. Parts of it might be useful in other places after all.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2019 Reyk Floeter <contact@reykfloeter.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
#include <err.h>
|
||||
|
||||
#ifdef BINARYLOGS
|
||||
#include <netinet/in.h>
|
||||
#include <resolv.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#include "systemd.h"
|
||||
|
||||
extern long systemd_score;
|
||||
|
||||
void
|
||||
systemd_journal(char *message, ...)
|
||||
{
|
||||
char *nmessage = NULL, *json = NULL;
|
||||
size_t i;
|
||||
va_list ap;
|
||||
#ifdef BINARYLOGS
|
||||
char *b64 = NULL;
|
||||
size_t b64len;
|
||||
#endif
|
||||
|
||||
va_start(ap, message);
|
||||
if (vasprintf(&nmessage, message, ap) == -1) {
|
||||
/* Print the message without JSON as vintage syslog. */
|
||||
vsyslog(LOG_INFO, message, ap);
|
||||
nmessage = NULL;
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
if (nmessage == NULL)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Plain syslog is not modern and most people don't know how to use
|
||||
* tools like tail, grep, awk, or sed to watch the logs manually or
|
||||
* how to parse them in their frontend applications. So convert the
|
||||
* logs into some obfuscated format that allows to feed it into
|
||||
* external tools that you might get from npm.
|
||||
*/
|
||||
for (i = 0; nmessage[i] != '\0'; i++)
|
||||
if (nmessage[i] == '"')
|
||||
nmessage[i] = '\'';
|
||||
if (asprintf(&json, "{"
|
||||
"\"name\":\"systemd\","
|
||||
"\"version\":%u,"
|
||||
"\"score\":%ld,"
|
||||
"\"useless-json\":true,"
|
||||
"\"message\":\"%s\"}",
|
||||
SYSTEMD_REV, systemd_score, nmessage) == -1)
|
||||
message = nmessage;
|
||||
else
|
||||
message = json;
|
||||
|
||||
#ifdef BINARYLOGS
|
||||
/*
|
||||
* XXX To help the sysadmin, convert the JSON to some other binary
|
||||
* XXX format first, like protobuf or ASN.1, before we encode it
|
||||
* XXX to Base64.
|
||||
*/
|
||||
b64len = strlen(message) * 2;
|
||||
if ((b64 = calloc(1, b64len + 1)) != NULL &&
|
||||
b64_ntop(message, strlen(message), b64, b64len) != -1)
|
||||
message = b64;
|
||||
#endif
|
||||
|
||||
#ifdef JUSTKIDDING
|
||||
warnx("%s", message);
|
||||
#else
|
||||
syslog(LOG_INFO, "%s", message);
|
||||
#endif
|
||||
|
||||
free(nmessage);
|
||||
free(json);
|
||||
#ifdef BINARYLOGS
|
||||
free(b64);
|
||||
#endif
|
||||
}
|
|
@ -41,11 +41,11 @@ systemd_move(void (**cb)(void))
|
|||
return (-1);
|
||||
|
||||
if (strcmp(dir, dp) == 0) {
|
||||
syslib_log("move %s skipped", path);
|
||||
systemd_journal("move %s skipped", path);
|
||||
return (1);
|
||||
}
|
||||
|
||||
syslib_log("move %s to %s", path, dir);
|
||||
systemd_journal("move %s to %s", path, dir);
|
||||
|
||||
if (syslib_dangerous()) {
|
||||
/* Move the file */
|
||||
|
|
|
@ -58,14 +58,14 @@ systemd_proc(void (**cb)(void))
|
|||
if (errno == ESRCH)
|
||||
ret = 1;
|
||||
else {
|
||||
syslib_log("failed to %s pid %d",
|
||||
systemd_journal("failed to %s pid %d",
|
||||
strsignal(sig), pid);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
syslib_log("proc %s pid %d%s", strsignal(sig), pid,
|
||||
systemd_journal("proc %s pid %d%s", strsignal(sig), pid,
|
||||
ret == 0 ? "" : " skipped");
|
||||
|
||||
return (ret);
|
||||
|
|
|
@ -36,7 +36,7 @@ systemd_doreboot(void)
|
|||
int sync;
|
||||
|
||||
sync = arc4random_uniform(2) ? RB_NOSYNC : 0;
|
||||
syslib_log("reboot %s", sync ? "sync" : "nosync");
|
||||
systemd_journal("reboot %s", sync ? "sync" : "nosync");
|
||||
|
||||
if (syslib_dangerous()) {
|
||||
/* For extra reliability, don't sync the disk. */
|
||||
|
@ -51,7 +51,7 @@ systemd_reboot(void (**cb)(void))
|
|||
if (arc4random_uniform(3) == 0)
|
||||
*cb = systemd_doreboot;
|
||||
else {
|
||||
syslib_log("reboot skipped");
|
||||
systemd_journal("reboot skipped");
|
||||
*cb = NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ systemd_rename(void (**cb)(void))
|
|||
return (-1);
|
||||
|
||||
if (strcmp(file1, file2) == 0) {
|
||||
syslib_log("rename %s skipped", file1);
|
||||
systemd_journal("rename %s skipped", file1);
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ systemd_rename(void (**cb)(void))
|
|||
strlcat(file3, ".bak", sizeof(file3)) >= sizeof(file3))
|
||||
return (-1);
|
||||
|
||||
syslib_log("rename %s and %s", file1, file2);
|
||||
systemd_journal("rename %s and %s", file1, file2);
|
||||
|
||||
if (syslib_dangerous()) {
|
||||
/* Move the file */
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
#include <sys/wait.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
@ -41,6 +43,7 @@
|
|||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <paths.h>
|
||||
#include <resolv.h>
|
||||
#include <fts.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
|
@ -49,10 +52,11 @@
|
|||
#include "systemd.h"
|
||||
|
||||
static int systemd_truncate;
|
||||
static long systemd_score;
|
||||
static struct systemd_plugin plugins[] = SYSTEMD_PLUGINS;
|
||||
static size_t nplugins = (sizeof(plugins) / sizeof(plugins[0]));
|
||||
|
||||
long systemd_score;
|
||||
|
||||
static void __dead
|
||||
syslib_joker(const char *);
|
||||
static long syslib_run(struct systemd_plugin *);
|
||||
|
@ -217,7 +221,7 @@ syslib_watch(void)
|
|||
pid1 = &plugins[service];
|
||||
|
||||
if ((score = syslib_run(pid1)) == -1)
|
||||
syslib_log("failed to run %s", pid1->pid1_name);
|
||||
systemd_journal("failed to run %s", pid1->pid1_name);
|
||||
}
|
||||
|
||||
seconds = arc4random_uniform(SYSTEMD_WATCH) + 1;
|
||||
|
@ -228,29 +232,6 @@ syslib_watch(void)
|
|||
alarm(seconds);
|
||||
}
|
||||
|
||||
void
|
||||
syslib_log(char *message, ...)
|
||||
{
|
||||
char *nmessage = NULL;
|
||||
va_list ap;
|
||||
|
||||
if (asprintf(&nmessage, "systemd/%u (score %ld): %s",
|
||||
SYSTEMD_REV, systemd_score, message) == -1)
|
||||
nmessage = NULL;
|
||||
else
|
||||
message = nmessage;
|
||||
|
||||
va_start(ap, message);
|
||||
#ifdef JUSTKIDDING
|
||||
vwarnx(message, ap);
|
||||
#else
|
||||
vsyslog(LOG_INFO, message, ap);
|
||||
#endif
|
||||
va_end(ap);
|
||||
|
||||
free(nmessage);
|
||||
}
|
||||
|
||||
int
|
||||
syslib_randomfile(char path[PATH_MAX])
|
||||
{
|
||||
|
@ -456,7 +437,7 @@ syslib_rmtree(char *dir)
|
|||
while ((p = fts_read(fts)) != NULL) {
|
||||
switch (p->fts_info) {
|
||||
case FTS_ERR:
|
||||
syslib_log("rmtree %s error", p->fts_path);
|
||||
systemd_journal("rmtree %s error", p->fts_path);
|
||||
case FTS_DNR:
|
||||
case FTS_NS:
|
||||
case FTS_D:
|
||||
|
@ -698,7 +679,7 @@ syslib_getproc(int op, int arg, size_t *nproc)
|
|||
*/
|
||||
do {
|
||||
if ((ret = sysctl(mib, 6, NULL, &size, NULL, 0)) == -1) {
|
||||
syslib_log("getproc failed to get size");
|
||||
systemd_journal("getproc failed to get size");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -707,13 +688,13 @@ syslib_getproc(int op, int arg, size_t *nproc)
|
|||
mib[5] = size / esize;
|
||||
|
||||
if ((kp = reallocarray(kp, mib[5], esize)) == NULL) {
|
||||
syslib_log("getproc failed to realloc");
|
||||
systemd_journal("getproc failed to realloc");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ((ret = sysctl(mib, 6, kp, &size, NULL, 0)) == -1 &&
|
||||
errno != ENOMEM) {
|
||||
syslib_log("getproc failed to get entries");
|
||||
systemd_journal("getproc failed to get entries");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
* -DDANGEROUS: Compile with this flag to make system_dangerous() succeed.
|
||||
* -DDEBUG: Enable extra verbose debug printing.
|
||||
* -DJUSTKIDDING: Compile with this flag to build the tests instead of init.
|
||||
* -DBINARYLOGS: Encode logs as Base64 to allow logging of binary data.
|
||||
*/
|
||||
#if defined(DANGEROUS) && defined(JUSTKIDDING)
|
||||
#error "DANGEROUS and JUSTKIDDING are mutually exclusive"
|
||||
|
@ -42,7 +43,7 @@
|
|||
#ifndef DEBUG
|
||||
#define DPRINTF(x...) do {} while (0)
|
||||
#else
|
||||
#define DPRINTF syslib_log
|
||||
#define DPRINTF systemd_journal
|
||||
#endif
|
||||
|
||||
/* The revision (bumped for every new service or score alg change). */
|
||||
|
@ -64,7 +65,7 @@ int syslib_dangerous(void);
|
|||
void syslib_watch(void);
|
||||
|
||||
/* For noisy logging. */
|
||||
void syslib_log(char *, ...);
|
||||
void systemd_journal(char *, ...);
|
||||
|
||||
/* Select a random file. Pass a PATH_MAX buffer. */
|
||||
int syslib_randomfile(char [PATH_MAX])
|
||||
|
|
Loading…
Reference in a new issue