Added logfile option for non-syslog logging

This commit is contained in:
Takeshi Nakatani 2020-10-13 14:00:11 +00:00 committed by Andrew Gaul
parent 6aa786b886
commit 38e1eaa8a3
11 changed files with 426 additions and 136 deletions

View File

@ -337,6 +337,11 @@ Specify the path of the mime.types file.
If this option is not specified, the existence of "/etc/mime.types" is checked, and that file is loaded as mime information.
If this file does not exist on macOS, then "/etc/apache2/mime.types" is checked as well.
.TP
\fB\-o\fR logfile - specify the log output file.
s3fs outputs the log file to syslog. Alternatively, if s3fs is started with the "-f" option specified, the log will be output to the stdout/stderr.
You can use this option to specify the log file that s3fs outputs.
If you specify a log file with this option, it will reopen the log file when s3fs receives a SIGHUP signal. You can use the SIGHUP signal for log rotation.
.TP
\fB\-o\fR dbglevel (default="crit")
Set the debug message level. set value as crit (critical), err (error), warn (warning), info (information) to debug level. default debug level is critical.
If s3fs run with "-d" option, the debug level is set information.

View File

@ -65,7 +65,7 @@ s3fs_LDADD = $(DEPS_LIBS)
noinst_PROGRAMS = test_string_util
test_string_util_SOURCES = string_util.cpp test_string_util.cpp
test_string_util_SOURCES = string_util.cpp test_string_util.cpp s3fs_logger.cpp
TESTS = test_string_util

View File

@ -233,7 +233,7 @@ struct curl_slist* AdditionalHeader::AddHeader(struct curl_slist* list, const ch
bool AdditionalHeader::Dump() const
{
if(!IS_S3FS_LOG_DBG()){
if(!S3fsLog::IsS3fsLogDbg()){
return true;
}

View File

@ -2203,7 +2203,7 @@ bool S3fsCurl::RemakeHandle()
//
int S3fsCurl::RequestPerform(bool dontAddAuthHeaders /*=false*/)
{
if(IS_S3FS_LOG_DBG()){
if(S3fsLog::IsS3fsLogDbg()){
char* ptr_url = NULL;
curl_easy_getinfo(hCurl, CURLINFO_EFFECTIVE_URL , &ptr_url);
S3FS_PRN_DBG("connecting to URL %s", SAFESTRPTR(ptr_url));

View File

@ -2406,7 +2406,7 @@ static int s3fs_release(const char* _path, struct fuse_file_info* fi)
}
// check - for debug
if(IS_S3FS_LOG_DBG()){
if(S3fsLog::IsS3fsLogDbg()){
AutoFdEntity autoent;
FdEntity* ent;
if(NULL != (ent = autoent.GetFdEntity(path, static_cast<int>(fi->fh)))){
@ -4619,20 +4619,31 @@ static int my_fuse_opt_proc(void* data, const char* arg, int key, struct fuse_ar
return 0;
}
//
// debug option for s3fs
// log file option
//
if(is_prefix(arg, "logfile=")){
const char* strlogfile = strchr(arg, '=') + sizeof(char);
if(!S3fsLog::SetLogfile(strlogfile)){
S3FS_PRN_EXIT("The file(%s) specified by logfile option could not be opened.", strlogfile);
return -1;
}
return 0;
}
//
// debug level option
//
if(is_prefix(arg, "dbglevel=")){
const char* strlevel = strchr(arg, '=') + sizeof(char);
if(0 == strcasecmp(strlevel, "silent") || 0 == strcasecmp(strlevel, "critical") || 0 == strcasecmp(strlevel, "crit")){
S3fsSignals::SetLogLevel(S3FS_LOG_CRIT);
S3fsLog::SetLogLevel(S3fsLog::LEVEL_CRIT);
}else if(0 == strcasecmp(strlevel, "error") || 0 == strcasecmp(strlevel, "err")){
S3fsSignals::SetLogLevel(S3FS_LOG_ERR);
S3fsLog::SetLogLevel(S3fsLog::LEVEL_ERR);
}else if(0 == strcasecmp(strlevel, "wan") || 0 == strcasecmp(strlevel, "warn") || 0 == strcasecmp(strlevel, "warning")){
S3fsSignals::SetLogLevel(S3FS_LOG_WARN);
S3fsLog::SetLogLevel(S3fsLog::LEVEL_WARN);
}else if(0 == strcasecmp(strlevel, "inf") || 0 == strcasecmp(strlevel, "info") || 0 == strcasecmp(strlevel, "information")){
S3fsSignals::SetLogLevel(S3FS_LOG_INFO);
S3fsLog::SetLogLevel(S3fsLog::LEVEL_INFO);
}else if(0 == strcasecmp(strlevel, "dbg") || 0 == strcasecmp(strlevel, "debug")){
S3fsSignals::SetLogLevel(S3FS_LOG_DBG);
S3fsLog::SetLogLevel(S3fsLog::LEVEL_DBG);
}else{
S3FS_PRN_EXIT("option dbglevel has unknown parameter(%s).", strlevel);
return -1;
@ -4642,11 +4653,11 @@ static int my_fuse_opt_proc(void* data, const char* arg, int key, struct fuse_ar
//
// debug option
//
// debug_level is S3FS_LOG_INFO, after second -d is passed to fuse.
// S3fsLog level is LEVEL_INFO, after second -d is passed to fuse.
//
if(0 == strcmp(arg, "-d") || 0 == strcmp(arg, "--debug")){
if(!IS_S3FS_LOG_INFO() && !IS_S3FS_LOG_DBG()){
S3fsSignals::SetLogLevel(S3FS_LOG_INFO);
if(!S3fsLog::IsS3fsLogInfo() && !S3fsLog::IsS3fsLogDbg()){
S3fsLog::SetLogLevel(S3fsLog::LEVEL_INFO);
return 0;
}
if(0 == strcmp(arg, "--debug")){
@ -4656,9 +4667,9 @@ static int my_fuse_opt_proc(void* data, const char* arg, int key, struct fuse_ar
}
}
// "f2" is not used no more.
// (set S3FS_LOG_DBG)
// (set S3fsLog::LEVEL_DBG)
if(0 == strcmp(arg, "f2")){
S3fsSignals::SetLogLevel(S3FS_LOG_DBG);
S3fsLog::SetLogLevel(S3fsLog::LEVEL_DBG);
return 0;
}
if(0 == strcmp(arg, "curldbg")){
@ -4734,6 +4745,7 @@ int main(int argc, char* argv[])
int option_index = 0;
struct fuse_operations s3fs_oper;
time_t incomp_abort_time = (24 * 60 * 60);
S3fsLog singletonLog;
static const struct option long_opts[] = {
{"help", no_argument, NULL, 'h'},
@ -4744,10 +4756,6 @@ int main(int argc, char* argv[])
{NULL, 0, NULL, 0}
};
// init syslog(default CRIT)
openlog("s3fs", LOG_PID | LOG_ODELAY | LOG_NOWAIT, LOG_USER);
S3fsSignals::SetLogLevel(debug_level);
// init xml2
xmlInitParser();
LIBXML_TEST_VERSION

View File

@ -431,6 +431,15 @@ static const char help_string[] =
" If this file does not exist on macOS, then \"/etc/apache2/mime.types\"\n"
" is checked as well.\n"
"\n"
" logfile - specify the log output file.\n"
" s3fs outputs the log file to syslog. Alternatively, if s3fs is\n"
" started with the \"-f\" option specified, the log will be output\n"
" to the stdout/stderr.\n"
" You can use this option to specify the log file that s3fs outputs.\n"
" If you specify a log file with this option, it will reopen the log\n"
" file when s3fs receives a SIGHUP signal. You can use the SIGHUP\n"
" signal for log rotation.\n"
"\n"
" dbglevel (default=\"crit\")\n"
" Set the debug message level. set value as crit (critical), err\n"
" (error), warn (warning), info (information) to debug level.\n"

View File

@ -18,13 +18,207 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <cstdlib>
#include <string>
#include "common.h"
#include "s3fs_logger.h"
//-------------------------------------------------------------------
// Global variables
// S3fsLog class : variables
//-------------------------------------------------------------------
s3fs_log_level debug_level = S3FS_LOG_CRIT;
const char* s3fs_log_nest[S3FS_LOG_NEST_MAX] = {"", " ", " ", " "};
const int S3fsLog::NEST_MAX;
const char* S3fsLog::nest_spaces[S3fsLog::NEST_MAX] = {"", " ", " ", " "};
const char* S3fsLog::LOGFILEENV = "S3FS_LOGFILE";
S3fsLog* S3fsLog::pSingleton = NULL;
S3fsLog::s3fs_log_level S3fsLog::debug_level = S3fsLog::LEVEL_CRIT;
FILE* S3fsLog::logfp = NULL;
std::string* S3fsLog::plogfile = NULL;
//-------------------------------------------------------------------
// S3fsLog class : class methods
//-------------------------------------------------------------------
bool S3fsLog::IsS3fsLogLevel(s3fs_log_level level)
{
return (level == (S3fsLog::debug_level & level));
}
bool S3fsLog::SetLogfile(const char* pfile)
{
if(!S3fsLog::pSingleton){
S3FS_PRN_CRIT("S3fsLog::pSingleton is NULL.");
return false;
}
return S3fsLog::pSingleton->LowSetLogfile(pfile);
}
bool S3fsLog::ReopenLogfile()
{
if(!S3fsLog::pSingleton){
S3FS_PRN_CRIT("S3fsLog::pSingleton is NULL.");
return false;
}
if(!S3fsLog::logfp){
S3FS_PRN_INFO("Currently the log file is output to stdout/stderr.");
return true;
}
if(!S3fsLog::plogfile){
S3FS_PRN_ERR("There is a problem with the path to the log file being NULL.");
return false;
}
std::string tmp = *(S3fsLog::plogfile);
return S3fsLog::pSingleton->LowSetLogfile(tmp.c_str());
}
S3fsLog::s3fs_log_level S3fsLog::SetLogLevel(s3fs_log_level level)
{
if(!S3fsLog::pSingleton){
S3FS_PRN_CRIT("S3fsLog::pSingleton is NULL.");
return S3fsLog::debug_level; // Although it is an error, it returns the current value.
}
return S3fsLog::pSingleton->LowSetLogLevel(level);
}
S3fsLog::s3fs_log_level S3fsLog::BumpupLogLevel()
{
if(!S3fsLog::pSingleton){
S3FS_PRN_CRIT("S3fsLog::pSingleton is NULL.");
return S3fsLog::debug_level; // Although it is an error, it returns the current value.
}
return S3fsLog::pSingleton->LowBumpupLogLevel();
}
//-------------------------------------------------------------------
// S3fsLog class : methods
//-------------------------------------------------------------------
S3fsLog::S3fsLog()
{
if(!S3fsLog::pSingleton){
S3fsLog::pSingleton = this;
// init syslog(default CRIT)
openlog("s3fs", LOG_PID | LOG_ODELAY | LOG_NOWAIT, LOG_USER);
LowLoadEnv();
}else{
S3FS_PRN_ERR("Already set singleton object for S3fsLog.");
}
}
S3fsLog::~S3fsLog()
{
if(S3fsLog::pSingleton == this){
FILE* oldfp = S3fsLog::logfp;
S3fsLog::logfp = NULL;
if(oldfp && 0 != fclose(oldfp)){
S3FS_PRN_ERR("Could not close old log file(%s), but continue...", (S3fsLog::plogfile ? S3fsLog::plogfile->c_str() : "null"));
}
if(S3fsLog::plogfile){
delete S3fsLog::plogfile;
S3fsLog::plogfile = NULL;
}
S3fsLog::pSingleton = NULL;
S3fsLog::debug_level = S3fsLog::LEVEL_CRIT;
closelog();
}else{
S3FS_PRN_ERR("This object is not singleton S3fsLog object.");
}
}
bool S3fsLog::LowLoadEnv()
{
if(S3fsLog::pSingleton != this){
S3FS_PRN_ERR("This object is not as same as S3fsLog::pSingleton.");
return false;
}
char* pEnvVal;
if(NULL == (pEnvVal = getenv(S3fsLog::LOGFILEENV))){
return true;
}
if(!SetLogfile(pEnvVal)){
return false;
}
return true;
}
bool S3fsLog::LowSetLogfile(const char* pfile)
{
if(S3fsLog::pSingleton != this){
S3FS_PRN_ERR("This object is not as same as S3fsLog::pSingleton.");
return false;
}
if(!pfile){
// close log file if it is opened
if(S3fsLog::logfp && 0 != fclose(S3fsLog::logfp)){
S3FS_PRN_ERR("Could not close log file(%s).", (S3fsLog::plogfile ? S3fsLog::plogfile->c_str() : "null"));
return false;
}
S3fsLog::logfp = NULL;
if(S3fsLog::plogfile){
delete S3fsLog::plogfile;
S3fsLog::plogfile = NULL;
}
}else{
// open new log file
//
// [NOTE]
// It will reopen even if it is the same file.
//
FILE* newfp;
if(NULL == (newfp = fopen(pfile, "a+"))){
S3FS_PRN_ERR("Could not open log file(%s).", pfile);
return false;
}
// switch new log file and close old log file if it is opened
FILE* oldfp = S3fsLog::logfp;
S3fsLog::logfp = newfp;
if(oldfp && 0 != fclose(oldfp)){
S3FS_PRN_ERR("Could not close old log file(%s).", (S3fsLog::plogfile ? S3fsLog::plogfile->c_str() : "null"));
S3fsLog::logfp = oldfp;
fclose(newfp);
return false;
}
if(S3fsLog::plogfile){
delete S3fsLog::plogfile;
}
S3fsLog::plogfile = new std::string(pfile);
}
return true;
}
S3fsLog::s3fs_log_level S3fsLog::LowSetLogLevel(s3fs_log_level level)
{
if(S3fsLog::pSingleton != this){
S3FS_PRN_ERR("This object is not as same as S3fsLog::pSingleton.");
return S3fsLog::debug_level; // Although it is an error, it returns the current value.
}
if(level == S3fsLog::debug_level){
return S3fsLog::debug_level;
}
s3fs_log_level old = S3fsLog::debug_level;
S3fsLog::debug_level = level;
setlogmask(LOG_UPTO(GetSyslogLevel(S3fsLog::debug_level)));
S3FS_PRN_CRIT("change debug level from %sto %s", GetLevelString(old), GetLevelString(S3fsLog::debug_level));
return old;
}
S3fsLog::s3fs_log_level S3fsLog::LowBumpupLogLevel()
{
if(S3fsLog::pSingleton != this){
S3FS_PRN_ERR("This object is not as same as S3fsLog::pSingleton.");
return S3fsLog::debug_level; // Although it is an error, it returns the current value.
}
s3fs_log_level old = S3fsLog::debug_level;
S3fsLog::debug_level = ( LEVEL_CRIT == S3fsLog::debug_level ? LEVEL_ERR :
LEVEL_ERR == S3fsLog::debug_level ? LEVEL_WARN :
LEVEL_WARN == S3fsLog::debug_level ? LEVEL_INFO :
LEVEL_INFO == S3fsLog::debug_level ? LEVEL_DBG : LEVEL_CRIT );
setlogmask(LOG_UPTO(GetSyslogLevel(S3fsLog::debug_level)));
S3FS_PRN_CRIT("change debug level from %sto %s", GetLevelString(old), GetLevelString(S3fsLog::debug_level));
return old;
}
/*
* Local variables:

View File

@ -21,127 +21,200 @@
#ifndef S3FS_LOGGER_H_
#define S3FS_LOGGER_H_
#include <cstdio>
#include <syslog.h>
//-------------------------------------------------------------------
// Debug level
// S3fsLog class
//-------------------------------------------------------------------
enum s3fs_log_level{
S3FS_LOG_CRIT = 0, // LOG_CRIT
S3FS_LOG_ERR = 1, // LOG_ERR
S3FS_LOG_WARN = 3, // LOG_WARNING
S3FS_LOG_INFO = 7, // LOG_INFO
S3FS_LOG_DBG = 15 // LOG_DEBUG
class S3fsLog
{
public:
enum s3fs_log_level{
LEVEL_CRIT = 0, // LEVEL_CRIT
LEVEL_ERR = 1, // LEVEL_ERR
LEVEL_WARN = 3, // LEVEL_WARNING
LEVEL_INFO = 7, // LEVEL_INFO
LEVEL_DBG = 15 // LEVEL_DEBUG
};
protected:
static const int NEST_MAX = 4;
static const char* nest_spaces[NEST_MAX];
static const char* LOGFILEENV;
static S3fsLog* pSingleton;
static s3fs_log_level debug_level;
static FILE* logfp;
static std::string* plogfile;
protected:
bool LowLoadEnv();
bool LowSetLogfile(const char* pfile);
s3fs_log_level LowSetLogLevel(s3fs_log_level level);
s3fs_log_level LowBumpupLogLevel();
public:
static bool IsS3fsLogLevel(s3fs_log_level level);
static bool IsS3fsLogCrit() { return IsS3fsLogLevel(LEVEL_CRIT); }
static bool IsS3fsLogErr() { return IsS3fsLogLevel(LEVEL_ERR); }
static bool IsS3fsLogWarn() { return IsS3fsLogLevel(LEVEL_WARN); }
static bool IsS3fsLogInfo() { return IsS3fsLogLevel(LEVEL_INFO); }
static bool IsS3fsLogDbg() { return IsS3fsLogLevel(LEVEL_DBG); }
static int GetSyslogLevel(s3fs_log_level level)
{
return ( LEVEL_DBG == (level & LEVEL_DBG) ? LOG_DEBUG :
LEVEL_INFO == (level & LEVEL_DBG) ? LOG_INFO :
LEVEL_WARN == (level & LEVEL_DBG) ? LOG_WARNING :
LEVEL_ERR == (level & LEVEL_DBG) ? LOG_ERR : LOG_CRIT );
}
static const char* GetLevelString(s3fs_log_level level)
{
return ( LEVEL_DBG == (level & LEVEL_DBG) ? "[DBG] " :
LEVEL_INFO == (level & LEVEL_DBG) ? "[INF] " :
LEVEL_WARN == (level & LEVEL_DBG) ? "[WAN] " :
LEVEL_ERR == (level & LEVEL_DBG) ? "[ERR] " : "[CRT] " );
}
static const char* GetS3fsLogNest(int nest)
{
if(nest < NEST_MAX){
return nest_spaces[nest];
}else{
return nest_spaces[NEST_MAX - 1];
}
}
static bool IsSetLogFile()
{
return (NULL != logfp);
}
static FILE* GetOutputLogFile()
{
return (logfp ? logfp : stdout);
}
static FILE* GetErrorLogFile()
{
return (logfp ? logfp : stderr);
}
static void SeekEnd()
{
if(logfp){
fseek(logfp, 0, SEEK_END);
}
}
static void Flush()
{
if(logfp){
fflush(logfp);
}
}
static bool SetLogfile(const char* pfile);
static bool ReopenLogfile();
static s3fs_log_level SetLogLevel(s3fs_log_level level);
static s3fs_log_level BumpupLogLevel();
explicit S3fsLog();
~S3fsLog();
};
//-------------------------------------------------------------------
// Debug macros
//-------------------------------------------------------------------
#define IS_S3FS_LOG_CRIT() (S3FS_LOG_CRIT == debug_level)
#define IS_S3FS_LOG_ERR() (S3FS_LOG_ERR == (debug_level & S3FS_LOG_DBG))
#define IS_S3FS_LOG_WARN() (S3FS_LOG_WARN == (debug_level & S3FS_LOG_DBG))
#define IS_S3FS_LOG_INFO() (S3FS_LOG_INFO == (debug_level & S3FS_LOG_DBG))
#define IS_S3FS_LOG_DBG() (S3FS_LOG_DBG == (debug_level & S3FS_LOG_DBG))
#define S3FS_LOG_LEVEL_TO_SYSLOG(level) \
( S3FS_LOG_DBG == (level & S3FS_LOG_DBG) ? LOG_DEBUG : \
S3FS_LOG_INFO == (level & S3FS_LOG_DBG) ? LOG_INFO : \
S3FS_LOG_WARN == (level & S3FS_LOG_DBG) ? LOG_WARNING : \
S3FS_LOG_ERR == (level & S3FS_LOG_DBG) ? LOG_ERR : LOG_CRIT )
#define S3FS_LOG_LEVEL_STRING(level) \
( S3FS_LOG_DBG == (level & S3FS_LOG_DBG) ? "[DBG] " : \
S3FS_LOG_INFO == (level & S3FS_LOG_DBG) ? "[INF] " : \
S3FS_LOG_WARN == (level & S3FS_LOG_DBG) ? "[WAN] " : \
S3FS_LOG_ERR == (level & S3FS_LOG_DBG) ? "[ERR] " : "[CRT] " )
#define S3FS_LOG_NEST_MAX 4
#define S3FS_LOG_NEST(nest) (nest < S3FS_LOG_NEST_MAX ? s3fs_log_nest[nest] : s3fs_log_nest[S3FS_LOG_NEST_MAX - 1])
#define S3FS_LOW_LOGPRN(level, fmt, ...) \
do{ \
if(S3FS_LOG_CRIT == level || (S3FS_LOG_CRIT != debug_level && level == (debug_level & level))){ \
if(foreground){ \
fprintf(stdout, "%s%s:%s(%d): " fmt "%s\n", S3FS_LOG_LEVEL_STRING(level), __FILE__, __func__, __LINE__, __VA_ARGS__); \
}else{ \
syslog(S3FS_LOG_LEVEL_TO_SYSLOG(level), "%s%s:%s(%d): " fmt "%s", instance_name.c_str(), __FILE__, __func__, __LINE__, __VA_ARGS__); \
} \
} \
}while(0)
do{ \
if(S3fsLog::IsS3fsLogLevel(level)){ \
if(foreground || S3fsLog::IsSetLogFile()){ \
S3fsLog::SeekEnd(); \
fprintf(S3fsLog::GetOutputLogFile(), "%s%s:%s(%d): " fmt "%s\n", S3fsLog::GetLevelString(level), __FILE__, __func__, __LINE__, __VA_ARGS__); \
S3fsLog::Flush(); \
}else{ \
syslog(S3fsLog::GetSyslogLevel(level), "%s%s:%s(%d): " fmt "%s", instance_name.c_str(), __FILE__, __func__, __LINE__, __VA_ARGS__); \
} \
} \
}while(0)
#define S3FS_LOW_LOGPRN2(level, nest, fmt, ...) \
do{ \
if(S3FS_LOG_CRIT == level || (S3FS_LOG_CRIT != debug_level && level == (debug_level & level))){ \
if(foreground){ \
fprintf(stdout, "%s%s%s:%s(%d): " fmt "%s\n", S3FS_LOG_LEVEL_STRING(level), S3FS_LOG_NEST(nest), __FILE__, __func__, __LINE__, __VA_ARGS__); \
}else{ \
syslog(S3FS_LOG_LEVEL_TO_SYSLOG(level), "%s%s" fmt "%s", instance_name.c_str(), S3FS_LOG_NEST(nest), __VA_ARGS__); \
} \
} \
}while(0)
do{ \
if(S3fsLog::IsS3fsLogLevel(level)){ \
if(foreground || S3fsLog::IsSetLogFile()){ \
S3fsLog::SeekEnd(); \
fprintf(S3fsLog::GetOutputLogFile(), "%s%s%s:%s(%d): " fmt "%s\n", S3fsLog::GetLevelString(level), S3fsLog::GetS3fsLogNest(nest), __FILE__, __func__, __LINE__, __VA_ARGS__); \
S3fsLog::Flush(); \
}else{ \
syslog(S3fsLog::GetSyslogLevel(level), "%s%s" fmt "%s", instance_name.c_str(), S3fsLog::GetS3fsLogNest(nest), __VA_ARGS__); \
} \
} \
}while(0)
#define S3FS_LOW_CURLDBG(fmt, ...) \
do{ \
if(foreground){ \
fprintf(stdout, "[CURL DBG] " fmt "%s\n", __VA_ARGS__); \
}else{ \
syslog(S3FS_LOG_LEVEL_TO_SYSLOG(S3FS_LOG_CRIT), "%s" fmt "%s", instance_name.c_str(), __VA_ARGS__); \
} \
}while(0)
do{ \
if(foreground || S3fsLog::IsSetLogFile()){ \
S3fsLog::SeekEnd(); \
fprintf(S3fsLog::GetOutputLogFile(), "[CURL DBG] " fmt "%s\n", __VA_ARGS__); \
S3fsLog::Flush(); \
}else{ \
syslog(S3fsLog::GetSyslogLevel(S3fsLog::LEVEL_CRIT), "%s" fmt "%s", instance_name.c_str(), __VA_ARGS__); \
} \
}while(0)
#define S3FS_LOW_LOGPRN_EXIT(fmt, ...) \
do{ \
if(foreground){ \
fprintf(stderr, "s3fs: " fmt "%s\n", __VA_ARGS__); \
}else{ \
fprintf(stderr, "s3fs: " fmt "%s\n", __VA_ARGS__); \
syslog(S3FS_LOG_LEVEL_TO_SYSLOG(S3FS_LOG_CRIT), "%ss3fs: " fmt "%s", instance_name.c_str(), __VA_ARGS__); \
} \
}while(0)
do{ \
if(foreground || S3fsLog::IsSetLogFile()){ \
S3fsLog::SeekEnd(); \
fprintf(S3fsLog::GetErrorLogFile(), "s3fs: " fmt "%s\n", __VA_ARGS__); \
S3fsLog::Flush(); \
}else{ \
fprintf(S3fsLog::GetErrorLogFile(), "s3fs: " fmt "%s\n", __VA_ARGS__); \
syslog(S3fsLog::GetSyslogLevel(S3fsLog::LEVEL_CRIT), "%ss3fs: " fmt "%s", instance_name.c_str(), __VA_ARGS__); \
} \
}while(0)
// Special macro for init message
#define S3FS_PRN_INIT_INFO(fmt, ...) \
do{ \
if(foreground){ \
fprintf(stdout, "%s%s%s:%s(%d): " fmt "%s\n", S3FS_LOG_LEVEL_STRING(S3FS_LOG_INFO), S3FS_LOG_NEST(0), __FILE__, __func__, __LINE__, __VA_ARGS__, ""); \
}else{ \
syslog(S3FS_LOG_LEVEL_TO_SYSLOG(S3FS_LOG_INFO), "%s%s" fmt "%s", instance_name.c_str(), S3FS_LOG_NEST(0), __VA_ARGS__, ""); \
} \
}while(0)
do{ \
if(foreground || S3fsLog::IsSetLogFile()){ \
S3fsLog::SeekEnd(); \
fprintf(S3fsLog::GetOutputLogFile(), "%s%s%s:%s(%d): " fmt "%s\n", S3fsLog::GetLevelString(S3fsLog::LEVEL_INFO), S3fsLog::GetS3fsLogNest(0), __FILE__, __func__, __LINE__, __VA_ARGS__, ""); \
S3fsLog::Flush(); \
}else{ \
syslog(S3fsLog::GetSyslogLevel(S3fsLog::LEVEL_INFO), "%s%s" fmt "%s", instance_name.c_str(), S3fsLog::GetS3fsLogNest(0), __VA_ARGS__, ""); \
} \
}while(0)
// Special macro for checking cache files
#define S3FS_LOW_CACHE(fp, fmt, ...) \
do{ \
if(foreground){ \
fprintf(fp, fmt "%s\n", __VA_ARGS__); \
}else{ \
syslog(S3FS_LOG_LEVEL_TO_SYSLOG(S3FS_LOG_INFO), "%s: " fmt "%s", instance_name.c_str(), __VA_ARGS__); \
} \
}while(0)
do{ \
if(foreground || S3fsLog::IsSetLogFile()){ \
S3fsLog::SeekEnd(); \
fprintf(fp, fmt "%s\n", __VA_ARGS__); \
S3fsLog::Flush(); \
}else{ \
syslog(S3fsLog::GetSyslogLevel(S3fsLog::LEVEL_INFO), "%s: " fmt "%s", instance_name.c_str(), __VA_ARGS__); \
} \
}while(0)
// [NOTE]
// small trick for VA_ARGS
//
#define S3FS_PRN_EXIT(fmt, ...) S3FS_LOW_LOGPRN_EXIT(fmt, ##__VA_ARGS__, "")
#define S3FS_PRN_CRIT(fmt, ...) S3FS_LOW_LOGPRN(S3FS_LOG_CRIT, fmt, ##__VA_ARGS__, "")
#define S3FS_PRN_ERR(fmt, ...) S3FS_LOW_LOGPRN(S3FS_LOG_ERR, fmt, ##__VA_ARGS__, "")
#define S3FS_PRN_WARN(fmt, ...) S3FS_LOW_LOGPRN(S3FS_LOG_WARN, fmt, ##__VA_ARGS__, "")
#define S3FS_PRN_DBG(fmt, ...) S3FS_LOW_LOGPRN(S3FS_LOG_DBG, fmt, ##__VA_ARGS__, "")
#define S3FS_PRN_INFO(fmt, ...) S3FS_LOW_LOGPRN2(S3FS_LOG_INFO, 0, fmt, ##__VA_ARGS__, "")
#define S3FS_PRN_INFO0(fmt, ...) S3FS_LOG_INFO(fmt, __VA_ARGS__)
#define S3FS_PRN_INFO1(fmt, ...) S3FS_LOW_LOGPRN2(S3FS_LOG_INFO, 1, fmt, ##__VA_ARGS__, "")
#define S3FS_PRN_INFO2(fmt, ...) S3FS_LOW_LOGPRN2(S3FS_LOG_INFO, 2, fmt, ##__VA_ARGS__, "")
#define S3FS_PRN_INFO3(fmt, ...) S3FS_LOW_LOGPRN2(S3FS_LOG_INFO, 3, fmt, ##__VA_ARGS__, "")
#define S3FS_PRN_CRIT(fmt, ...) S3FS_LOW_LOGPRN(S3fsLog::LEVEL_CRIT, fmt, ##__VA_ARGS__, "")
#define S3FS_PRN_ERR(fmt, ...) S3FS_LOW_LOGPRN(S3fsLog::LEVEL_ERR, fmt, ##__VA_ARGS__, "")
#define S3FS_PRN_WARN(fmt, ...) S3FS_LOW_LOGPRN(S3fsLog::LEVEL_WARN, fmt, ##__VA_ARGS__, "")
#define S3FS_PRN_DBG(fmt, ...) S3FS_LOW_LOGPRN(S3fsLog::LEVEL_DBG, fmt, ##__VA_ARGS__, "")
#define S3FS_PRN_INFO(fmt, ...) S3FS_LOW_LOGPRN2(S3fsLog::LEVEL_INFO, 0, fmt, ##__VA_ARGS__, "")
#define S3FS_PRN_INFO1(fmt, ...) S3FS_LOW_LOGPRN2(S3fsLog::LEVEL_INFO, 1, fmt, ##__VA_ARGS__, "")
#define S3FS_PRN_INFO2(fmt, ...) S3FS_LOW_LOGPRN2(S3fsLog::LEVEL_INFO, 2, fmt, ##__VA_ARGS__, "")
#define S3FS_PRN_INFO3(fmt, ...) S3FS_LOW_LOGPRN2(S3fsLog::LEVEL_INFO, 3, fmt, ##__VA_ARGS__, "")
#define S3FS_PRN_CURL(fmt, ...) S3FS_LOW_CURLDBG(fmt, ##__VA_ARGS__, "")
#define S3FS_PRN_CACHE(fp, ...) S3FS_LOW_CACHE(fp, ##__VA_ARGS__, "")
//-------------------------------------------------------------------
// Global variables
//-------------------------------------------------------------------
// TODO: namespace these
extern s3fs_log_level debug_level;
extern const char* s3fs_log_nest[S3FS_LOG_NEST_MAX];
#endif // S3FS_LOGGER_H_
/*

View File

@ -123,7 +123,7 @@ void* S3fsSignals::CheckCacheWorker(void* arg)
void S3fsSignals::HandlerUSR2(int sig)
{
if(SIGUSR2 == sig){
S3fsSignals::BumpupLogLevel();
S3fsLog::BumpupLogLevel();
}else{
S3FS_PRN_ERR("The handler for SIGUSR2 received signal(%d)", sig);
}
@ -142,29 +142,26 @@ bool S3fsSignals::InitUsr2Handler()
return true;
}
s3fs_log_level S3fsSignals::SetLogLevel(s3fs_log_level level)
void S3fsSignals::HandlerHUP(int sig)
{
if(level == debug_level){
return debug_level;
if(SIGHUP == sig){
S3fsLog::ReopenLogfile();
}else{
S3FS_PRN_ERR("The handler for SIGHUP received signal(%d)", sig);
}
s3fs_log_level old = debug_level;
debug_level = level;
setlogmask(LOG_UPTO(S3FS_LOG_LEVEL_TO_SYSLOG(debug_level)));
S3FS_PRN_CRIT("change debug level from %sto %s", S3FS_LOG_LEVEL_STRING(old), S3FS_LOG_LEVEL_STRING(debug_level));
return old;
}
s3fs_log_level S3fsSignals::BumpupLogLevel()
bool S3fsSignals::InitHupHandler()
{
s3fs_log_level old = debug_level;
debug_level = ( S3FS_LOG_CRIT == debug_level ? S3FS_LOG_ERR :
S3FS_LOG_ERR == debug_level ? S3FS_LOG_WARN :
S3FS_LOG_WARN == debug_level ? S3FS_LOG_INFO :
S3FS_LOG_INFO == debug_level ? S3FS_LOG_DBG :
S3FS_LOG_CRIT );
setlogmask(LOG_UPTO(S3FS_LOG_LEVEL_TO_SYSLOG(debug_level)));
S3FS_PRN_CRIT("change debug level from %sto %s", S3FS_LOG_LEVEL_STRING(old), S3FS_LOG_LEVEL_STRING(debug_level));
return old;
struct sigaction sa;
memset(&sa, 0, sizeof(struct sigaction));
sa.sa_handler = S3fsSignals::HandlerHUP;
sa.sa_flags = SA_RESTART;
if(0 != sigaction(SIGHUP, &sa, NULL)){
return false;
}
return true;
}
//-------------------------------------------------------------------
@ -180,6 +177,9 @@ S3fsSignals::S3fsSignals() : pThreadUsr1(NULL), pSemUsr1(NULL)
if(!S3fsSignals::InitUsr2Handler()){
S3FS_PRN_ERR("failed to initialize SIGUSR2 handler for bumping log level, but continue...");
}
if(!S3fsSignals::InitHupHandler()){
S3FS_PRN_ERR("failed to initialize SIGHUP handler for reopen log file, but continue...");
}
}
S3fsSignals::~S3fsSignals()

View File

@ -44,6 +44,9 @@ class S3fsSignals
static void HandlerUSR2(int sig);
static bool InitUsr2Handler();
static void HandlerHUP(int sig);
static bool InitHupHandler();
S3fsSignals();
~S3fsSignals();
@ -56,9 +59,6 @@ class S3fsSignals
static bool Destroy();
static bool SetUsr1Handler(const char* path);
static s3fs_log_level SetLogLevel(s3fs_log_level level);
static s3fs_log_level BumpupLogLevel();
};
#endif // S3FS_SIGHANDLERS_H_

View File

@ -34,7 +34,6 @@
// Global variables for test_string_util
//-------------------------------------------------------------------
bool foreground = false;
s3fs_log_level debug_level = S3FS_LOG_CRIT;
std::string instance_name;
void test_trim()
@ -141,6 +140,8 @@ void test_wtf8_encoding()
int main(int argc, char *argv[])
{
S3fsLog singletonLog;
test_trim();
test_base64();
test_strtoofft();