OpenCPN Partial API docs
Loading...
Searching...
No Matches
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 "logger.h"
35
36const wxLogLevel OcpnLog::LOG_BADLEVEL = wxLOG_Max + 1;
37
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"}};
44
45static std::map<std::string, wxLogLevel> level_by_name;
46
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);
50}
51
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;
55 }
56}
57
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();
64 return stamp.str();
65}
66
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;
70}
71
72wxLogLevel 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
82OcpnLog::OcpnLog(const char* path) {
83 log.open(path, std::fstream::out | std::fstream::app);
84}
85
86OcpnLog::~OcpnLog() { log.close(); }
87
88void OcpnLog::Flush() {
89 wxLog::Flush();
90 log.flush();
91}
92
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;
98 log << oss.str();
99}
100
101Logger::Logger() : info("", 0, "", ""), level(wxLOG_Info){};
102
103Logger::~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
112std::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
119void 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
128void 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