mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
log: log warnings and errors via report if set; add log_set_report* fns
This patch adds structures and functions to reroute error and warning logs to log report, if it's set. There are 5 new functions: - log_set_report Set log report where logging will be rerouted. - log_set_report_context Set context globally so any report_cmdlog call will use it. - log_set_report_object_type Set object type globally so any report_cmdlog call will use it. - log_set_report_object_name_and_id Set object ID and name globally so any report_cmdlog call will use it. - log_set_report_object_group_and_group_id Set object group ID and name globally so any report_cmdlog call will use it. These functions will be called during LVM command processing so any logs which are rerouted to log report contain proper information about current processing state.
This commit is contained in:
parent
8cfc385491
commit
7d4a15e53a
@ -1,5 +1,6 @@
|
||||
Version 2.02.158 -
|
||||
=================================
|
||||
Log warnings and errors via report during cmd processing if this is enabled.
|
||||
Make it possible to iterate over internal 'orphan' VGs in process_each_vg fn.
|
||||
Make -S|--select option groupable that allows this option to be repeated.
|
||||
Make -O|--sort option groupable that allows this option to be repeated.
|
||||
|
101
lib/log/log.c
101
lib/log/log.c
@ -17,6 +17,7 @@
|
||||
#include "device.h"
|
||||
#include "memlock.h"
|
||||
#include "defaults.h"
|
||||
#include "report.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
@ -47,6 +48,15 @@ static size_t _lvm_errmsg_size = 0;
|
||||
static size_t _lvm_errmsg_len = 0;
|
||||
#define MAX_ERRMSG_LEN (512 * 1024) /* Max size of error buffer 512KB */
|
||||
|
||||
static log_report_t _log_report = {
|
||||
.report = NULL,
|
||||
.context = LOG_REPORT_CONTEXT_NULL,
|
||||
.object_type = LOG_REPORT_OBJECT_TYPE_NULL,
|
||||
.object_id = NULL,
|
||||
.object_name = NULL,
|
||||
.object_group = NULL
|
||||
};
|
||||
|
||||
void init_log_fn(lvm2_log_fn_t log_fn)
|
||||
{
|
||||
_lvm2_log_fn = log_fn;
|
||||
@ -260,6 +270,38 @@ void reset_log_duplicated(void) {
|
||||
}
|
||||
}
|
||||
|
||||
static const char *_get_log_level_name(int level)
|
||||
{
|
||||
static const char *log_level_names[] = {"", /* unassigned */
|
||||
"", /* unassigned */
|
||||
"fatal", /* _LOG_FATAL */
|
||||
"error", /* _LOG_ERROR */
|
||||
"warn", /* _LOG_WARN */
|
||||
"notice" /* _LOG_NOTICE */
|
||||
"info", /* _LOG_INFO */
|
||||
"debug" /* _LOG_DEBUG */
|
||||
};
|
||||
level &= ~_LOG_STDERR;
|
||||
return log_level_names[level];
|
||||
}
|
||||
|
||||
const char *log_get_report_context_name(log_report_context_t context)
|
||||
{
|
||||
static const char *log_context_names[LOG_REPORT_CONTEXT_COUNT] = {[LOG_REPORT_CONTEXT_NULL] = "",
|
||||
[LOG_REPORT_CONTEXT_PROCESSING] = "processing"};
|
||||
return log_context_names[context];
|
||||
}
|
||||
|
||||
|
||||
const char *log_get_report_object_type_name(log_report_object_type_t object_type)
|
||||
{
|
||||
static const char *log_object_type_names[LOG_REPORT_OBJECT_TYPE_COUNT] = {[LOG_REPORT_OBJECT_TYPE_NULL] = "",
|
||||
[LOG_REPORT_OBJECT_TYPE_PV] = "pv",
|
||||
[LOG_REPORT_OBJECT_TYPE_VG] = "vg",
|
||||
[LOG_REPORT_OBJECT_TYPE_LV] = "lv"};
|
||||
return log_object_type_names[object_type];
|
||||
}
|
||||
|
||||
void print_log(int level, const char *file, int line, int dm_errno_or_class,
|
||||
const char *format, ...)
|
||||
{
|
||||
@ -277,6 +319,8 @@ void print_log(int level, const char *file, int line, int dm_errno_or_class,
|
||||
static int _abort_on_internal_errors_env_present = -1;
|
||||
static int _abort_on_internal_errors_env = 0;
|
||||
char *env_str;
|
||||
struct dm_report *orig_report;
|
||||
int logged_via_report = 0;
|
||||
|
||||
level &= ~(_LOG_STDERR|_LOG_ONCE);
|
||||
|
||||
@ -309,6 +353,7 @@ void print_log(int level, const char *file, int line, int dm_errno_or_class,
|
||||
|
||||
if (_lvm2_log_fn ||
|
||||
(_store_errmsg && (level <= _LOG_ERR)) ||
|
||||
(_log_report.report && (use_stderr || (level <=_LOG_ERR))) ||
|
||||
log_once) {
|
||||
va_start(ap, format);
|
||||
n = vsnprintf(message, sizeof(message), trformat, ap);
|
||||
@ -356,6 +401,23 @@ void print_log(int level, const char *file, int line, int dm_errno_or_class,
|
||||
}
|
||||
}
|
||||
|
||||
if (_log_report.report && (use_stderr || (level <= _LOG_ERR))) {
|
||||
orig_report = _log_report.report;
|
||||
_log_report.report = NULL;
|
||||
|
||||
if (!report_cmdlog(orig_report, _get_log_level_name(level),
|
||||
log_get_report_context_name(_log_report.context),
|
||||
log_get_report_object_type_name(_log_report.object_type),
|
||||
_log_report.object_name, _log_report.object_id,
|
||||
_log_report.object_group, _log_report.object_group_id,
|
||||
message, _lvm_errno, 0))
|
||||
fprintf(stderr, _("failed to report cmdstatus"));
|
||||
else
|
||||
logged_via_report = 1;
|
||||
|
||||
_log_report.report = orig_report;
|
||||
}
|
||||
|
||||
if (_lvm2_log_fn) {
|
||||
_lvm2_log_fn(level, file, line, 0, message);
|
||||
if (fatal_internal_error)
|
||||
@ -364,7 +426,7 @@ void print_log(int level, const char *file, int line, int dm_errno_or_class,
|
||||
}
|
||||
|
||||
log_it:
|
||||
if ((verbose_level() >= level) && !_log_suppress) {
|
||||
if (!logged_via_report && ((verbose_level() >= level) && !_log_suppress)) {
|
||||
if (verbose_level() > _LOG_DEBUG) {
|
||||
(void) dm_snprintf(buf, sizeof(buf), "#%s:%d ",
|
||||
file, line);
|
||||
@ -462,3 +524,40 @@ void print_log(int level, const char *file, int line, int dm_errno_or_class,
|
||||
_already_logging = 0;
|
||||
}
|
||||
}
|
||||
|
||||
log_report_t log_get_report_state(void)
|
||||
{
|
||||
return _log_report;
|
||||
}
|
||||
|
||||
void log_restore_report_state(log_report_t log_report)
|
||||
{
|
||||
_log_report = log_report;
|
||||
}
|
||||
|
||||
void log_set_report(struct dm_report *report)
|
||||
{
|
||||
_log_report.report = report;
|
||||
}
|
||||
|
||||
void log_set_report_context(log_report_context_t context)
|
||||
{
|
||||
_log_report.context = context;
|
||||
}
|
||||
|
||||
void log_set_report_object_type(log_report_object_type_t object_type)
|
||||
{
|
||||
_log_report.object_type = object_type;
|
||||
}
|
||||
|
||||
void log_set_report_object_group_and_group_id(const char *group, const char *id)
|
||||
{
|
||||
_log_report.object_group = group;
|
||||
_log_report.object_group_id = id;
|
||||
}
|
||||
|
||||
void log_set_report_object_name_and_id(const char *name, const char *id)
|
||||
{
|
||||
_log_report.object_name = name;
|
||||
_log_report.object_id = id;
|
||||
}
|
||||
|
@ -65,4 +65,41 @@ int log_suppress(int suppress);
|
||||
/* Suppress messages to syslog */
|
||||
void syslog_suppress(int suppress);
|
||||
|
||||
/* Hooks to handle logging through report. */
|
||||
typedef enum {
|
||||
LOG_REPORT_CONTEXT_NULL,
|
||||
LOG_REPORT_CONTEXT_PROCESSING,
|
||||
LOG_REPORT_CONTEXT_COUNT
|
||||
} log_report_context_t;
|
||||
|
||||
typedef enum {
|
||||
LOG_REPORT_OBJECT_TYPE_NULL,
|
||||
LOG_REPORT_OBJECT_TYPE_PV,
|
||||
LOG_REPORT_OBJECT_TYPE_VG,
|
||||
LOG_REPORT_OBJECT_TYPE_LV,
|
||||
LOG_REPORT_OBJECT_TYPE_COUNT
|
||||
} log_report_object_type_t;
|
||||
|
||||
typedef struct log_report {
|
||||
struct dm_report *report;
|
||||
log_report_context_t context;
|
||||
log_report_object_type_t object_type;
|
||||
const char *object_name;
|
||||
const char *object_id;
|
||||
const char *object_group;
|
||||
const char *object_group_id;
|
||||
} log_report_t;
|
||||
|
||||
log_report_t log_get_report_state(void);
|
||||
void log_restore_report_state(log_report_t log_report);
|
||||
|
||||
void log_set_report(struct dm_report *report);
|
||||
void log_set_report_context(log_report_context_t context);
|
||||
void log_set_report_object_type(log_report_object_type_t object_type);
|
||||
void log_set_report_object_group_and_group_id(const char *group, const char *group_id);
|
||||
void log_set_report_object_name_and_id(const char *name, const char *id);
|
||||
|
||||
const char *log_get_report_context_name(log_report_context_t context);
|
||||
const char *log_get_report_object_type_name(log_report_object_type_t object_type);
|
||||
|
||||
#endif
|
||||
|
@ -82,7 +82,8 @@ typedef int (*field_report_fn) (struct report_handle * dh, struct field * field,
|
||||
const void *data);
|
||||
|
||||
int report_format_init(struct cmd_context *cmd, dm_report_group_type_t *report_group_type,
|
||||
struct dm_report_group **report_group, struct dm_report **log_rh);
|
||||
struct dm_report_group **report_group, struct dm_report **log_rh,
|
||||
log_report_t *saved_log_report_state);
|
||||
|
||||
void *report_init(struct cmd_context *cmd, const char *format, const char *keys,
|
||||
report_type_t *report_type, const char *separator,
|
||||
|
@ -1418,7 +1418,8 @@ int devtypes(struct cmd_context *cmd, int argc, char **argv)
|
||||
#define REPORT_FORMAT_NAME_JSON "json"
|
||||
|
||||
int report_format_init(struct cmd_context *cmd, dm_report_group_type_t *report_group_type,
|
||||
struct dm_report_group **report_group, struct dm_report **log_rh)
|
||||
struct dm_report_group **report_group, struct dm_report **log_rh,
|
||||
log_report_t *saved_log_report_state)
|
||||
{
|
||||
int config_set = find_config_tree_node(cmd, report_output_format_CFG, NULL) != NULL;
|
||||
const char *config_format_str = find_config_tree_str(cmd, report_output_format_CFG, NULL);
|
||||
@ -1483,6 +1484,11 @@ int report_format_init(struct cmd_context *cmd, dm_report_group_type_t *report_g
|
||||
*report_group = new_report_group;
|
||||
if (tmp_log_rh)
|
||||
*log_rh = tmp_log_rh;
|
||||
|
||||
if (saved_log_report_state) {
|
||||
*saved_log_report_state = log_get_report_state();
|
||||
log_set_report(*log_rh);
|
||||
}
|
||||
return 1;
|
||||
bad:
|
||||
if (!dm_report_group_destroy(new_report_group))
|
||||
|
@ -1729,11 +1729,12 @@ struct processing_handle *init_processing_handle(struct cmd_context *cmd, struct
|
||||
|
||||
if (!parent_handle) {
|
||||
if (!report_format_init(cmd, &handle->report_group_type, &handle->report_group,
|
||||
&handle->log_rh)) {
|
||||
&handle->log_rh, &handle->saved_log_report_state)) {
|
||||
dm_pool_free(cmd->mem, handle);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
} else
|
||||
handle->saved_log_report_state = log_get_report_state();
|
||||
|
||||
return handle;
|
||||
}
|
||||
@ -1767,6 +1768,9 @@ void destroy_processing_handle(struct cmd_context *cmd, struct processing_handle
|
||||
if (handle) {
|
||||
if (handle->selection_handle && handle->selection_handle->selection_rh)
|
||||
dm_report_free(handle->selection_handle->selection_rh);
|
||||
|
||||
log_restore_report_state(handle->saved_log_report_state);
|
||||
|
||||
if (!dm_report_group_destroy(handle->report_group))
|
||||
stack;
|
||||
if (handle->log_rh)
|
||||
|
@ -76,6 +76,7 @@ struct processing_handle {
|
||||
dm_report_group_type_t report_group_type;
|
||||
struct dm_report_group *report_group;
|
||||
struct dm_report *log_rh;
|
||||
log_report_t saved_log_report_state;
|
||||
void *custom_handle;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user