31#include <wx/datetime.h>
32#include <wx/filename.h>
36const wxLogLevel OcpnLog::LOG_BADLEVEL = wxLOG_Max + 1;
38const static std::map<wxLogLevel, const char*> name_by_level = {
39 {wxLOG_FatalError,
"FATALERR"}, {wxLOG_Error,
"ERROR"},
40 {wxLOG_Warning,
"WARNING"}, {wxLOG_Message,
"MESSAGE"},
41 {wxLOG_Status,
"STATUS"}, {wxLOG_Info,
"INFO"},
42 {wxLOG_Debug,
"DEBUG"}, {wxLOG_Trace,
"TRACE"},
43 {wxLOG_Progress,
"PROGRESS"}};
45static std::map<std::string, wxLogLevel> level_by_name;
47static std::string basename(
const std::string path) {
48 size_t pos = path.rfind(wxFileName::GetPathSeparator(), path.length());
49 return pos == std::string::npos ? path : path.substr(pos + 1);
52static void init_level_by_name() {
53 for (
auto it = name_by_level.begin(); it != name_by_level.end(); it++) {
54 level_by_name[std::string(it->second)] = it->first;
58static std::string timeStamp() {
59 wxDateTime now = wxDateTime::UNow();
60 std::stringstream stamp;
61 stamp << std::setfill(
'0') << std::setw(2) << now.GetHour() <<
":"
62 << std::setw(2) << now.GetMinute() <<
":" << std::setw(2)
63 << now.GetSecond() <<
"." << std::setw(3) << now.GetMillisecond();
67std::string OcpnLog::level2str(wxLogLevel level) {
68 auto search = name_by_level.find(level);
69 return search == name_by_level.end() ?
"Unknown level" : search->second;
72wxLogLevel OcpnLog::str2level(
const char*
string) {
73 if (level_by_name.size() == 0) {
76 std::string key(
string);
77 std::transform(key.begin(), key.end(), key.begin(), ::toupper);
78 auto search = level_by_name.find(key);
79 return search == level_by_name.end() ? LOG_BADLEVEL : search->second;
83 log.open(path, std::fstream::out | std::fstream::app);
86OcpnLog::~OcpnLog() { log.close(); }
88void OcpnLog::Flush() {
93void OcpnLog::DoLogRecord(wxLogLevel level,
const wxString& msg,
94 const wxLogRecordInfo& info) {
95 std::ostringstream oss;
96 oss << timeStamp() <<
" " << std::setw(7) << level2str(level) <<
" "
97 << basename(info.filename) <<
":" << info.line <<
" " << msg << std::endl;
101Logger::Logger() : info(
"", 0,
"",
""), level(wxLOG_Info){};
104 wxString msg(os.str());
105 wxLog* log = wxLog::GetActiveTarget();
106 auto ocpnLog =
dynamic_cast<OcpnLog*
>(log);
108 ocpnLog->LogRecord(level, msg, info);
112std::ostream& Logger::get(wxLogLevel l,
const char* path,
int line) {
113 info.filename = path;
120 const wxLogRecordInfo info) {
121 wxLog* log = wxLog::GetActiveTarget();
122 auto ocpnLog =
dynamic_cast<OcpnLog*
>(log);
124 ocpnLog->LogRecord(level, wxString(msg), info);
128void Logger::logMessage(wxLogLevel level,
const char* path,
int line,
129 const char* fmt, ...) {
130 wxLogRecordInfo info(__FILE__, __LINE__,
"",
"");
134 vsnprintf(buf,
sizeof(buf), fmt, ap);
136 auto log =
dynamic_cast<OcpnLog*
>(wxLog::GetActiveTarget());
138 log->LogRecord(level, buf, info);
void logRecord(wxLogLevel level, const char *msg, const wxLogRecordInfo info)
DoLogRecord public wrapper.
OcpnLog(const char *path)
Create logger appending to given filename.