同时具备多线程和多进程安全的写日志工具

接口请浏览:https://github.com/eyjian/mooon/blob/master/mooon/include/mooon/sys/log.h 实现头文件请浏览:https://github.com/eyjian/mooon/blob/master/mooon/include/mooon/sys/safe_logger.h 测试代码:https://github.com/eyjian/mooon/blob/master/mooon/test/sys/test_safe_logger.cpp 使用示例: MYLOG_DEBUG("[%d]MMMMM", 2015); 支持自动添加换行符,默认会自动添加换行符,但可以禁止自动添加换行符。还支持自动在行尾添加点号等功能。 下面是实现

 #include "mooon/sys/safe_logger.h"
  
 			#include "mooon/sys/datetime_utils.h"
 
 			#include "mooon/sys/file_locker.h"
 
 			#include "mooon/sys/file_utils.h"
 
 			#include "mooon/utils/scoped_ptr.h"
 
 			#include "mooon/utils/string_utils.h"
 
 			#include <libgen.h>
 
 			#include <pthread.h>
 
 			#include <sstream>
 
 			#include <syslog.h>
 
 			#include <unistd.h>
 
 
 
 			#define WRITE_SYSLOG 0 // 出错时是否记录系统日志,1表示记录
 
 			SYS_NAMESPACE_BEGIN
 
 
 
 // 线程级别的
 
 			static __thread int sg_thread_log_fd = -1;
 
 
 
 			CSafeLogger* create_safe_logger(bool enable_program_path, uint16_t log_line_size) throw (CSyscallException)
 
 {
 
 			    std::string log_dirpath = get_log_dirpath(enable_program_path);
 
 			    std::string log_filename = get_log_filename();
 
 			    CSafeLogger* logger = new CSafeLogger(log_dirpath.c_str(), log_filename.c_str(), log_line_size);
 
 
 
 			    set_log_level_by_env(logger);
 
 			    enable_screen_log_by_env(logger);
 
 			    enable_trace_log_by_env(logger);
 
 			    set_log_filesize_by_env(logger);
 
 			    set_log_backup_by_env(logger);
 
 
 
 			    return logger;
 
 }
 
 
 
 			CSafeLogger* create_safe_logger(const std::string& log_dirpath, const std::string& cpp_filename, uint16_t log_line_size) throw (CSyscallException)
 
 {
 
 			    char* cpp_filepath = strdup(cpp_filename.c_str());
 
 			    std::string only_filename = basename(cpp_filepath);
 
 			    free(cpp_filepath);
 
 
 
 			    std::string log_filename = utils::CStringUtils::replace_suffix(only_filename, ".log");
 
 			    CSafeLogger* logger = new CSafeLogger(log_dirpath.c_str(), log_filename.c_str(), log_line_size);
 
 
 
 			    set_log_level_by_env(logger);
 
 			    enable_screen_log_by_env(logger);
 
 			    enable_trace_log_by_env(logger);
 
 			    set_log_filesize_by_env(logger);
 
 			    set_log_backup_by_env(logger);
 
 
 
 			    return logger;
 
 }
 
 
 
 ////////////////////////////////////////////////////////////////////////////////
 
 			CSafeLogger::CSafeLogger(const char* log_dir, const char* log_filename, uint16_t log_line_size) throw (CSyscallException)
 
 :_auto_adddot(false)
 
 ,_auto_newline(true)
 
 ,_bin_log_enabled(false)
 
 ,_trace_log_enabled(false)
 
 ,_raw_log_enabled(false)
 
 ,_screen_enabled(false)
 
 ,_log_dir(log_dir)
 
 ,_log_filename(log_filename)
 
 ,_log_filepath(_log_dir + std::string("/") + _log_filename)
 
 {
 
 			    atomic_set(&_max_bytes, DEFAULT_LOG_FILE_SIZE);
 
 			    atomic_set(&_log_level, LOG_LEVEL_INFO);
 
 			    atomic_set(&_backup_number, DEFAULT_LOG_FILE_BACKUP_NUMBER);
 
 
 
 // 保证日志行最大长度不小于指定值
 
 			    _log_line_size = (log_line_size < LOG_LINE_SIZE_MIN)? LOG_LINE_SIZE_MIN: log_line_size;
 
 if (_log_line_size > LOG_LINE_SIZE_MAX)
 
 			        _log_line_size = LOG_LINE_SIZE_MAX;
 
 
 
 int log_fd = open(_log_filepath.c_str(), O_WRONLY|O_CREAT|O_APPEND, FILE_DEFAULT_PERM);
 
 if (-1 == log_fd)
 
 {
 
 int errcode = errno;
 
 			        fprintf(stderr, "[%d:%lu] SafeLogger open %s error: %m\n", getpid(), pthread_self(), _log_filepath.c_str());
 
 
 
 			        THROW_SYSCALL_EXCEPTION(NULL, errcode, "open");
 
 }
 
 else
 
 {
 
 			        close(log_fd);
 
 }
 
 }
 
 
 
 			CSafeLogger::~CSafeLogger()
 
 {
 
 (void)release();
 
 }
 
 
 
 int CSafeLogger::release()
 
 {
 
 int ret = 0;
 
 if (sg_thread_log_fd != -1)
 
 {
 
 			#if 0 // 由系统决定何时fsync
 
 			        ret = fsync(sg_thread_log_fd);
 
 if (-1 == ret)
 
 {
 
 			            fprintf(stderr, "process(%u,%lu) fsync fd(%d) error: %m\n", getpid(), pthread_self(), sg_thread_log_fd);
 
 }
 
 else
 
 			#endif
 
 {
 
 			            ret = close(sg_thread_log_fd);
 
 if (0 == ret)
 
 			                sg_thread_log_fd = -1;
 
 else
 
 			                fprintf(stderr, "process(%u,%lu) close fd(%d) error: %m\n", getpid(), pthread_self(), sg_thread_log_fd);
 
 }
 
 }
 
 
 
 			    return ret;
 
 }
 
 
 
 			void CSafeLogger::enable_screen(bool enabled)
 
 {
 
 			    _screen_enabled = enabled;
 
 }
 
 
 
 			void CSafeLogger::enable_bin_log(bool enabled)
 
 {
 
 			    _bin_log_enabled = enabled;
 
 }
 
 
 
 			void CSafeLogger::enable_trace_log(bool enabled)
 
 {
 
 			    _trace_log_enabled = enabled;
 
 }
 
 
 
 			void CSafeLogger::enable_raw_log(bool enabled)
 
 {
 
 			    _raw_log_enabled = enabled;
 
 }
 
 
 
 			void CSafeLogger::enable_auto_adddot(bool enabled)
 
 {
 
 			    _auto_adddot = enabled;
 
 }
 
 
 
 			void CSafeLogger::enable_auto_newline(bool enabled)
 
 {
 
 			    _auto_newline = enabled;
 
 }
 
 
 
 			void CSafeLogger::set_log_level(log_level_t log_level)
 
 {
 
 			    atomic_set(&_log_level, log_level);
 
 }
 
 
 
 			void CSafeLogger::set_single_filesize(uint32_t filesize)
 
 {
 
 			    uint32_t max_bytes = (filesize < LOG_LINE_SIZE_MIN*10)? LOG_LINE_SIZE_MIN*10: filesize;
 
 			    atomic_set(&_max_bytes, max_bytes);
 
 }
 
 
 
 			void CSafeLogger::set_backup_number(uint16_t backup_number)
 
 {
 
 			    atomic_set(&_backup_number, backup_number);
 
 }
 
 
 
 			bool CSafeLogger::enabled_bin()
 
 {
 
 			    return _bin_log_enabled;
 
 }
 
 
 
 			bool CSafeLogger::enabled_detail()
 
 {
 
 			    return atomic_read(&_log_level) <= LOG_LEVEL_DETAIL;
 
 }
 
 
 
 			bool CSafeLogger::enabled_debug()
 
 {
 
 			    return atomic_read(&_log_level) <= LOG_LEVEL_DEBUG;
 
 }
 
 
 
 			bool CSafeLogger::enabled_info()
 
 {
 
 			    return atomic_read(&_log_level) <= LOG_LEVEL_INFO;
 
 }
 
 
 
 			bool CSafeLogger::enabled_warn()
 
 {
 
 			    return atomic_read(&_log_level) <= LOG_LEVEL_WARN;
 
 }
 
 
 
 			bool CSafeLogger::enabled_error()
 
 {
 
 			    return atomic_read(&_log_level) <= LOG_LEVEL_ERROR;
 
 }
 
 
 
 			bool CSafeLogger::enabled_fatal()
 
 {
 
 			    return atomic_read(&_log_level) <= LOG_LEVEL_FATAL;
 
 }
 
 
 
 			bool CSafeLogger::enabled_state()
 
 {
 
 			    return atomic_read(&_log_level) <= LOG_LEVEL_STATE;
 
 }
 
 
 
 			bool CSafeLogger::enabled_trace()
 
 {
 
 			    return _trace_log_enabled;
 
 }
 
 
 
 			bool CSafeLogger::enabled_raw()
 
 {
 
 			    return _raw_log_enabled;
 
 }
 
 
 
 			void CSafeLogger::log_detail(const char* filename, int lineno, const char* module_name, const char* format, va_list& args)
 
 {
 
 if (enabled_detail())
 
 			        do_log(LOG_LEVEL_DETAIL, filename, lineno, module_name, format, args);
 
 }
 
 
 
 			void CSafeLogger::log_detail(const char* filename, int lineno, const char* module_name, const char* format, ...)
 
 {
 
 if (enabled_detail())
 
 {
 
 			        va_list args;
 
 			        va_start(args, format);
 
 			        utils::VaListHelper vh(args);
 
 
 
 			        do_log(LOG_LEVEL_DETAIL, filename, lineno, module_name, format, args);
 
 }
 
 }
 
 
 
 			void CSafeLogger::log_debug(const char* filename, int lineno, const char* module_name, const char* format, va_list& args)
 
 {
 
 if (enabled_detail())
 
 			        do_log(LOG_LEVEL_DEBUG, filename, lineno, module_name, format, args);
 
 }
 
 
 
 			void CSafeLogger::log_debug(const char* filename, int lineno, const char* module_name, const char* format, ...)
 
 {
 
 if (enabled_debug())
 
 {
 
 			        va_list args;
 
 			        va_start(args, format);
 
 			        utils::VaListHelper vh(args);
 
 
 
 			        do_log(LOG_LEVEL_DEBUG, filename, lineno, module_name, format, args);
 
 }
 
 }
 
 
 
 			void CSafeLogger::log_info(const char* filename, int lineno, const char* module_name, const char* format, va_list& args)
 
 {
 
 if (enabled_info())
 
 			        do_log(LOG_LEVEL_INFO, filename, lineno, module_name, format, args);
 
 }
 
 
 
 			void CSafeLogger::log_info(const char* filename, int lineno, const char* module_name, const char* format, ...)
 
 {
 
 if (enabled_info())
 
 {
 
 			        va_list args;
 
 			        va_start(args, format);
 
 			        utils::VaListHelper vh(args);
 
 
 
 			        do_log(LOG_LEVEL_INFO, filename, lineno, module_name, format, args);
 
 }
 
 }
 
 
 
 			void CSafeLogger::log_warn(const char* filename, int lineno, const char* module_name, const char* format, va_list& args)
 
 {
 
 if (enabled_warn())
 
 			        do_log(LOG_LEVEL_WARN, filename, lineno, module_name, format, args);
 
 }
 
 
 
 			void CSafeLogger::log_warn(const char* filename, int lineno, const char* module_name, const char* format, ...)
 
 {
 
 if (enabled_warn())
 
 {
 
 			        va_list args;
 
 			        va_start(args, format);
 
 			        utils::VaListHelper vh(args);
 
 
 
 			        do_log(LOG_LEVEL_WARN, filename, lineno, module_name, format, args);
 
 }
 
 }
 
 
 
 			void CSafeLogger::log_error(const char* filename, int lineno, const char* module_name, const char* format, va_list& args)
 
 {
 
 if (enabled_error())
 
 			        do_log(LOG_LEVEL_ERROR, filename, lineno, module_name, format, args);
 
 }
 
 
 
 			void CSafeLogger::log_error(const char* filename, int lineno, const char* module_name, const char* format, ...)
 
 {
 
 if (enabled_error())
 
 {
 
 			        va_list args;
 
 			        va_start(args, format);
 
 			        utils::VaListHelper vh(args);
 
 
 
 			        do_log(LOG_LEVEL_ERROR, filename, lineno, module_name, format, args);
 
 }
 
 }
 
 
 
 			void CSafeLogger::log_fatal(const char* filename, int lineno, const char* module_name, const char* format, va_list& args)
 
 {
 
 if (enabled_fatal())
 
 			        do_log(LOG_LEVEL_FATAL, filename, lineno, module_name, format, args);
 
 }
 
 
 
 			void CSafeLogger::log_fatal(const char* filename, int lineno, const char* module_name, const char* format, ...)
 
 {
 
 if (enabled_fatal())
 
 {
 
 			        va_list args;
 
 			        va_start(args, format);
 
 			        utils::VaListHelper vh(args);
 
 
 
 			        do_log(LOG_LEVEL_FATAL, filename, lineno, module_name, format, args);
 
 }
 
 }
 
 
 
 			void CSafeLogger::log_state(const char* filename, int lineno, const char* module_name, const char* format, va_list& args)
 
 {
 
 if (enabled_state())
 
 			        do_log(LOG_LEVEL_STATE, filename, lineno, module_name, format, args);
 
 }
 
 
 
 			void CSafeLogger::log_state(const char* filename, int lineno, const char* module_name, const char* format, ...)
 
 {
 
 if (enabled_state())
 
 {
 
 			        va_list args;
 
 			        va_start(args, format);
 
 			        utils::VaListHelper vh(args);
 
 
 
 			        do_log(LOG_LEVEL_STATE, filename, lineno, module_name, format, args);
 
 }
 
 }
 
 
 
 			void CSafeLogger::log_trace(const char* filename, int lineno, const char* module_name, const char* format, va_list& args)
 
 {
 
 if (enabled_trace())
 
 			        do_log(LOG_LEVEL_TRACE, filename, lineno, module_name, format, args);
 
 }
 
 
 
 			void CSafeLogger::log_trace(const char* filename, int lineno, const char* module_name, const char* format, ...)
 
 {
 
 if (enabled_trace())
 
 {
 
 			        va_list args;
 
 			        va_start(args, format);
 
 			        utils::VaListHelper vh(args);
 
 
 
 			        do_log(LOG_LEVEL_TRACE, filename, lineno, module_name, format, args);
 
 }
 
 }
 
 
 
 			void CSafeLogger::log_raw(const char* format, va_list& args)
 
 {
 
 if (enabled_raw())
 
 			        do_log(LOG_LEVEL_RAW, NULL, -1, NULL, format, args);
 
 }
 
 
 
 			void CSafeLogger::log_raw(const char* format, ...)
 
 {
 
 if (enabled_raw())
 
 {
 
 			        va_list args;
 
 			        va_start(args, format);
 
 			        utils::VaListHelper vh(args);
 
 			        do_log(LOG_LEVEL_RAW, NULL, -1, NULL, format, args);
 
 }
 
 }
 
 
 
 			void CSafeLogger::log_bin(const char* filename, int lineno, const char* module_name, const char* log, uint16_t size)
 
 {
 
 if (enabled_bin())
 
 {
 
 			        std::string str(size*2, '\0');
 
 			        char* str_p = const_cast<char*>(str.data());
 
 for (uint16_t i=0; i<size; ++i)
 
 {
 
 			            snprintf(str_p, 3, "%02X", (int)log[i]);
 
 			            str_p += 2;
 
 }
 
 
 
 			        va_list args;
 
 			        do_log(LOG_LEVEL_BIN, filename, lineno, module_name, str.c_str(), args);
 
 }
 
 }
 
 
 
 int CSafeLogger::get_thread_log_fd() const
 
 {
 
 if (-1 == sg_thread_log_fd)
 
 {
 
 			        sg_thread_log_fd = open(_log_filepath.c_str(), O_WRONLY|O_CREAT|O_APPEND, FILE_DEFAULT_PERM);
 
 if (-1 == sg_thread_log_fd)
 
 			            fprintf(stderr, "open %s error: %m\n", _log_filepath.c_str());
 
 }
 
 
 
 			    return sg_thread_log_fd;
 
 }
 
 
 
 			bool CSafeLogger::need_rotate(int fd) const
 
 {
 
 			    off_t file_size = CFileUtils::get_file_size(fd);
 
 			    return file_size > static_cast<off_t>(atomic_read(&_max_bytes));
 
 }
 
 
 
 			void CSafeLogger::do_log(log_level_t log_level, const char* filename, int lineno, const char* module_name, const char* format, va_list& args)
 
 {
 
 int log_real_size;
 
 			    utils::ScopedArray<char> log_line(new char[_log_line_size]);
 
 
 
 if (LOG_LEVEL_RAW == log_level)
 
 {
 
 // fix_vsnprintf()的返回值包含了结尾符在内的长度
 
 			        log_real_size = utils::CStringUtils::fix_vsnprintf(log_line.get(), _log_line_size, format, args);
 
 --log_real_size; // 结尾符不需要写入日志文件中
 
 }
 
 else
 
 {
 
 			        std::stringstream log_header; // 每条日志的头
 
 			        char datetime[sizeof("2012-12-12 12:12:12/0123456789")];
 
 			        get_formatted_current_datetime(datetime, sizeof(datetime));
 
 
 
 // 日志头内容:[日期][线程ID/进程ID][日志级别][模块名][代码文件名][代码行号]
 
 			        log_header << "[" << datetime << "]"
 
 << "[" << pthread_self() << "/" << getpid() << "]"
 
 << "[" << get_log_level_name(log_level) << "]";
 
 if (module_name != NULL)
 
 			            log_header << "[" << module_name << "]";
 
 if (filename != NULL)
 
 			            log_header << "[" << utils::CStringUtils::extract_filename(filename) << ":" << lineno << "]";
 
 
 
 int m, n;
 
 // 注意fix_snprintf()的返回值大小包含了结尾符
 
 			        m = utils::CStringUtils::fix_snprintf(log_line.get(), _log_line_size, "%s", log_header.str().c_str());
 
 
 
 if (LOG_LEVEL_BIN == log_level)
 
 			            n = utils::CStringUtils::fix_snprintf(log_line.get()+m-1, _log_line_size-m, "%s", format);
 
 else
 
 			            n = utils::CStringUtils::fix_vsnprintf(log_line.get()+m-1, _log_line_size-m, format, args);
 
 			        log_real_size = m + n - 2;
 
 
 
 // 是否自动添加结尾用的点号
 
 if (_auto_adddot)
 
 {
 
 // 如果已有结尾的点,则不再添加,以免重复
 
 if (log_line.get()[log_real_size-1] != '.')
 
 {
 
 			                log_line.get()[log_real_size] = '.';
 
 ++log_real_size;
 
 }
 
 }
 
 
 
 // 是否自动换行
 
 if (_auto_newline)
 
 {
 
 // 如果已有一个换行符,则不再添加
 
 if (log_line.get()[log_real_size-1] != '\n')
 
 {
 
 			                log_line.get()[log_real_size] = '\n';
 
 ++log_real_size;
 
 }
 
 }
 
 }
 
 
 
 // 允许打屏
 
 if (_screen_enabled)
 
 {
 
 (void)write(STDOUT_FILENO, log_line.get(), log_real_size);
 
 }
 
 
 
 if (false)
 
 {
 
 // 异步写入日志文件
 
 //log_line.release();
 
 }
 
 else
 
 {
 
 // 同步写入日志文件
 
 int thread_log_fd = get_thread_log_fd();
 
 if (thread_log_fd != -1)
 
 {
 
 			            write_log(thread_log_fd, log_line.get(), log_real_size);
 
 }
 
 else
 
 {
 
 			            fprintf(stderr, "process(%u,%lu) without thread log\n", getpid(), pthread_self());
 
 
 
 			#if WRITE_SYSLOG==1
 
 			            openlog("mooon-safe-logger", LOG_CONS|LOG_PID, 0);
 
 			            syslog(LOG_ERR, "process(%u,%lu) without thread log\n", getpid(), pthread_self());
 
 			            closelog();
 
 			#endif // WRITE_SYSLOG
 
 }
 
 }
 
 }
 
 
 
 			void CSafeLogger::rotate_log()
 
 {
 
 			    std::string new_path; // 滚动后的文件路径,包含目录和文件名
 
 			    std::string old_path; // 滚动前的文件路径,包含目录和文件名
 
 
 
 // 历史滚动
 
 int backup_number = atomic_read(&_backup_number);
 
 for (int i=backup_number-1; i>1; --i)
 
 {
 
 			        new_path = _log_dir + std::string("/") + _log_filename + std::string(".") + utils::CStringUtils::any2string(static_cast<int>(i));
 
 			        old_path = _log_dir + std::string("/") + _log_filename + std::string(".") + utils::CStringUtils::any2string(static_cast<int>(i-1));
 
 
 
 if (0 == access(old_path.c_str(), F_OK))
 
 {
 
 if (-1 == rename(old_path.c_str(), new_path.c_str()))
 
 			                fprintf(stderr, "[%d:%lu] SafeLogger rename %s to %s error: %m.\n", getpid(), pthread_self(), old_path.c_str(), new_path.c_str());
 
 }
 
 else
 
 {
 
 if (errno != ENOENT)
 
 			                fprintf(stderr, "[%d:%lu] SafeLogger access %s error: %m.\n", getpid(), pthread_self(), old_path.c_str());
 
 }
 
 }
 
 
 
 if (backup_number > 0)
 
 {
 
 // 当前滚动
 
 			        new_path = _log_dir + std::string("/") + _log_filename + std::string(".1");
 
 if (0 == access(_log_filepath.c_str(), F_OK))
 
 {
 
 if (-1 == rename(_log_filepath.c_str(), new_path.c_str()))
 
 			                fprintf(stderr, "[%d:%lu] SafeLogger rename %s to %s error: %m\n", getpid(), pthread_self(), _log_filepath.c_str(), new_path.c_str());
 
 }
 
 else
 
 {
 
 if (errno != ENOENT)
 
 			                fprintf(stderr, "[%d:%lu] SafeLogger access %s error: %m\n", getpid(), pthread_self(), _log_filepath.c_str());
 
 }
 
 }
 
 
 
 // 重新创建
 
 //fprintf(stdout, "[%d:%lu] SafeLogger create %s\n", getpid(), pthread_self(), _log_filepath.c_str());
 
 int new_log_fd = open(_log_filepath.c_str(), O_WRONLY|O_CREAT|O_APPEND, FILE_DEFAULT_PERM); // O_EXCL
 
 if (new_log_fd != -1)
 
 {
 
 			        sg_thread_log_fd = new_log_fd;
 
 }
 
 else
 
 {
 
 			        fprintf(stderr, "[%d:%lu] SafeLogger create %s error: %m\n", getpid(), pthread_self(), _log_filepath.c_str());
 
 
 
 			#if WRITE_SYSLOG==1
 
 			        openlog("mooon-safe-logger", LOG_CONS|LOG_PID, 0);
 
 			        syslog(LOG_ERR, "[%d:%lu] SafeLogger create %s error: %m\n", getpid(), pthread_self(), _log_filepath.c_str());
 
 			        closelog();
 
 			#endif // WRITE_SYSLOG
 
 }
 
 }
 
 
 
 			void CSafeLogger::write_log(int thread_log_fd, const char* log_line, int log_line_size)
 
 {
 
 int bytes = write(thread_log_fd, log_line, log_line_size);
 
 if (-1 == bytes)
 
 {
 
 			        fprintf(stderr, "[%d:%lu] SafeLogger[%d] write error: %m\n", getpid(), pthread_self(), thread_log_fd);
 
 }
 
 else if (0 == bytes)
 
 {
 
 			        fprintf(stderr, "[%d:%lu] write nothing: SafeLogger[%d]\n", getpid(), pthread_self(), thread_log_fd);
 
 }
 
 else if (bytes > 0)
 
 {
 
 			        try
 
 {
 
 // 判断是否需要滚动
 
 if (need_rotate(thread_log_fd))
 
 {
 
 			                std::string lock_path = _log_dir + std::string("/.") + _log_filename + std::string(".lock");
 
 			                FileLocker file_locker(lock_path.c_str(), true); // 确保这里一定加锁
 
 
 
 // _fd可能已被其它进程或线程滚动了,所以这里需要重新open一下
 
 int new_log_fd = open(_log_filepath.c_str(), O_WRONLY|O_CREAT|O_APPEND, FILE_DEFAULT_PERM);
 
 if (-1 == new_log_fd)
 
 {
 
 			                    fprintf(stderr, "[%d:%lu] SafeLogger open %s error: %m\n", getpid(), pthread_self(), _log_filepath.c_str());
 
 }
 
 else
 
 {
 
 			                    try
 
 {
 
 			                        release();
 
 
 
 if (!need_rotate(new_log_fd))
 
 {
 
 // 其它进程或线程抢先做了滚动
 
 			                            sg_thread_log_fd = new_log_fd;
 
 }
 
 else
 
 {
 
 			                            close(new_log_fd);
 
 			                            rotate_log();
 
 }
 
 }
 
 			                    catch (CSyscallException& syscall_ex)
 
 {
 
 			                        fprintf(stderr, "[%d:%lu] SafeLogger[%d] rotate error: %s.\n", getpid(), pthread_self(), new_log_fd, syscall_ex.str().c_str());
 
 }
 
 }
 
 }
 
 }
 
 			        catch (CSyscallException& syscall_ex)
 
 {
 
 			            fprintf(stderr, "[%d:%lu] SafeLogger[%d] rotate error: %s\n", getpid(), pthread_self(), thread_log_fd, syscall_ex.str().c_str());
 
 }
 
 }
 
 }
 
 
 
 			SYS_NAMESPACE_END 		

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏向治洪

android PakageManagerService启动流程分析

PakageManagerService的启动流程图 ? 1.PakageManagerService概述 PakageManagerService是andro...

552100
来自专栏Golang语言社区

Golang:使用 httprouter 构建 API 服务器

我 10 个月前开始成为一名 Gopher,没有回头。像许多其他 gopher 一样,我很快发现简单的语言特性对于快速构建快速、可扩展的软件非常有用。当我刚开始...

842140
来自专栏FreeBuf

EE 4GEE Mini本地提权漏洞(CVE-2018-14327)分析

我在前段时间从买了一个4G调制解调器。这是一个便携式4G WiFi移动宽带调制解调器。有一天,我查看了安装在电脑上的用于故障排除的服务,我看到了一个奇怪的服务,...

9430
来自专栏芋道源码1024

分布式作业系统 Elastic-Job-Lite 源码分析 —— 作业事件追踪

另外,Elastic-Job-Cloud 作业事件追踪 和 Elastic-Job-Lite 基本类似,不单独开一篇文章,记录在该文章里。如果你对 Elasti...

10630
来自专栏liulun

CEF C++环境搭建

第一步:下载CEF 到这里下载最新版本的CEF http://cefbuilds.com/ 下载解压之后,大概会看到如下图所示的文件 cefclien...

30770
来自专栏移动端周边技术扩展

iOS打开系统功能对应的URL

18830
来自专栏CDN及云技术分享

Openssl状态机的实现

Openssl是通过“握手“建立加密信道,在该信道双方的身份都是合法的,并且传输数据都是密文传输。Openssl握手通过客户端和服务端互相交换信息计算出secr...

43630
来自专栏微信公众号:Java团长

抢红包案例分析以及代码实现

电商的秒杀、抢购,春运抢票,微信QQ抢红包,从技术的角度来说,这对于Web 系统是一个很大的考验. 高并发场景下,系统的优化和稳定是至关重要的.

52240
来自专栏杨建荣的学习笔记

一条执行4秒的sql语句导致的系统问题(r3笔记第10天)

一般来说一条sql语句执行个4秒钟是可以接受的,没有什么问题,但是如果应该执行1秒,却执行了4秒,问题就挺大的了。 今天查看数据库负载,发现在中午12:00 ...

37880
来自专栏杨建荣的学习笔记

探究AWR 第二篇(r3笔记第93天)

在探究awr第一篇中介绍了awr的一些基本操作 http://blog.itpub.net/23718752/viewspace-1123134/ 在这一篇中,...

32270

扫码关注云+社区

领取腾讯云代金券