关于Logger

Logger是我在各类编程语言中使用最多,同时也是改进最多的一个函数,今天在iOS下又折腾了一番,终于找到我想要的一个版本,这里做一个总结。

python版

python对logger有专门的支持,只需要把log格式设置为自己想要的即可:

import logging

......
loggingFormat = '%(asctime)s %(lineno)4d %(levelname)-8s %(message)s'
logging.basicConfig(level=logging.DEBUG, format=loggingFormat, datefmt='%H:%M')

logging.debug('hello word!')

输出:

00:08     1 DEBUG    hello world!

C++版

C++版本中我借鉴了ATL的做法:

#pragma once
// author : palanceli.blog.163.com

#include <windows.h>
#include <atlstr.h>

#include <stdio.h>
#define WIDEN2(x) L ## x
#define WIDEN(x) WIDEN2(x)
#define __WFILE__ WIDEN(__FILE__)
#ifdef  _UNICODE
#define __TFILE__    __WFILE__
#else
#define    __TFILE__    __FILE__
#endif


#ifdef _DEBUG
#define Logging        CLogger(__TFILE__, __LINE__).Log
#else
#define Logging        __noop
#endif

class CLogger
{
public:    

    CLogger(const TCHAR *pszFileName, int nLineNo)
        : m_pszFileName(pszFileName), m_nLineNo(nLineNo)
    {
        const TCHAR* p = _tcsrchr(m_pszFileName, '\\');
        if(p != NULL)
            m_pszFileName = p + 1;
    }
    void __cdecl Log(const WCHAR* pszFmt, ...) const;

private:
    void __cdecl FormatLog(va_list& ptr, LPCTSTR pszFmt, LPCTSTR szType, ATL::CString& strMsg) const;

    void __cdecl DoLog(ATL::CString& strMsg) const;

    CLogger &__cdecl operator=(const CLogger &right);

    const TCHAR* m_pszFileName;
    const int m_nLineNo;
};

void __cdecl CLogger::Log(const WCHAR *pszFmt, ...) const
{
    va_list ptr; va_start(ptr, pszFmt);
    ATL::CString strMsg;
    FormatLog(ptr, pszFmt, _T("LOG"), strMsg);
    va_end(ptr);
    
    DoLog(strMsg);
}

void __cdecl CLogger::FormatLog(va_list& ptr, LPCTSTR pszFmt, LPCTSTR szType, ATL::CString& strMsg) const
{
    ATL::CString strFileNameAndLine, strTemp2;
    strTemp2.FormatV(pszFmt, ptr);
    strFileNameAndLine.Format(_T("%s:%d"), m_pszFileName, m_nLineNo);
    strMsg.Format(_T("%-16s %3s %s\n"), strFileNameAndLine, szType, strTemp2);
}

void __cdecl CLogger::DoLog(ATL::CString& strMsg) const
{
    OutputDebugStringW(strMsg);
}

使用的时候,只需要

Logging(_T("Hello %s!"), _T("word"));

 

objective-c版本

经历一番折腾之后,找到最精简的方式,只需要在预编译头文件中添加这么一个宏定义,即可更改NSLog的输出格式:

#if DEBUG
#define NSLog(FORMAT, ...) fprintf(stderr,"[%s:%d]\t%s\n",[[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__, [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String])
#else
#define NSLog(FORMAT, ...) nil
#endif

代码

NSLog(@"Hello %@!", @"word");

输出为:

[main.m:15] Hello word!

需要补充说明一点,xcode添加预编译头文件的步骤:

1、需要添加文件,类型选择Other - PCH File

2、在PROJECT和TARGET的Build Settings - Apple LLVM 7.0 - Language - Precompile Prefix Header 选择Yes;Prefix Header 添加$(SRCROOT)/<pch文件名>

 

由于之前不知道宏定义中的##__VA_ARGS__的写法,使用这种方式,前面的C++版本也不用搞那么复杂了。

 

posted @ 2015-10-03 00:26 palance 阅读(...) 评论(...) 编辑 收藏