OpenCPN Partial API docs
logger.cpp
1 /******************************************************************************
2  *
3  * Project: OpenCPN
4  *
5  ***************************************************************************
6  * Copyright (C) 2013 by David S. Register *
7  * *
8  * This program is free software; you can redistribute it and/or modify *
9  * it under the terms of the GNU General Public License as published by *
10  * the Free Software Foundation; either version 2 of the License, or *
11  * (at your option) any later version. *
12  * *
13  * This program is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16  * GNU General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU General Public License *
19  * along with this program; if not, write to the *
20  * Free Software Foundation, Inc., *
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
22  ***************************************************************************
23  */
24 
25 #include <algorithm>
26 #include <iomanip>
27 #include <map>
28 #include <sstream>
29 #include <string>
30 
31 #include <wx/datetime.h>
32 #include <wx/filename.h>
33 
34 #include "model/logger.h"
35 
36 const wxLogLevel OcpnLog::LOG_BADLEVEL = wxLOG_Max + 1;
37 
38 const 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"}};
44 
45 static std::map<std::string, wxLogLevel> level_by_name;
46 
47 static 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);
50 }
51 
52 static 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;
55  }
56 }
57 
58 static 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();
64  return stamp.str();
65 }
66 
67 std::string OcpnLog::level2str(wxLogLevel level) {
68  auto search = name_by_level.find(level);
69  return search == name_by_level.end() ? "Unknown level" : search->second;
70 }
71 
72 wxLogLevel OcpnLog::str2level(const char* string) {
73  if (level_by_name.size() == 0) {
74  init_level_by_name();
75  }
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;
80 }
81 
82 OcpnLog::OcpnLog(const char* path) {
83  log.open(path, std::fstream::out | std::fstream::app);
84 }
85 
86 OcpnLog::~OcpnLog() { log.close(); }
87 
88 void OcpnLog::Flush() {
89  wxLog::Flush();
90  log.flush();
91 }
92 
93 void 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;
98  log << oss.str();
99 }
100 
101 Logger::Logger() : info("", 0, "", ""), level(wxLOG_Info){};
102 
103 Logger::~Logger() {
104  wxString msg(os.str());
105  wxLog* log = wxLog::GetActiveTarget();
106  auto ocpnLog = dynamic_cast<OcpnLog*>(log);
107  if (ocpnLog) {
108  ocpnLog->LogRecord(level, msg, info);
109  }
110 }
111 
112 std::ostream& Logger::get(wxLogLevel l, const char* path, int line) {
113  info.filename = path;
114  info.line = line;
115  level = l;
116  return os;
117 }
118 
119 void Logger::logRecord(wxLogLevel level, const char* msg,
120  const wxLogRecordInfo info) {
121  wxLog* log = wxLog::GetActiveTarget();
122  auto ocpnLog = dynamic_cast<OcpnLog*>(log);
123  if (ocpnLog) {
124  ocpnLog->LogRecord(level, wxString(msg), info);
125  }
126 }
127 
128 void Logger::logMessage(wxLogLevel level, const char* path, int line,
129  const char* fmt, ...) {
130  wxLogRecordInfo info(__FILE__, __LINE__, "", "");
131  char buf[1024];
132  va_list ap;
133  va_start(ap, fmt);
134  vsnprintf(buf, sizeof(buf), fmt, ap);
135  va_end(ap);
136  auto log = dynamic_cast<OcpnLog*>(wxLog::GetActiveTarget());
137  if (log) {
138  log->LogRecord(level, buf, info);
139  }
140 }
void logRecord(wxLogLevel level, const char *msg, const wxLogRecordInfo info)
DoLogRecord public wrapper.
Definition: logger.cpp:119
Logging interface.
Definition: logger.h:62
OcpnLog(const char *path)
Create logger appending to given filename.
Definition: logger.cpp:82