mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
ctdb-logging: Remove duplicate logging code
ctdb_logging_init() now uses logging_init(). Signed-off-by: Amitay Isaacs <amitay@gmail.com> Reviewed-by: Martin Schwenke <martin@meltin.net>
This commit is contained in:
parent
c9124a001f
commit
02aa65cede
@ -676,12 +676,6 @@ struct lock_request *ctdb_lock_db(TALLOC_CTX *mem_ctx,
|
||||
|
||||
extern const char *debug_extra;
|
||||
|
||||
typedef int (*ctdb_log_setup_fn_t)(TALLOC_CTX *mem_ctx,
|
||||
const char *logging,
|
||||
const char *app_name);
|
||||
|
||||
void ctdb_log_register_backend(const char *prefix, ctdb_log_setup_fn_t init);
|
||||
|
||||
bool ctdb_logging_init(TALLOC_CTX *mem_ctx, const char *logging);
|
||||
|
||||
struct ctdb_log_state *ctdb_vfork_with_logging(TALLOC_CTX *mem_ctx,
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include "replace.h"
|
||||
#include "system/filesys.h"
|
||||
#include "system/network.h"
|
||||
#include "system/syslog.h"
|
||||
#include "system/time.h"
|
||||
|
||||
#include <talloc.h>
|
||||
@ -40,12 +39,6 @@
|
||||
|
||||
const char *debug_extra = "";
|
||||
|
||||
struct ctdb_log_backend {
|
||||
struct ctdb_log_backend *prev, *next;
|
||||
const char *prefix;
|
||||
ctdb_log_setup_fn_t setup;
|
||||
};
|
||||
|
||||
struct ctdb_log_state {
|
||||
const char *prefix;
|
||||
int fd, pfd;
|
||||
@ -53,62 +46,27 @@ struct ctdb_log_state {
|
||||
uint16_t buf_used;
|
||||
void (*logfn)(const char *, uint16_t, void *);
|
||||
void *logfn_private;
|
||||
struct ctdb_log_backend *backends;
|
||||
};
|
||||
|
||||
/* Used by ctdb_set_child_logging() */
|
||||
static struct ctdb_log_state *log_state;
|
||||
|
||||
void ctdb_log_register_backend(const char *prefix, ctdb_log_setup_fn_t setup)
|
||||
{
|
||||
struct ctdb_log_backend *b;
|
||||
|
||||
b = talloc_zero(log_state, struct ctdb_log_backend);
|
||||
if (b == NULL) {
|
||||
printf("Failed to register backend \"%s\" - no memory\n",
|
||||
prefix);
|
||||
return;
|
||||
}
|
||||
|
||||
b->prefix = prefix;
|
||||
b->setup = setup;
|
||||
|
||||
DLIST_ADD_END(log_state->backends, b);
|
||||
}
|
||||
|
||||
|
||||
/* Initialise logging */
|
||||
bool ctdb_logging_init(TALLOC_CTX *mem_ctx, const char *logging)
|
||||
{
|
||||
struct ctdb_log_backend *b;
|
||||
int ret;
|
||||
|
||||
log_state = talloc_zero(mem_ctx, struct ctdb_log_state);
|
||||
if (log_state == NULL) {
|
||||
printf("talloc_zero failed\n");
|
||||
abort();
|
||||
return false;
|
||||
}
|
||||
|
||||
ctdb_log_init_file();
|
||||
ctdb_log_init_syslog();
|
||||
|
||||
for (b = log_state->backends; b != NULL; b = b->next) {
|
||||
size_t l = strlen(b->prefix);
|
||||
/* Exact match with prefix or prefix followed by ':' */
|
||||
if (strncmp(b->prefix, logging, l) == 0 &&
|
||||
(logging[l] == '\0' || logging[l] == ':')) {
|
||||
ret = b->setup(mem_ctx, logging, "ctdbd");
|
||||
if (ret == 0) {
|
||||
return true;
|
||||
}
|
||||
printf("Log init for \"%s\" failed with \"%s\"\n",
|
||||
logging, strerror(ret));
|
||||
return false;
|
||||
}
|
||||
ret = logging_init(mem_ctx, logging, NULL, "ctdbd");
|
||||
if (ret != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
printf("Unable to find log backend for \"%s\"\n", logging);
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Note that do_debug always uses the global log state. */
|
||||
@ -279,11 +237,6 @@ int ctdb_set_child_logging(struct ctdb_context *ctdb)
|
||||
int old_stdout, old_stderr;
|
||||
struct tevent_fd *fde;
|
||||
|
||||
if (log_state->fd == STDOUT_FILENO) {
|
||||
/* not needed for stdout logging */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* setup a pipe to catch IO from subprocesses */
|
||||
if (pipe(p) != 0) {
|
||||
DEBUG(DEBUG_ERR,(__location__ " Failed to setup for child logging pipe\n"));
|
||||
|
@ -1,120 +0,0 @@
|
||||
/*
|
||||
ctdb logging code
|
||||
|
||||
Copyright (C) Andrew Tridgell 2008
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "replace.h"
|
||||
#include "system/time.h"
|
||||
#include "system/filesys.h"
|
||||
#include "system/network.h"
|
||||
|
||||
#include <talloc.h>
|
||||
|
||||
#include "lib/util/debug.h"
|
||||
#include "lib/util/sys_rw.h"
|
||||
#include "lib/util/time_basic.h"
|
||||
|
||||
#include "ctdb_private.h"
|
||||
#include "ctdb_client.h"
|
||||
|
||||
#define CTDB_LOG_FILE_PREFIX "file"
|
||||
|
||||
struct file_state {
|
||||
int fd;
|
||||
};
|
||||
|
||||
/*
|
||||
log file logging function
|
||||
*/
|
||||
static void ctdb_log_to_file(void *private_ptr, int dbglevel, const char *s)
|
||||
{
|
||||
struct file_state *state = talloc_get_type(
|
||||
private_ptr, struct file_state);
|
||||
struct timeval tv;
|
||||
struct timeval_buf tvbuf;
|
||||
char *s2 = NULL;
|
||||
int ret;
|
||||
|
||||
GetTimeOfDay(&tv);
|
||||
timeval_str_buf(&tv, false, true, &tvbuf);
|
||||
|
||||
ret = asprintf(&s2, "%s [%s%5u]: %s\n",
|
||||
tvbuf.buf,
|
||||
debug_extra, (unsigned)getpid(), s);
|
||||
if (ret == -1) {
|
||||
const char *errstr = "asprintf failed\n";
|
||||
sys_write(state->fd, errstr, strlen(errstr));
|
||||
return;
|
||||
}
|
||||
if (s2) {
|
||||
sys_write(state->fd, s2, strlen(s2));
|
||||
free(s2);
|
||||
}
|
||||
}
|
||||
|
||||
static int file_state_destructor(struct file_state *state)
|
||||
{
|
||||
close(state->fd);
|
||||
state->fd = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ctdb_log_setup_file(TALLOC_CTX *mem_ctx,
|
||||
const char *logging,
|
||||
const char *app_name)
|
||||
{
|
||||
struct file_state *state;
|
||||
const char *logfile;
|
||||
size_t l;
|
||||
|
||||
l = strlen(CTDB_LOG_FILE_PREFIX);
|
||||
if (logging[l] != ':') {
|
||||
return EINVAL;
|
||||
}
|
||||
logfile = &logging[0] + l + 1;
|
||||
|
||||
state = talloc_zero(mem_ctx, struct file_state);
|
||||
if (state == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
if (logfile == NULL || strcmp(logfile, "-") == 0) {
|
||||
int ret;
|
||||
|
||||
state->fd = 1;
|
||||
/* also catch stderr of subcommands to stdout */
|
||||
ret = dup2(1, 2);
|
||||
if (ret == -1) {
|
||||
return errno;
|
||||
}
|
||||
} else {
|
||||
state->fd = open(logfile, O_WRONLY|O_APPEND|O_CREAT, 0666);
|
||||
if (state->fd == -1) {
|
||||
return errno;
|
||||
}
|
||||
}
|
||||
|
||||
talloc_set_destructor(state, file_state_destructor);
|
||||
debug_set_callback(state, ctdb_log_to_file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ctdb_log_init_file(void)
|
||||
{
|
||||
ctdb_log_register_backend(CTDB_LOG_FILE_PREFIX, ctdb_log_setup_file);
|
||||
}
|
@ -1,328 +0,0 @@
|
||||
/*
|
||||
ctdb logging code - syslog backend
|
||||
|
||||
Copyright (C) Andrew Tridgell 2008
|
||||
Copyright (C) Martin Schwenke 2014
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "replace.h"
|
||||
#include "system/network.h"
|
||||
#include "system/syslog.h"
|
||||
|
||||
#include "lib/util/debug.h"
|
||||
#include "lib/util/blocking.h"
|
||||
#include "lib/util/time_basic.h"
|
||||
#include "lib/util/samba_util.h" /* get_myname */
|
||||
|
||||
#include "ctdb_private.h"
|
||||
|
||||
#include "common/logging.h"
|
||||
|
||||
/* Linux and FreeBSD define this appropriately - try good old /dev/log
|
||||
* for anything that doesn't... */
|
||||
#ifndef _PATH_LOG
|
||||
#define _PATH_LOG "/dev/log"
|
||||
#endif
|
||||
|
||||
#define CTDB_LOG_SYSLOG_PREFIX "syslog"
|
||||
#define CTDB_SYSLOG_FACILITY LOG_USER
|
||||
|
||||
struct ctdb_syslog_sock_state {
|
||||
int fd;
|
||||
const char *app_name;
|
||||
const char *hostname;
|
||||
int (*format)(int dbglevel, struct ctdb_syslog_sock_state *state,
|
||||
const char *str, char *buf, int bsize);
|
||||
};
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
static int ctdb_debug_to_syslog_level(int dbglevel)
|
||||
{
|
||||
int level;
|
||||
|
||||
switch (dbglevel) {
|
||||
case DEBUG_ERR:
|
||||
level = LOG_ERR;
|
||||
break;
|
||||
case DEBUG_WARNING:
|
||||
level = LOG_WARNING;
|
||||
break;
|
||||
case DEBUG_NOTICE:
|
||||
level = LOG_NOTICE;
|
||||
break;
|
||||
case DEBUG_INFO:
|
||||
level = LOG_INFO;
|
||||
break;
|
||||
default:
|
||||
level = LOG_DEBUG;
|
||||
break;
|
||||
}
|
||||
|
||||
return level;
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
/* Format messages as per RFC3164. */
|
||||
|
||||
/* It appears that some syslog daemon implementations do not allow a
|
||||
* hostname when messages are sent via a Unix domain socket, so omit
|
||||
* it. Similarly, syslogd on FreeBSD does not understand the hostname
|
||||
* part of the header, even when logging via UDP. Note that most
|
||||
* implementations will log messages against "localhost" when logging
|
||||
* via UDP. A timestamp could be sent but rsyslogd on Linux limits
|
||||
* the timestamp logged to the precision that was received on
|
||||
* /dev/log. It seems sane to send degenerate RFC3164 messages
|
||||
* without a header at all, so that the daemon will generate high
|
||||
* resolution timestamps if configured. */
|
||||
static int format_rfc3164(int dbglevel, struct ctdb_syslog_sock_state *state,
|
||||
const char *str, char *buf, int bsize)
|
||||
{
|
||||
int pri;
|
||||
int len;
|
||||
|
||||
pri = CTDB_SYSLOG_FACILITY | ctdb_debug_to_syslog_level(dbglevel);
|
||||
len = snprintf(buf, bsize, "<%d>%s[%u]: %s%s",
|
||||
pri, state->app_name, getpid(), debug_extra, str);
|
||||
len = MIN(len, bsize - 1);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/* Format messages as per RFC5424
|
||||
*
|
||||
* <165>1 2003-08-24T05:14:15.000003-07:00 192.0.2.1
|
||||
* myproc 8710 - - %% It's time to make the do-nuts.
|
||||
*/
|
||||
static int format_rfc5424(int dbglevel, struct ctdb_syslog_sock_state *state,
|
||||
const char *str, char *buf, int bsize)
|
||||
{
|
||||
int pri;
|
||||
struct timeval tv;
|
||||
struct timeval_buf tvbuf;
|
||||
int len, s;
|
||||
|
||||
/* Header */
|
||||
pri = CTDB_SYSLOG_FACILITY | ctdb_debug_to_syslog_level(dbglevel);
|
||||
GetTimeOfDay(&tv);
|
||||
len = snprintf(buf, bsize,
|
||||
"<%d>1 %s %s %s %u - - ",
|
||||
pri, timeval_str_buf(&tv, true, true, &tvbuf),
|
||||
state->hostname, state->app_name, getpid());
|
||||
/* A truncated header is not useful... */
|
||||
if (len >= bsize) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Message */
|
||||
s = snprintf(&buf[len], bsize - len, "%s %s", debug_extra, str);
|
||||
len = MIN(len + s, bsize - 1);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
/* Non-blocking logging */
|
||||
|
||||
static void ctdb_log_to_syslog_sock(void *private_ptr,
|
||||
int dbglevel, const char *str)
|
||||
{
|
||||
struct ctdb_syslog_sock_state *state = talloc_get_type(
|
||||
private_ptr, struct ctdb_syslog_sock_state);
|
||||
|
||||
/* RFC3164 says: The total length of the packet MUST be 1024
|
||||
bytes or less. */
|
||||
char buf[1024];
|
||||
int n;
|
||||
|
||||
n = state->format(dbglevel, state, str, buf, sizeof(buf));
|
||||
if (n == -1) {
|
||||
fprintf(stderr, "Failed to format syslog message %s\n", str);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Could extend this to count failures, which probably
|
||||
* indicate dropped messages due to EAGAIN or EWOULDBLOCK */
|
||||
(void)send(state->fd, buf, n, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
ctdb_syslog_sock_state_destructor(struct ctdb_syslog_sock_state *state)
|
||||
{
|
||||
if (state->fd != -1) {
|
||||
close(state->fd);
|
||||
state->fd = -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ctdb_syslog_sock_state *
|
||||
ctdb_log_setup_syslog_common(TALLOC_CTX *mem_ctx,
|
||||
const char *app_name)
|
||||
{
|
||||
struct ctdb_syslog_sock_state *state;
|
||||
|
||||
state = talloc_zero(mem_ctx, struct ctdb_syslog_sock_state);
|
||||
if (state == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
state->fd = -1;
|
||||
state->app_name = app_name;
|
||||
talloc_set_destructor(state, ctdb_syslog_sock_state_destructor);
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
static int ctdb_log_setup_syslog_un(TALLOC_CTX *mem_ctx,
|
||||
const char *app_name)
|
||||
{
|
||||
struct ctdb_syslog_sock_state *state;
|
||||
struct sockaddr_un dest;
|
||||
int ret;
|
||||
|
||||
state = ctdb_log_setup_syslog_common(mem_ctx, app_name);
|
||||
if (state == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
state->fd = socket(AF_UNIX, SOCK_DGRAM, 0);
|
||||
if (state->fd == -1) {
|
||||
int save_errno = errno;
|
||||
talloc_free(state);
|
||||
return save_errno;
|
||||
}
|
||||
|
||||
dest.sun_family = AF_UNIX;
|
||||
strncpy(dest.sun_path, _PATH_LOG, sizeof(dest.sun_path)-1);
|
||||
ret = connect(state->fd,
|
||||
(struct sockaddr *)&dest, sizeof(dest));
|
||||
if (ret == -1) {
|
||||
int save_errno = errno;
|
||||
talloc_free(state);
|
||||
return save_errno;
|
||||
}
|
||||
|
||||
ret = set_blocking(state->fd, false);
|
||||
if (ret != 0) {
|
||||
int save_errno = errno;
|
||||
talloc_free(state);
|
||||
return save_errno;
|
||||
}
|
||||
|
||||
state->hostname = NULL; /* Make this explicit */
|
||||
state->format = format_rfc3164;
|
||||
|
||||
debug_set_callback(state, ctdb_log_to_syslog_sock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ctdb_log_setup_syslog_udp(TALLOC_CTX *mem_ctx,
|
||||
const char *app_name,
|
||||
bool rfc5424)
|
||||
{
|
||||
struct ctdb_syslog_sock_state *state;
|
||||
struct sockaddr_in dest;
|
||||
int ret;
|
||||
|
||||
state = ctdb_log_setup_syslog_common(mem_ctx, app_name);
|
||||
if (state == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
state->fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (state->fd == -1) {
|
||||
int save_errno = errno;
|
||||
talloc_free(state);
|
||||
return save_errno;
|
||||
}
|
||||
|
||||
dest.sin_family = AF_INET;
|
||||
dest.sin_port = htons(514);
|
||||
dest.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
ret = connect(state->fd,
|
||||
(struct sockaddr *)&dest, sizeof(dest));
|
||||
if (ret == -1) {
|
||||
int save_errno = errno;
|
||||
talloc_free(state);
|
||||
return save_errno;
|
||||
}
|
||||
|
||||
state->hostname = get_myname(state);
|
||||
if (state->hostname == NULL) {
|
||||
/* Use a fallback instead of failing initialisation */
|
||||
state->hostname = "localhost";
|
||||
}
|
||||
if (rfc5424) {
|
||||
state->format = format_rfc5424;
|
||||
} else {
|
||||
state->format = format_rfc3164;
|
||||
}
|
||||
|
||||
debug_set_callback(state, ctdb_log_to_syslog_sock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
static void ctdb_log_to_syslog(void *private_ptr, int dbglevel, const char *s)
|
||||
{
|
||||
syslog(ctdb_debug_to_syslog_level(dbglevel),
|
||||
"%s%s", debug_extra, s);
|
||||
}
|
||||
|
||||
static int ctdb_log_setup_syslog(TALLOC_CTX *mem_ctx,
|
||||
const char *logging,
|
||||
const char *app_name)
|
||||
{
|
||||
size_t l = strlen(CTDB_LOG_SYSLOG_PREFIX);
|
||||
|
||||
if (logging[l] != '\0') {
|
||||
/* Handle non-blocking extensions here */
|
||||
const char *method;
|
||||
|
||||
if (logging[l] != ':') {
|
||||
return EINVAL;
|
||||
}
|
||||
method = &logging[0] + l + 1;
|
||||
if (strcmp(method, "nonblocking") == 0) {
|
||||
ctdb_log_setup_syslog_un(mem_ctx, app_name);
|
||||
return 0;
|
||||
}
|
||||
if (strcmp(method, "udp") == 0) {
|
||||
ctdb_log_setup_syslog_udp(mem_ctx, app_name, false);
|
||||
return 0;
|
||||
}
|
||||
if (strcmp(method, "udp-rfc5424") == 0) {
|
||||
ctdb_log_setup_syslog_udp(mem_ctx, app_name, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
debug_set_callback(NULL, ctdb_log_to_syslog);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ctdb_log_init_syslog(void)
|
||||
{
|
||||
ctdb_log_register_backend(CTDB_LOG_SYSLOG_PREFIX,
|
||||
ctdb_log_setup_syslog);
|
||||
}
|
@ -404,8 +404,6 @@ def build(bld):
|
||||
ctdb_persistent.c ctdb_keepalive.c
|
||||
ctdb_cluster_mutex.c
|
||||
ctdb_logging.c
|
||||
ctdb_logging_syslog.c
|
||||
ctdb_logging_file.c
|
||||
ctdb_uptime.c
|
||||
ctdb_vacuum.c ctdb_banning.c
|
||||
ctdb_statistics.c
|
||||
|
Loading…
Reference in New Issue
Block a user