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: capitalize a function name Created March 20, 2015, 10:09 a.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() =0;
sergei 2015/03/30 13:45:26 I guess, the method should have const modifier.
Eric 2015/03/31 15:42:22 Done.
52 };
53
54 class LogTextFixed
55 : public LogText
56 {
57 protected:
58 const std::string fixedText;
59
60 public:
61 LogTextFixed(std::string text)
sergei 2015/03/30 13:45:26 explicit and const ref are missed
Eric 2015/03/31 15:42:22 We don't have 'explict' in VS 2012. 'const' done.
sergei 2015/04/02 07:41:12 Why do we not have explicit in VS 2012? It's a goo
Eric 2015/05/19 15:13:56 I'm confused. We don't have 'explicit' for convers
62 : fixedText(text)
63 {}
64
65 virtual std::string Text() override
Eric 2015/03/20 10:17:04 I remembered to look this up. VS 2012 does support
66 {
67 return fixedText;
68 }
69 };
70
71 class LogTextErrorCode
72 : public LogTextFixed
73 {
74 protected:
75 const DWORD errorCode;
76
77 public:
78 LogTextErrorCode(DWORD errorCode, const std::string& text)
79 : LogTextFixed(text), errorCode(errorCode)
80 {}
81
82 virtual std::string Text() override
83 {
84 std::ostringstream ss;
85 ss << fixedText << ". error = " << errorCode << " (0x";
86 ss << std::setfill('0') << std::setw(2 * sizeof(DWORD)) << std::hex << err orCode;
87 ss << ")";
88 return ss.str();
89 }
90 };
91
92 class LogTextException
93 : public LogText
94 {
95 protected:
96 const std::exception ex;
97
98 public:
99 LogTextException(const std::exception& ex)
100 : ex(ex)
sergei 2015/03/30 13:45:26 I'm not sure that it is safe to copy std::exceptio
Eric 2015/03/31 15:42:22 The point behind subclassing LogText is to defer c
Eric 2015/03/31 15:42:22 You're right; it's not. There's also no 'clone()'
sergei 2015/04/02 07:41:12 It's clear, but I would say lazy evaluation here m
Eric 2015/05/19 15:13:56 I'll leave it in. It's not harming anything. I may
101 {}
102
103 virtual std::string Text() override
104 {
105 auto text = std::string("!!! Exception: ");
106 text += ex.what();
107 return text;
108 }
109 };
110
111 /**
112 * Wrapper around SYSTEMTIME allows initialization of 'const' instances.
113 */
114 struct SystemTime
115 : public SYSTEMTIME
116 {
117 SystemTime()
118 {
119 ::GetSystemTime(static_cast<SYSTEMTIME*>(this));
120 }
121 };
122
123 class LogEntry
124 {
125 const std::unique_ptr<LogText> text;
126
127 std::string InitialPrefix()
128 {
129 std::stringstream ss;
130 ss << std::setfill('0') << std::setw(2) << st.wHour;
131 ss << ":";
132 ss << std::setfill('0') << std::setw(2) << st.wMinute;
133 ss << ":";
134 ss << std::setfill('0') << std::setw(2) << st.wSecond;
135 ss << ".";
136 ss << std::setfill('0') << std::setw(3) << st.wMilliseconds;
137 ss << " [";
138 ss << std::setfill(' ') << std::setw(5) << threadId;
139 ss << "] - ";
140 return ss.str();
141 }
142
143 std::string SubsequentPrefix()
144 {
145 return " + ";
146 }
147
148 public:
149 /**
150 * The time at which the log-generating statement executes.
151 */
152 const SystemTime st;
153
154 /**
155 * The process within which the log-generating statement executes.
156 */
157 const DWORD processId;
158
159 /**
160 * The thread within which the log-generating statement executes.
161 */
162 const DWORD threadId;
163
164 LogEntry(LogText* text)
sergei 2015/03/30 13:45:26 explicit is missed
Eric 2015/03/31 15:42:22 No 'explicit' in VS 2012.
165 : processId(::GetCurrentProcessId()), threadId(::GetCurrentThreadId()), te xt(text)
166 {}
167
168 LogEntry(LogText* text, DWORD processId, DWORD threadId)
169 : processId(processId), threadId(threadId), text(text)
170 {}
171
172 void Write(std::ostream& out)
sergei 2015/03/30 13:45:26 this method should be const
Eric 2015/03/31 15:42:22 Done.
173 {
174 CPluginDebugLock lock;
175 if (lock.IsLocked())
176 {
177 auto lines = text->Text();
178 size_t linePosition = 0;
179 while (true)
180 {
181 auto eolPosition = lines.find('\n', linePosition);
182 auto prefix = linePosition == 0 ? InitialPrefix() : SubsequentPrefix() ;
183 out << prefix;
184 if (eolPosition == std::string::npos)
185 {
186 out << lines.substr(linePosition) << "\n";
187 break;
188 }
189 else
190 {
191 out << lines.substr(linePosition, eolPosition - linePosition) << "\n ";
192 linePosition = eolPosition + 1;
193 }
194 }
195 out.flush();
196 }
197 }
198
199 void WriteFile(const std::wstring& logFileName)
sergei 2015/03/30 13:45:26 it also should be const
Eric 2015/03/31 15:42:22 Done.
200 {
201 std::ofstream out;
202 out.open(logFileName, std::ios::app);
203 Write(out);
204 }
205 };
206
207 std::wstring GetDataPath(const std::wstring& filename)
208 {
209 return GetAppDataPath() + L"\\" + filename;
36 } 210 }
37 211
38 ~CPluginDebugLock() 212 void LogWriteDefault(LogEntry& le)
sergei 2015/03/30 13:45:26 LogEntry should be const ref
Eric 2015/03/31 15:42:22 Done.
39 { 213 {
40 s_criticalSectionDebugLock.Unlock(); 214 std::wstring debugFileName = GetDataPath(L"debug_" + std::to_wstring(le.proc essId) + L".txt");
215 le.WriteFile(debugFileName);
41 } 216 }
42 }; 217
43 218 void LogWriteResult(LogEntry& le)
sergei 2015/03/30 13:45:26 it also should be const
Eric 2015/03/31 15:42:22 Done.
44 CComAutoCriticalSection CPluginDebugLock::s_criticalSectionDebugLock; 219 {
220 std::wstring debugFileName = GetDataPath(L"debug_result.txt");
221 le.WriteFile(debugFileName);
222 }
223 }
224
225 #ifdef ENABLE_DEBUG_INFO
226
227 void CPluginDebug::Debug(const std::string& text)
228 {
229 LogWriteDefault(LogEntry(new LogTextFixed(text)));
230 }
231
232 void CPluginDebug::Debug(const std::wstring& text)
233 {
234 Debug(ToUtf8String(text));
235 }
236
237 #endif
45 238
46 void CPluginDebug::DebugSystemException(const std::system_error& ex, int errorId , int errorSubid, const std::string& description) 239 void CPluginDebug::DebugSystemException(const std::system_error& ex, int errorId , int errorSubid, const std::string& description)
47 { 240 {
48 std::string message = description + ", " + ex.code().message() + ", " + ex.wha t(); 241 std::string message = description + ", " + ex.code().message() + ", " + ex.wha t();
49 DEBUG_ERROR_LOG(ex.code().value(), errorId, errorSubid, message); 242 DEBUG_ERROR_LOG(ex.code().value(), errorId, errorSubid, message);
50 } 243 }
51 244
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) 245 #if (defined ENABLE_DEBUG_INFO)
136 246
137 void CPluginDebug::DebugException(const std::exception& ex) 247 void CPluginDebug::DebugException(const std::exception& ex)
138 { 248 {
139 auto error = std::string("!!! Exception:") + ex.what(); 249 auto lt = new LogTextException(ex);
140 #ifdef ENABLE_DEBUG_ERROR 250 #ifdef ENABLE_DEBUG_ERROR
141 Debug(error); 251 LogWriteDefault(LogEntry(lt));
142 #endif 252 #endif
143 253 DEBUG_SELFTEST(
144 DEBUG_SELFTEST("************************************************************** ******************\n" + error + "\n********************************************* ***********************************") 254 "*************************************************************************** *****\n"
145 } 255 + lt.text() + "\n"
146 256 "*************************************************************************** *****")
147 void DebugErrorCodeLegacy(DWORD errorCode, const CString& error, DWORD dwProcess Id, DWORD dwThreadId)
148 {
149 CString errorCodeText;
150 errorCodeText.Format(L"%u (0x%8.8x)", errorCode, errorCode);
151
152 CString finalError = error + L". error=" + errorCodeText;
153
154 #ifdef ENABLE_DEBUG_ERROR
155 DebugLegacy(finalError, dwProcessId, dwThreadId);
156 #endif
157
158 DEBUG_SELFTEST(L"************************************************************* *******************\n" + finalError + "\n*************************************** *****************************************")
159 } 257 }
160 258
161 void CPluginDebug::DebugErrorCode(DWORD errorCode, const std::string& error, DWO RD processId, DWORD threadId) 259 void CPluginDebug::DebugErrorCode(DWORD errorCode, const std::string& error, DWO RD processId, DWORD threadId)
162 { 260 {
163 DebugErrorCodeLegacy(errorCode, CString(error.c_str()), processId, threadId); 261 auto lt = new LogTextErrorCode(errorCode, error);
262 #ifdef ENABLE_DEBUG_ERROR
263 LogWriteDefault(LogEntry(lt, processId, threadId));
264 #endif
265 DEBUG_SELFTEST(
266 "*************************************************************************** *****\n"
267 + lt.text() + "\n"
268 "*************************************************************************** *****")
164 } 269 }
165 270
166 #endif 271 #endif
167 272
168 // ============================================================================ 273 // ============================================================================
169 // Debug result 274 // Debug result
170 // ============================================================================ 275 // ============================================================================
171 276
172 #ifdef ENABLE_DEBUG_RESULT 277 #ifdef ENABLE_DEBUG_RESULT
173 278
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) 279 void CPluginDebug::DebugResult(const std::wstring& text)
198 { 280 {
199 DebugResultLegacy(ToCString(text)); 281 LogWriteResult(LogEntry(new LogTextFixed(ToUtf8String(text))));
200 } 282 }
201 283
202 void CPluginDebug::DebugResultDomain(const std::wstring& domain) 284 void CPluginDebug::DebugResultDomain(const std::wstring& domain)
203 { 285 {
204 DebugResult(L"================================================================ ================================================================================ ==========================================="); 286 DebugResult(
205 DebugResult(domain); 287 L"========================================================================== ===============\n"
206 DebugResult(L"================================================================ ================================================================================ ==========================================="); 288 + domain + L"\n"
289 L"========================================================================== ===============");
207 } 290 }
208 291
292 namespace
293 {
294 void DebugResultFormat(const std::wstring& action, const std::wstring& type, c onst std::wstring& param1, const std::wstring& param2)
295 {
296 std::wostringstream ss;
297 ss << std::setw(7) << std::setiosflags(std::ios::left) << action;
298 ss << L" ";
299 ss << std::setw(12) << std::setiosflags(std::ios::left) << type;
300 ss << L" " << param1 << L" " << param2;
301 CPluginDebug::DebugResult(ss.str());
302 }
303
304 std::wstring Shorten(const std::wstring& s)
305 {
306 auto n = s.length();
307 if (n <= 100) return s;
308 auto r = s.substr(0, 67);
309 r += L"...";
310 r += s.substr(n - 30, 30);
311 return r;
312 }
313 }
209 314
210 void CPluginDebug::DebugResultBlocking(const std::wstring& type, const std::wstr ing& src, const std::wstring& domain) 315 void CPluginDebug::DebugResultBlocking(const std::wstring& type, const std::wstr ing& src, const std::wstring& domain)
211 { 316 {
212 CString srcTrunc = ToCString(src); 317 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 } 318 }
223 319
224 320
225 void CPluginDebug::DebugResultHiding(const std::wstring& tag, const std::wstring & id, const std::wstring& filter) 321 void CPluginDebug::DebugResultHiding(const std::wstring& tag, const std::wstring & id, const std::wstring& filter)
226 { 322 {
227 CString srcTrunc = ToCString(id); 323 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 } 324 }
238 325
239 #endif // ENABLE_DEBUG_RESULT 326 #endif // ENABLE_DEBUG_RESULT
240 327
241 328
242 #ifdef ENABLE_DEBUG_RESULT_IGNORED 329 #ifdef ENABLE_DEBUG_RESULT_IGNORED
243 330
244 void CPluginDebug::DebugResultIgnoring(const std::wstring& type, const std::wstr ing& src, const std::wstring& domain) 331 void CPluginDebug::DebugResultIgnoring(const std::wstring& type, const std::wstr ing& src, const std::wstring& domain)
245 { 332 {
246 CString srcTrunc = ToCString(src); 333 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 } 334 }
257 335
258 #endif // ENABLE_DEBUG_RESULT_IGNORED 336 #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