关于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 + ;
}
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的更多相关文章
- ABP源码分析八:Logger集成
ABP使用Castle日志记录工具,并且可以使用不同的日志类库,比如:Log4Net, NLog, Serilog... 等等.对于所有的日志类库,Castle提供了一个通用的接口来实现,我们可以很方 ...
- org.apache.log4j.Logger详解
org.apache.log4j.Logger 详解 1. 概述 1.1. 背景 在应用程序中添加日志记录总的来说基于三个目的 :监视代码中变量的变化情况,周期性的记录到文件中供其他应用进行统计分析工 ...
- Java程序日志:java.util.logging.Logger类
一.Logger 的级别 比log4j的级别详细,全部定义在java.util.logging.Level里面.各级别按降序排列如下:SEVERE(最高值)WARNINGINFOCONFIGFINEF ...
- [LeetCode] Logger Rate Limiter 记录速率限制器
Design a logger system that receive stream of messages along with its timestamps, each message shoul ...
- .Net Core Logger 实现log写入本地文件系统
.net core 自带一个基础的logger框架Microsoft.Extensions.Logging. 微软默认实现了Microsoft.Extensions.Logging.Console.d ...
- Android源码——Logger日志系统
Android的Logger日志系统是基于内核中的Logger日志驱动程序实现的. 日志保存在内核空间中 缓冲区保存日志 分类方法:日志的类型 + 日志的输出量 日志类型: main ...
- java.lang.NoClassDefFoundError: Lorg/slf4j/Logger;
如果你出现类似如下错误 1. Install tomcat7 in my home directory and set up `CATALINA_HOME` environment variable ...
- LeetCode 359 Logger Rate Limiter
Problem: Design a logger system that receive stream of messages along with its timestamps, each mess ...
- 你的日志组件记录够清晰嘛?--自己开发日志组件 Logger
现在现成的日志组件实在是太多太多,为什么我还需要自己实现呢????? 需求来源于java的log4j, [07-31 16:40:00:557:WARN : com.game.engine.threa ...
- log4j2 不使用配置文件,动态生成logger对象
大家平时使用Log4j一般都是在classpath下放置一个log4j的配置文件,比如log4j.xml,里面配置好Appenders和Loggers,但是前一阵想做某需求的时候,想要的效果是每一个任 ...
随机推荐
- 摘之知乎网友...PHYTIN学习
作者:东瓜王链接:https://www.zhihu.com/question/19593179/answer/23746083来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...
- 2015.4.25利用UIAutomation 替代API函数,解决了ListView无法读数据的难题,顺便实现了鼠标模拟滚轮
UIAutomation比API的优点是类似于消息处理机制,而不是主要靠模拟鼠标键盘发送消息 首先添加引用UIAutomationClient和UIAutomationTypes,在安装.net3.5 ...
- 问题:oracle 字符串转换成日期;结果:[oracle] to_date() 与 to_char() 日期和字符串转换
to_date("要转换的字符串","转换的格式") 两个参数的格式必须匹配,否则会报错. 即按照第二个参数的格式解释第一个参数. to_char(日期,& ...
- C语言学习笔记--#error 、 #line 和 #pragma 的使用
1. #error 的用法 (1)#error 是一种预编译器指示字,用于生成一个编译错误消息 (2)用法:#error message //注意:message 不需要用双引号包围 (3)#erro ...
- Http 与Https
一个Http请求 DNS域名解析 --> 发起TCP的三次握手 --> 建立TCP连接后发起http请求 --> 服务器响应http请求,浏览器得到html代码 --> 浏览器 ...
- JS继承方式详解
js继承的概念 js里常用的如下两种继承方式: 原型链继承(对象间的继承) 类式继承(构造函数间的继承) 由于js不像java那样是真正面向对象的语言,js是基于对象的,它没有类的概念.所以,要想实现 ...
- Quartz_1_简单编程式任务调度使用(SimpleTrigger)
最近在工作中,要做定时任务的更能,最开始的时候,想到的是 JavaSE 中,自带 Timer 及 TimerTask 联合使用,完成定时任务.最后发现,随着业务的复杂,JDK 中的 Timer 和 T ...
- 去除Activity上面的标题边框
实现方法:1.在代码中实现:在此方法setContentView(R.layout.main)之前加入:requestWindowFeature(Window.FEATURE_NO_TITLE);标题 ...
- 使用myeclipse自动导入hibernate3的jar包,如何关联hibernate源码的解决办法
1.在网上找了好久,今天终于解决了,如果你的myeclipse自动生成的添加hibernate3jar包时,依靠通常的方法是无法关联其相应版本的源代码的,就是你在编写代码是,按住ctrl + hibe ...
- Codeforces 1077E (二分乱搞或者dp)
题意:给你一个数组,可以从中选区若干种元素,但每种元素选区的个数前一种必须是后一种的2倍,选区的任意2种元素不能相同,问可以选取最多的元素个数是多少? 思路1(乱搞):记录一下每种元素的个数,然后暴力 ...