Join Now
Quality Rating:
  • Currently 0.0 / 5
(0.0 / 5 - 0 votes cast)
Expertise Level:
  • Currently 0.0 / 5
(0.0 / 5 - 0 votes cast)

This page was last modified 15:38, 19 December 2007.

File logger

From Forum Nokia Wiki

Below is an example of a file logger. You can build it as a dll and use in your projects.

Contents

filelogger.h

#ifndef __FILELOGGER_H__
#define __FILELOGGER_H__
 
#include <f32file.h>
 
const TInt KMaxLogEntrySize = 400;
 
#define LOGCLOSE            CFileLogger::Close()
#define LOGARG(txt,parm...) {_LIT8(KTxt, txt); CFileLogger::Write(KTxt, parm);}
#define LOGTXT(txt)         {_LIT8(KTxt, txt); CFileLogger::Write((const TDesC8&)KTxt);}
#define LOGDES8(des)        CFileLogger::Write((const TDesC8&)des);
#define LOGDES16(des)       CFileLogger::Write(des);
#define LOGERR(txt,err)     if (err) LOGARG(txt, err)
#define LOGCALL(exp)        {LOGARG("Calling \"%s\"", #exp); exp; LOGARG("Call to \"%s\" passed.", #exp);}
#define LOGENTER            LOGARG("%s start", __PRETTY_FUNCTION__)
#define LOGEXIT             LOGARG("%s end", __PRETTY_FUNCTION__)
#define LOGMEM(ptr)         LOGARG("%s [0x%x]", #ptr, (TUint)ptr)
 
class CFileLogger : public CBase
{
public:
	IMPORT_C static void Write(const TDesC8& aText);
	IMPORT_C static void Write(const TDesC16& aText);
	IMPORT_C static void Write(TRefByValue<const TDesC8> aFmt,...);
	IMPORT_C static void Close();
 
private:
	CFileLogger();
	~CFileLogger();
	TBool Construct();
	static CFileLogger* Logger();
	void DoWrite();
	TBool GetLogFileNameWithoutExt(TDes& aFileName);
 
private:
	RFs                     iFs;
	RFile                   iFile;
	TBuf8<KMaxLogEntrySize> iLogBuffer;
};
 
#endif	// __FILELOGGER_H__







filelogger.cpp

#include "filelogger.h"
 
#include <bautils.H>
#include <pathinfo.h>
 
_LIT(KLogFolder, "logs\\");
_LIT(KLogFileExt, ".log");
_LIT(KOldFileExt, ".old");
 
const TUint8 KBackSlash = '\\';
_LIT8(KLineEnd, "\r\n");
 
const TInt KTimeRecordSize = 20;
 
_LIT8(KTimeFormat,"%04d-%02d-%02d %02d:%02d:%02d ");
_LIT8(KLogStart, "--== New %S log ==--\r\n");
 
_LIT(KSquareBracket, "[");
 
CFileLogger::CFileLogger()
{
}
 
TBool CFileLogger::Construct()
{
	TInt err = iFs.Connect();
	if (!err)
	{
		TFileName logFileName;
		err = !GetLogFileNameWithoutExt(logFileName);
		if(!err)
		{
			TFileName oldLogFileName(logFileName);
			oldLogFileName.Append(KOldFileExt);
			iFs.Delete(oldLogFileName);
			logFileName.Append(KLogFileExt);
			iFs.Rename(logFileName, oldLogFileName);
			err = iFile.Create(iFs, logFileName, EFileShareAny | EFileWrite);
			if(!err)
			{
				TInt pos(0);
				iFile.Seek(ESeekEnd, pos);
				TBuf8<KMaxFullName> appName;
				appName.Copy(BaflUtils::ExtractAppNameFromFullName(RThread().FullName()));
				iLogBuffer.AppendFormat(KLogStart, &appName);
				err = iFile.Write(iLogBuffer);
			}
		}
	}
	return (!err);
}
 
CFileLogger* CFileLogger::Logger()
{
	CFileLogger* logger = (CFileLogger*)Dll::Tls();
	if (!logger)
	{
		logger = new CFileLogger;
		if (logger)
		{
			if (logger->Construct())
			{
				Dll::SetTls(logger);
			}
			else
			{
				delete logger;
				logger = NULL;
			}
		}
	}
	return logger;
}
 
EXPORT_C void CFileLogger::Close()
{
	delete (CFileLogger*)Dll::Tls();
	Dll::FreeTls();
}
 
CFileLogger::~CFileLogger()
{
	iFile.Close();
	iFs.Close();
}
 
TBool CFileLogger::GetLogFileNameWithoutExt(TDes& aFileName)
{
 
#ifndef _DEBUG
// Phone target
// You must create this folder for the logfile to be written:
// E:\Logs
	aFileName.Copy(PathInfo::MemoryCardRootPath());
#else
// Emulator target
// You must create this folder for the logfile to be written:
// C:\Symbian\9.1\S60_3rd_MR_2\Epoc32\winscw\c\Logs
	TChar drive;
	iFs.DriveToChar(EDriveC, drive);
	aFileName.Append(drive);
	const TUint8 KColon = ':';
	aFileName.Append(KColon);
	aFileName.Append(KBackSlash);
#endif
	aFileName.Append(KLogFolder);
	TBool res = BaflUtils::FolderExists(iFs, aFileName);
	if (!res)
	{
		aFileName.Zero();
 
	}
        else	
       {
		TPtrC fileName(BaflUtils::ExtractAppNameFromFullName(RThread().FullName()));
// The following code will search for a subfolder 
// with the name of your process. 
// If you want to use this subfolder,
// you must create it manually or the logfile will not be written.
	/*     TPtrC procName(RProcess().FullName());
		TPtrC folderName(TParsePtrC(procName.Left(procName.Find(KSquareBracket))).Name());
		aFileName.Append(folderName);
		aFileName.Append(KBackSlash);
        */
		aFileName.Append(fileName);
	}
	return res;
}
 
EXPORT_C void CFileLogger::Write(const TDesC8& aText)
{
	CFileLogger* logger = Logger();
	if(logger)
	{
		logger->iLogBuffer.Copy(aText);
		logger->DoWrite();
	}
}
 
EXPORT_C void CFileLogger::Write(const TDesC16& aText)
{
	CFileLogger* logger = Logger();
	if(logger)
	{
		logger->iLogBuffer.Copy(aText);
		logger->DoWrite();
	}
}
 
EXPORT_C void CFileLogger::Write(TRefByValue<const TDesC8> aFmt,...)
{
	CFileLogger* logger = Logger();
	if (logger)
	{
		VA_LIST list;
		VA_START(list, aFmt);
		logger->iLogBuffer.FormatList(aFmt, list);
		logger->DoWrite();
		VA_END(list);
	}
}
 
void CFileLogger::DoWrite()
{
	if(iFile.SubSessionHandle())
	{
		TTime time;
		time.HomeTime();
		TDateTime dateTime;
		dateTime = time.DateTime();
		TBuf8<KTimeRecordSize> timeRecord;
		timeRecord.Format(KTimeFormat, dateTime.Year(), dateTime.Month()+1, dateTime.Day()+1, dateTime.Hour(), dateTime.Minute(), dateTime.Second());
		iLogBuffer.Insert(0, timeRecord);
		iLogBuffer.Append(KLineEnd);
		iFile.Write(iLogBuffer);
#ifdef _DEBUG
		iFile.Flush();
#endif // _DEBUG
	}
}







MMP file

You should link against the following libs:

LIBRARY       euser.lib
LIBRARY       efsrv.lib
LIBRARY       PlatformEnv.lib
LIBRARY       bafl.lib







Sample usage

// a simple log entry
LOGTXT("log entry");
 
// log entry with 3 params
LOGARG("params: %d, %u, %S", aTIntParam, aTUintParam, &aTDesC8Param);
 
// log an error. The log entry is written only if err != KErrNone
LOGERR("error : %d", err);
 
LOGDES8(aDes8); // log an 8-bit descriptor
 
LOGDES16(aDes16); // log an 16-bit descriptor
 
// write a log entry before the call, call the function
// and write an entry after it
LOGCALL(User::LeaveIfError(iFs.Connect()));
 
// Log memory address.
// The following line will produce an entry like "iMyPointer [0x1e1f4470]"
LOGMEM(iMyPointer);
 
// Write log entries when you enter a function
// and when you return from it.
// The following example writes to log the following:
// 2007-08-29 06:02:04 CMyClass::Foo(int) start
// 2007-08-29 06:02:04 CMyClass::Foo(int) end
TBool CMyClass::Foo(TInt aArg)
{
	LOGENTER;
	//...
	LOGEXIT;
	return ETrue;
}
 
// closes the log. Should be called before the program exits
LOGCLOSE;
Related Discussions
Thread Thread Starter Forum Replies Last Post
File was not found sanjayks84 General Symbian C++ 15 2008-04-29 10:31
file opening sarayu General Symbian C++ 3 2007-05-04 13:37
Asking for building a .aif file hillstar50 General Symbian C++ 5 2005-04-09 15:51
ACK not sent sowgandhikaramakrishna VoIP 0 2008-05-20 07:54
File management in Nokia 9500 laouali Mobile Java General 0 2005-02-15 12:57
 
Powered by MediaWiki
     
     RDF Facets:
     
     
     qfnZtypeQUqfnTypeZCommunityContentQ
     qfnZtypeQUqfnTypeZWebpageQ
     qfnZtypeQUqfnTypeZWikiContentQ
     qmarsZlanguageQUxhttpE3aE2fE2fswE2enokiaE2ecomE2flanguageE2d1E2fenX