summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/src/glfs.c11
-rw-r--r--glusterfsd/src/Makefile.am2
-rw-r--r--glusterfsd/src/glusterfsd-messages.h111
-rw-r--r--glusterfsd/src/glusterfsd.c275
-rw-r--r--libglusterfs/src/Makefile.am3
-rw-r--r--libglusterfs/src/common-utils.c241
-rw-r--r--libglusterfs/src/common-utils.h1
-rw-r--r--libglusterfs/src/glfs-message-id.h48
-rw-r--r--libglusterfs/src/glusterfs.h1
-rw-r--r--libglusterfs/src/logging.c1074
-rw-r--r--libglusterfs/src/logging.h129
-rw-r--r--libglusterfs/src/mem-pool.c6
-rw-r--r--libglusterfs/src/mem-pool.h6
-rw-r--r--libglusterfs/src/template-component-messages.h55
-rw-r--r--libglusterfs/src/unittest/log_mock.c7
-rw-r--r--rpc/rpc-transport/rdma/src/rdma.c2
-rw-r--r--tests/basic/logchecks-messages.h84
-rw-r--r--tests/basic/logchecks.c208
18 files changed, 1762 insertions, 502 deletions
diff --git a/api/src/glfs.c b/api/src/glfs.c
index 9e9a55ccb..d09c737f6 100644
--- a/api/src/glfs.c
+++ b/api/src/glfs.c
@@ -486,7 +486,7 @@ glfs_set_volfile_server (struct glfs *fs, const char *transport,
int
glfs_set_logging (struct glfs *fs, const char *logfile, int loglevel)
{
- int ret = 0;
+ int ret = 0;
char *tmplog = NULL;
if (!logfile) {
@@ -498,15 +498,16 @@ glfs_set_logging (struct glfs *fs, const char *logfile, int loglevel)
tmplog = (char *)logfile;
}
+ /* finish log set parameters before init */
+ if (loglevel >= 0)
+ gf_log_set_loglevel (loglevel);
+
ret = gf_log_init (fs->ctx, tmplog, NULL);
if (ret)
goto out;
- if (loglevel >= 0)
- gf_log_set_loglevel (loglevel);
-
out:
- return ret;
+ return ret;
}
diff --git a/glusterfsd/src/Makefile.am b/glusterfsd/src/Makefile.am
index 05a10dee3..1797c32be 100644
--- a/glusterfsd/src/Makefile.am
+++ b/glusterfsd/src/Makefile.am
@@ -6,7 +6,7 @@ glusterfsd_LDADD = $(top_builddir)/libglusterfs/src/libglusterfs.la \
$(top_builddir)/rpc/xdr/src/libgfxdr.la \
$(GF_LDADD) $(GF_GLUSTERFS_LIBS)
glusterfsd_LDFLAGS = $(GF_LDFLAGS)
-noinst_HEADERS = glusterfsd.h glusterfsd-mem-types.h
+noinst_HEADERS = glusterfsd.h glusterfsd-mem-types.h glusterfsd-messages.h
AM_CPPFLAGS = $(GF_CPPFLAGS) \
-I$(top_srcdir)/libglusterfs/src -DDATADIR=\"$(localstatedir)\" \
diff --git a/glusterfsd/src/glusterfsd-messages.h b/glusterfsd/src/glusterfsd-messages.h
new file mode 100644
index 000000000..48a0b17f6
--- /dev/null
+++ b/glusterfsd/src/glusterfsd-messages.h
@@ -0,0 +1,111 @@
+/*
+ Copyright (c) 2013 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+
+#ifndef _GLUSTERFSD_MESSAGES_H_
+#define _GLUSTERFSD_MESSAGES_H_
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "glfs-message-id.h"
+
+/* NOTE: Rules for message additions
+ * 1) Each instance of a message is _better_ left with a unique message ID, even
+ * if the message format is the same. Reasoning is that, if the message
+ * format needs to change in one instance, the other instances are not
+ * impacted or the new change does not change the ID of the instance being
+ * modified.
+ * 2) Addition of a message,
+ * - Should increment the GLFS_NUM_MESSAGES
+ * - Append to the list of messages defined, towards the end
+ * - Retain macro naming as glfs_msg_X (for redability across developers)
+ * NOTE: Rules for message format modifications
+ * 3) Check acorss the code if the message ID macro in question is reused
+ * anywhere. If reused then then the modifications should ensure correctness
+ * everywhere, or needs a new message ID as (1) above was not adhered to. If
+ * not used anywhere, proceed with the required modification.
+ * NOTE: Rules for message deletion
+ * 4) Check (3) and if used anywhere else, then cannot be deleted. If not used
+ * anywhere, then can be deleted, but will leave a hole by design, as
+ * addition rules specify modification to the end of the list and not filling
+ * holes.
+ */
+
+#define GLFS_COMP_BASE GLFS_MSGID_COMP_GLUSTERFSD
+#define GLFS_NUM_MESSAGES 33
+#define GLFS_MSGID_END (GLFS_COMP_BASE + GLFS_NUM_MESSAGES + 1)
+/* Messaged with message IDs */
+#define glfs_msg_start_x GLFS_COMP_BASE, "Invalid: Start of messages"
+/*------------*/
+#define glusterfsd_msg_1 (GLFS_COMP_BASE + 1), "Could not create absolute" \
+ " mountpoint path"
+#define glusterfsd_msg_2 (GLFS_COMP_BASE + 2), "Could not get current " \
+ "working directory"
+#define glusterfsd_msg_3 (GLFS_COMP_BASE + 3), "failed to set mount-point" \
+ " to options dictionary"
+#define glusterfsd_msg_4 (GLFS_COMP_BASE + 4), "failed to set dict value" \
+ " for key %s"
+#define glusterfsd_msg_5 (GLFS_COMP_BASE + 5), "failed to set 'disable'" \
+ " for key %s"
+#define glusterfsd_msg_6 (GLFS_COMP_BASE + 6), "failed to set 'enable'" \
+ " for key %s"
+#define glusterfsd_msg_7 (GLFS_COMP_BASE + 7), "Not a client process, not" \
+ " performing mount operation"
+#define glusterfsd_msg_8 (GLFS_COMP_BASE + 8), "MOUNT-POINT %s" \
+ " initialization failed"
+#define glusterfsd_msg_9 (GLFS_COMP_BASE + 9), "loading volume file %s" \
+ " failed"
+#define glusterfsd_msg_10 (GLFS_COMP_BASE + 10), "xlator option %s is" \
+ " invalid"
+#define glusterfsd_msg_11 (GLFS_COMP_BASE + 11), "Fetching the volume" \
+ " file from server..."
+#define glusterfsd_msg_12 (GLFS_COMP_BASE + 12), "volume initialization" \
+ " failed."
+#define glusterfsd_msg_13 (GLFS_COMP_BASE + 13), "ERROR: glusterfs uuid" \
+ " generation failed"
+#define glusterfsd_msg_14 (GLFS_COMP_BASE + 14), "ERROR: glusterfs %s" \
+ " pool creation failed"
+#define glusterfsd_msg_15 (GLFS_COMP_BASE + 15), "ERROR: '--volfile-id' is" \
+ " mandatory if '-s' OR '--volfile-server'" \
+ " option is given"
+#define glusterfsd_msg_16 (GLFS_COMP_BASE + 16), "ERROR: parsing the" \
+ " volfile failed"
+#define glusterfsd_msg_17 (GLFS_COMP_BASE + 17), "pidfile %s open failed"
+#define glusterfsd_msg_18 (GLFS_COMP_BASE + 18), "pidfile %s lock failed"
+#define glusterfsd_msg_19 (GLFS_COMP_BASE + 19), "pidfile %s unlock failed"
+#define glusterfsd_msg_20 (GLFS_COMP_BASE + 20), "pidfile %s truncation" \
+ " failed"
+#define glusterfsd_msg_21 (GLFS_COMP_BASE + 21), "pidfile %s write failed"
+#define glusterfsd_msg_22 (GLFS_COMP_BASE + 22), "failed to execute" \
+ " pthread_sigmask"
+#define glusterfsd_msg_23 (GLFS_COMP_BASE + 23), "failed to create pthread"
+#define glusterfsd_msg_24 (GLFS_COMP_BASE + 24), "daemonization failed"
+#define glusterfsd_msg_25 (GLFS_COMP_BASE + 25), "mount failed"
+#define glusterfsd_msg_26 (GLFS_COMP_BASE + 26), "failed to construct" \
+ " the graph"
+#define glusterfsd_msg_27 (GLFS_COMP_BASE + 27), "fuse xlator cannot be" \
+ " specified in volume file"
+#define glusterfsd_msg_28 (GLFS_COMP_BASE + 28), "Cannot reach volume" \
+ " specification file"
+#define glusterfsd_msg_29 (GLFS_COMP_BASE + 29), "ERROR: glusterfs context" \
+ " not initialized"
+#define glusterfsd_msg_30 (GLFS_COMP_BASE + 30), "Started running %s" \
+ " version %s (args: %s)"
+#define glusterfsd_msg_31 (GLFS_COMP_BASE + 31), "Could not create new" \
+ " sync-environment"
+#define glusterfsd_msg_32 (GLFS_COMP_BASE + 32), "received signum (%d)," \
+ " shutting down"
+/*------------*/
+#define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages"
+
+
+#endif /* !_GLUSTERFSD_MESSAGES_H_ */
diff --git a/glusterfsd/src/glusterfsd.c b/glusterfsd/src/glusterfsd.c
index 6a4655fc6..449fadda6 100644
--- a/glusterfsd/src/glusterfsd.c
+++ b/glusterfsd/src/glusterfsd.c
@@ -50,6 +50,7 @@
#include "glusterfs.h"
#include "compat.h"
#include "logging.h"
+#include "glusterfsd-messages.h"
#include "dict.h"
#include "list.h"
#include "timer.h"
@@ -240,14 +241,13 @@ set_fuse_mount_options (glusterfs_ctx_t *ctx, dict_t *options)
ret = gf_asprintf (&mount_point, "%s/%s", cwd,
cmd_args->mount_point);
if (ret == -1) {
- gf_log ("glusterfsd", GF_LOG_ERROR,
- "Could not create absolute mountpoint "
- "path");
+ gf_msg ("glusterfsd", GF_LOG_ERROR, errno,
+ glusterfsd_msg_1);
goto err;
}
} else {
- gf_log ("glusterfsd", GF_LOG_ERROR,
- "Could not get current working directory");
+ gf_msg ("glusterfsd", GF_LOG_ERROR, errno,
+ glusterfsd_msg_2);
goto err;
}
} else
@@ -255,8 +255,7 @@ set_fuse_mount_options (glusterfs_ctx_t *ctx, dict_t *options)
ret = dict_set_dynstr (options, ZR_MOUNTPOINT_OPT, mount_point);
if (ret < 0) {
- gf_log ("glusterfsd", GF_LOG_ERROR,
- "failed to set mount-point to options dictionary");
+ gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_3);
goto err;
}
@@ -265,9 +264,8 @@ set_fuse_mount_options (glusterfs_ctx_t *ctx, dict_t *options)
cmd_args->fuse_attribute_timeout);
if (ret < 0) {
- gf_log ("glusterfsd", GF_LOG_ERROR,
- "failed to set dict value for key %s",
- ZR_ATTR_TIMEOUT_OPT);
+ gf_msg ("glusterfsd", GF_LOG_ERROR, errno,
+ glusterfsd_msg_4, ZR_ATTR_TIMEOUT_OPT);
goto err;
}
}
@@ -276,8 +274,7 @@ set_fuse_mount_options (glusterfs_ctx_t *ctx, dict_t *options)
ret = dict_set_double (options, ZR_ENTRY_TIMEOUT_OPT,
cmd_args->fuse_entry_timeout);
if (ret < 0) {
- gf_log ("glusterfsd", GF_LOG_ERROR,
- "failed to set dict value for key %s",
+ gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
ZR_ENTRY_TIMEOUT_OPT);
goto err;
}
@@ -287,8 +284,7 @@ set_fuse_mount_options (glusterfs_ctx_t *ctx, dict_t *options)
ret = dict_set_double (options, ZR_NEGATIVE_TIMEOUT_OPT,
cmd_args->fuse_negative_timeout);
if (ret < 0) {
- gf_log ("glusterfsd", GF_LOG_ERROR,
- "failed to set dict value for key %s",
+ gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
ZR_NEGATIVE_TIMEOUT_OPT);
goto err;
}
@@ -298,8 +294,7 @@ set_fuse_mount_options (glusterfs_ctx_t *ctx, dict_t *options)
ret = dict_set_int32 (options, "client-pid",
cmd_args->client_pid);
if (ret < 0) {
- gf_log ("glusterfsd", GF_LOG_ERROR,
- "failed to set dict value for key %s",
+ gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
"client-pid");
goto err;
}
@@ -309,8 +304,7 @@ set_fuse_mount_options (glusterfs_ctx_t *ctx, dict_t *options)
ret = dict_set_int32 (options, "uid-map-root",
cmd_args->uid_map_root);
if (ret < 0) {
- gf_log ("glusterfsd", GF_LOG_ERROR,
- "failed to set dict value for key %s",
+ gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
"uid-map-root");
goto err;
}
@@ -320,8 +314,7 @@ set_fuse_mount_options (glusterfs_ctx_t *ctx, dict_t *options)
ret = dict_set_int32 (options, ZR_STRICT_VOLFILE_CHECK,
cmd_args->volfile_check);
if (ret < 0) {
- gf_log ("glusterfsd", GF_LOG_ERROR,
- "failed to set dict value for key %s",
+ gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
ZR_STRICT_VOLFILE_CHECK);
goto err;
}
@@ -331,8 +324,7 @@ set_fuse_mount_options (glusterfs_ctx_t *ctx, dict_t *options)
ret = dict_set_static_ptr (options, ZR_DUMP_FUSE,
cmd_args->dump_fuse);
if (ret < 0) {
- gf_log ("glusterfsd", GF_LOG_ERROR,
- "failed to set dict value for key %s",
+ gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
ZR_DUMP_FUSE);
goto err;
}
@@ -341,8 +333,8 @@ set_fuse_mount_options (glusterfs_ctx_t *ctx, dict_t *options)
if (cmd_args->acl) {
ret = dict_set_static_ptr (options, "acl", "on");
if (ret < 0) {
- gf_log ("glusterfsd", GF_LOG_ERROR,
- "failed to set dict value for key acl");
+ gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
+ "acl");
goto err;
}
}
@@ -350,8 +342,8 @@ set_fuse_mount_options (glusterfs_ctx_t *ctx, dict_t *options)
if (cmd_args->selinux) {
ret = dict_set_static_ptr (options, "selinux", "on");
if (ret < 0) {
- gf_log ("glusterfsd", GF_LOG_ERROR,
- "failed to set dict value for key selinux");
+ gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
+ "selinux");
goto err;
}
}
@@ -360,8 +352,7 @@ set_fuse_mount_options (glusterfs_ctx_t *ctx, dict_t *options)
ret = dict_set_static_ptr (options, "virtual-gfid-access",
"on");
if (ret < 0) {
- gf_log ("glusterfsd", GF_LOG_ERROR,
- "failed to set dict value for key "
+ gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
"aux-gfid-mount");
goto err;
}
@@ -370,8 +361,8 @@ set_fuse_mount_options (glusterfs_ctx_t *ctx, dict_t *options)
if (cmd_args->enable_ino32) {
ret = dict_set_static_ptr (options, "enable-ino32", "on");
if (ret < 0) {
- gf_log ("glusterfsd", GF_LOG_ERROR,
- "failed to set dict value for key enable-ino32");
+ gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
+ "enable-ino32");
goto err;
}
}
@@ -379,8 +370,8 @@ set_fuse_mount_options (glusterfs_ctx_t *ctx, dict_t *options)
if (cmd_args->read_only) {
ret = dict_set_static_ptr (options, "read-only", "on");
if (ret < 0) {
- gf_log ("glusterfsd", GF_LOG_ERROR,
- "failed to set dict value for key read-only");
+ gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
+ "read-only");
goto err;
}
}
@@ -390,8 +381,7 @@ set_fuse_mount_options (glusterfs_ctx_t *ctx, dict_t *options)
ret = dict_set_static_ptr(options, "fopen-keep-cache",
"on");
if (ret < 0) {
- gf_log("glusterfsd", GF_LOG_ERROR,
- "failed to set dict value for key "
+ gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
"fopen-keep-cache");
goto err;
}
@@ -400,17 +390,15 @@ set_fuse_mount_options (glusterfs_ctx_t *ctx, dict_t *options)
ret = dict_set_static_ptr(options, "fopen-keep-cache",
"off");
if (ret < 0) {
- gf_log("glusterfsd", GF_LOG_ERROR,
- "failed to set dict value for key "
+ gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
"fopen-keep-cache");
goto err;
}
break;
case GF_OPTION_DEFERRED: /* default */
default:
- gf_log ("glusterfsd", GF_LOG_DEBUG,
- "fopen-keep-cache mode %d",
- cmd_args->fopen_keep_cache);
+ gf_msg_debug ("glusterfsd", 0, "fopen-keep-cache mode %d",
+ cmd_args->fopen_keep_cache);
break;
}
@@ -418,8 +406,8 @@ set_fuse_mount_options (glusterfs_ctx_t *ctx, dict_t *options)
ret = dict_set_int32(options, "gid-timeout",
cmd_args->gid_timeout);
if (ret < 0) {
- gf_log("glusterfsd", GF_LOG_ERROR, "failed to set dict "
- "value for key gid-timeout");
+ gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
+ "gid-timeout");
goto err;
}
}
@@ -427,8 +415,8 @@ set_fuse_mount_options (glusterfs_ctx_t *ctx, dict_t *options)
ret = dict_set_int32 (options, "background-qlen",
cmd_args->background_qlen);
if (ret < 0) {
- gf_log("glusterfsd", GF_LOG_ERROR, "failed to set dict "
- "value for key background-qlen");
+ gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
+ "background-qlen");
goto err;
}
}
@@ -436,8 +424,8 @@ set_fuse_mount_options (glusterfs_ctx_t *ctx, dict_t *options)
ret = dict_set_int32 (options, "congestion-threshold",
cmd_args->congestion_threshold);
if (ret < 0) {
- gf_log("glusterfsd", GF_LOG_ERROR, "failed to set dict "
- "value for key congestion-threshold");
+ gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
+ "congestion-threshold");
goto err;
}
}
@@ -447,8 +435,7 @@ set_fuse_mount_options (glusterfs_ctx_t *ctx, dict_t *options)
ret = dict_set_static_ptr (options, ZR_DIRECT_IO_OPT,
"disable");
if (ret < 0) {
- gf_log ("glusterfsd", GF_LOG_ERROR,
- "failed to set 'disable' for key %s",
+ gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_5,
ZR_DIRECT_IO_OPT);
goto err;
}
@@ -457,16 +444,15 @@ set_fuse_mount_options (glusterfs_ctx_t *ctx, dict_t *options)
ret = dict_set_static_ptr (options, ZR_DIRECT_IO_OPT,
"enable");
if (ret < 0) {
- gf_log ("glusterfsd", GF_LOG_ERROR,
- "failed to set 'enable' for key %s",
+ gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_6,
ZR_DIRECT_IO_OPT);
goto err;
}
break;
case GF_OPTION_DEFERRED: /* default */
default:
- gf_log ("", GF_LOG_DEBUG, "fuse direct io type %d",
- cmd_args->fuse_direct_io_mode);
+ gf_msg_debug ("glusterfsd", 0, "fuse direct io type %d",
+ cmd_args->fuse_direct_io_mode);
break;
}
@@ -500,8 +486,8 @@ set_fuse_mount_options (glusterfs_ctx_t *ctx, dict_t *options)
ret = dict_set_static_ptr (options, "sync-to-mount",
"enable");
if (ret < 0) {
- gf_log ("glusterfsd", GF_LOG_ERROR,
- "failed to set dict value for key sync-mtab");
+ gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
+ "sync-mtab");
goto err;
}
}
@@ -510,8 +496,8 @@ set_fuse_mount_options (glusterfs_ctx_t *ctx, dict_t *options)
ret = dict_set_str (options, "use-readdirp",
cmd_args->use_readdirp);
if (ret < 0) {
- gf_log ("glusterfsd", GF_LOG_ERROR, "failed to set dict"
- " value for key use-readdirp");
+ gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
+ "use-readdirp");
goto err;
}
}
@@ -530,14 +516,13 @@ create_fuse_mount (glusterfs_ctx_t *ctx)
cmd_args = &ctx->cmd_args;
if (!cmd_args->mount_point) {
- gf_log ("", GF_LOG_TRACE,
- "mount point not found, not a client process");
+ gf_msg_trace ("glusterfsd", 0,
+ "mount point not found, not a client process");
return 0;
}
if (ctx->process_mode != GF_CLIENT_PROCESS) {
- gf_log("glusterfsd", GF_LOG_ERROR,
- "Not a client process, not performing mount operation");
+ gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_7);
return -1;
}
@@ -551,8 +536,7 @@ create_fuse_mount (glusterfs_ctx_t *ctx)
goto err;
if (xlator_set_type (master, "mount/fuse") == -1) {
- gf_log ("glusterfsd", GF_LOG_ERROR,
- "MOUNT-POINT %s initialization failed",
+ gf_msg ("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_8,
cmd_args->mount_point);
goto err;
}
@@ -570,8 +554,7 @@ create_fuse_mount (glusterfs_ctx_t *ctx)
ret = dict_set_static_ptr (master->options, ZR_FUSE_MOUNTOPTS,
cmd_args->fuse_mountopts);
if (ret < 0) {
- gf_log ("glusterfsd", GF_LOG_ERROR,
- "failed to set dict value for key %s",
+ gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_4,
ZR_FUSE_MOUNTOPTS);
goto err;
}
@@ -579,7 +562,8 @@ create_fuse_mount (glusterfs_ctx_t *ctx)
ret = xlator_init (master);
if (ret) {
- gf_log ("", GF_LOG_DEBUG, "failed to initialize fuse translator");
+ gf_msg_debug ("glusterfsd", 0,
+ "failed to initialize fuse translator");
goto err;
}
@@ -608,21 +592,19 @@ get_volfp (glusterfs_ctx_t *ctx)
ret = sys_lstat (cmd_args->volfile, &statbuf);
if (ret == -1) {
- gf_log ("glusterfsd", GF_LOG_ERROR,
- "%s: %s", cmd_args->volfile, strerror (errno));
+ gf_msg ("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_9,
+ cmd_args->volfile);
return NULL;
}
if ((specfp = fopen (cmd_args->volfile, "r")) == NULL) {
- gf_log ("glusterfsd", GF_LOG_ERROR,
- "volume file %s: %s",
- cmd_args->volfile,
- strerror (errno));
+ gf_msg ("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_9,
+ cmd_args->volfile);
return NULL;
}
- gf_log ("glusterfsd", GF_LOG_DEBUG,
- "loading volume file %s", cmd_args->volfile);
+ gf_msg_debug ("glusterfsd", 0, "loading volume file %s",
+ cmd_args->volfile);
return specfp;
}
@@ -658,8 +640,8 @@ gf_remember_backup_volfile_server (char *arg)
}
if (!server->volfile_server) {
- gf_log ("", GF_LOG_WARNING,
- "xlator option %s is invalid", arg);
+ gf_msg ("glusterfsd", GF_LOG_WARNING, 0, glusterfsd_msg_10,
+ arg);
goto out;
}
@@ -700,8 +682,7 @@ gf_remember_xlator_option (char *arg)
dot = strchr (arg, '.');
if (!dot) {
- gf_log ("", GF_LOG_WARNING,
- "xlator option %s is invalid", arg);
+ gf_msg ("", GF_LOG_WARNING, 0, glusterfsd_msg_10, arg);
goto out;
}
@@ -714,8 +695,7 @@ gf_remember_xlator_option (char *arg)
equals = strchr (arg, '=');
if (!equals) {
- gf_log ("", GF_LOG_WARNING,
- "xlator option %s is invalid", arg);
+ gf_msg ("", GF_LOG_WARNING, 0, glusterfsd_msg_10, arg);
goto out;
}
@@ -727,8 +707,7 @@ gf_remember_xlator_option (char *arg)
strncpy (option->key, dot + 1, (equals - dot - 1));
if (!*(equals + 1)) {
- gf_log ("", GF_LOG_WARNING,
- "xlator option %s is invalid", arg);
+ gf_msg ("", GF_LOG_WARNING, 0, glusterfsd_msg_10, arg);
goto out;
}
@@ -1124,8 +1103,7 @@ cleanup_and_exit (int signum)
if (!ctx)
return;
- gf_log_callingfn ("", GF_LOG_WARNING,
- "received signum (%d), shutting down", signum);
+ gf_msg_callingfn ("", GF_LOG_WARNING, 0, glusterfsd_msg_32, signum);
if (ctx->cleanup_started)
return;
@@ -1190,20 +1168,19 @@ reincarnate (int signum)
cmd_args = &ctx->cmd_args;
if (cmd_args->volfile_server) {
- gf_log ("glusterfsd", GF_LOG_INFO,
- "Fetching the volume file from server...");
+ gf_msg ("glusterfsd", GF_LOG_INFO, 0, glusterfsd_msg_11);
ret = glusterfs_volfile_fetch (ctx);
} else {
- gf_log ("glusterfsd", GF_LOG_DEBUG,
- "Not reloading volume specification file on SIGHUP");
+ gf_msg_debug ("glusterfsd", 0,
+ "Not reloading volume specification file"
+ " on SIGHUP");
}
/* Also, SIGHUP should do logrotate */
gf_log_logrotate (1);
if (ret < 0)
- gf_log ("glusterfsd", GF_LOG_ERROR,
- "volume initialization failed.");
+ gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_12);
return;
}
@@ -1253,8 +1230,7 @@ glusterfs_ctx_defaults_init (glusterfs_ctx_t *ctx)
ctx->process_uuid = generate_glusterfs_ctx_id ();
if (!ctx->process_uuid) {
- gf_log ("", GF_LOG_CRITICAL,
- "ERROR: glusterfs uuid generation failed");
+ gf_msg ("", GF_LOG_CRITICAL, 0, glusterfsd_msg_13);
goto out;
}
@@ -1262,22 +1238,19 @@ glusterfs_ctx_defaults_init (glusterfs_ctx_t *ctx)
ctx->iobuf_pool = iobuf_pool_new ();
if (!ctx->iobuf_pool) {
- gf_log ("", GF_LOG_CRITICAL,
- "ERROR: glusterfs iobuf pool creation failed");
+ gf_msg ("", GF_LOG_CRITICAL, 0, glusterfsd_msg_14, "iobuf");
goto out;
}
ctx->event_pool = event_pool_new (DEFAULT_EVENT_POOL_SIZE);
if (!ctx->event_pool) {
- gf_log ("", GF_LOG_CRITICAL,
- "ERROR: glusterfs event pool creation failed");
+ gf_msg ("", GF_LOG_CRITICAL, 0, glusterfsd_msg_14, "event");
goto out;
}
ctx->pool = GF_CALLOC (1, sizeof (call_pool_t), gfd_mt_call_pool_t);
if (!ctx->pool) {
- gf_log ("", GF_LOG_CRITICAL,
- "ERROR: glusterfs call pool creation failed");
+ gf_msg ("", GF_LOG_CRITICAL, 0, glusterfsd_msg_14, "call");
goto out;
}
@@ -1287,22 +1260,19 @@ glusterfs_ctx_defaults_init (glusterfs_ctx_t *ctx)
/* frame_mem_pool size 112 * 4k */
ctx->pool->frame_mem_pool = mem_pool_new (call_frame_t, 4096);
if (!ctx->pool->frame_mem_pool) {
- gf_log ("", GF_LOG_CRITICAL,
- "ERROR: glusterfs frame pool creation failed");
+ gf_msg ("", GF_LOG_CRITICAL, 0, glusterfsd_msg_14, "frame");
goto out;
}
/* stack_mem_pool size 256 * 1024 */
ctx->pool->stack_mem_pool = mem_pool_new (call_stack_t, 1024);
if (!ctx->pool->stack_mem_pool) {
- gf_log ("", GF_LOG_CRITICAL,
- "ERROR: glusterfs stack pool creation failed");
+ gf_msg ("", GF_LOG_CRITICAL, 0, glusterfsd_msg_14, "stack");
goto out;
}
ctx->stub_mem_pool = mem_pool_new (call_stub_t, 1024);
if (!ctx->stub_mem_pool) {
- gf_log ("", GF_LOG_CRITICAL,
- "ERROR: glusterfs stub pool creation failed");
+ gf_msg ("", GF_LOG_CRITICAL, 0, glusterfsd_msg_14, "stub");
goto out;
}
@@ -1373,43 +1343,36 @@ logging_init (glusterfs_ctx_t *ctx, const char *progpath)
{
cmd_args_t *cmd_args = NULL;
int ret = 0;
- char ident[1024] = {0,};
- char *progname = NULL;
- char *ptr = NULL;
cmd_args = &ctx->cmd_args;
if (cmd_args->log_file == NULL) {
ret = gf_set_log_file_path (cmd_args);
if (ret == -1) {
- fprintf (stderr, "ERROR: failed to set the log file path\n");
+ fprintf (stderr, "ERROR: failed to set the log file "
+ "path\n");
return -1;
}
}
-#ifdef GF_USE_SYSLOG
- progname = gf_strdup (progpath);
- snprintf (ident, 1024, "%s_%s", basename(progname),
- basename(cmd_args->log_file));
- GF_FREE (progname);
- /* remove .log suffix */
- if (NULL != (ptr = strrchr(ident, '.'))) {
- if (strcmp(ptr, ".log") == 0) {
- /* note: ptr points to location in ident only */
- ptr[0] = '\0';
+ if (cmd_args->log_ident == NULL) {
+ ret = gf_set_log_ident (cmd_args);
+ if (ret == -1) {
+ fprintf (stderr, "ERROR: failed to set the log "
+ "identity\n");
+ return -1;
}
}
- ptr = ident;
-#endif
- if (gf_log_init (ctx, cmd_args->log_file, ptr) == -1) {
+ /* finish log set parameters before init */
+ gf_log_set_loglevel (cmd_args->log_level);
+
+ if (gf_log_init (ctx, cmd_args->log_file, cmd_args->log_ident) == -1) {
fprintf (stderr, "ERROR: failed to open logfile %s\n",
cmd_args->log_file);
return -1;
}
- gf_log_set_loglevel (cmd_args->log_level);
-
return 0;
}
@@ -1453,9 +1416,7 @@ parse_cmdline (int argc, char *argv[], glusterfs_ctx_t *ctx)
/* Make sure after the parsing cli, if '--volfile-server' option is
given, then '--volfile-id' is mandatory */
if (cmd_args->volfile_server && !cmd_args->volfile_id) {
- gf_log ("glusterfs", GF_LOG_CRITICAL,
- "ERROR: '--volfile-id' is mandatory if '-s' OR "
- "'--volfile-server' option is given");
+ gf_msg ("glusterfs", GF_LOG_CRITICAL, 0, glusterfsd_msg_15);
ret = -1;
goto out;
}
@@ -1473,9 +1434,8 @@ parse_cmdline (int argc, char *argv[], glusterfs_ctx_t *ctx)
and exit */
ret = stat (cmd_args->volfile, &stbuf);
if (ret) {
- gf_log ("glusterfs", GF_LOG_CRITICAL,
- "ERROR: parsing the volfile failed (%s)\n",
- strerror (errno));
+ gf_msg ("glusterfs", GF_LOG_CRITICAL, errno,
+ glusterfsd_msg_16);
/* argp_usage (argp.) */
fprintf (stderr, "USAGE: %s [options] [mountpoint]\n",
argv[0]);
@@ -1551,9 +1511,8 @@ glusterfs_pidfile_setup (glusterfs_ctx_t *ctx)
pidfp = fopen (cmd_args->pid_file, "a+");
if (!pidfp) {
- gf_log ("glusterfsd", GF_LOG_ERROR,
- "pidfile %s error (%s)",
- cmd_args->pid_file, strerror (errno));
+ gf_msg ("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_17,
+ cmd_args->pid_file);
goto out;
}
@@ -1576,9 +1535,8 @@ glusterfs_pidfile_cleanup (glusterfs_ctx_t *ctx)
if (!ctx->pidfp)
return 0;
- gf_log ("glusterfsd", GF_LOG_TRACE,
- "pidfile %s cleanup",
- cmd_args->pid_file);
+ gf_msg_trace ("glusterfsd", 0, "pidfile %s cleanup",
+ cmd_args->pid_file);
if (ctx->cmd_args.pid_file) {
unlink (ctx->cmd_args.pid_file);
@@ -1607,39 +1565,34 @@ glusterfs_pidfile_update (glusterfs_ctx_t *ctx)
ret = lockf (fileno (pidfp), F_TLOCK, 0);
if (ret) {
- gf_log ("glusterfsd", GF_LOG_ERROR,
- "pidfile %s lock failed",
+ gf_msg ("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_18,
cmd_args->pid_file);
return ret;
}
ret = ftruncate (fileno (pidfp), 0);
if (ret) {
- gf_log ("glusterfsd", GF_LOG_ERROR,
- "pidfile %s truncation failed",
+ gf_msg ("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_20,
cmd_args->pid_file);
return ret;
}
ret = fprintf (pidfp, "%d\n", getpid ());
if (ret <= 0) {
- gf_log ("glusterfsd", GF_LOG_ERROR,
- "pidfile %s write failed",
+ gf_msg ("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_21,
cmd_args->pid_file);
return ret;
}
ret = fflush (pidfp);
if (ret) {
- gf_log ("glusterfsd", GF_LOG_ERROR,
- "pidfile %s write failed",
+ gf_msg ("glusterfsd", GF_LOG_ERROR, errno, glusterfsd_msg_21,
cmd_args->pid_file);
return ret;
}
- gf_log ("glusterfsd", GF_LOG_DEBUG,
- "pidfile %s updated with pid %d",
- cmd_args->pid_file, getpid ());
+ gf_msg_debug ("glusterfsd", 0, "pidfile %s updated with pid %d",
+ cmd_args->pid_file, getpid ());
return 0;
}
@@ -1723,9 +1676,7 @@ glusterfs_signals_setup (glusterfs_ctx_t *ctx)
ret = pthread_sigmask (SIG_BLOCK, &set, NULL);
if (ret) {
- gf_log ("glusterfsd", GF_LOG_WARNING,
- "failed to execute pthread_signmask %s",
- strerror (errno));
+ gf_msg ("glusterfsd", GF_LOG_WARNING, errno, glusterfsd_msg_22);
return ret;
}
@@ -1737,9 +1688,7 @@ glusterfs_signals_setup (glusterfs_ctx_t *ctx)
fallback to signals getting handled by other threads.
setup the signal handlers
*/
- gf_log ("glusterfsd", GF_LOG_WARNING,
- "failed to create pthread %s",
- strerror (errno));
+ gf_msg ("glusterfsd", GF_LOG_WARNING, errno, glusterfsd_msg_23);
return ret;
}
@@ -1784,8 +1733,7 @@ daemonize (glusterfs_ctx_t *ctx)
close (ctx->daemon_pipe[1]);
}
- gf_log ("daemonize", GF_LOG_ERROR,
- "Daemonization failed: %s", strerror(errno));
+ gf_msg ("daemonize", GF_LOG_ERROR, errno, glusterfsd_msg_24);
goto out;
case 0:
/* child */
@@ -1800,8 +1748,8 @@ daemonize (glusterfs_ctx_t *ctx)
if (ctx->mnt_pid > 0) {
ret = waitpid (ctx->mnt_pid, &cstatus, 0);
if (!(ret == ctx->mnt_pid && cstatus == 0)) {
- gf_log ("daemonize", GF_LOG_ERROR,
- "mount failed");
+ gf_msg ("daemonize", GF_LOG_ERROR, 0,
+ glusterfsd_msg_25);
exit (1);
}
}
@@ -1831,15 +1779,14 @@ glusterfs_process_volfp (glusterfs_ctx_t *ctx, FILE *fp)
graph = glusterfs_graph_construct (fp);
if (!graph) {
- gf_log ("", GF_LOG_ERROR, "failed to construct the graph");
+ gf_msg ("", GF_LOG_ERROR, 0, glusterfsd_msg_26);
goto out;
}
for (trav = graph->first; trav; trav = trav->next) {
if (strcmp (trav->type, "mount/fuse") == 0) {
- gf_log ("glusterfsd", GF_LOG_ERROR,
- "fuse xlator cannot be specified "
- "in volume file");
+ gf_msg ("glusterfsd", GF_LOG_ERROR, 0,
+ glusterfsd_msg_27);
goto out;
}
}
@@ -1897,8 +1844,7 @@ glusterfs_volumes_init (glusterfs_ctx_t *ctx)
fp = get_volfp (ctx);
if (!fp) {
- gf_log ("glusterfsd", GF_LOG_ERROR,
- "Cannot reach volume specification file");
+ gf_msg ("glusterfsd", GF_LOG_ERROR, 0, glusterfsd_msg_28);
ret = -1;
goto out;
}
@@ -1925,8 +1871,7 @@ main (int argc, char *argv[])
ctx = glusterfs_ctx_new ();
if (!ctx) {
- gf_log ("glusterfs", GF_LOG_CRITICAL,
- "ERROR: glusterfs context not initialized");
+ gf_msg ("glusterfs", GF_LOG_CRITICAL, 0, glusterfsd_msg_29);
return ENOMEM;
}
glusterfsd_ctx = ctx;
@@ -1965,8 +1910,7 @@ main (int argc, char *argv[])
strcat (cmdlinestr, " ");
strcat (cmdlinestr, argv[i]);
}
- gf_log (argv[0], GF_LOG_INFO,
- "Started running %s version %s (%s)",
+ gf_msg (argv[0], GF_LOG_INFO, 0, glusterfsd_msg_30,
argv[0], PACKAGE_VERSION, cmdlinestr);
}
@@ -1982,8 +1926,7 @@ main (int argc, char *argv[])
ctx->env = syncenv_new (0, 0, 0);
if (!ctx->env) {
- gf_log ("", GF_LOG_ERROR,
- "Could not create new sync-environment");
+ gf_msg ("", GF_LOG_ERROR, 0, glusterfsd_msg_31);
goto out;
}
diff --git a/libglusterfs/src/Makefile.am b/libglusterfs/src/Makefile.am
index 634e217ed..b1a853687 100644
--- a/libglusterfs/src/Makefile.am
+++ b/libglusterfs/src/Makefile.am
@@ -42,7 +42,8 @@ noinst_HEADERS = common-utils.h defaults.h dict.h glusterfs.h hashfn.h timespec.
$(CONTRIBDIR)/uuid/uuid.h $(CONTRIBDIR)/uuid/uuidP.h \
$(CONTRIB_BUILDDIR)/uuid/uuid_types.h syncop.h graph-utils.h trie.h \
run.h options.h lkowner.h fd-lk.h circ-buff.h event-history.h \
- gidcache.h client_t.h glusterfs-acl.h
+ gidcache.h client_t.h glusterfs-acl.h glfs-message-id.h \
+ template-component-messages.h
EXTRA_DIST = graph.l graph.y
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c
index 1dfb418e4..1ccb27d16 100644
--- a/libglusterfs/src/common-utils.c
+++ b/libglusterfs/src/common-utils.c
@@ -281,26 +281,37 @@ err:
struct xldump {
int lineno;
- FILE *logfp;
};
-
+/* to catch any format discrepencies that may arise in code */
+static int nprintf (struct xldump *dump, const char *fmt, ...)
+ __attribute__ ((__format__ (__printf__, 2, 3)));
static int
nprintf (struct xldump *dump, const char *fmt, ...)
{
- va_list ap;
- int ret = 0;
-
+ va_list ap;
+ char *msg = NULL;
+ char header[32];
+ int ret = 0;
- ret += fprintf (dump->logfp, "%3d: ", ++dump->lineno);
+ ret = snprintf (header, 32, "%3d:", ++dump->lineno);
+ if (ret < 0)
+ goto out;
- va_start (ap, fmt);
- ret += vfprintf (dump->logfp, fmt, ap);
- va_end (ap);
+ va_start (ap, fmt);
+ ret = vasprintf (&msg, fmt, ap);
+ va_end (ap);
+ if (-1 == ret)
+ goto out;
- ret += fprintf (dump->logfp, "\n");
+ /* NOTE: No ret value from gf_msg_plain, so unable to compute printed
+ * characters. The return value from nprintf is not used, so for now
+ * living with it */
+ gf_msg_plain (GF_LOG_WARNING, "%s %s", header, msg);
- return ret;
+out:
+ FREE (msg);
+ return 0;
}
@@ -349,175 +360,125 @@ xldump (xlator_t *each, void *d)
xldump_subvolumes (each, d);
nprintf (d, "end-volume");
- nprintf (d, "");
+ nprintf (d, " ");
}
void
gf_log_dump_graph (FILE *specfp, glusterfs_graph_t *graph)
{
- glusterfs_ctx_t *ctx;
struct xldump xld = {0, };
-
- ctx = THIS->ctx;
- xld.logfp = ctx->log.gf_log_logfile;
-
- fprintf (ctx->log.gf_log_logfile, "Final graph:\n");
- fprintf (ctx->log.gf_log_logfile,
- "+---------------------------------------"
- "---------------------------------------+\n");
+ gf_msg_plain (GF_LOG_WARNING, "Final graph:");
+ gf_msg_plain (GF_LOG_WARNING,
+ "+---------------------------------------"
+ "---------------------------------------+");
xlator_foreach_depth_first (graph->top, xldump, &xld);
- fprintf (ctx->log.gf_log_logfile,
- "+---------------------------------------"
- "---------------------------------------+\n");
- fflush (ctx->log.gf_log_logfile);
+ gf_msg_plain (GF_LOG_WARNING,
+ "+---------------------------------------"
+ "---------------------------------------+");
}
static void
-gf_dump_config_flags (int fd)
+gf_dump_config_flags ()
{
- int ret = 0;
-
- ret = write (fd, "configuration details:\n", 23);
- if (ret == -1)
- goto out;
+ gf_msg_plain_nomem (GF_LOG_ALERT, "configuration details:");
/* have argp */
#ifdef HAVE_ARGP
- ret = write (fd, "argp 1\n", 7);
- if (ret == -1)
- goto out;
+ gf_msg_plain_nomem (GF_LOG_ALERT, "argp 1");
#endif
/* ifdef if found backtrace */
#ifdef HAVE_BACKTRACE
- ret = write (fd, "backtrace 1\n", 12);
- if (ret == -1)
- goto out;
+ gf_msg_plain_nomem (GF_LOG_ALERT, "backtrace 1");
#endif
/* Berkeley-DB version has cursor->get() */
#ifdef HAVE_BDB_CURSOR_GET
- ret = write (fd, "bdb->cursor->get 1\n", 19);
- if (ret == -1)
- goto out;
+ gf_msg_plain_nomem (GF_LOG_ALERT, "bdb->cursor->get 1");
#endif
/* Define to 1 if you have the <db.h> header file. */
#ifdef HAVE_DB_H
- ret = write (fd, "db.h 1\n", 7);
- if (ret == -1)
- goto out;
+ gf_msg_plain_nomem (GF_LOG_ALERT, "db.h 1");
#endif
/* Define to 1 if you have the <dlfcn.h> header file. */
#ifdef HAVE_DLFCN_H
- ret = write (fd, "dlfcn 1\n", 8);
- if (ret == -1)
- goto out;
+ gf_msg_plain_nomem (GF_LOG_ALERT, "dlfcn 1");
#endif
/* define if fdatasync exists */
#ifdef HAVE_FDATASYNC
- ret = write (fd, "fdatasync 1\n", 12);
- if (ret == -1)
- goto out;
+ gf_msg_plain_nomem (GF_LOG_ALERT, "fdatasync 1");
#endif
/* Define to 1 if you have the `pthread' library (-lpthread). */
#ifdef HAVE_LIBPTHREAD
- ret = write (fd, "libpthread 1\n", 13);
- if (ret == -1)
- goto out;
+ gf_msg_plain_nomem (GF_LOG_ALERT, "libpthread 1");
#endif
/* define if llistxattr exists */
#ifdef HAVE_LLISTXATTR
- ret = write (fd, "llistxattr 1\n", 13);
- if (ret == -1)
- goto out;
+ gf_msg_plain_nomem (GF_LOG_ALERT, "llistxattr 1");
#endif
/* define if found setfsuid setfsgid */
#ifdef HAVE_SET_FSID
- ret = write (fd, "setfsid 1\n", 10);
- if (ret == -1)
- goto out;
+ gf_msg_plain_nomem (GF_LOG_ALERT, "setfsid 1");
#endif
/* define if found spinlock */
#ifdef HAVE_SPINLOCK
- ret = write (fd, "spinlock 1\n", 11);
- if (ret == -1)
- goto out;
+ gf_msg_plain_nomem (GF_LOG_ALERT, "spinlock 1");
#endif
/* Define to 1 if you have the <sys/epoll.h> header file. */
#ifdef HAVE_SYS_EPOLL_H
- ret = write (fd, "epoll.h 1\n", 10);
- if (ret == -1)
- goto out;
+ gf_msg_plain_nomem (GF_LOG_ALERT, "epoll.h 1");
#endif
/* Define to 1 if you have the <sys/extattr.h> header file. */
#ifdef HAVE_SYS_EXTATTR_H
- ret = write (fd, "extattr.h 1\n", 12);
- if (ret == -1)
- goto out;
+ gf_msg_plain_nomem (GF_LOG_ALERT, "extattr.h 1");
#endif
/* Define to 1 if you have the <sys/xattr.h> header file. */
#ifdef HAVE_SYS_XATTR_H
- ret = write (fd, "xattr.h 1\n", 10);
- if (ret == -1)
- goto out;
+ gf_msg_plain_nomem (GF_LOG_ALERT, "xattr.h 1");
#endif
/* define if found st_atim.tv_nsec */
#ifdef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
- ret = write (fd, "st_atim.tv_nsec 1\n", 18);
- if (ret == -1)
- goto out;
+ gf_msg_plain_nomem (GF_LOG_ALERT, "st_atim.tv_nsec 1");
#endif
/* define if found st_atimespec.tv_nsec */
#ifdef HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC
- ret = write (fd, "st_atimespec.tv_nsec 1\n",23);
- if (ret == -1)
- goto out;
+ gf_msg_plain_nomem (GF_LOG_ALERT, "st_atimespec.tv_nsec 1");
#endif
/* Define to the full name and version of this package. */
#ifdef PACKAGE_STRING
{
char msg[128];
- sprintf (msg, "package-string: %s\n", PACKAGE_STRING);
- ret = write (fd, msg, strlen (msg));
- if (ret == -1)
- goto out;
+ sprintf (msg, "package-string: %s", PACKAGE_STRING);
+ gf_msg_plain_nomem (GF_LOG_ALERT, msg);
}
#endif
-out:
return;
}
-/* Obtain a backtrace and print it to stdout. */
-/* TODO: It looks like backtrace_symbols allocates memory,
- it may be problem because mostly memory allocation/free causes 'sigsegv' */
-
+/* Obtain a backtrace and print it to the log */
void
gf_print_trace (int32_t signum, glusterfs_ctx_t *ctx)
{
char msg[1024] = {0,};
char timestr[64] = {0,};
- int ret = 0;
- int fd = 0;
-
- fd = fileno (ctx->log.gf_log_logfile);
/* Now every gf_log call will just write to a buffer and when the
* buffer becomes full, its written to the log-file. Suppose the process
@@ -526,75 +487,51 @@ gf_print_trace (int32_t signum, glusterfs_ctx_t *ctx)
* contents of the buffer to the log file before printing the backtrace
* which helps in debugging.
*/
- fflush (ctx->log.gf_log_logfile);
+ gf_log_flush();
/* Pending frames, (if any), list them in order */
- ret = write (fd, "pending frames:\n", 16);
- if (ret < 0)
- goto out;
-
+ gf_msg_plain_nomem (GF_LOG_ALERT, "pending frames:");
{
- struct list_head *trav = ((call_pool_t *)ctx->pool)->all_frames.next;
+ struct list_head *trav =
+ ((call_pool_t *)ctx->pool)->all_frames.next;
while (trav != (&((call_pool_t *)ctx->pool)->all_frames)) {
- call_frame_t *tmp = (call_frame_t *)(&((call_stack_t *)trav)->frames);
+ call_frame_t *tmp =
+ (call_frame_t *)(&((call_stack_t *)trav)->frames);
if (tmp->root->type == GF_OP_TYPE_FOP)
- sprintf (msg,"frame : type(%d) op(%s)\n",
+ sprintf (msg,"frame : type(%d) op(%s)",
tmp->root->type,
gf_fop_list[tmp->root->op]);
else
- sprintf (msg,"frame : type(%d) op(%d)\n",
+ sprintf (msg,"frame : type(%d) op(%d)",
tmp->root->type,
tmp->root->op);
- ret = write (fd, msg, strlen (msg));
- if (ret < 0)
- goto out;
+ gf_msg_plain_nomem (GF_LOG_ALERT, msg);
trav = trav->next;
}
- ret = write (fd, "\n", 1);
- if (ret < 0)
- goto out;
}
- sprintf (msg, "patchset: %s\n", GLUSTERFS_REPOSITORY_REVISION);
- ret = write (fd, msg, strlen (msg));
- if (ret < 0)
- goto out;
-
- sprintf (msg, "signal received: %d\n", signum);
- ret = write (fd, msg, strlen (msg));
- if (ret < 0)
- goto out;
+ sprintf (msg, "patchset: %s", GLUSTERFS_REPOSITORY_REVISION);
+ gf_msg_plain_nomem (GF_LOG_ALERT, msg);
+ sprintf (msg, "signal received: %d", signum);
+ gf_msg_plain_nomem (GF_LOG_ALERT, msg);
{
/* Dump the timestamp of the crash too, so the previous logs
can be related */
- gf_time_fmt (timestr, sizeof timestr, time (NULL), gf_timefmt_FT);
- ret = write (fd, "time of crash: ", 15);
- if (ret < 0)
- goto out;
- ret = write (fd, timestr, strlen (timestr));
- if (ret < 0)
- goto out;
+ gf_time_fmt (timestr, sizeof timestr, time (NULL),
+ gf_timefmt_FT);
+ gf_msg_plain_nomem (GF_LOG_ALERT, "time of crash: ");
+ gf_msg_plain_nomem (GF_LOG_ALERT, timestr);
}
- gf_dump_config_flags (fd);
+ gf_dump_config_flags ();
#if HAVE_BACKTRACE
- /* Print 'backtrace' */
- {
- void *array[200];
- size_t size;
-
- size = backtrace (array, 200);
- backtrace_symbols_fd (&array[1], size-1, fd);
- sprintf (msg, "---------\n");
- ret = write (fd, msg, strlen (msg));
- if (ret < 0)
- goto out;
- }
+ gf_msg_backtrace_nomem (GF_LOG_ALERT, 200);
+ sprintf (msg, "---------");
+ gf_msg_plain_nomem (GF_LOG_ALERT, msg);
#endif /* HAVE_BACKTRACE */
-out:
/* Send a signal to terminate the process */
signal (signum, SIG_DFL);
raise (signum);
@@ -2919,6 +2856,42 @@ done:
}
int
+gf_set_log_ident (cmd_args_t *cmd_args)
+{
+ int ret = 0;
+ char *ptr = NULL;
+
+ if (cmd_args->log_file == NULL) {
+ /* no ident source */
+ return 0;
+ }
+
+ /* TODO: Some idents would look like, etc-glusterfs-glusterd.vol, which
+ * seems ugly and can be bettered? */
+ /* just get the filename as the ident */
+ if (NULL != (ptr = strrchr (cmd_args->log_file, '/'))) {
+ ret = gf_asprintf (&cmd_args->log_ident, "%s", ptr + 1);
+ } else {
+ ret = gf_asprintf (&cmd_args->log_ident, "%s",
+ cmd_args->log_file);
+ }
+
+ if (ret > 0)
+ ret = 0;
+ else
+ return ret;
+
+ /* remove .log suffix */
+ if (NULL != (ptr = strrchr (cmd_args->log_ident, '.'))) {
+ if (strcmp (ptr, ".log") == 0) {
+ ptr[0] = '\0';
+ }
+ }
+
+ return ret;
+}
+
+int
gf_thread_create (pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg)
{
diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h
index f877590f4..ee4e5b7e6 100644
--- a/libglusterfs/src/common-utils.h
+++ b/libglusterfs/src/common-utils.h
@@ -121,6 +121,7 @@ int32_t gf_resolve_ip6 (const char *hostname, uint16_t port, int family,
void gf_log_dump_graph (FILE *specfp, glusterfs_graph_t *graph);
void gf_print_trace (int32_t signal, glusterfs_ctx_t *ctx);
int gf_set_log_file_path (cmd_args_t *cmd_args);
+int gf_set_log_ident (cmd_args_t *cmd_args);
#define VECTORSIZE(count) (count * (sizeof (struct iovec)))
diff --git a/libglusterfs/src/glfs-message-id.h b/libglusterfs/src/glfs-message-id.h
new file mode 100644
index 000000000..42c16f12d
--- /dev/null
+++ b/libglusterfs/src/glfs-message-id.h
@@ -0,0 +1,48 @@
+/*
+ Copyright (c) 2013 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+*/
+
+#ifndef _GLFS_MESSAGE_ID_H_
+#define _GLFS_MESSAGE_ID_H_
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+/* Base of all message IDs, all message IDs would be
+ * greater than this */
+#define GLFS_MSGID_BASE 100000
+
+/* Segment size of allocated range. Any component needing more than this
+ * segment size should take multiple segments (at times non contiguous,
+ * if extensions are being made post the next segment already allocated) */
+#define GLFS_MSGID_SEGMENT 1000
+
+/* Per module message segments allocated */
+/* NOTE: For any new module add to the end the modules */
+#define GLFS_MSGID_COMP_GLUSTERFSD GLFS_MSGID_BASE
+#define GLFS_MSGID_COMP_LIBGLUSTERFS GLFS_MSGID_COMP_GLUSTERFSD + \
+ GLFS_MSGID_SEGMENT
+#define GLFS_MSGID_COMP_RPC_LIB GLFS_MSGID_COMP_LIBGLUSTERFS + \
+ GLFS_MSGID_SEGMENT
+#define GLFS_MSGID_COMP_RPC_TRANSPORT GLFS_MSGID_COMP_RPC_LIB + \
+ GLFS_MSGID_SEGMENT
+#define GLFS_MSGID_COMP_API GLFS_MSGID_COMP_RPC_TRANSPORT + \
+ GLFS_MSGID_SEGMENT
+#define GLFS_MSGID_COMP_CLI GLFS_MSGID_COMP_API + \
+ GLFS_MSGID_SEGMENT
+/* glusterd has a lot of messages, taking 2 segments for the same */
+#define GLFS_MSGID_GLUSTERD GLFS_MSGID_COMP_CLI + \
+ GLFS_MSGID_SEGMENT + \
+ GLFS_MSGID_SEGMENT
+
+/* --- new segments for messages goes above this line --- */
+
+#endif /* !_GLFS_MESSAGE_ID_H_ */
diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h
index 5ce0d6e70..852d686c1 100644
--- a/libglusterfs/src/glusterfs.h
+++ b/libglusterfs/src/glusterfs.h
@@ -342,6 +342,7 @@ struct _cmd_args {
char *log_server;
gf_loglevel_t log_level;
char *log_file;
+ char *log_ident;
int32_t max_connect_attempts;
/* advanced options */
uint32_t volfile_server_port;
diff --git a/libglusterfs/src/logging.c b/libglusterfs/src/logging.c
index 2bd40b2c2..f343731c7 100644
--- a/libglusterfs/src/logging.c
+++ b/libglusterfs/src/logging.c
@@ -22,7 +22,6 @@
#include <string.h>
#include <stdlib.h>
-#ifdef GF_USE_SYSLOG
#include <libintl.h>
#include <syslog.h>
#include <sys/stat.h>
@@ -32,7 +31,9 @@
#define GF_SYSLOG_CEE_FORMAT \
"@cee: {\"msg\": \"%s\", \"gf_code\": \"%u\", \"gf_message\": \"%s\"}"
#define GF_LOG_CONTROL_FILE "/etc/glusterfs/logger.conf"
-#endif /* GF_USE_SYSLOG */
+#define GF_LOG_BACKTRACE_DEPTH 5
+#define GF_LOG_BACKTRACE_SIZE 4096
+#define GF_LOG_TIMESTR_SIZE 256
#include "xlator.h"
#include "logging.h"
@@ -47,6 +48,19 @@
#include <execinfo.h>
#endif
+static char *gf_level_strings[] = {"", /* NONE */
+ "M", /* EMERGENCY */
+ "A", /* ALERT */
+ "C", /* CRITICAL */
+ "E", /* ERROR */
+ "W", /* WARNING */
+ "N", /* NOTICE */
+ "I", /* INFO */
+ "D", /* DEBUG */
+ "T", /* TRACE */
+ ""
+};
+
/* Ideally this should get moved to logging.h */
struct _msg_queue {
struct list_head msgs;
@@ -60,41 +74,77 @@ struct _log_msg {
void
gf_log_logrotate (int signum)
{
- THIS->ctx->log.logrotate = 1;
+ glusterfs_ctx_t *ctx = NULL;
+
+ ctx = THIS->ctx;
+
+ if (ctx)
+ ctx->log.logrotate = 1;
}
void
gf_log_enable_syslog (void)
{
- THIS->ctx->log.gf_log_syslog = 1;
+ glusterfs_ctx_t *ctx = NULL;
+
+ ctx = THIS->ctx;
+
+ if (ctx)
+ ctx->log.gf_log_syslog = 1;
}
void
gf_log_disable_syslog (void)
{
- THIS->ctx->log.gf_log_syslog = 0;
+ glusterfs_ctx_t *ctx = NULL;
+
+ ctx = THIS->ctx;
+
+ if (ctx)
+ ctx->log.gf_log_syslog = 0;
}
gf_loglevel_t
gf_log_get_loglevel (void)
{
- return THIS->ctx->log.loglevel;
+ glusterfs_ctx_t *ctx = NULL;
+
+ ctx = THIS->ctx;
+
+ if (ctx)
+ return ctx->log.loglevel;
+ else
+ /* return global defaluts (see gf_log_globals_init) */
+ return GF_LOG_INFO;
}
void
gf_log_set_loglevel (gf_loglevel_t level)
{
- THIS->ctx->log.loglevel = level;
-}
+ glusterfs_ctx_t *ctx = NULL;
+ ctx = THIS->ctx;
-gf_loglevel_t
-gf_log_get_xl_loglevel (void *this)
+ if (ctx)
+ ctx->log.loglevel = level;
+}
+
+void
+gf_log_flush (void)
{
- xlator_t *xl = this;
- if (!xl)
- return 0;
- return xl->loglevel;
+ xlator_t *this = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+
+ this = THIS;
+ ctx = this->ctx;
+
+ if (ctx && ctx->log.logger == gf_logger_glusterlog) {
+ pthread_mutex_lock (&ctx->log.logfile_mutex);
+ fflush (ctx->log.gf_log_logfile);
+ pthread_mutex_unlock (&ctx->log.logfile_mutex);
+ }
+
+ return;
}
void
@@ -107,9 +157,142 @@ gf_log_set_xl_loglevel (void *this, gf_loglevel_t level)
xl->loglevel = level;
}
+/* TODO: The following get/set functions are yet not invoked from anywhere
+ * in the code. The _intention_ is to pass CLI arguments to various daemons
+ * that are started, which would then invoke these set APIs as required.
+ *
+ * glusterd would read the defaults from its .vol file configuration shipped
+ * as a part of the packages distributed.
+ *
+ * For any gluster* daemon that is started the shipped configuration becomes the
+ * default, if a volume has to change its logging format or logger, then a
+ * gluster CLI is invoked to set this property for the volume in question.
+ *
+ * The property is maintained by glusterd, and passed to the daemon as a CLI
+ * option, IOW persistence of the option is maintained by glusterd persistent
+ * storage (i.e .vol file) only
+ *
+ * care needs to be taken to configure and start daemons based on the versions
+ * that supports these features */
+gf_log_format_t
+gf_log_get_logformat (void)
+{
+ glusterfs_ctx_t *ctx = NULL;
+
+ ctx = THIS->ctx;
+
+ if (ctx)
+ return ctx->log.logformat;
+ else
+ /* return global defaluts (see gf_log_globals_init) */
+ return gf_logformat_withmsgid;
+}
+
+void
+gf_log_set_logformat (gf_log_format_t format)
+{
+ glusterfs_ctx_t *ctx = NULL;
+
+ ctx = THIS->ctx;
+
+ if (ctx)
+ ctx->log.logformat = format;
+}
+
+gf_log_logger_t
+gf_log_get_logger (void)
+{
+ glusterfs_ctx_t *ctx = NULL;
+
+ ctx = THIS->ctx;
+
+ if (ctx)
+ return ctx->log.logger;
+ else
+ /* return global defaluts (see gf_log_globals_init) */
+ return gf_logger_glusterlog;
+}
+
+void
+gf_log_set_logger (gf_log_logger_t logger)
+{
+ glusterfs_ctx_t *ctx = NULL;
+
+ ctx = THIS->ctx;
+
+ if (ctx)
+ ctx->log.logger = logger;
+}
+
+gf_loglevel_t
+gf_log_get_xl_loglevel (void *this)
+{
+ xlator_t *xl = this;
+ if (!xl)
+ return 0;
+ return xl->loglevel;
+}
+
+static void
+gf_log_rotate(glusterfs_ctx_t *ctx)
+{
+ int fd = -1;
+ FILE *new_logfile = NULL;
+ FILE *old_logfile = NULL;
+
+ /* not involving locks on initial check to speed it up */
+ if (ctx->log.logrotate) {
+ /* let only one winner through on races */
+ pthread_mutex_lock (&ctx->log.logfile_mutex);
+
+ if (!ctx->log.logrotate) {
+ pthread_mutex_unlock (&ctx->log.logfile_mutex);
+ return;
+ } else {
+ ctx->log.logrotate = 0;
+ pthread_mutex_unlock (&ctx->log.logfile_mutex);
+ }
+
+ fd = open (ctx->log.filename,
+ O_CREAT | O_RDONLY, S_IRUSR | S_IWUSR);
+ if (fd < 0) {
+ gf_log ("logrotate", GF_LOG_ERROR,
+ "%s", strerror (errno));
+ return;
+ }
+ close (fd);
+
+ new_logfile = fopen (ctx->log.filename, "a");
+ if (!new_logfile) {
+ gf_log ("logrotate", GF_LOG_CRITICAL,
+ "failed to open logfile %s (%s)",
+ ctx->log.filename, strerror (errno));
+ return;
+ }
+
+ pthread_mutex_lock (&ctx->log.logfile_mutex);
+ {
+ if (ctx->log.logfile)
+ old_logfile = ctx->log.logfile;
+
+ ctx->log.gf_log_logfile = ctx->log.logfile =
+ new_logfile;
+ }
+ pthread_mutex_unlock (&ctx->log.logfile_mutex);
+
+ if (old_logfile != NULL)
+ fclose (old_logfile);
+ }
+
+ return;
+}
+
void
gf_log_globals_fini (void)
{
+ /* TODO: Nobody is invoking the fini, but cleanup needs to happen here,
+ * needs cleanup for, log.ident, log.filename, closelog, log file close
+ * rotate state, possibly under a lock */
pthread_mutex_destroy (&THIS->ctx->log.logfile_mutex);
}
@@ -122,7 +305,8 @@ int
gf_log_fini (void *data)
{
glusterfs_ctx_t *ctx = data;
- int ret = 0;
+ int ret = 0;
+ FILE *old_logfile = NULL;
if (ctx == NULL) {
ret = -1;
@@ -132,8 +316,8 @@ gf_log_fini (void *data)
pthread_mutex_lock (&ctx->log.logfile_mutex);
{
if (ctx->log.logfile) {
- if (fclose (ctx->log.logfile) != 0)
- ret = -1;
+ old_logfile = ctx->log.logfile;
+
/* Logfile needs to be set to NULL, so that any
call to gf_log after calling gf_log_fini, will
log the message to stderr.
@@ -144,11 +328,13 @@ gf_log_fini (void *data)
}
pthread_mutex_unlock (&ctx->log.logfile_mutex);
+ if (old_logfile && (fclose (old_logfile) != 0))
+ ret = -1;
+
out:
return ret;
}
-#ifdef GF_USE_SYSLOG
/**
* gf_get_error_message -function to get error message for given error code
* @error_code: error code defined by log book
@@ -186,10 +372,13 @@ gf_openlog (const char *ident, int option, int facility)
_facility = LOG_LOCAL1;
}
+ /* TODO: Should check for errors here and return appropriately */
setlocale(LC_ALL, "");
bindtextdomain("gluster", "/usr/share/locale");
textdomain("gluster");
+ /* close the previous syslog if open as we are changing settings */
+ closelog ();
openlog(ident, _option, _facility);
}
@@ -347,7 +536,6 @@ gf_syslog (int error_code, int facility_priority, char *format, ...)
}
va_end (ap);
}
-#endif /* GF_USE_SYSLOG */
void
gf_log_globals_init (void *data)
@@ -359,47 +547,45 @@ gf_log_globals_init (void *data)
ctx->log.loglevel = GF_LOG_INFO;
ctx->log.gf_log_syslog = 1;
ctx->log.sys_log_level = GF_LOG_CRITICAL;
+ ctx->log.logger = gf_logger_glusterlog;
+ ctx->log.logformat = gf_logformat_withmsgid;
-#ifndef GF_USE_SYSLOG
#ifdef GF_LINUX_HOST_OS
/* For the 'syslog' output. one can grep 'GlusterFS' in syslog
for serious logs */
openlog ("GlusterFS", LOG_PID, LOG_DAEMON);
#endif
-#endif
+
}
int
gf_log_init (void *data, const char *file, const char *ident)
{
glusterfs_ctx_t *ctx = NULL;
- int fd = -1;
+ int fd = -1;
+ struct stat buf;
ctx = data;
-#if defined(GF_USE_SYSLOG)
- {
- /* use default ident and option */
- /* TODO: make FACILITY configurable than LOG_DAEMON */
- struct stat buf;
-
- if (stat (GF_LOG_CONTROL_FILE, &buf) == 0) {
- /* use syslog logging */
- ctx->log.log_control_file_found = 1;
- if (ident) {
- /* we need to keep this value as */
- /* syslog uses it on every logging */
- ctx->log.ident = gf_strdup (ident);
- gf_openlog (ctx->log.ident, -1, LOG_DAEMON);
- } else {
- gf_openlog (NULL, -1, LOG_DAEMON);
- }
- } else {
- /* use old style logging */
- ctx->log.log_control_file_found = 0;
- }
+ if (ident) {
+ ctx->log.ident = gf_strdup (ident);
+ }
+
+ /* we keep the files and the syslog open, so that on logger change, we
+ * are ready to log anywhere, that the new value specifies */
+ if (ctx->log.ident) {
+ gf_openlog (ctx->log.ident, -1, LOG_DAEMON);
+ } else {
+ gf_openlog (NULL, -1, LOG_DAEMON);
+ }
+ /* TODO: make FACILITY configurable than LOG_DAEMON */
+ if (stat (GF_LOG_CONTROL_FILE, &buf) == 0) {
+ /* use syslog logging */
+ ctx->log.log_control_file_found = 1;
+ } else {
+ /* use old style logging */
+ ctx->log.log_control_file_found = 0;
}
-#endif
if (!file){
fprintf (stderr, "ERROR: no filename specified\n");
@@ -407,7 +593,7 @@ gf_log_init (void *data, const char *file, const char *ident)
}
if (strcmp (file, "-") == 0) {
- file = "/dev/stderr";
+ file = "/dev/stderr";
}
ctx->log.filename = gf_strdup (file);
@@ -419,8 +605,8 @@ gf_log_init (void *data, const char *file, const char *ident)
fd = open (file, O_CREAT | O_RDONLY, S_IRUSR | S_IWUSR);
if (fd < 0) {
- fprintf (stderr, "ERROR: failed to create logfile \"%s\" (%s)\n",
- file, strerror (errno));
+ fprintf (stderr, "ERROR: failed to create logfile"
+ " \"%s\" (%s)\n", file, strerror (errno));
return -1;
}
close (fd);
@@ -440,21 +626,29 @@ gf_log_init (void *data, const char *file, const char *ident)
void
set_sys_log_level (gf_loglevel_t level)
{
- THIS->ctx->log.sys_log_level = level;
+ glusterfs_ctx_t *ctx = NULL;
+
+ ctx = THIS->ctx;
+
+ if (ctx)
+ ctx->log.sys_log_level = level;
}
int
-_gf_log_nomem (const char *domain, const char *file,
- const char *function, int line, gf_loglevel_t level,
- size_t size)
+_gf_log_callingfn (const char *domain, const char *file, const char *function,
+ int line, gf_loglevel_t level, const char *fmt, ...)
{
const char *basename = NULL;
xlator_t *this = NULL;
- struct timeval tv = {0,};
- int ret = 0;
- char msg[8092] = {0,};
+ char *str1 = NULL;
+ char *str2 = NULL;
+ char *msg = NULL;
char timestr[256] = {0,};
char callstr[4096] = {0,};
+ struct timeval tv = {0,};
+ size_t len = 0;
+ int ret = 0;
+ va_list ap;
glusterfs_ctx_t *ctx = NULL;
this = THIS;
@@ -479,7 +673,7 @@ _gf_log_nomem (const char *domain, const char *file,
"T", /* TRACE */
""};
- if (!domain || !file || !function) {
+ if (!domain || !file || !function || !fmt) {
fprintf (stderr,
"logging: %s:%s():%d: invalid argument\n",
__FILE__, __PRETTY_FUNCTION__, __LINE__);
@@ -497,28 +691,27 @@ _gf_log_nomem (const char *domain, const char *file,
do {
void *array[5];
char **callingfn = NULL;
- size_t bt_size = 0;
+ size_t size = 0;
- bt_size = backtrace (array, 5);
- if (bt_size)
- callingfn = backtrace_symbols (&array[2], bt_size-2);
+ size = backtrace (array, 5);
+ if (size)
+ callingfn = backtrace_symbols (&array[2], size-2);
if (!callingfn)
break;
- if (bt_size == 5)
+ if (size == 5)
snprintf (callstr, 4096, "(-->%s (-->%s (-->%s)))",
callingfn[2], callingfn[1], callingfn[0]);
- if (bt_size == 4)
+ if (size == 4)
snprintf (callstr, 4096, "(-->%s (-->%s))",
callingfn[1], callingfn[0]);
- if (bt_size == 3)
+ if (size == 3)
snprintf (callstr, 4096, "(-->%s)", callingfn[0]);
free (callingfn);
} while (0);
#endif /* HAVE_BACKTRACE */
-#if defined(GF_USE_SYSLOG)
if (ctx->log.log_control_file_found)
{
int priority;
@@ -529,30 +722,50 @@ _gf_log_nomem (const char *domain, const char *file,
} else {
priority = level - 1;
}
+
+ va_start (ap, fmt);
+ vasprintf (&str2, fmt, ap);
+ va_end (ap);
+
gf_syslog (GF_ERR_DEV, priority,
- "[%s:%d:%s] %s %s: no memory "
- "available for size (%"GF_PRI_SIZET")",
- basename, line, function, callstr, domain,
- size);
+ "[%s:%d:%s] %s %d-%s: %s",
+ basename, line, function,
+ callstr,
+ ((this->graph) ? this->graph->id:0), domain,
+ str2);
+
goto out;
}
-#endif /* GF_USE_SYSLOG */
+
ret = gettimeofday (&tv, NULL);
if (-1 == ret)
goto out;
+ va_start (ap, fmt);
gf_time_fmt (timestr, sizeof timestr, tv.tv_sec, gf_timefmt_FT);
snprintf (timestr + strlen (timestr), sizeof timestr - strlen (timestr),
".%"GF_PRI_SUSECONDS, tv.tv_usec);
- ret = sprintf (msg, "[%s] %s [%s:%d:%s] %s %s: no memory "
- "available for size (%"GF_PRI_SIZET")",
- timestr, level_strings[level],
- basename, line, function, callstr,
- domain, size);
+ ret = gf_asprintf (&str1, "[%s] %s [%s:%d:%s] %s %d-%s: ",
+ timestr, level_strings[level],
+ basename, line, function, callstr,
+ ((this->graph) ? this->graph->id:0), domain);
+ if (-1 == ret) {
+ goto out;
+ }
+
+ ret = vasprintf (&str2, fmt, ap);
if (-1 == ret) {
goto out;
}
+ va_end (ap);
+
+ len = strlen (str1);
+ msg = GF_MALLOC (len + strlen (str2) + 1, gf_common_mt_char);
+
+ strcpy (msg, str1);
+ strcpy (msg + len, str2);
+
pthread_mutex_lock (&ctx->log.logfile_mutex);
{
if (ctx->log.logfile) {
@@ -571,30 +784,82 @@ _gf_log_nomem (const char *domain, const char *file,
}
pthread_mutex_unlock (&ctx->log.logfile_mutex);
+
out:
+ GF_FREE (msg);
+
+ GF_FREE (str1);
+
+ FREE (str2);
+
return ret;
- }
+}
int
-_gf_log_callingfn (const char *domain, const char *file, const char *function,
- int line, gf_loglevel_t level, const char *fmt, ...)
+_gf_msg_plain_internal (gf_loglevel_t level, const char *msg)
{
- const char *basename = NULL;
- xlator_t *this = NULL;
- char *str1 = NULL;
- char *str2 = NULL;
- char *msg = NULL;
- char timestr[256] = {0,};
- char callstr[4096] = {0,};
- struct timeval tv = {0,};
- size_t len = 0;
- int ret = 0;
- va_list ap;
+ xlator_t *this = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ int priority;
+
+ this = THIS;
+ ctx = this->ctx;
+
+ /* log to the configured logging service */
+ switch (ctx->log.logger) {
+ case gf_logger_syslog:
+ if (ctx->log.log_control_file_found && ctx->log.gf_log_syslog) {
+ SET_LOG_PRIO (level, priority);
+
+ syslog (priority, "%s", msg);
+ break;
+ }
+ /* NOTE: If syslog control file is absent, which is another
+ * way to control logging to syslog, then we will fall through
+ * to the gluster log. The ideal way to do things would be to
+ * not have the extra control file check */
+ case gf_logger_glusterlog:
+ pthread_mutex_lock (&ctx->log.logfile_mutex);
+ {
+ if (ctx->log.logfile) {
+ fprintf (ctx->log.logfile, "%s\n", msg);
+ fflush (ctx->log.logfile);
+ } else {
+ fprintf (stderr, "%s\n", msg);
+ fflush (stderr);
+ }
+
+#ifdef GF_LINUX_HOST_OS
+ /* We want only serious logs in 'syslog', not our debug
+ * and trace logs */
+ if (ctx->log.gf_log_syslog && level &&
+ (level <= ctx->log.sys_log_level))
+ syslog ((level-1), "%s\n", msg);
+#endif
+ }
+ pthread_mutex_unlock (&ctx->log.logfile_mutex);
+
+ break;
+ }
+
+ return 0;
+}
+
+int
+_gf_msg_plain (gf_loglevel_t level, const char *fmt, ...)
+{
+ xlator_t *this = NULL;
+ int ret = 0;
+ va_list ap;
+ char *msg = NULL;
glusterfs_ctx_t *ctx = NULL;
this = THIS;
ctx = this->ctx;
+ if (!ctx)
+ goto out;
+
if (ctx->log.gf_log_xl_log_set) {
if (this->loglevel && (level > this->loglevel))
goto out;
@@ -602,141 +867,604 @@ _gf_log_callingfn (const char *domain, const char *file, const char *function,
if (level > ctx->log.loglevel)
goto out;
- static char *level_strings[] = {"", /* NONE */
- "M", /* EMERGENCY */
- "A", /* ALERT */
- "C", /* CRITICAL */
- "E", /* ERROR */
- "W", /* WARNING */
- "N", /* NOTICE */
- "I", /* INFO */
- "D", /* DEBUG */
- "T", /* TRACE */
- ""};
+ va_start (ap, fmt);
+ ret = vasprintf (&msg, fmt, ap);
+ va_end (ap);
+ if (-1 == ret) {
+ goto out;
+ }
- if (!domain || !file || !function || !fmt) {
- fprintf (stderr,
- "logging: %s:%s():%d: invalid argument\n",
- __FILE__, __PRETTY_FUNCTION__, __LINE__);
- return -1;
+ ret = _gf_msg_plain_internal (level, msg);
+
+ FREE (msg);
+
+out:
+ return ret;
+}
+
+int
+_gf_msg_vplain (gf_loglevel_t level, const char *fmt, va_list ap)
+{
+ xlator_t *this = NULL;
+ int ret = 0;
+ char *msg = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+
+ this = THIS;
+ ctx = this->ctx;
+
+ if (!ctx)
+ goto out;
+
+ if (ctx->log.gf_log_xl_log_set) {
+ if (this->loglevel && (level > this->loglevel))
+ goto out;
}
+ if (level > ctx->log.loglevel)
+ goto out;
- basename = strrchr (file, '/');
- if (basename)
- basename++;
- else
- basename = file;
+ ret = vasprintf (&msg, fmt, ap);
+ if (-1 == ret) {
+ goto out;
+ }
+
+ ret = _gf_msg_plain_internal (level, msg);
+
+ FREE (msg);
+out:
+ return ret;
+}
+
+int
+_gf_msg_plain_nomem (gf_loglevel_t level, const char *msg)
+{
+ xlator_t *this = NULL;
+ int ret = 0;
+ glusterfs_ctx_t *ctx = NULL;
+
+ this = THIS;
+ ctx = this->ctx;
+
+ if (!ctx)
+ goto out;
+
+ if (ctx->log.gf_log_xl_log_set) {
+ if (this->loglevel && (level > this->loglevel))
+ goto out;
+ }
+ if (level > ctx->log.loglevel)
+ goto out;
+
+ ret = _gf_msg_plain_internal (level, msg);
+
+out:
+ return ret;
+}
#if HAVE_BACKTRACE
- /* Print 'calling function' */
- do {
- void *array[5];
- char **callingfn = NULL;
- size_t size = 0;
+void
+_gf_msg_backtrace_nomem (gf_loglevel_t level, int stacksize)
+{
+ xlator_t *this = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ void *array[200];
+ size_t bt_size = 0;
+ int fd = -1;
- size = backtrace (array, 5);
- if (size)
- callingfn = backtrace_symbols (&array[2], size-2);
- if (!callingfn)
- break;
+ this = THIS;
+ ctx = this->ctx;
- if (size == 5)
- snprintf (callstr, 4096, "(-->%s (-->%s (-->%s)))",
- callingfn[2], callingfn[1], callingfn[0]);
- if (size == 4)
- snprintf (callstr, 4096, "(-->%s (-->%s))",
- callingfn[1], callingfn[0]);
- if (size == 3)
- snprintf (callstr, 4096, "(-->%s)", callingfn[0]);
+ if (!ctx)
+ goto out;
- free (callingfn);
- } while (0);
-#endif /* HAVE_BACKTRACE */
+ /* syslog does not have fd support, hence no no-mem variant */
+ if (ctx->log.logger != gf_logger_glusterlog)
+ goto out;
-#if defined(GF_USE_SYSLOG)
- if (ctx->log.log_control_file_found)
+ if (ctx->log.gf_log_xl_log_set) {
+ if (this->loglevel && (level > this->loglevel))
+ goto out;
+ }
+ if (level > ctx->log.loglevel)
+ goto out;
+
+ bt_size = backtrace (array, ((stacksize <= 200)? stacksize : 200));
+ pthread_mutex_lock (&ctx->log.logfile_mutex);
{
- int priority;
- /* treat GF_LOG_TRACE and GF_LOG_NONE as LOG_DEBUG and
- other level as is */
- if (GF_LOG_TRACE == level || GF_LOG_NONE == level) {
- priority = LOG_DEBUG;
- } else {
- priority = level - 1;
+ fd = ctx->log.logfile?
+ fileno (ctx->log.logfile) :
+ fileno (stderr);
+ if (bt_size && (fd != -1)) {
+ /* print to the file fd, to prevent any
+ * allocations from backtrace_symbols */
+ backtrace_symbols_fd (&array[0], bt_size, fd);
}
+ }
+ pthread_mutex_unlock (&ctx->log.logfile_mutex);
- va_start (ap, fmt);
- vasprintf (&str2, fmt, ap);
- va_end (ap);
+out:
+ return;
+}
- gf_syslog (GF_ERR_DEV, priority,
- "[%s:%d:%s] %s %d-%s: %s",
- basename, line, function,
- callstr,
- ((this->graph) ? this->graph->id:0), domain,
- str2);
+int
+_gf_msg_backtrace (int stacksize, char *callstr, size_t strsize)
+{
+ int ret = -1;
+ int i = 0;
+ int size = 0;
+ int savstrsize = strsize;
+ void *array[200];
+ char **callingfn = NULL;
+
+ /* We chop off last 2 anyway, so if request is less than tolerance
+ * nothing to do */
+ if (stacksize < 3)
+ goto out;
+ size = backtrace (array, ((stacksize <= 200)? stacksize : 200));
+ if ((size - 3) < 0)
+ goto out;
+ if (size)
+ callingfn = backtrace_symbols (&array[2], size - 2);
+ if (!callingfn)
goto out;
+
+ ret = snprintf (callstr, strsize, "(");
+ PRINT_SIZE_CHECK (ret, out, strsize);
+
+ for ((i = size - 3); i >= 0; i--) {
+ ret = snprintf (callstr + savstrsize - strsize, strsize,
+ "-->%s ", callingfn[i]);
+ PRINT_SIZE_CHECK (ret, out, strsize);
}
-#endif /* GF_USE_SYSLOG */
+
+ ret = snprintf (callstr + savstrsize - strsize, strsize, ")");
+ PRINT_SIZE_CHECK (ret, out, strsize);
+out:
+ FREE (callingfn);
+ return ret;
+}
+#endif /* HAVE_BACKTRACE */
+
+int
+_gf_msg_nomem (const char *domain, const char *file,
+ const char *function, int line, gf_loglevel_t level,
+ size_t size)
+{
+ const char *basename = NULL;
+ xlator_t *this = NULL;
+ struct timeval tv = {0,};
+ int ret = 0;
+ int fd = -1;
+ char msg[2048] = {0,};
+ char timestr[GF_LOG_TIMESTR_SIZE] = {0,};
+ glusterfs_ctx_t *ctx = NULL;
+ int wlen = 0;
+ int priority;
+
+ this = THIS;
+ ctx = this->ctx;
+
+ if (!ctx)
+ goto out;
+
+ if (ctx->log.gf_log_xl_log_set) {
+ if (this->loglevel && (level > this->loglevel))
+ goto out;
+ }
+ if (level > ctx->log.loglevel)
+ goto out;
+
+ if (!domain || !file || !function) {
+ fprintf (stderr,
+ "logging: %s:%s():%d: invalid argument\n",
+ __FILE__, __PRETTY_FUNCTION__, __LINE__);
+ return -1;
+ }
+
+ GET_FILE_NAME_TO_LOG (file, basename);
+
ret = gettimeofday (&tv, NULL);
if (-1 == ret)
goto out;
- va_start (ap, fmt);
gf_time_fmt (timestr, sizeof timestr, tv.tv_sec, gf_timefmt_FT);
- snprintf (timestr + strlen (timestr), sizeof timestr - strlen (timestr),
- ".%"GF_PRI_SUSECONDS, tv.tv_usec);
-
- ret = gf_asprintf (&str1, "[%s] %s [%s:%d:%s] %s %d-%s: ",
- timestr, level_strings[level],
- basename, line, function, callstr,
- ((this->graph) ? this->graph->id:0), domain);
+ ret = snprintf (timestr + strlen (timestr),
+ sizeof timestr - strlen (timestr),
+ ".%"GF_PRI_SUSECONDS, tv.tv_usec);
if (-1 == ret) {
goto out;
}
- ret = vasprintf (&str2, fmt, ap);
+ /* TODO: Currently we print in the enhanced format, with a message ID
+ * of 0. Need to enhance this to support format as configured */
+ ret = snprintf (msg, sizeof msg, "[%s] %s [MSGID: %"PRIu64"]"
+ " [%s:%d:%s] %s: no memory "
+ "available for size (%"GF_PRI_SIZET")"
+ " [call stack follows]\n",
+ timestr, gf_level_strings[level], (uint64_t) 0,
+ basename, line, function, domain, size);
if (-1 == ret) {
goto out;
}
- va_end (ap);
+ /* log to the configured logging service */
+ switch (ctx->log.logger) {
+ case gf_logger_syslog:
+ if (ctx->log.log_control_file_found && ctx->log.gf_log_syslog) {
+ SET_LOG_PRIO (level, priority);
- len = strlen (str1);
- msg = GF_MALLOC (len + strlen (str2) + 1, gf_common_mt_char);
+ /* if syslog allocates, then this may fail, but we
+ * cannot do much about it at the moment */
+ /* There is no fd for syslog, hence no stack printed */
+ syslog (priority, "%s", msg);
+ break;
+ }
+ /* NOTE: If syslog control file is absent, which is another
+ * way to control logging to syslog, then we will fall through
+ * to the gluster log. The ideal way to do things would be to
+ * not have the extra control file check */
+ case gf_logger_glusterlog:
+ pthread_mutex_lock (&ctx->log.logfile_mutex);
+ {
+ fd = ctx->log.logfile? fileno (ctx->log.logfile) :
+ fileno (stderr);
+ if (fd == -1) {
+ pthread_mutex_unlock (&ctx->log.logfile_mutex);
+ goto out;
+ }
- strcpy (msg, str1);
- strcpy (msg + len, str2);
+ wlen = strlen (msg);
+
+ /* write directly to the fd to prevent out of order
+ * message and stack */
+ ret = write (fd, msg, wlen);
+ if (ret == -1) {
+ pthread_mutex_unlock (&ctx->log.logfile_mutex);
+ goto out;
+ }
+#ifdef GF_LINUX_HOST_OS
+ /* We want only serious log in 'syslog', not our debug
+ * and trace logs */
+ if (ctx->log.gf_log_syslog && level &&
+ (level <= ctx->log.sys_log_level))
+ syslog ((level-1), "%s\n", msg);
+#endif
+ }
+ pthread_mutex_unlock (&ctx->log.logfile_mutex);
+
+#ifdef HAVE_BACKTRACE
+ _gf_msg_backtrace_nomem (level, GF_LOG_BACKTRACE_DEPTH);
+#endif
+
+ break;
+ }
+
+out:
+ return ret;
+}
+
+static int
+gf_log_syslog (const char *domain, const char *file, const char *function,
+ int32_t line, gf_loglevel_t level, int errnum,
+ uint64_t msgid, char **appmsgstr, char *callstr)
+{
+ int priority;
+ xlator_t *this = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+
+ this = THIS;
+ ctx = this->ctx;
+
+ SET_LOG_PRIO (level, priority);
+
+ /* log with appropriate format */
+ if (ctx->log.logformat == gf_logformat_traditional) {
+ if (!callstr) {
+ if (errnum) {
+ syslog (priority, "[%s:%d:%s] %d-%s: %s [%s]",
+ file, line, function,
+ ((this->graph)?this->graph->id:0),
+ domain, *appmsgstr, strerror(errnum));
+ } else {
+ syslog (priority, "[%s:%d:%s] %d-%s: %s",
+ file, line, function,
+ ((this->graph)?this->graph->id:0),
+ domain, *appmsgstr);
+ }
+ } else {
+ if (errnum) {
+ syslog (priority, "[%s:%d:%s] %s %d-%s:"
+ " %s [%s]",
+ file, line, function, callstr,
+ ((this->graph)?this->graph->id:0),
+ domain, *appmsgstr, strerror(errnum));
+ } else {
+ syslog (priority, "[%s:%d:%s] %s %d-%s: %s",
+ file, line, function, callstr,
+ ((this->graph)?this->graph->id:0),
+ domain, *appmsgstr);
+ }
+ }
+ } else if (ctx->log.logformat == gf_logformat_withmsgid) {
+ if (!callstr) {
+ if (errnum) {
+ syslog (priority, "[MSGID: %"PRIu64"]"
+ " [%s:%d:%s] %d-%s: %s [%s]",
+ msgid, file, line, function,
+ ((this->graph)?this->graph->id:0),
+ domain, *appmsgstr, strerror(errnum));
+ } else {
+ syslog (priority, "[MSGID: %"PRIu64"]"
+ " [%s:%d:%s] %d-%s: %s",
+ msgid, file, line, function,
+ ((this->graph)?this->graph->id:0),
+ domain, *appmsgstr);
+ }
+ } else {
+ if (errnum) {
+ syslog (priority, "[MSGID: %"PRIu64"]"
+ " [%s:%d:%s] %s %d-%s: %s [%s]",
+ msgid, file, line, function, callstr,
+ ((this->graph)?this->graph->id:0),
+ domain, *appmsgstr, strerror(errnum));
+ } else {
+ syslog (priority, "[MSGID: %"PRIu64"]"
+ " [%s:%d:%s] %s %d-%s: %s",
+ msgid, file, line, function, callstr,
+ ((this->graph)?this->graph->id:0),
+ domain, *appmsgstr);
+ }
+ }
+ } else if (ctx->log.logformat == gf_logformat_cee) {
+ /* TODO: Enhance CEE with additional parameters */
+ gf_syslog (GF_ERR_DEV, priority,
+ "[%s:%d:%s] %d-%s: %s",
+ file, line, function,
+ ((this->graph) ? this->graph->id:0),
+ domain, *appmsgstr);
+ } else {
+ /* NOTE: should not get here without logging */
+ }
+
+ /* TODO: There can be no errors from gf_syslog? */
+ return 0;
+}
+
+static int
+gf_log_glusterlog (const char *domain, const char *file, const char *function,
+ int32_t line, gf_loglevel_t level, int errnum,
+ uint64_t msgid, char **appmsgstr, char *callstr)
+{
+ char timestr[GF_LOG_TIMESTR_SIZE] = {0,};
+ struct timeval tv = {0,};
+ char *header = NULL;
+ char *footer = NULL;
+ char *msg = NULL;
+ size_t hlen = 0, flen = 0, mlen = 0;
+ int ret = 0;
+ xlator_t *this = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+
+ this = THIS;
+ ctx = this->ctx;
+
+ /* rotate if required */
+ gf_log_rotate(ctx);
+
+ /* format the time stanp */
+ ret = gettimeofday (&tv, NULL);
+ if (-1 == ret)
+ goto out;
+ gf_time_fmt (timestr, sizeof timestr, tv.tv_sec, gf_timefmt_FT);
+ snprintf (timestr + strlen (timestr), sizeof timestr - strlen (timestr),
+ ".%"GF_PRI_SUSECONDS, tv.tv_usec);
+
+ /* generate header and footer */
+ if (ctx->log.logformat == gf_logformat_traditional) {
+ if (!callstr) {
+ ret = gf_asprintf (&header, "[%s] %s [%s:%d:%s]"
+ " %d-%s: ",
+ timestr, gf_level_strings[level],
+ file, line, function,
+ ((this->graph)?this->graph->id:0),
+ domain);
+ } else {
+ ret = gf_asprintf (&header, "[%s] %s [%s:%d:%s] %s"
+ " %d-%s: ",
+ timestr, gf_level_strings[level],
+ file, line, function, callstr,
+ ((this->graph)?this->graph->id:0),
+ domain);
+ }
+ if (-1 == ret) {
+ goto err;
+ }
+ } else { /* gf_logformat_withmsgid */
+ /* CEE log format unsupported in logger_glusterlog, so just
+ * print enhanced log format */
+ if (!callstr) {
+ ret = gf_asprintf (&header, "[%s] %s [MSGID: %"PRIu64"]"
+ " [%s:%d:%s] %d-%s: ",
+ timestr, gf_level_strings[level],
+ msgid, file, line, function,
+ ((this->graph)?this->graph->id:0),
+ domain);
+ } else {
+ ret = gf_asprintf (&header, "[%s] %s [MSGID: %"PRIu64"]"
+ " [%s:%d:%s] %s %d-%s: ",
+ timestr, gf_level_strings[level],
+ msgid, file, line, function, callstr,
+ ((this->graph)?this->graph->id:0),
+ domain);
+ }
+ if (-1 == ret) {
+ goto err;
+ }
+ }
+
+ if (errnum) {
+ ret = gf_asprintf (&footer, " [%s]",strerror(errnum));
+ if (-1 == ret) {
+ goto err;
+ }
+ }
+
+ /* generate the full message to log */
+ hlen = strlen (header);
+ flen = footer? strlen (footer) : 0;
+ mlen = strlen (*appmsgstr);
+ msg = GF_MALLOC (hlen + flen + mlen + 1, gf_common_mt_char);
+
+ strcpy (msg, header);
+ strcpy (msg + hlen, *appmsgstr);
+ if (footer)
+ strcpy (msg + hlen + mlen, footer);
pthread_mutex_lock (&ctx->log.logfile_mutex);
{
if (ctx->log.logfile) {
fprintf (ctx->log.logfile, "%s\n", msg);
+ fflush (ctx->log.logfile);
} else if (ctx->log.loglevel >= level) {
fprintf (stderr, "%s\n", msg);
+ fflush (stderr);
}
#ifdef GF_LINUX_HOST_OS
- /* We want only serious log in 'syslog', not our debug
- and trace logs */
+ /* We want only serious logs in 'syslog', not our debug
+ * and trace logs */
if (ctx->log.gf_log_syslog && level &&
- (level <= ctx->log.sys_log_level))
+ (level <= ctx->log.sys_log_level))
syslog ((level-1), "%s\n", msg);
#endif
}
+ /* TODO: Plugin in memory log buffer retention here. For logs not
+ * flushed during cores, it would be useful to retain some of the last
+ * few messages in memory */
pthread_mutex_unlock (&ctx->log.logfile_mutex);
-out:
+err:
GF_FREE (msg);
+ GF_FREE (header);
+ GF_FREE (footer);
- GF_FREE (str1);
+out:
+ return ret;
+}
- FREE (str2);
+static int
+_gf_msg_internal (const char *domain, const char *file, const char *function,
+ int32_t line, gf_loglevel_t level, int errnum, uint64_t msgid,
+ char **appmsgstr, char *callstr)
+{
+ const char *basename = NULL;
+ int ret = -1;
+ xlator_t *this = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+
+ this = THIS;
+ ctx = this->ctx;
+
+ GET_FILE_NAME_TO_LOG (file, basename);
+
+ /* TODO: Plug in repeated message suppression for gluster logs here.
+ * Comparison of last few messages stored based on, appmsgstr, errnum
+ * msgid. */
+ /* log to the configured logging service */
+ switch (ctx->log.logger) {
+ case gf_logger_syslog:
+ if (ctx->log.log_control_file_found && ctx->log.gf_log_syslog) {
+ ret = gf_log_syslog (domain, basename, function, line,
+ level, errnum, msgid, appmsgstr,
+ callstr);
+ break;
+ }
+ /* NOTE: If syslog control file is absent, which is another
+ * way to control logging to syslog, then we will fall through
+ * to the gluster log. The ideal way to do things would be to
+ * not have the extra control file check */
+ case gf_logger_glusterlog:
+ ret = gf_log_glusterlog (domain, basename, function, line,
+ level, errnum, msgid, appmsgstr,
+ callstr);
+ break;
+ }
+
+ return ret;
+}
+
+int
+_gf_msg (const char *domain, const char *file, const char *function,
+ int32_t line, gf_loglevel_t level, int errnum, int trace,
+ uint64_t msgid, const char *fmt, ...)
+{
+ int ret = 0;
+ char *msgstr = NULL;
+ va_list ap;
+ xlator_t *this = NULL;
+ glusterfs_ctx_t *ctx = NULL;
+ char callstr[GF_LOG_BACKTRACE_SIZE] = {0,};
+ int passcallstr = 0;
+
+ /* in args check */
+ if (!domain || !file || !function || !fmt) {
+ fprintf (stderr,
+ "logging: %s:%s():%d: invalid argument\n",
+ __FILE__, __PRETTY_FUNCTION__, __LINE__);
+ return -1;
+ }
+
+ this = THIS;
+ ctx = this->ctx;
+ if (ctx == NULL) {
+ /* messages before context initialization are ignored */
+ return -1;
+ }
+
+ /* check if we should be logging */
+ if (ctx->log.gf_log_xl_log_set) {
+ if (this->loglevel && (level > this->loglevel))
+ goto out;
+ }
+ if (level > ctx->log.loglevel)
+ goto out;
+
+#if HAVE_BACKTRACE
+ if (trace) {
+ ret = _gf_msg_backtrace (GF_LOG_BACKTRACE_DEPTH, callstr,
+ GF_LOG_BACKTRACE_DEPTH);
+ if (ret >= 0)
+ passcallstr = 1;
+ else
+ ret = 0;
+ }
+#endif /* HAVE_BACKTRACE */
+
+ /* form the message */
+ va_start (ap, fmt);
+ ret = vasprintf (&msgstr, fmt, ap);
+ va_end (ap);
+
+ /* log */
+ if (ret != -1)
+ ret = _gf_msg_internal(domain, file, function, line, level,
+ errnum, msgid, &msgstr,
+ (passcallstr? callstr : NULL));
+ else
+ /* man (3) vasprintf states on error strp contents
+ * are undefined, be safe */
+ msgstr = NULL;
+
+ FREE (msgstr);
+
+out:
return ret;
}
+/* TODO: Deprecate (delete) _gf_log, _gf_log_callingfn,
+ * once messages are changed to use _gf_msgXXX APIs for logging */
int
_gf_log (const char *domain, const char *file, const char *function, int line,
gf_loglevel_t level, const char *fmt, ...)
@@ -744,7 +1472,7 @@ _gf_log (const char *domain, const char *file, const char *function, int line,
const char *basename = NULL;
FILE *new_logfile = NULL;
va_list ap;
- char timestr[256] = {0,};
+ char timestr[GF_LOG_TIMESTR_SIZE] = {0,};
struct timeval tv = {0,};
char *str1 = NULL;
char *str2 = NULL;
@@ -790,7 +1518,6 @@ _gf_log (const char *domain, const char *file, const char *function, int line,
else
basename = file;
-#if defined(GF_USE_SYSLOG)
if (ctx->log.log_control_file_found)
{
int priority;
@@ -812,7 +1539,6 @@ _gf_log (const char *domain, const char *file, const char *function, int line,
((this->graph) ? this->graph->id:0), domain, str2);
goto err;
}
-#endif /* GF_USE_SYSLOG */
if (ctx->log.logrotate) {
ctx->log.logrotate = 0;
@@ -839,7 +1565,8 @@ _gf_log (const char *domain, const char *file, const char *function, int line,
if (ctx->log.logfile)
fclose (ctx->log.logfile);
- ctx->log.gf_log_logfile = ctx->log.logfile = new_logfile;
+ ctx->log.gf_log_logfile =
+ ctx->log.logfile = new_logfile;
}
pthread_mutex_unlock (&ctx->log.logfile_mutex);
@@ -1033,7 +1760,8 @@ gf_cmd_log (const char *domain, const char *fmt, ...)
goto out;
va_start (ap, fmt);
gf_time_fmt (timestr, sizeof timestr, tv.tv_sec, gf_timefmt_FT);
- snprintf (timestr + strlen (timestr), 256 - strlen (timestr),
+ snprintf (timestr + strlen (timestr),
+ GF_LOG_TIMESTR_SIZE - strlen (timestr),
".%"GF_PRI_SUSECONDS, tv.tv_usec);
ret = gf_asprintf (&str1, "[%s] %s : ",
diff --git a/libglusterfs/src/logging.h b/libglusterfs/src/logging.h
index e2b7e664d..b6b13fbd0 100644
--- a/libglusterfs/src/logging.h
+++ b/libglusterfs/src/logging.h
@@ -61,6 +61,20 @@ typedef enum {
GF_LOG_TRACE, /* full trace of operation */
} gf_loglevel_t;
+/* format for the logs */
+typedef enum {
+ gf_logformat_traditional = 0, /* Format as in gluster 3.5 */
+ gf_logformat_withmsgid, /* Format enhanced with MsgID, ident, errstr */
+ gf_logformat_cee /* log enhanced format in cee */
+} gf_log_format_t;
+
+/* log infrastructure to log to */
+typedef enum {
+ gf_logger_glusterlog = 0, /* locations and files as in gluster 3.5 */
+ gf_logger_syslog /* log to (r)syslog, based on (r)syslog conf */
+ /* NOTE: In the future journald, lumberjack, next new thing here */
+} gf_log_logger_t;
+
#define DEFAULT_LOG_FILE_DIRECTORY DATADIR "/log/glusterfs"
#define DEFAULT_LOG_LEVEL GF_LOG_INFO
@@ -76,11 +90,10 @@ typedef struct gf_log_handle_ {
FILE *gf_log_logfile;
char *cmd_log_filename;
FILE *cmdlogfile;
-#ifdef GF_USE_SYSLOG
- int log_control_file_found;
+ gf_log_logger_t logger;
+ gf_log_format_t logformat;
char *ident;
-#endif /* GF_USE_SYSLOG */
-
+ int log_control_file_found;
} gf_log_handle_t;
void gf_log_globals_init (void *ctx);
@@ -90,25 +103,117 @@ void gf_log_logrotate (int signum);
void gf_log_cleanup (void);
+/* Internal interfaces to log messages with message IDs */
+int _gf_msg (const char *domain, const char *file,
+ const char *function, int32_t line, gf_loglevel_t level,
+ int errnum, int trace, uint64_t msgid, const char *fmt, ...)
+ __attribute__ ((__format__ (__printf__, 9, 10)));
+
+void _gf_msg_backtrace_nomem (gf_loglevel_t level, int stacksize);
+
+int _gf_msg_plain (gf_loglevel_t level, const char *fmt, ...)
+ __attribute__ ((__format__ (__printf__, 2, 3)));
+
+int _gf_msg_plain_nomem (gf_loglevel_t level, const char *msg);
+
+int _gf_msg_vplain (gf_loglevel_t level, const char *fmt, va_list ap);
+
+int _gf_msg_nomem (const char *domain, const char *file,
+ const char *function, int line, gf_loglevel_t level,
+ size_t size);
+
int _gf_log (const char *domain, const char *file,
const char *function, int32_t line, gf_loglevel_t level,
const char *fmt, ...)
__attribute__ ((__format__ (__printf__, 6, 7)));
+
int _gf_log_callingfn (const char *domain, const char *file,
const char *function, int32_t line, gf_loglevel_t level,
const char *fmt, ...)
__attribute__ ((__format__ (__printf__, 6, 7)));
-int _gf_log_nomem (const char *domain, const char *file,
- const char *function, int line, gf_loglevel_t level,
- size_t size);
-
int _gf_log_eh (const char *function, const char *fmt, ...);
+/* treat GF_LOG_TRACE and GF_LOG_NONE as LOG_DEBUG and
+ * other level as is */
+#define SET_LOG_PRIO(level, priority) do { \
+ if (GF_LOG_TRACE == (level) || GF_LOG_NONE == (level)) { \
+ priority = LOG_DEBUG; \
+ } else { \
+ priority = (level) - 1; \
+ } \
+ } while (0)
+
+/* extract just the file name from the path */
+#define GET_FILE_NAME_TO_LOG(file, basename) do { \
+ basename = strrchr ((file), '/'); \
+ if (basename) \
+ basename++; \
+ else \
+ basename = (file); \
+ } while (0)
+
+#define PRINT_SIZE_CHECK(ret, label, strsize) do { \
+ if (ret < 0) \
+ goto label; \
+ if ((strsize - ret) > 0) { \
+ strsize -= ret; \
+ } else { \
+ ret = 0; \
+ goto label; \
+ } \
+ } while (0)
+
#define FMT_WARN(fmt...) do { if (0) printf (fmt); } while (0)
+/* Interface to log messages with message IDs */
+#define gf_msg(dom, levl, errnum, msgid, fmt...) do { \
+ _gf_msg (dom, __FILE__, __FUNCTION__, __LINE__, \
+ levl, errnum, 0, msgid, ##fmt); \
+ } while (0)
+
+/* no frills, no thrills, just a vanilla message, used to print the graph */
+#define gf_msg_plain(levl, fmt...) do { \
+ _gf_msg_plain (levl, ##fmt); \
+ } while (0)
+
+#define gf_msg_plain_nomem(levl, msg) do { \
+ _gf_msg_plain_nomem (levl, msg); \
+ } while (0)
+
+#define gf_msg_vplain(levl, fmt, va) do { \
+ _gf_msg_vplain (levl, fmt, va); \
+ } while (0)
+
+#define gf_msg_backtrace_nomem(level, stacksize) do { \
+ _gf_msg_backtrace_nomem (level, stacksize); \
+ } while (0)
+
+#define gf_msg_callingfn(dom, levl, errnum, msgid, fmt...) do { \
+ _gf_msg (dom, __FILE__, __FUNCTION__, __LINE__, \
+ levl, errnum, 1, msgid, ##fmt); \
+ } while (0)
+
+/* No malloc or calloc should be called in this function */
+#define gf_msg_nomem(dom, levl, size) do { \
+ _gf_msg_nomem (dom, __FILE__, __FUNCTION__, __LINE__, \
+ levl, size); \
+ } while (0)
+
+/* Debug or trace messages do not need message IDs as these are more developer
+ * related. Hence, the following abstractions are provided for the same */
+#define gf_msg_debug(dom, errnum, fmt...) do { \
+ _gf_msg (dom, __FILE__, __FUNCTION__, __LINE__, \
+ GF_LOG_DEBUG, errnum, 0, 0, ##fmt); \
+ } while (0)
+
+#define gf_msg_trace(dom, errnum, fmt...) do { \
+ _gf_msg (dom, __FILE__, __FUNCTION__, __LINE__, \
+ GF_LOG_TRACE, errnum, 0, 0, ##fmt); \
+ } while (0)
+
#define gf_log(dom, levl, fmt...) do { \
FMT_WARN (fmt); \
_gf_log (dom, __FILE__, __FUNCTION__, __LINE__, \
@@ -127,13 +232,6 @@ int _gf_log_eh (const char *function, const char *fmt, ...);
} while (0)
-/* No malloc or calloc should be called in this function */
-#define gf_log_nomem(dom, levl, size) do { \
- _gf_log_nomem (dom, __FILE__, __FUNCTION__, __LINE__, \
- levl, size); \
- } while (0)
-
-
/* Log once in GF_UNIVERSAL_ANSWER times */
#define GF_LOG_OCCASIONALLY(var, args...) if (!(var++%GF_UNIVERSAL_ANSWER)) { \
gf_log (args); \
@@ -143,6 +241,7 @@ void gf_log_disable_syslog (void);
void gf_log_enable_syslog (void);
gf_loglevel_t gf_log_get_loglevel (void);
void gf_log_set_loglevel (gf_loglevel_t level);
+void gf_log_flush (void);
gf_loglevel_t gf_log_get_xl_loglevel (void *xl);
void gf_log_set_xl_loglevel (void *xl, gf_loglevel_t level);
diff --git a/libglusterfs/src/mem-pool.c b/libglusterfs/src/mem-pool.c
index b92803d4d..c5ff58f4f 100644
--- a/libglusterfs/src/mem-pool.c
+++ b/libglusterfs/src/mem-pool.c
@@ -105,7 +105,7 @@ __gf_calloc (size_t nmemb, size_t size, uint32_t type)
ptr = calloc (1, tot_size);
if (!ptr) {
- gf_log_nomem ("", GF_LOG_ALERT, tot_size);
+ gf_msg_nomem ("", GF_LOG_ALERT, tot_size);
return NULL;
}
gf_mem_set_acct_info (xl, &ptr, req_size, type);
@@ -129,7 +129,7 @@ __gf_malloc (size_t size, uint32_t type)
ptr = malloc (tot_size);
if (!ptr) {
- gf_log_nomem ("", GF_LOG_ALERT, tot_size);
+ gf_msg_nomem ("", GF_LOG_ALERT, tot_size);
return NULL;
}
gf_mem_set_acct_info (xl, &ptr, size, type);
@@ -163,7 +163,7 @@ __gf_realloc (void *ptr, size_t size)
new_ptr = realloc (orig_ptr, tot_size);
if (!new_ptr) {
- gf_log_nomem ("", GF_LOG_ALERT, tot_size);
+ gf_msg_nomem ("", GF_LOG_ALERT, tot_size);
return NULL;
}
diff --git a/libglusterfs/src/mem-pool.h b/libglusterfs/src/mem-pool.h
index aa6bf7843..9ffeef4da 100644
--- a/libglusterfs/src/mem-pool.h
+++ b/libglusterfs/src/mem-pool.h
@@ -75,7 +75,7 @@ void* __gf_default_malloc (size_t size)
ptr = malloc (size);
if (!ptr)
- gf_log_nomem ("", GF_LOG_ALERT, size);
+ gf_msg_nomem ("", GF_LOG_ALERT, size);
return ptr;
}
@@ -87,7 +87,7 @@ void* __gf_default_calloc (int cnt, size_t size)
ptr = calloc (cnt, size);
if (!ptr)
- gf_log_nomem ("", GF_LOG_ALERT, (cnt * size));
+ gf_msg_nomem ("", GF_LOG_ALERT, (cnt * size));
return ptr;
}
@@ -99,7 +99,7 @@ void* __gf_default_realloc (void *oldptr, size_t size)
ptr = realloc (oldptr, size);
if (!ptr)
- gf_log_nomem ("", GF_LOG_ALERT, size);
+ gf_msg_nomem ("", GF_LOG_ALERT, size);
return ptr;
}
diff --git a/libglusterfs/src/template-component-messages.h b/libglusterfs/src/template-component-messages.h
new file mode 100644
index 000000000..c1ea38cf7
--- /dev/null
+++ b/libglusterfs/src/template-component-messages.h
@@ -0,0 +1,55 @@
+/*
+ Copyright (c) 2013 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+ */
+
+#ifndef _component_MESSAGES_H_
+#define _component_MESSAGES_H_
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "glfs-message-id.h"
+
+/* NOTE: Rules for message additions
+ * 1) Each instance of a message is _better_ left with a unique message ID, even
+ * if the message format is the same. Reasoning is that, if the message
+ * format needs to change in one instance, the other instances are not
+ * impacted or the new change does not change the ID of the instance being
+ * modified.
+ * 2) Addition of a message,
+ * - Should increment the GLFS_NUM_MESSAGES
+ * - Append to the list of messages defined, towards the end
+ * - Retain macro naming as glfs_msg_X (for redability across developers)
+ * NOTE: Rules for message format modifications
+ * 3) Check acorss the code if the message ID macro in question is reused
+ * anywhere. If reused then then the modifications should ensure correctness
+ * everywhere, or needs a new message ID as (1) above was not adhered to. If
+ * not used anywhere, proceed with the required modification.
+ * NOTE: Rules for message deletion
+ * 4) Check (3) and if used anywhere else, then cannot be deleted. If not used
+ * anywhere, then can be deleted, but will leave a hole by design, as
+ * addition rules specify modification to the end of the list and not filling
+ * holes.
+ */
+
+#define GLFS_COMP_BASE GLFS_MSGID_COMP_<component>
+#define GLFS_NUM_MESSAGES 1
+#define GLFS_MSGID_END (GLFS_COMP_BASE + GLFS_NUM_MESSAGES + 1)
+/* Messaged with message IDs */
+#define glfs_msg_start_x GLFS_COMP_BASE, "Invalid: Start of messages"
+/*------------*/
+#define <component>_msg_1 (GLFS_COMP_BASE + 1), "Test message, replace with"\
+ " original when using the template"
+
+/*------------*/
+#define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages"
+
+#endif /* !_component_MESSAGES_H_ */ \ No newline at end of file
diff --git a/libglusterfs/src/unittest/log_mock.c b/libglusterfs/src/unittest/log_mock.c
index 676df7cfd..fec48bafc 100644
--- a/libglusterfs/src/unittest/log_mock.c
+++ b/libglusterfs/src/unittest/log_mock.c
@@ -39,5 +39,12 @@ int _gf_log_nomem (const char *domain, const char *file,
return 0;
}
+int _gf_msg_nomem (const char *domain, const char *file,
+ const char *function, int line, gf_loglevel_t level,
+ size_t size)
+{
+ return 0;
+}
+
void
gf_log_globals_init (void *data) {}
diff --git a/rpc/rpc-transport/rdma/src/rdma.c b/rpc/rpc-transport/rdma/src/rdma.c
index 6e6099a98..c09067230 100644
--- a/rpc/rpc-transport/rdma/src/rdma.c
+++ b/rpc/rpc-transport/rdma/src/rdma.c
@@ -104,7 +104,7 @@ gf_rdma_new_post (rpc_transport_t *this, gf_rdma_device_t *device, int32_t len,
post->buf = valloc (len);
if (!post->buf) {
- gf_log_nomem (GF_RDMA_LOG_NAME, GF_LOG_ERROR, len);
+ gf_msg_nomem (GF_RDMA_LOG_NAME, GF_LOG_ERROR, len);
goto out;
}
diff --git a/tests/basic/logchecks-messages.h b/tests/basic/logchecks-messages.h
new file mode 100644
index 000000000..50efe9dfa
--- /dev/null
+++ b/tests/basic/logchecks-messages.h
@@ -0,0 +1,84 @@
+/*
+ Copyright (c) 2013 Red Hat, Inc. <http://www.redhat.com>
+ This file is part of GlusterFS.
+
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
+ */
+
+#ifndef _LOGCHECKS_MESSAGES_H_
+#define _LOGCHECKS_MESSAGES_H_
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "glfs-message-id.h"
+
+/* NOTE: Rules for message additions
+ * 1) Each instance of a message is _better_ left with a unique message ID, even
+ * if the message format is the same. Reasoning is that, if the message
+ * format needs to change in one instance, the other instances are not
+ * impacted or the new change does not change the ID of the instance being
+ * modified.
+ * 2) Addition of a message,
+ * - Should increment the GLFS_NUM_MESSAGES
+ * - Append to the list of messages defined, towards the end
+ * - Retain macro naming as glfs_msg_X (for redability across developers)
+ * NOTE: Rules for message format modifications
+ * 3) Check acorss the code if the message ID macro in question is reused
+ * anywhere. If reused then then the modifications should ensure correctness
+ * everywhere, or needs a new message ID as (1) above was not adhered to. If
+ * not used anywhere, proceed with the required modification.
+ * NOTE: Rules for message deletion
+ * 4) Check (3) and if used anywhere else, then cannot be deleted. If not used
+ * anywhere, then can be deleted, but will leave a hole by design, as
+ * addition rules specify modification to the end of the list and not filling
+ * holes.
+ */
+
+#define GLFS_COMP_BASE 1000
+#define GLFS_NUM_MESSAGES 19
+#define GLFS_MSGID_END (GLFS_COMP_BASE + GLFS_NUM_MESSAGES + 1)
+/* Messaged with message IDs */
+#define glfs_msg_start_x GLFS_COMP_BASE, "Invalid: Start of messages"
+/*------------*/
+#define logchecks_msg_1 (GLFS_COMP_BASE + 1), "Informational: Testing logging" \
+ " in gluster"
+#define logchecks_msg_2 (GLFS_COMP_BASE + 2), "Informational: Format testing:" \
+ " %d:%s:%x"
+#define logchecks_msg_3 (GLFS_COMP_BASE + 3), "Critical: Testing logging" \
+ " in gluster"
+#define logchecks_msg_4 (GLFS_COMP_BASE + 4), "Critical: Format testing:" \
+ " %d:%s:%x"
+#define logchecks_msg_5 (GLFS_COMP_BASE + 5), "Critical: Rotated the log"
+#define logchecks_msg_6 (GLFS_COMP_BASE + 6), "Critical: Flushed the log"
+#define logchecks_msg_7 (GLFS_COMP_BASE + 7), "Informational: gf_msg_callingfn"
+#define logchecks_msg_8 (GLFS_COMP_BASE + 8), "Informational: " \
+ "gf_msg_callingfn: Format testing: %d:%s:%x"
+#define logchecks_msg_9 (GLFS_COMP_BASE + 9), "Critical: gf_msg_callingfn"
+#define logchecks_msg_10 (GLFS_COMP_BASE + 10), "Critical: " \
+ "gf_msg_callingfn: Format testing: %d:%s:%x"
+#define logchecks_msg_11 (GLFS_COMP_BASE + 11), "=========================="
+#define logchecks_msg_12 (GLFS_COMP_BASE + 12), "Test 1: Only stderr and" \
+ " partial syslog"
+#define logchecks_msg_13 (GLFS_COMP_BASE + 13), "Test 2: Only checklog and" \
+ " partial syslog"
+#define logchecks_msg_14 (GLFS_COMP_BASE + 14), "Test 5: Changing to" \
+ " traditional format"
+#define logchecks_msg_15 (GLFS_COMP_BASE + 15), "Test 6: Changing log level" \
+ " to critical and above"
+#define logchecks_msg_16 (GLFS_COMP_BASE + 16), "Test 7: Only to syslog"
+#define logchecks_msg_17 (GLFS_COMP_BASE + 17), "Test 8: Only to syslog," \
+ " traditional format"
+#define logchecks_msg_18 (GLFS_COMP_BASE + 18), "Test 9: Only to syslog," \
+ " only critical and above"
+#define logchecks_msg_19 (GLFS_COMP_BASE + 19), "Pre init message, not to be" \
+ " seen in logs"
+/*------------*/
+#define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages"
+
+#endif /* !_component_MESSAGES_H_ */ \ No newline at end of file
diff --git a/tests/basic/logchecks.c b/tests/basic/logchecks.c
new file mode 100644
index 000000000..4f858a7fc
--- /dev/null
+++ b/tests/basic/logchecks.c
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2013 Red Hat, Inc. <http://www.redhat.com>
+ * This file is part of GlusterFS.
+ *
+ * This file is licensed to you under your choice of the GNU Lesser
+ * General Public License, version 3 or any later version (LGPLv3 or
+ * later), or the GNU General Public License, version 2 (GPLv2), in all
+ * cases as published by the Free Software Foundation.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include "glusterfs.h"
+#include "globals.h"
+#include "logging.h"
+
+#include "logchecks-messages.h"
+#include "../../libglusterfs/src/logging.h"
+
+glusterfs_ctx_t *ctx = NULL;
+
+#define TEST_FILENAME "/tmp/logchecks.log"
+#define GF_LOG_CONTROL_FILE "/etc/glusterfs/logger.conf"
+
+int
+go_log_vargs(gf_loglevel_t level, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start (ap, fmt);
+ gf_msg_vplain (level, fmt, ap);
+ va_end (ap);
+
+ return 0;
+}
+
+int
+go_log (void)
+{
+ /*** gf_msg ***/
+ gf_msg ("logchecks", GF_LOG_INFO, 0, logchecks_msg_1);
+ gf_msg ("logchecks", GF_LOG_INFO, 22, logchecks_msg_2, 42, "Forty-Two",
+ 42);
+ /* change criticality */
+ gf_msg ("logchecks", GF_LOG_CRITICAL, 0, logchecks_msg_3);
+ gf_msg ("logchecks", GF_LOG_CRITICAL, 22, logchecks_msg_4, 42,
+ "Forty-Two", 42);
+
+ /*** msg_nomem ***/
+ gf_msg_nomem ("logchecks", GF_LOG_ALERT, 555);
+ gf_msg_nomem ("logchecks", GF_LOG_INFO, 555);
+
+ /*** msg_plain ***/
+ gf_msg_plain (GF_LOG_INFO, "Informational: gf_msg_plain with"
+ " args %d:%s:%x", 42, "Forty-Two", 42);
+ gf_msg_plain (GF_LOG_ALERT, "Alert: gf_msg_plain with"
+ " args %d:%s:%x", 42, "Forty-Two", 42);
+
+ /*** msg_vplain ***/
+ go_log_vargs (GF_LOG_INFO, "Informational: gf_msg_vplain: No args!!!");
+ go_log_vargs (GF_LOG_INFO, "Informational: gf_msg_vplain: Some"
+ " args %d:%s:%x", 42, "Forty-Two", 42);
+ go_log_vargs (GF_LOG_INFO, "Critical: gf_msg_vplain: No args!!!");
+ go_log_vargs (GF_LOG_INFO, "Critical: gf_msg_vplain: Some"
+ " args %d:%s:%x", 42, "Forty-Two", 42);
+
+ /*** msg_plain_nomem ***/
+ gf_msg_plain_nomem (GF_LOG_INFO, "Informational: gf_msg_plain_nomem");
+ gf_msg_plain_nomem (GF_LOG_ALERT, "Alert: gf_msg_plain_nomem");
+
+ /*** msg_backtrace_nomem ***/
+ // TODO: Need to create a stack depth and then call
+ gf_msg_backtrace_nomem (GF_LOG_INFO, 5);
+ gf_msg_backtrace_nomem (GF_LOG_ALERT, 5);
+
+ /*** gf_msg_callingfn ***/
+ // TODO: Need to create a stack depth and then call
+ gf_msg_callingfn ("logchecks", GF_LOG_INFO, 0, logchecks_msg_7);
+ gf_msg_callingfn ("logchecks", GF_LOG_INFO, 0, logchecks_msg_8, 42,
+ "Forty-Two", 42);
+ gf_msg_callingfn ("logchecks", GF_LOG_CRITICAL, 0, logchecks_msg_9);
+ gf_msg_callingfn ("logchecks", GF_LOG_CRITICAL, 0, logchecks_msg_10, 42,
+ "Forty-Two", 42);
+
+ /*** gf_msg_debug ***/
+ gf_msg_debug ("logchecks", 0, "Debug: Hello World!!!");
+ gf_msg_debug ("logchecks", 22, "Debug: With args %d:%s:%x", 42,
+ "Forty-Two", 42);
+
+ /*** gf_msg_trace ***/
+ gf_msg_trace ("logchecks", 0, "Trace: Hello World!!!");
+ gf_msg_trace ("logchecks", 22, "Trace: With args %d:%s:%x", 42,
+ "Forty-Two", 42);
+
+ /*** gf_msg_backtrace ***/
+ // TODO: Test with lower callstr values to check truncation
+
+ return 0;
+}
+
+int
+main (int argc, char *argv[])
+{
+ int ret = -1;
+
+ unlink (GF_LOG_CONTROL_FILE);
+ creat (GF_LOG_CONTROL_FILE, O_RDONLY);
+ ctx = glusterfs_ctx_new ();
+ if (!ctx)
+ return -1;
+
+ ret = glusterfs_globals_init (ctx);
+ if (ret) {
+ printf ("Error from glusterfs_globals_init [%s]\n",
+ strerror (errno));
+ return ret;
+ }
+
+ /* Pre init test, message should not be printed */
+ gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_19);
+
+ THIS->ctx = ctx;
+
+ /* TEST 1: messages before initializing the log, goes to stderr
+ * and syslog based on criticality */
+ gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11);
+ gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_12);
+ go_log ();
+ gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11);
+
+ /* TEST 2: messages post initialization, goes to glusterlog and
+ * syslog based on severity */
+ ret = gf_log_init(ctx, TEST_FILENAME, "logchecks");
+ if (ret != 0) {
+ printf ("Error from gf_log_init [%s]\n", strerror (errno));
+ return -1;
+ }
+ gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11);
+ gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_13);
+ go_log ();
+ gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11);
+
+ /* TEST 3: Test rotation */
+ gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11);
+ gf_log_logrotate (0);
+ gf_msg ("logchecks", GF_LOG_CRITICAL, 0, logchecks_msg_5);
+ gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11);
+
+ /* TEST 4: Check flush, nothing noticable should occur :) */
+ gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11);
+ gf_log_flush ();
+ gf_msg ("logchecks", GF_LOG_CRITICAL, 0, logchecks_msg_6);
+ gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11);
+
+ /* TEST 5: Change format */
+ gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11);
+ gf_log_set_logformat (gf_logformat_traditional);
+ gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_14);
+ go_log ();
+ gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11);
+
+ /* TEST 6: Change level */
+ gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11);
+ gf_log_set_loglevel (GF_LOG_CRITICAL);
+ gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_15);
+ go_log ();
+ gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11);
+
+ /* Reset to run with syslog */
+ gf_log_set_logformat (gf_logformat_withmsgid);
+ gf_log_set_loglevel (GF_LOG_INFO);
+
+ /* Run tests with logger changed to syslog */
+ /* TEST 7: No more gluster logs */
+ gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11);
+ gf_log_set_logger (gf_logger_syslog);
+ gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_16);
+ go_log ();
+ gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11);
+
+ /* TEST 8: Change format */
+ gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11);
+ gf_log_set_logformat (gf_logformat_traditional);
+ gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_14);
+ go_log ();
+ gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11);
+
+ /* TEST 9: Change level */
+ gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11);
+ gf_log_set_loglevel (GF_LOG_CRITICAL);
+ gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_15);
+ go_log ();
+ gf_msg ("logchecks", GF_LOG_ALERT, 0, logchecks_msg_11);
+
+ // TODO: signal crash prints, but not yet feasible here
+ // TODO: Graph printing
+ // TODO: Multi threaded logging
+
+ /* Close out the logging */
+ gf_log_fini (ctx);
+ gf_log_globals_fini ();
+
+ unlink (GF_LOG_CONTROL_FILE);
+ unlink (TEST_FILENAME);
+
+ return 0;
+} \ No newline at end of file