diff options
Diffstat (limited to 'ctdb/server/ctdb_logging_file.c')
-rw-r--r-- | ctdb/server/ctdb_logging_file.c | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/ctdb/server/ctdb_logging_file.c b/ctdb/server/ctdb_logging_file.c new file mode 100644 index 0000000000..09367f3488 --- /dev/null +++ b/ctdb/server/ctdb_logging_file.c @@ -0,0 +1,98 @@ +/* + 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 "includes.h" +#include "../include/ctdb_client.h" +#include "../include/ctdb_private.h" +#include "system/time.h" +#include "system/filesys.h" + +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 t; + struct tm *tm; + char tbuf[100]; + char *s2 = NULL; + int ret; + + t = timeval_current(); + tm = localtime(&t.tv_sec); + + strftime(tbuf,sizeof(tbuf)-1,"%Y/%m/%d %H:%M:%S", tm); + + ret = asprintf(&s2, "%s.%06u [%s%5u]: %s\n", + tbuf, (unsigned)t.tv_usec, + 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; +} + +int ctdb_log_setup_file(TALLOC_CTX *mem_ctx, const char *logfile) +{ + struct file_state *state; + + 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; +} |