2 * Copyright (C) 2017 Cisco Inc.
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License, version 2,
6 * as published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 // @author Changxue Deng <chadeng@cisco.com>
26 #define MAX_NUM_LOG 10
30 std::string Logger::log_file = "";
31 std::ofstream* Logger::log_stream = NULL;
32 int Logger::log_level_ = LOG_LEVEL_WARN;
33 int Logger::roll_size = 50*1024*1024;
34 const char* Logger::LOG_LEVEL[4] =
52 if(log_stream != NULL)
54 if(log_stream->is_open())
62 // Should only be called by writer for now.
63 // Readers will send logs to stdout or stderr.
64 void Logger::InitLogFile(const std::string &logfile)
69 log_level_ = LOG_LEVEL_INFO;
70 log_stream = new std::ofstream();
71 log_stream->open(log_file.c_str(), std::ios::out | std::ios::app);
75 void Logger::FillDateTime(char *buffer, int bufsize)
80 if(localtime_r(&rawtime, &timeinfo))
81 strftime(buffer, bufsize, "%Y-%m-%d.%X", &timeinfo);
83 snprintf(buffer, bufsize, "Time unknown");
88 if(log_stream == NULL)
90 if(log_stream->is_open())
93 std::string filepath_old;
94 std::string filepath_new;
95 for(int i = MAX_NUM_LOG-2; i > 0; i--)
97 filepath_old = log_file + "." + std::to_string(i);
98 if(access(filepath_old.c_str(), R_OK) == 0)
100 filepath_new = log_file + "." + std::to_string(i+1);
101 if(rename(filepath_old.c_str(), filepath_new.c_str()))
102 std::cerr << "failed to move log file\n";
105 filepath_new = log_file + ".1";
106 if(rename(log_file.c_str(), filepath_new.c_str()))
107 std::cerr << "failed to move log file\n";
109 log_stream->open(log_file.c_str(), std::ios::out | std::ios::app);
112 void Logger::Log(int level, const std::string &message)
114 if(level > log_level_)
117 if(log_stream != NULL)
120 FillDateTime(buffer, sizeof(buffer));
121 *log_stream << buffer << LOG_LEVEL[level] << message << std::endl;
122 if(log_stream->tellp() > roll_size)
125 else if(level < LOG_LEVEL_INFO)
126 std::cerr << message << std::endl;
128 std::cout << message << std::endl;
131 void Logger::Log(int level, const char *format, ... )
133 if(level > log_level_)
138 va_start(args, format);
139 vsprintf(message, format, args);
140 if(log_stream != NULL)
143 FillDateTime(buffer, sizeof(buffer));
144 *log_stream << buffer << LOG_LEVEL[level] << message << std::endl;
145 if(log_stream->tellp() > roll_size)
148 else if(level < LOG_LEVEL_INFO)
149 std::cerr << message << std::endl;
151 std::cout << message << std::endl;
155 int Logger::SetLogLevel(int level)
157 if(level < 0 || level > LOG_LEVEL_DEBUG)
159 Logger::Log(LOG_LEVEL_WARN, "invaid logging level %d", level);
160 return MBError::INVALID_ARG;
165 return MBError::SUCCESS;
168 std::ofstream* Logger::GetLogStream()