ctdb-logging: Refactor logging code
[Samba.git] / ctdb / server / ctdb_logging_file.c
blobfc6720b942e426bba60a7d05e200e738d6c611de
1 /*
2 ctdb logging code
4 Copyright (C) Andrew Tridgell 2008
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, see <http://www.gnu.org/licenses/>.
20 #include "replace.h"
21 #include "system/time.h"
22 #include "system/filesys.h"
23 #include "system/network.h"
25 #include <talloc.h>
27 #include "lib/util/debug.h"
28 #include "lib/util/sys_rw.h"
29 #include "lib/util/time_basic.h"
31 #include "ctdb_private.h"
32 #include "ctdb_client.h"
34 #define CTDB_LOG_FILE_PREFIX "file"
36 struct file_state {
37 int fd;
41 log file logging function
43 static void ctdb_log_to_file(void *private_ptr, int dbglevel, const char *s)
45 struct file_state *state = talloc_get_type(
46 private_ptr, struct file_state);
47 struct timeval tv;
48 struct timeval_buf tvbuf;
49 char *s2 = NULL;
50 int ret;
52 GetTimeOfDay(&tv);
53 timeval_str_buf(&tv, false, true, &tvbuf);
55 ret = asprintf(&s2, "%s [%s%5u]: %s\n",
56 tvbuf.buf,
57 debug_extra, (unsigned)getpid(), s);
58 if (ret == -1) {
59 const char *errstr = "asprintf failed\n";
60 sys_write(state->fd, errstr, strlen(errstr));
61 return;
63 if (s2) {
64 sys_write(state->fd, s2, strlen(s2));
65 free(s2);
69 static int file_state_destructor(struct file_state *state)
71 close(state->fd);
72 state->fd = -1;
73 return 0;
76 static int ctdb_log_setup_file(TALLOC_CTX *mem_ctx,
77 const char *logging,
78 const char *app_name)
80 struct file_state *state;
81 const char *logfile;
82 size_t l;
84 l = strlen(CTDB_LOG_FILE_PREFIX);
85 if (logging[l] != ':') {
86 return EINVAL;
88 logfile = &logging[0] + l + 1;
90 state = talloc_zero(mem_ctx, struct file_state);
91 if (state == NULL) {
92 return ENOMEM;
95 if (logfile == NULL || strcmp(logfile, "-") == 0) {
96 int ret;
98 state->fd = 1;
99 /* also catch stderr of subcommands to stdout */
100 ret = dup2(1, 2);
101 if (ret == -1) {
102 return errno;
104 } else {
105 state->fd = open(logfile, O_WRONLY|O_APPEND|O_CREAT, 0666);
106 if (state->fd == -1) {
107 return errno;
111 talloc_set_destructor(state, file_state_destructor);
112 debug_set_callback(state, ctdb_log_to_file);
114 return 0;
117 void ctdb_log_init_file(void)
119 ctdb_log_register_backend(CTDB_LOG_FILE_PREFIX, ctdb_log_setup_file);