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 + ;
}
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++版本也不用搞那么复杂了。

关于Logger的更多相关文章

  1. ABP源码分析八:Logger集成

    ABP使用Castle日志记录工具,并且可以使用不同的日志类库,比如:Log4Net, NLog, Serilog... 等等.对于所有的日志类库,Castle提供了一个通用的接口来实现,我们可以很方 ...

  2. org.apache.log4j.Logger详解

    org.apache.log4j.Logger 详解 1. 概述 1.1. 背景 在应用程序中添加日志记录总的来说基于三个目的 :监视代码中变量的变化情况,周期性的记录到文件中供其他应用进行统计分析工 ...

  3. Java程序日志:java.util.logging.Logger类

    一.Logger 的级别 比log4j的级别详细,全部定义在java.util.logging.Level里面.各级别按降序排列如下:SEVERE(最高值)WARNINGINFOCONFIGFINEF ...

  4. [LeetCode] Logger Rate Limiter 记录速率限制器

    Design a logger system that receive stream of messages along with its timestamps, each message shoul ...

  5. .Net Core Logger 实现log写入本地文件系统

    .net core 自带一个基础的logger框架Microsoft.Extensions.Logging. 微软默认实现了Microsoft.Extensions.Logging.Console.d ...

  6. Android源码——Logger日志系统

    Android的Logger日志系统是基于内核中的Logger日志驱动程序实现的. 日志保存在内核空间中 缓冲区保存日志   分类方法:日志的类型  +   日志的输出量   日志类型:   main ...

  7. java.lang.NoClassDefFoundError: Lorg/slf4j/Logger;

    如果你出现类似如下错误 1. Install tomcat7 in my home directory and set up `CATALINA_HOME` environment variable ...

  8. LeetCode 359 Logger Rate Limiter

    Problem: Design a logger system that receive stream of messages along with its timestamps, each mess ...

  9. 你的日志组件记录够清晰嘛?--自己开发日志组件 Logger

    现在现成的日志组件实在是太多太多,为什么我还需要自己实现呢????? 需求来源于java的log4j, [07-31 16:40:00:557:WARN : com.game.engine.threa ...

  10. log4j2 不使用配置文件,动态生成logger对象

    大家平时使用Log4j一般都是在classpath下放置一个log4j的配置文件,比如log4j.xml,里面配置好Appenders和Loggers,但是前一阵想做某需求的时候,想要的效果是每一个任 ...

随机推荐

  1. 摘之知乎网友...PHYTIN学习

    作者:东瓜王链接:https://www.zhihu.com/question/19593179/answer/23746083来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...

  2. 2015.4.25利用UIAutomation 替代API函数,解决了ListView无法读数据的难题,顺便实现了鼠标模拟滚轮

    UIAutomation比API的优点是类似于消息处理机制,而不是主要靠模拟鼠标键盘发送消息 首先添加引用UIAutomationClient和UIAutomationTypes,在安装.net3.5 ...

  3. 问题:oracle 字符串转换成日期;结果:[oracle] to_date() 与 to_char() 日期和字符串转换

    to_date("要转换的字符串","转换的格式")   两个参数的格式必须匹配,否则会报错. 即按照第二个参数的格式解释第一个参数. to_char(日期,& ...

  4. C语言学习笔记--#error 、 #line 和 #pragma 的使用

    1. #error 的用法 (1)#error 是一种预编译器指示字,用于生成一个编译错误消息 (2)用法:#error message //注意:message 不需要用双引号包围 (3)#erro ...

  5. Http 与Https

    一个Http请求 DNS域名解析 --> 发起TCP的三次握手 --> 建立TCP连接后发起http请求 --> 服务器响应http请求,浏览器得到html代码 --> 浏览器 ...

  6. JS继承方式详解

    js继承的概念 js里常用的如下两种继承方式: 原型链继承(对象间的继承) 类式继承(构造函数间的继承) 由于js不像java那样是真正面向对象的语言,js是基于对象的,它没有类的概念.所以,要想实现 ...

  7. Quartz_1_简单编程式任务调度使用(SimpleTrigger)

    最近在工作中,要做定时任务的更能,最开始的时候,想到的是 JavaSE 中,自带 Timer 及 TimerTask 联合使用,完成定时任务.最后发现,随着业务的复杂,JDK 中的 Timer 和 T ...

  8. 去除Activity上面的标题边框

    实现方法:1.在代码中实现:在此方法setContentView(R.layout.main)之前加入:requestWindowFeature(Window.FEATURE_NO_TITLE);标题 ...

  9. 使用myeclipse自动导入hibernate3的jar包,如何关联hibernate源码的解决办法

    1.在网上找了好久,今天终于解决了,如果你的myeclipse自动生成的添加hibernate3jar包时,依靠通常的方法是无法关联其相应版本的源代码的,就是你在编写代码是,按住ctrl + hibe ...

  10. Codeforces 1077E (二分乱搞或者dp)

    题意:给你一个数组,可以从中选区若干种元素,但每种元素选区的个数前一种必须是后一种的2倍,选区的任意2种元素不能相同,问可以选取最多的元素个数是多少? 思路1(乱搞):记录一下每种元素的个数,然后暴力 ...