Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: src/plugin/PluginDebug.cpp

Issue 5187613258416128: Issue #1234 - Rewrite internals of debug facility (Closed)
Patch Set: rebase + address comments Created March 31, 2015, 1:56 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/plugin/PluginDebug.h ('k') | src/plugin/PluginSettings.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>, 2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-2015 Eyeo GmbH 3 * Copyright (C) 2006-2015 Eyeo GmbH
4 * 4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify 5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as 6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Adblock Plus is distributed in the hope that it will be useful, 9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18 #include "PluginStdAfx.h" 18 #include "PluginStdAfx.h"
19
20 #include "PluginDebug.h" 19 #include "PluginDebug.h"
21 #include "PluginMutex.h" 20 #include "PluginMutex.h"
22 #include "PluginSettings.h" 21 #include "PluginClient.h"
23 22 #include "../shared/Utils.h"
24 class CPluginDebugLock : public CPluginMutex 23 #include <iomanip>
25 { 24
26 25 namespace
27 private: 26 {
28 27 class CPluginDebugLock
29 static CComAutoCriticalSection s_criticalSectionDebugLock; 28 : public CPluginMutex
30 29 {
31 public: 30 private:
32 31 static CComAutoCriticalSection s_criticalSectionDebugLock;
33 CPluginDebugLock() : CPluginMutex(L"DebugFile", PLUGIN_ERROR_MUTEX_DEBUG_FILE) 32
34 { 33 public:
35 s_criticalSectionDebugLock.Lock(); 34 CPluginDebugLock()
35 : CPluginMutex(L"DebugFile", PLUGIN_ERROR_MUTEX_DEBUG_FILE)
36 {
37 s_criticalSectionDebugLock.Lock();
38 }
39
40 ~CPluginDebugLock()
41 {
42 s_criticalSectionDebugLock.Unlock();
43 }
44 };
45
46 CComAutoCriticalSection CPluginDebugLock::s_criticalSectionDebugLock;
47
48 class LogText
49 {
50 public:
51 virtual std::string Text() const = 0;
52 };
53
54 class LogTextFixed
55 : public LogText
56 {
57 protected:
58 const std::string fixedText;
59
60 public:
61 LogTextFixed(const std::string& text)
62 : fixedText(text)
63 {}
64
65 LogTextFixed(const std::exception& ex)
66 : fixedText(std::string("!!! Exception: ") + ex.what())
67 {}
68
69 virtual std::string Text() const override
70 {
71 return fixedText;
72 }
73 };
74
75 class LogTextErrorCode
76 : public LogTextFixed
77 {
78 protected:
79 const DWORD errorCode;
80
81 public:
82 LogTextErrorCode(DWORD errorCode, const std::string& text)
83 : LogTextFixed(text), errorCode(errorCode)
84 {}
85
86 virtual std::string Text() const override
87 {
88 std::ostringstream ss;
89 ss << fixedText << ". error = " << errorCode << " (0x";
90 ss << std::setfill('0') << std::setw(2 * sizeof(DWORD)) << std::hex << err orCode;
91 ss << ")";
92 return ss.str();
93 }
94 };
95
96 /**
97 * Wrapper around SYSTEMTIME allows initialization of 'const' instances.
98 */
99 struct SystemTime
100 : public SYSTEMTIME
101 {
102 SystemTime()
103 {
104 ::GetSystemTime(static_cast<SYSTEMTIME*>(this));
105 }
106 };
107
108 class LogEntry
109 {
110 const std::unique_ptr<LogText> text;
111
112 std::string InitialPrefix() const
113 {
114 std::stringstream ss;
115 ss << std::setfill('0') << std::setw(2) << st.wHour;
116 ss << ":";
117 ss << std::setfill('0') << std::setw(2) << st.wMinute;
118 ss << ":";
119 ss << std::setfill('0') << std::setw(2) << st.wSecond;
120 ss << ".";
121 ss << std::setfill('0') << std::setw(3) << st.wMilliseconds;
122 ss << " [";
123 ss << std::setfill(' ') << std::setw(5) << threadId;
124 ss << "] - ";
125 return ss.str();
126 }
127
128 std::string SubsequentPrefix() const
129 {
130 return " + ";
131 }
132
133 public:
134 /**
135 * The time at which the log-generating statement executes.
136 */
137 const SystemTime st;
138
139 /**
140 * The process within which the log-generating statement executes.
141 */
142 const DWORD processId;
143
144 /**
145 * The thread within which the log-generating statement executes.
146 */
147 const DWORD threadId;
148
149 LogEntry(LogText* text)
150 : processId(::GetCurrentProcessId()), threadId(::GetCurrentThreadId()), te xt(text)
151 {}
152
153 LogEntry(LogText* text, DWORD processId, DWORD threadId)
154 : processId(processId), threadId(threadId), text(text)
155 {}
156
157 void Write(std::ostream& out) const
158 {
159 CPluginDebugLock lock;
160 if (lock.IsLocked())
161 {
162 auto lines = text->Text();
163 size_t linePosition = 0;
164 while (true)
165 {
166 auto eolPosition = lines.find('\n', linePosition);
167 auto prefix = linePosition == 0 ? InitialPrefix() : SubsequentPrefix() ;
168 out << prefix;
169 if (eolPosition == std::string::npos)
170 {
171 out << lines.substr(linePosition) << "\n";
172 break;
173 }
174 else
175 {
176 out << lines.substr(linePosition, eolPosition - linePosition) << "\n ";
177 linePosition = eolPosition + 1;
178 }
179 }
180 out.flush();
181 }
182 }
183
184 void WriteFile(const std::wstring& logFileName) const
185 {
186 std::ofstream out;
187 out.open(logFileName, std::ios::app);
188 Write(out);
189 }
190 };
191
192 std::wstring GetDataPath(const std::wstring& filename)
193 {
194 return GetAppDataPath() + L"\\" + filename;
36 } 195 }
37 196
38 ~CPluginDebugLock() 197 void LogWriteDefault(const LogEntry& le)
39 { 198 {
40 s_criticalSectionDebugLock.Unlock(); 199 std::wstring debugFileName = GetDataPath(L"debug_" + std::to_wstring(le.proc essId) + L".txt");
200 le.WriteFile(debugFileName);
41 } 201 }
42 }; 202
43 203 void LogWriteResult(const LogEntry& le)
44 CComAutoCriticalSection CPluginDebugLock::s_criticalSectionDebugLock; 204 {
205 std::wstring debugFileName = GetDataPath(L"debug_result.txt");
206 le.WriteFile(debugFileName);
207 }
208 }
209
210 #ifdef ENABLE_DEBUG_INFO
211
212 void CPluginDebug::Debug(const std::string& text)
213 {
214 LogWriteDefault(LogEntry(new LogTextFixed(text)));
215 }
216
217 void CPluginDebug::Debug(const std::wstring& text)
218 {
219 Debug(ToUtf8String(text));
220 }
221
222 #endif
45 223
46 void CPluginDebug::DebugSystemException(const std::system_error& ex, int errorId , int errorSubid, const std::string& description) 224 void CPluginDebug::DebugSystemException(const std::system_error& ex, int errorId , int errorSubid, const std::string& description)
47 { 225 {
48 std::string message = description + ", " + ex.code().message() + ", " + ex.wha t(); 226 std::string message = description + ", " + ex.code().message() + ", " + ex.wha t();
49 DEBUG_ERROR_LOG(ex.code().value(), errorId, errorSubid, message); 227 DEBUG_ERROR_LOG(ex.code().value(), errorId, errorSubid, message);
50 } 228 }
51 229
52 #ifdef ENABLE_DEBUG_INFO
53
54 void DebugLegacy(const CString& text, DWORD dwProcessId, DWORD dwThreadId)
55 {
56 #ifdef USE_CONSOLE
57 CONSOLE("%s", CT2A(text.GetString(), CP_UTF8));
58 #endif
59
60 if (CPluginSettings::HasInstance())
61 {
62 #ifdef ENABLE_DEBUG_SPLIT_FILE
63 CPluginSettings* settings = CPluginSettings::GetInstance();
64
65 bool isWorkingThread = settings->IsWorkingThread(dwThreadId);
66
67 std::wstring processor;
68 wchar_t tmp[10];
69 _itow_s(::GetCurrentProcessId(), tmp, 10);
70 if (isWorkingThread)
71 processor = L"tab" + std::wstring(tmp) + L"_thread";
72 else
73 processor = L"tab" + std::wstring(tmp) + L"_ui";
74 #else
75 if (dwProcessId == 0)
76 {
77 dwProcessId = ::GetCurrentProcessId();
78 }
79 if (dwThreadId == 0)
80 {
81 dwThreadId = ::GetCurrentThreadId();
82 }
83
84 CStringA processInfo;
85 processInfo.Format("%4.4u.%4.4u - ", dwProcessId, dwThreadId);
86 #endif
87 SYSTEMTIME st;
88 ::GetSystemTime(&st);
89
90 CStringA sysTime;
91 sysTime.Format("%2.2d:%2.2d:%2.2d.%3.3d - ", st.wHour, st.wMinute, st.wSecon d, st.wMilliseconds);
92
93 CPluginDebugLock lock;
94 if (lock.IsLocked())
95 {
96 std::ofstream debugFile;
97
98 #ifdef ENABLE_DEBUG_SPLIT_FILE
99 debugFile.open(GetDataPath(L"debug_" + processor + L".txt"), std::ios::app );
100 #else
101 debugFile.open(GetDataPath(L"debug.txt"), std::ios::app);
102 #endif
103 int pos = 0;
104 CStringA line = text.Tokenize(L"\n\r", pos);
105
106 while (pos >= 0)
107 {
108 debugFile.write(sysTime.GetBuffer(), sysTime.GetLength());
109 #ifndef ENABLE_DEBUG_SPLIT_FILE
110 debugFile.write(processInfo.GetBuffer(), processInfo.GetLength());
111 #endif
112 debugFile.write(line.GetBuffer(), line.GetLength());
113 debugFile.write("\n", 1);
114
115 line = text.Tokenize(L"\n\r", pos);
116 }
117
118 debugFile.flush();
119 }
120 }
121 }
122
123 void CPluginDebug::Debug(const std::string& text, DWORD processId, DWORD threadI d)
124 {
125 DebugLegacy(CString(text.c_str()), processId, threadId);
126 }
127
128 void CPluginDebug::Debug(const std::wstring& text, DWORD processId, DWORD thread Id)
129 {
130 DebugLegacy(ToCString(text), processId, threadId);
131 }
132
133 #endif
134
135 #if (defined ENABLE_DEBUG_INFO) 230 #if (defined ENABLE_DEBUG_INFO)
136 231
137 void CPluginDebug::DebugException(const std::exception& ex) 232 void CPluginDebug::DebugException(const std::exception& ex)
138 { 233 {
139 auto error = std::string("!!! Exception:") + ex.what(); 234 auto lt = new LogTextFixed(ex);
140 #ifdef ENABLE_DEBUG_ERROR 235 #ifdef ENABLE_DEBUG_ERROR
141 Debug(error); 236 LogWriteDefault(LogEntry(lt));
142 #endif 237 #endif
143 238 DEBUG_SELFTEST(
144 DEBUG_SELFTEST("************************************************************** ******************\n" + error + "\n********************************************* ***********************************") 239 "*************************************************************************** *****\n"
145 } 240 + lt.text() + "\n"
146 241 "*************************************************************************** *****")
147 void DebugErrorCodeLegacy(DWORD errorCode, const CString& error, DWORD dwProcess Id, DWORD dwThreadId) 242 }
148 { 243
149 CString errorCodeText; 244 void CPluginDebug::DebugErrorCode(DWORD errorCode, const std::string& error, DWO RD processId, DWORD threadId)
150 errorCodeText.Format(L"%u (0x%8.8x)", errorCode, errorCode); 245 {
151 246 auto lt = new LogTextErrorCode(errorCode, error);
sergei 2015/04/02 07:41:12 Here and above, who will destroy it if ENABLE_DEBU
Eric 2015/05/19 15:13:56 Fixed.
152 CString finalError = error + L". error=" + errorCodeText;
153
154 #ifdef ENABLE_DEBUG_ERROR 247 #ifdef ENABLE_DEBUG_ERROR
155 DebugLegacy(finalError, dwProcessId, dwThreadId); 248 LogWriteDefault(LogEntry(lt, processId, threadId));
156 #endif 249 #endif
157 250 DEBUG_SELFTEST(
158 DEBUG_SELFTEST(L"************************************************************* *******************\n" + finalError + "\n*************************************** *****************************************") 251 "*************************************************************************** *****\n"
159 } 252 + lt.text() + "\n"
sergei 2015/04/02 07:41:12 should it be `lt->`?
Eric 2015/05/19 15:13:56 Fixed. It should also be that we just eliminate D
160 253 "*************************************************************************** *****")
161 void CPluginDebug::DebugErrorCode(DWORD errorCode, const std::string& error, DWO RD processId, DWORD threadId) 254 }
162 { 255
163 DebugErrorCodeLegacy(errorCode, CString(error.c_str()), processId, threadId); 256 #endif
164 }
165
166 #endif
167 257
168 // ============================================================================ 258 // ============================================================================
169 // Debug result 259 // Debug result
170 // ============================================================================ 260 // ============================================================================
171 261
172 #ifdef ENABLE_DEBUG_RESULT 262 #ifdef ENABLE_DEBUG_RESULT
173 263
174 void DebugResultLegacy(const CString& text)
175 {
176 SYSTEMTIME st;
177 ::GetSystemTime(&st);
178
179 CStringA sysTime;
180 sysTime.Format("%2.2d:%2.2d:%2.2d.%3.3d - ", st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
181
182 CStringA textA = text;
183
184 CPluginDebugLock lock;
185 if (lock.IsLocked())
186 {
187 std::ofstream debugFile;
188
189 debugFile.open(GetDataPath(L"debug_result.txt"), std::ios::app);
190 debugFile.write(sysTime.GetBuffer(), sysTime.GetLength());
191 debugFile.write(LPCSTR(textA), textA.GetLength());
192 debugFile.write("\n", 1);
193 debugFile.flush();
194 }
195 }
196
197 void CPluginDebug::DebugResult(const std::wstring& text) 264 void CPluginDebug::DebugResult(const std::wstring& text)
198 { 265 {
199 DebugResultLegacy(ToCString(text)); 266 LogWriteResult(LogEntry(new LogTextFixed(ToUtf8String(text))));
200 } 267 }
201 268
202 void CPluginDebug::DebugResultDomain(const std::wstring& domain) 269 void CPluginDebug::DebugResultDomain(const std::wstring& domain)
203 { 270 {
204 DebugResult(L"================================================================ ================================================================================ ==========================================="); 271 DebugResult(
205 DebugResult(domain); 272 L"========================================================================== ===============\n"
206 DebugResult(L"================================================================ ================================================================================ ==========================================="); 273 + domain + L"\n"
274 L"========================================================================== ===============");
207 } 275 }
208 276
277 namespace
278 {
279 void DebugResultFormat(const std::wstring& action, const std::wstring& type, c onst std::wstring& param1, const std::wstring& param2)
280 {
281 std::wostringstream ss;
282 ss << std::setw(7) << std::setiosflags(std::ios::left) << action;
283 ss << L" ";
284 ss << std::setw(12) << std::setiosflags(std::ios::left) << type;
285 ss << L" " << param1 << L" " << param2;
286 CPluginDebug::DebugResult(ss.str());
287 }
288
289 std::wstring Shorten(const std::wstring& s)
290 {
291 auto n = s.length();
292 if (n <= 100) return s;
293 auto r = s.substr(0, 67);
294 r += L"...";
295 r += s.substr(n - 30, 30);
296 return r;
297 }
298 }
209 299
210 void CPluginDebug::DebugResultBlocking(const std::wstring& type, const std::wstr ing& src, const std::wstring& domain) 300 void CPluginDebug::DebugResultBlocking(const std::wstring& type, const std::wstr ing& src, const std::wstring& domain)
211 { 301 {
212 CString srcTrunc = ToCString(src); 302 DebugResultFormat(L"Blocked", type, domain.empty() ? L"-" : domain, Shorten(sr c));
213 if (src.length() > 100)
214 {
215 srcTrunc = srcTrunc.Left(67) + L"..." + srcTrunc.Right(30);
216 }
217
218 CString blocking;
219 blocking.Format(L"Blocked %-12s %-20s %s", ToCString(type), domain.empty()? L"-" : ToCString(domain), srcTrunc);
220
221 DebugResultLegacy(blocking);
222 } 303 }
223 304
224 305
225 void CPluginDebug::DebugResultHiding(const std::wstring& tag, const std::wstring & id, const std::wstring& filter) 306 void CPluginDebug::DebugResultHiding(const std::wstring& tag, const std::wstring & id, const std::wstring& filter)
226 { 307 {
227 CString srcTrunc = ToCString(id); 308 DebugResultFormat(L"Hidden", tag, L"- " + Shorten(id), filter);
228 if (srcTrunc.GetLength() > 100)
229 {
230 srcTrunc = srcTrunc.Left(67) + L"..." + srcTrunc.Right(30);
231 }
232
233 CString blocking;
234 blocking.Format(L"Hidden %-12s - %s %s", ToCString(tag), srcTrunc, ToCStri ng(filter));
235
236 DebugResultLegacy(blocking);
237 } 309 }
238 310
239 #endif // ENABLE_DEBUG_RESULT 311 #endif // ENABLE_DEBUG_RESULT
240 312
241 313
242 #ifdef ENABLE_DEBUG_RESULT_IGNORED 314 #ifdef ENABLE_DEBUG_RESULT_IGNORED
243 315
244 void CPluginDebug::DebugResultIgnoring(const std::wstring& type, const std::wstr ing& src, const std::wstring& domain) 316 void CPluginDebug::DebugResultIgnoring(const std::wstring& type, const std::wstr ing& src, const std::wstring& domain)
245 { 317 {
246 CString srcTrunc = ToCString(src); 318 DebugResultFormat(L"Ignored", type, domain.empty() ? L"-" : domain, Shorten(sr c));
247 if (src.length() > 100)
248 {
249 srcTrunc = srcTrunc.Left(67) + L"..." + srcTrunc.Right(30);
250 }
251
252 CString blocking;
253 blocking.Format(L"Ignored %-12s %s %s", ToCString(type), domain.empty()? L" -" : ToCString(domain), srcTrunc);
254
255 DebugResultLegacy(blocking);
256 } 319 }
257 320
258 #endif // ENABLE_DEBUG_RESULT_IGNORED 321 #endif // ENABLE_DEBUG_RESULT_IGNORED
OLDNEW
« no previous file with comments | « src/plugin/PluginDebug.h ('k') | src/plugin/PluginSettings.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld