static int testLogParseOutputs(const void *opaque) { int ret = -1; int noutputs; const struct testLogData *data = opaque; noutputs = virLogParseOutputs(data->str); if (noutputs < 0) { if (!data->pass) { VIR_TEST_DEBUG("Got expected error: %s\n", virGetLastErrorMessage()); virResetLastError(); ret = 0; goto cleanup; } } else if (noutputs != data->count) { VIR_TEST_DEBUG("Expected number of parsed outputs is %d, " "but got %d\n", data->count, noutputs); goto cleanup; } else if (!data->pass) { VIR_TEST_DEBUG("Test should have failed\n"); goto cleanup; } ret = 0; cleanup: virLogReset(); return ret; }
/* * Set up the logging environment * By default if daemonized all errors go to the logfile libvirtd.log, * but if verbose or error debugging is asked for then also output * informational and debug messages. Default size if 64 kB. */ static int daemonSetupLogging(struct daemonConfig *config, bool privileged, bool verbose, bool godaemon) { virLogReset(); /* * Libvirtd's order of precedence is: * cmdline > environment > config * * In order to achieve this, we must process configuration in * different order for the log level versus the filters and * outputs. Because filters and outputs append, we have to look at * the environment first and then only check the config file if * there was no result from the environment. The default output is * then applied only if there was no setting from either of the * first two. Because we don't have a way to determine if the log * level has been set, we must process variables in the opposite * order, each one overriding the previous. */ if (config->log_level != 0) virLogSetDefaultPriority(config->log_level); virLogSetFromEnv(); if (virLogGetNbFilters() == 0) virLogParseFilters(config->log_filters); if (virLogGetNbOutputs() == 0) virLogParseOutputs(config->log_outputs); /* * If no defined outputs, and either running * as daemon or not on a tty, then first try * to direct it to the systemd journal * (if it exists).... */ if (virLogGetNbOutputs() == 0 && (godaemon || !isatty(STDIN_FILENO))) { char *tmp; if (access("/run/systemd/journal/socket", W_OK) >= 0) { if (virAsprintf(&tmp, "%d:journald", virLogGetDefaultPriority()) < 0) goto error; virLogParseOutputs(tmp); VIR_FREE(tmp); } } /* * otherwise direct to libvirtd.log when running * as daemon. Otherwise the default output is stderr. */ if (virLogGetNbOutputs() == 0) { char *tmp = NULL; if (godaemon) { if (privileged) { if (virAsprintf(&tmp, "%d:file:%s/log/libvirt/libvirtd.log", virLogGetDefaultPriority(), LOCALSTATEDIR) == -1) goto error; } else { char *logdir = virGetUserCacheDirectory(); mode_t old_umask; if (!logdir) goto error; old_umask = umask(077); if (virFileMakePath(logdir) < 0) { umask(old_umask); goto error; } umask(old_umask); if (virAsprintf(&tmp, "%d:file:%s/libvirtd.log", virLogGetDefaultPriority(), logdir) == -1) { VIR_FREE(logdir); goto error; } VIR_FREE(logdir); } } else { if (virAsprintf(&tmp, "%d:stderr", virLogGetDefaultPriority()) < 0) goto error; } virLogParseOutputs(tmp); VIR_FREE(tmp); } /* * Command line override for --verbose */ if ((verbose) && (virLogGetDefaultPriority() > VIR_LOG_INFO)) virLogSetDefaultPriority(VIR_LOG_INFO); return 0; error: return -1; }