|
1 // log.cpp |
|
2 // |
|
3 // Copyright (c) 2006 - 2010 Accenture. All rights reserved. |
|
4 // This component and the accompanying materials are made available |
|
5 // under the terms of the "Eclipse Public License v1.0" |
|
6 // which accompanies this distribution, and is available |
|
7 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 // |
|
9 // Initial Contributors: |
|
10 // Accenture - Initial contribution |
|
11 // |
|
12 |
|
13 #include "log.h" |
|
14 #ifdef IOSRV_LOGGING |
|
15 |
|
16 #include "server.h" |
|
17 #include "clientserver.h" |
|
18 |
|
19 #ifndef IOSRV_LOGGING_USES_CLOGGER |
|
20 _LIT(KLogFileName, "c:\\logs\\iosrv.txt"); |
|
21 _LIT8(KNewLine, "\r\n"); |
|
22 #endif |
|
23 |
|
24 #if !defined(__WINS__) || defined (EKA2) |
|
25 CIoLog* gLog = NULL; |
|
26 #endif |
|
27 |
|
28 CIoLog* CIoLog::NewL(RFs& aFs) |
|
29 { |
|
30 CIoLog* self = new(ELeave) CIoLog(aFs); |
|
31 CleanupStack::PushL(self); |
|
32 self->ConstructL(); |
|
33 CleanupStack::Pop(self); |
|
34 return self; |
|
35 } |
|
36 |
|
37 CIoLog::~CIoLog() |
|
38 { |
|
39 #ifdef IOSRV_LOGGING_USES_CLOGGER |
|
40 iClogger.Close(); |
|
41 #else |
|
42 iFile.Close(); |
|
43 #endif |
|
44 #if defined(__WINS__) && !defined(EKA2) |
|
45 Dll::SetTls(NULL); |
|
46 #endif |
|
47 } |
|
48 |
|
49 |
|
50 #define CASE_RETURN_LIT(XXX) case XXX: { _LIT(_KLit, #XXX); return &_KLit; } |
|
51 #define DEFAULT_RETURN_LIT(XXX) default: { _LIT(_KLit, XXX); return &_KLit; } |
|
52 |
|
53 const TDesC* CIoLog::StringifyError(TInt aError) |
|
54 { |
|
55 switch (aError) |
|
56 { |
|
57 CASE_RETURN_LIT(KErrNone); |
|
58 CASE_RETURN_LIT(KErrNotFound); |
|
59 CASE_RETURN_LIT(KErrGeneral); |
|
60 CASE_RETURN_LIT(KErrCancel); |
|
61 CASE_RETURN_LIT(KErrNoMemory); |
|
62 CASE_RETURN_LIT(KErrNotSupported); |
|
63 CASE_RETURN_LIT(KErrArgument); |
|
64 CASE_RETURN_LIT(KErrBadHandle); |
|
65 CASE_RETURN_LIT(KErrOverflow); |
|
66 CASE_RETURN_LIT(KErrUnderflow); |
|
67 CASE_RETURN_LIT(KErrAlreadyExists); |
|
68 CASE_RETURN_LIT(KErrPathNotFound); |
|
69 CASE_RETURN_LIT(KErrDied); |
|
70 CASE_RETURN_LIT(KErrInUse); |
|
71 CASE_RETURN_LIT(KErrServerTerminated); |
|
72 CASE_RETURN_LIT(KErrServerBusy); |
|
73 CASE_RETURN_LIT(KErrCompletion); |
|
74 CASE_RETURN_LIT(KErrNotReady); |
|
75 CASE_RETURN_LIT(KErrUnknown); |
|
76 CASE_RETURN_LIT(KErrCorrupt); |
|
77 CASE_RETURN_LIT(KErrAccessDenied); |
|
78 CASE_RETURN_LIT(KErrLocked); |
|
79 CASE_RETURN_LIT(KErrWrite); |
|
80 CASE_RETURN_LIT(KErrDisMounted); |
|
81 CASE_RETURN_LIT(KErrEof); |
|
82 CASE_RETURN_LIT(KErrDiskFull); |
|
83 CASE_RETURN_LIT(KErrBadDriver); |
|
84 CASE_RETURN_LIT(KErrBadName); |
|
85 CASE_RETURN_LIT(KErrCommsLineFail); |
|
86 CASE_RETURN_LIT(KErrCommsFrame); |
|
87 CASE_RETURN_LIT(KErrCommsOverrun); |
|
88 CASE_RETURN_LIT(KErrCommsParity); |
|
89 CASE_RETURN_LIT(KErrTimedOut); |
|
90 CASE_RETURN_LIT(KErrCouldNotConnect); |
|
91 CASE_RETURN_LIT(KErrCouldNotDisconnect); |
|
92 CASE_RETURN_LIT(KErrDisconnected); |
|
93 CASE_RETURN_LIT(KErrBadLibraryEntryPoint); |
|
94 CASE_RETURN_LIT(KErrBadDescriptor); |
|
95 CASE_RETURN_LIT(KErrAbort); |
|
96 CASE_RETURN_LIT(KErrTooBig); |
|
97 CASE_RETURN_LIT(KErrDivideByZero); |
|
98 CASE_RETURN_LIT(KErrBadPower); |
|
99 CASE_RETURN_LIT(KErrDirFull); |
|
100 CASE_RETURN_LIT(KErrHardwareNotAvailable); |
|
101 #ifdef EKA2 |
|
102 CASE_RETURN_LIT(KErrPermissionDenied); |
|
103 #endif |
|
104 // CASE_RETURN_LIT(KErrExtensionNotSupported); |
|
105 // CASE_RETURN_LIT(KErrCommsBreak); |
|
106 DEFAULT_RETURN_LIT("*** ERROR UNKNOWN ***"); |
|
107 } |
|
108 } |
|
109 |
|
110 const TDesC* CIoLog::StringifyOpcode(TInt aOpCode) |
|
111 { |
|
112 switch (aOpCode) |
|
113 { |
|
114 CASE_RETURN_LIT(EIoHandleClose); |
|
115 CASE_RETURN_LIT(EIoHandleSetOwner); |
|
116 CASE_RETURN_LIT(EIoHandleSetUnderlyingConsole); |
|
117 CASE_RETURN_LIT(EIoHandleAttachedToConsole); |
|
118 CASE_RETURN_LIT(EIoCreateReader); |
|
119 CASE_RETURN_LIT(EIoOpenReaderByThreadId); |
|
120 CASE_RETURN_LIT(EIoOpenReaderByExplicitThreadId); |
|
121 CASE_RETURN_LIT(EIoDuplicateReader); |
|
122 CASE_RETURN_LIT(EIoCreateWriter); |
|
123 CASE_RETURN_LIT(EIoOpenWriterByThreadId); |
|
124 CASE_RETURN_LIT(EIoOpenWriterByExplicitThreadId); |
|
125 CASE_RETURN_LIT(EIoDuplicateWriter); |
|
126 CASE_RETURN_LIT(EIoSetReadWriteMode); |
|
127 CASE_RETURN_LIT(EIoSetReadMode); |
|
128 CASE_RETURN_LIT(EIoSetReaderToForeground); |
|
129 CASE_RETURN_LIT(EIoRead); |
|
130 CASE_RETURN_LIT(EIoSetLineSeparator); |
|
131 CASE_RETURN_LIT(EIoWrite); |
|
132 CASE_RETURN_LIT(EIoReadCancel); |
|
133 CASE_RETURN_LIT(EIoWriteCancel); |
|
134 CASE_RETURN_LIT(EIoIsForegroundReader); |
|
135 CASE_RETURN_LIT(EIoConsoleWaitForKey); |
|
136 CASE_RETURN_LIT(EIoConsoleWaitForKeyCancel); |
|
137 CASE_RETURN_LIT(EIoConsoleCaptureKey); |
|
138 CASE_RETURN_LIT(EIoConsoleCancelCaptureKey); |
|
139 CASE_RETURN_LIT(EIoConsoleCaptureAllKeys); |
|
140 CASE_RETURN_LIT(EIoConsoleCancelCaptureAllKeys); |
|
141 CASE_RETURN_LIT(EIoConsoleCursorPos); |
|
142 CASE_RETURN_LIT(EIoConsoleSetCursorPosAbs); |
|
143 CASE_RETURN_LIT(EIoConsoleSetCursorPosRel); |
|
144 CASE_RETURN_LIT(EIoConsoleSetCursorHeight); |
|
145 CASE_RETURN_LIT(EIoConsoleSetTitle); |
|
146 CASE_RETURN_LIT(EIoConsoleClearScreen); |
|
147 CASE_RETURN_LIT(EIoConsoleClearToEndOfLine); |
|
148 CASE_RETURN_LIT(EIoConsoleScreenSize); |
|
149 CASE_RETURN_LIT(EIoConsoleSetAttributes); |
|
150 CASE_RETURN_LIT(EIoEndPointAttachReader); |
|
151 CASE_RETURN_LIT(EIoEndPointAttachWriter); |
|
152 CASE_RETURN_LIT(EIoEndPointSetForegroundReadHandle); |
|
153 CASE_RETURN_LIT(EIoCreatePipe); |
|
154 CASE_RETURN_LIT(EIoCreateConsole); |
|
155 CASE_RETURN_LIT(EIoOpenConsole); |
|
156 CASE_RETURN_LIT(EIoConsoleImplementation); |
|
157 CASE_RETURN_LIT(EIoCreateFile); |
|
158 CASE_RETURN_LIT(EIoCreateNull); |
|
159 CASE_RETURN_LIT(EIoSetObjectName); |
|
160 CASE_RETURN_LIT(EIoCreatePersistentConsole); |
|
161 CASE_RETURN_LIT(EIoOpenPersistentConsoleByName); |
|
162 CASE_RETURN_LIT(EIoPersistentConsoleAttachReadEndPoint); |
|
163 CASE_RETURN_LIT(EIoPersistentConsoleAttachWriteEndPoint); |
|
164 CASE_RETURN_LIT(EIoPersistentConsoleDetachReadEndPoint); |
|
165 CASE_RETURN_LIT(EIoPersistentConsoleDetachWriteEndPoint); |
|
166 CASE_RETURN_LIT(EIoPersistentConsoleNotifyReadDetach); |
|
167 CASE_RETURN_LIT(EIoPersistentConsoleNotifyWriteDetach); |
|
168 CASE_RETURN_LIT(EIoPersistentConsoleCancelNotifyReadDetach); |
|
169 CASE_RETURN_LIT(EIoPersistentConsoleCancelNotifyWriteDetach); |
|
170 CASE_RETURN_LIT(EIoHandleIsType); |
|
171 CASE_RETURN_LIT(EIoHandleGetName); |
|
172 CASE_RETURN_LIT(EIoHandleEquals); |
|
173 CASE_RETURN_LIT(EIoReadHandleNotifyChange); |
|
174 CASE_RETURN_LIT(EIoReadHandleCancelNotifyChange); |
|
175 CASE_RETURN_LIT(EIoDuplicateReaderHandleFromThread); |
|
176 CASE_RETURN_LIT(EIoDuplicateWriterHandleFromThread); |
|
177 DEFAULT_RETURN_LIT("*** OPCODE UNKNOWN ***"); |
|
178 } |
|
179 } |
|
180 |
|
181 class TOverflowTruncate : public TDes16Overflow |
|
182 { |
|
183 public: |
|
184 virtual void Overflow(TDes16&) {} |
|
185 }; |
|
186 |
|
187 class RMessageAccess : public RMsg |
|
188 { |
|
189 public: |
|
190 TInt Handle() const { return iHandle; } |
|
191 }; |
|
192 |
|
193 void CIoLog::StartServiceLC(const RMsg& aMessage) |
|
194 { |
|
195 CIoLog& self = Self(); |
|
196 ASSERT(!self.iInServiceL); |
|
197 self.iScratchBuf.SetLength(0); |
|
198 self.iScratchBuf = ClientNameL(aMessage); |
|
199 CleanupStack::PushL(TCleanupItem(EndService, &self)); |
|
200 TOverflowTruncate overflow; |
|
201 self.iScratchBuf.AppendFormat(_L(" requested %S (opcode: %d, message handle: %d)"), &overflow, StringifyOpcode(aMessage.Function()), aMessage.Function(), static_cast<const RMessageAccess&>(aMessage).Handle()); |
|
202 self.Write(self.iScratchBuf); |
|
203 self.iInServiceL = ETrue; |
|
204 } |
|
205 |
|
206 void CIoLog::EndService(TAny* aSelf) |
|
207 { |
|
208 CIoLog& self = *(static_cast<CIoLog*>(aSelf)); |
|
209 ASSERT(self.iInServiceL); |
|
210 self.Write(KNullDesC); |
|
211 self.iInServiceL = EFalse; |
|
212 } |
|
213 |
|
214 void CIoLog::LogCompletion(const RMsg& aMessage, TInt aError) |
|
215 { |
|
216 TFullName threadName(_L("unknown")); |
|
217 TRAP_IGNORE(threadName = ClientNameL(aMessage)); |
|
218 CIoLog& self = Self(); |
|
219 self.iScratchBuf.SetLength(0); |
|
220 TOverflowTruncate overflow; |
|
221 self.iScratchBuf.AppendFormat(_L("Completing %S's request (opcode: %S, message handle: %d) with %S(%d)"), &overflow, &threadName, StringifyOpcode(aMessage.Function()), static_cast<const RMessageAccess&>(aMessage).Handle(), StringifyError(aError), aError); |
|
222 self.Write(self.iScratchBuf); |
|
223 } |
|
224 |
|
225 void CIoLog::Write(const TDesC& aData) |
|
226 { |
|
227 CIoLog& self = Self(); |
|
228 #ifdef IOSRV_LOGGING_USES_CLOGGER |
|
229 if (aData.Length() == 0) return; // The trick of writing knulldesc to get a newline is not really appropriate with clogger |
|
230 self.iClogger.Log(aData); |
|
231 #else |
|
232 if (self.iFile.SubSessionHandle()) |
|
233 { |
|
234 self.iNarrowBuf.Copy(aData.Left(self.iNarrowBuf.MaxLength() - KNewLine().Length() - 1)); |
|
235 if (self.iInServiceL) |
|
236 { |
|
237 self.iNarrowBuf.Insert(0, _L8("\t")); |
|
238 } |
|
239 self.iNarrowBuf.Append(KNewLine); |
|
240 self.iFile.Write(self.iNarrowBuf); |
|
241 self.iFile.Flush(); |
|
242 } |
|
243 #endif |
|
244 } |
|
245 |
|
246 void CIoLog::Printf(TRefByValue<const TDesC> aFmt, ...) |
|
247 { |
|
248 TOverflowTruncate overflow; |
|
249 VA_LIST list; |
|
250 VA_START(list, aFmt); |
|
251 CIoLog& self = Self(); |
|
252 self.iScratchBuf.SetLength(0); |
|
253 self.iScratchBuf.AppendFormatList(aFmt, list, &overflow); |
|
254 Write(self.iScratchBuf); |
|
255 } |
|
256 |
|
257 CIoLog::CIoLog(RFs& aFs) |
|
258 : iFs(aFs) |
|
259 { |
|
260 } |
|
261 |
|
262 void CIoLog::ConstructL() |
|
263 { |
|
264 #ifdef IOSRV_LOGGING_USES_CLOGGER |
|
265 _LIT(KIoSrvLog, "iosrv"); |
|
266 User::LeaveIfError(iClogger.Connect(KIoSrvLog)); |
|
267 #else |
|
268 // iFs.MkDirAll(KLogFileName); |
|
269 /*User::LeaveIfError*/(iFile.Replace(iFs, KLogFileName, EFileWrite)); |
|
270 #endif |
|
271 #if defined(__WINS__) && !defined(EKA2) |
|
272 Dll::SetTls(this); |
|
273 #else |
|
274 gLog = this; |
|
275 #endif |
|
276 Write(KNullDesC); |
|
277 Write(_L("New log created")); |
|
278 } |
|
279 |
|
280 CIoLog& CIoLog::Self() |
|
281 { |
|
282 #if defined(__WINS__) && !defined(EKA2) |
|
283 return *(static_cast<CIoLog*>(Dll::Tls())); |
|
284 #else |
|
285 return *gLog; |
|
286 #endif |
|
287 } |
|
288 |
|
289 #endif |