affected and to clean them up accordingly.
* mgr/snap-schedule: For clusters with multiple CephFS file systems, all the
snap-schedule commands now expect the '--fs' argument.
+* The `mon_cluster_log_file_level` and `mon_cluster_log_to_syslog_level` options
+ have been removed. Henceforth, users should use the new generic option
+ `mon_cluster_log_level` to control the cluster log level verbosity for the cluster
+ log file as well as for all external entities.
* RGW: Fixed a S3 Object Lock bug with PutObjectRetention requests that specify
a RetainUntilDate after the year 2106. This date was truncated to 32 bits when
stored, so a much earlier date was used for object lock enforcement. This does
teardown $dir || return 1
}
+function wait_for_string() {
+ local logfile=$1
+ local searchstr=$2
+
+ status=1
+ for ((i=0; i < $TIMEOUT; i++)); do
+ echo $i
+ if ! grep "$searchstr" $logfile; then
+ sleep 1
+ else
+ status=0
+ break
+ fi
+ done
+ return $status
+}
#######################################################################
--- /dev/null
+#!/usr/bin/env bash
+#
+# Copyright (C) 2022 Red Hat <contact@redhat.com>
+#
+# Author: Prashant D <pdhange@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Library Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Library Public License for more details.
+#
+
+source $CEPH_ROOT/qa/standalone/ceph-helpers.sh
+
+function run() {
+ local dir=$1
+ shift
+
+ export CEPH_MON="127.0.0.1:7156" # git grep '\<7156\>' : there must be only one
+ export CEPH_ARGS
+ CEPH_ARGS+="--fsid=$(uuidgen) --auth-supported=none "
+ CEPH_ARGS+="--mon-host=$CEPH_MON "
+
+ local funcs=${@:-$(set | sed -n -e 's/^\(TEST_[0-9a-z_]*\) .*/\1/p')}
+ for func in $funcs ; do
+ setup $dir || return 1
+ $func $dir || return 1
+ teardown $dir || return 1
+ done
+}
+
+function TEST_cluster_log_level() {
+ local dir=$1
+
+ run_mon $dir a || return 1
+ run_mgr $dir x || return 1
+ run_osd $dir 0 || return 1
+
+ ceph config set mon.a mon_cluster_log_level debug
+ ceph osd pool create replicated1 8 8
+ ceph osd pool set replicated1 size 1 --yes-i-really-mean-it
+ ceph osd pool set replicated1 min_size 1
+
+ WAIT_FOR_CLEAN_TIMEOUT=60 wait_for_clean
+ ERRORS=0
+ truncate $dir/log -s 0
+ ceph pg deep-scrub 1.0
+ search_str="cluster [[]DBG[]] 1.0 deep-scrub"
+ TIMEOUT=60 wait_for_string $dir/log "$search_str"
+ grep -q "$search_str" $dir/log
+ return_code=$?
+ if [ $return_code -ne 0 ]; then
+ echo "Failed : Could not find DBG log in the cluster log file"
+ ERRORS=$(($ERRORS + 1))
+ fi
+
+ ceph osd down 0
+ TIMEOUT=20 wait_for_osd up 0 || return 1
+ grep -q "cluster [[]INF[]] osd.0.*boot" $dir/log
+ return_code=$?
+ if [ $return_code -ne 0 ]; then
+ echo "Failed : Could not find INF log in the cluster log file"
+ ERRORS=$(($ERRORS + 1))
+ fi
+
+ ceph config set mon.a mon_cluster_log_level info
+ ceph pg deep-scrub 1.1
+ search_str="cluster [[]DBG[]] 1.1 deep-scrub"
+ TIMEOUT=60 wait_for_string $dir/log "$search_str"
+ grep -q "$search_str" $dir/log
+ return_code=$?
+ if [ $return_code -eq 0 ]; then
+ echo "Failed : Found DBG log in the cluster log file"
+ ERRORS=$(($ERRORS + 1))
+ fi
+
+ ceph config set mon.a mon_cluster_log_level warn
+ ceph osd set noup
+ ceph osd down osd.0
+ ceph osd unset noup
+ TIMEOUT=60 wait_for_osd up 0 || return 1
+ search_str="cluster [[]WRN[]] Health check failed: noup flag(s) set (OSDMAP_FLAGS)"
+ grep -q "$search_str" $dir/log
+ return_code=$?
+ if [ $return_code -ne 0 ]; then
+ echo "Failed : No WRN entries found in the cluster log file"
+ ERRORS=$(($ERRORS + 1))
+ fi
+
+ ceph osd out 0
+ ceph osd in 0
+ WAIT_FOR_CLEAN_TIMEOUT=60 wait_for_clean
+ search_str="cluster [[]INF[]] Client client.admin marked osd.0 out, while it was still marked up"
+ ceph log last 1000 | grep -q "$search_str" || return 1
+ TIMEOUT=60 wait_for_string $dir/log "$search_str"
+ grep -q "$search_str" $dir/log
+ return_code=$?
+ if [ $return_code -eq 0 ]; then
+ echo "Failed : Found INF log in the cluster log file"
+ ERRORS=$(($ERRORS + 1))
+ fi
+
+ if [ $ERRORS -gt 0 ]; then
+ echo "TEST FAILED WITH $ERRORS ERRORS"
+ return 1
+ fi
+
+ echo "TEST PASSED"
+ return 0
+}
+
+function TEST_journald_cluster_log_level() {
+ local dir=$1
+
+ run_mon $dir a || return 1
+ run_mgr $dir x || return 1
+ run_osd $dir 0 || return 1
+
+ ceph config set mon.a mon_cluster_log_level debug
+ ceph osd pool create replicated1 8 8
+ ceph osd pool set replicated1 size 1 --yes-i-really-mean-it
+ ceph osd pool set replicated1 min_size 1
+
+ WAIT_FOR_CLEAN_TIMEOUT=60 wait_for_clean
+ ERRORS=0
+ ceph config set mon.a mon_cluster_log_to_journald true
+
+ ceph pg deep-scrub 1.0
+ search_str="1.0 deep-scrub"
+ TIMEOUT=60
+ sleep $TIMEOUT
+ journalctl _COMM=ceph-mon CEPH_CHANNEL=cluster PRIORITY=7 --output=json-pretty --since "60 seconds ago" |jq '.MESSAGE' > $dir/journal.log
+ grep -q "$search_str" $dir/journal.log
+ return_code=$?
+ if [ $return_code -ne 0 ]; then
+ echo "Failed : Could not find DBG log in the journalctl log file"
+ ERRORS=$(($ERRORS + 1))
+ fi
+
+ ceph osd down 0
+ TIMEOUT=20 wait_for_osd up 0 || return 1
+ search_str="osd.0.*boot"
+ journalctl _COMM=ceph-mon CEPH_CHANNEL=cluster PRIORITY=6 --output=json-pretty --since "60 seconds ago" |jq '.MESSAGE' > $dir/journal.log
+ grep -q "$search_str" $dir/journal.log
+ return_code=$?
+ if [ $return_code -ne 0 ]; then
+ echo "Failed : Could not find INF log in the journalctl log file"
+ ERRORS=$(($ERRORS + 1))
+ fi
+
+ ceph config set mon.a mon_cluster_log_level info
+ ceph pg deep-scrub 1.1
+ TIMEOUT=60
+ sleep $TIMEOUT
+ search_str="1.1 deep-scrub"
+ journalctl _COMM=ceph-mon CEPH_CHANNEL=cluster PRIORITY=7 --output=json-pretty --since "60 seconds ago" |jq '.MESSAGE' > $dir/journal.log
+ grep -q "$search_str" $dir/journal.log
+ return_code=$?
+ if [ $return_code -eq 0 ]; then
+ echo "Failed : Found $clog_entries DBG log entries in the journalctl log file"
+ ERRORS=$(($ERRORS + 1))
+ fi
+
+ ceph config set mon.a mon_cluster_log_level warn
+ ceph osd set noup
+ ceph osd down osd.0
+ ceph osd unset noup
+ TIMEOUT=60 wait_for_osd up 0 || return 1
+ search_str="Health check failed: noup flag(s) set (OSDMAP_FLAGS)"
+ journalctl _COMM=ceph-mon CEPH_CHANNEL=cluster PRIORITY=4 --output=json-pretty --since "60 seconds ago" |jq '.MESSAGE' > $dir/journal.log
+ grep -q "$search_str" $dir/journal.log
+ return_code=$?
+ if [ $return_code -ne 0 ]; then
+ echo "Failed : No WRN entries found in the journalctl log file"
+ ERRORS=$(($ERRORS + 1))
+ fi
+
+ ceph osd out 0
+ ceph osd in 0
+ WAIT_FOR_CLEAN_TIMEOUT=60 wait_for_clean
+ search_str="Client client.admin marked osd.0 out, while it was still marked up"
+ ceph log last | grep -q "$search_str" || return 1
+ journalctl _COMM=ceph-mon CEPH_CHANNEL=cluster PRIORITY=6 --output=json-pretty --since "60 seconds ago" |jq '.MESSAGE' > $dir/journal.log
+ grep -q "$search_str" $dir/journal.log
+ return_code=$?
+ if [ $return_code -eq 0 ]; then
+ echo "Failed : Found $clog_entries INF log entries in the journalctl log file"
+ ERRORS=$(($ERRORS + 1))
+ fi
+
+ if [ $ERRORS -gt 0 ]; then
+ echo "TEST FAILED WITH $ERRORS ERRORS"
+ return 1
+ fi
+
+ echo "TEST PASSED"
+ return 0
+}
+
+main mon-cluster-log "$@"
flags:
- runtime
with_legacy: true
-- name: mon_cluster_log_to_syslog_level
- type: str
- level: advanced
- desc: Syslog level for cluster log messages
- default: info
- services:
- - mon
- see_also:
- - mon_cluster_log_to_syslog
- flags:
- - runtime
- with_legacy: true
- name: mon_cluster_log_to_syslog_facility
type: str
level: advanced
flags:
- runtime
with_legacy: true
-- name: mon_cluster_log_file_level
+- name: mon_cluster_log_level
type: str
level: advanced
- desc: Lowest level to include is cluster log file
+ desc: Lowest level to include in cluster log file and/or in external log server
+ long_desc: Log level to control the cluster log message verbosity for the cluster
+ log file as well as for all external entities.
default: debug
services:
- mon
void LogMonitor::log_channel_info::clear()
{
log_to_syslog.clear();
- syslog_level.clear();
syslog_facility.clear();
log_file.clear();
expanded_log_file.clear();
- log_file_level.clear();
+ log_level.clear();
log_to_graylog.clear();
log_to_graylog_host.clear();
log_to_graylog_port.clear();
channel = CLOG_CHANNEL_CLUSTER;
}
+ string level = channels.get_log_level(channel);
+ if (int log_level = LogEntry::str_to_level(level);log_level > le.prio) {
+ // Do not log LogEntry to any external entity if le.prio is
+ // less than channel log level.
+ return;
+ }
+
+ if (g_conf().get_val<bool>("mon_cluster_log_to_stderr")) {
+ cerr << channel << " " << le << std::endl;
+ }
+
if (channels.do_log_to_syslog(channel)) {
- string level = channels.get_level(channel);
string facility = channels.get_facility(channel);
if (level.empty() || facility.empty()) {
derr << __func__ << " unable to log to syslog -- level or facility"
<< " not defined (level: " << level << ", facility: "
<< facility << ")" << dendl;
} else {
- le.log_to_syslog(channels.get_level(channel),
- channels.get_facility(channel));
+ le.log_to_syslog(level, facility);
}
}
return;
}
- r = get_conf_str_map_helper(
- g_conf().get_val<string>("mon_cluster_log_to_syslog_level"),
- oss, &channels.syslog_level,
- CLOG_CONFIG_DEFAULT_KEY);
- if (r < 0) {
- derr << __func__ << " error parsing 'mon_cluster_log_to_syslog_level'"
- << dendl;
- return;
- }
-
r = get_conf_str_map_helper(
g_conf().get_val<string>("mon_cluster_log_to_syslog_facility"),
oss, &channels.syslog_facility,
}
r = get_conf_str_map_helper(
- g_conf().get_val<string>("mon_cluster_log_file_level"), oss,
- &channels.log_file_level,
+ g_conf().get_val<string>("mon_cluster_log_level"), oss,
+ &channels.log_level,
CLOG_CONFIG_DEFAULT_KEY);
if (r < 0) {
- derr << __func__ << " error parsing 'mon_cluster_log_file_level'"
+ derr << __func__ << " error parsing 'mon_cluster_log_level'"
<< dendl;
return;
}
const std::set<std::string> &changed)
{
if (changed.count("mon_cluster_log_to_syslog") ||
- changed.count("mon_cluster_log_to_syslog_level") ||
changed.count("mon_cluster_log_to_syslog_facility") ||
changed.count("mon_cluster_log_file") ||
- changed.count("mon_cluster_log_file_level") ||
+ changed.count("mon_cluster_log_level") ||
changed.count("mon_cluster_log_to_graylog") ||
changed.count("mon_cluster_log_to_graylog_host") ||
changed.count("mon_cluster_log_to_graylog_port") ||
struct log_channel_info {
std::map<std::string,std::string> log_to_syslog;
- std::map<std::string,std::string> syslog_level;
std::map<std::string,std::string> syslog_facility;
std::map<std::string,std::string> log_file;
std::map<std::string,std::string> expanded_log_file;
- std::map<std::string,std::string> log_file_level;
+ std::map<std::string,std::string> log_level;
std::map<std::string,std::string> log_to_graylog;
std::map<std::string,std::string> log_to_graylog_host;
std::map<std::string,std::string> log_to_graylog_port;
*/
void expand_channel_meta() {
expand_channel_meta(log_to_syslog);
- expand_channel_meta(syslog_level);
expand_channel_meta(syslog_facility);
- expand_channel_meta(log_file_level);
+ expand_channel_meta(log_level);
}
void expand_channel_meta(std::map<std::string,std::string> &m);
std::string expand_channel_meta(const std::string &input,
&CLOG_CONFIG_DEFAULT_KEY);
}
- std::string get_level(const std::string &channel) {
- return get_str_map_key(syslog_level, channel,
- &CLOG_CONFIG_DEFAULT_KEY);
- }
-
std::string get_log_file(const std::string &channel);
- std::string get_log_file_level(const std::string &channel) {
- return get_str_map_key(log_file_level, channel,
+ std::string get_log_level(const std::string &channel) {
+ return get_str_map_key(log_level, channel,
&CLOG_CONFIG_DEFAULT_KEY);
}
const char **get_tracked_conf_keys() const override {
static const char* KEYS[] = {
"mon_cluster_log_to_syslog",
- "mon_cluster_log_to_syslog_level",
"mon_cluster_log_to_syslog_facility",
"mon_cluster_log_file",
- "mon_cluster_log_file_level",
+ "mon_cluster_log_level",
"mon_cluster_log_to_graylog",
"mon_cluster_log_to_graylog_host",
"mon_cluster_log_to_graylog_port",