实现一个简单的Log框架
实际上算不上框架,只是自己对日志框架的一点理解。
核心接口:Logger,供调用者完成不同等级的日志输出
package com.lichmama.log.service; public interface Logger
{
public void debug(String msg); public void debug(String format, Object... args); public void info(String msg); public void info(String format, Object... args); public void warn(String msg); public void warn(String format, Object... args); public void error(String msg); public void error(String format, Object... args); public void fatal(String msg); public void fatal(String format, Object... args);
}
核心接口:LogWriter,内部使用,完成日志输出到文件或控制台的过程
package com.lichmama.log.service; public interface LogWriter
{
public void log(String log);
}
核心接口:LoggerBuilder,日志实例的生成器,提供对不同类型的日志实例的生成接口
package com.lichmama.log.service; public interface LoggerBuilder
{
//运行时日志
public Logger getRunLogger(Class<?> T); //命令行日志
public Logger getConLogger(Class<?> T);
}
日志类型枚举:LogType
package com.lichmama.log.service; public enum LogType
{
RUNTIME, CONSOLE
}
接口实现类:LogWriterImpl,具体实现日志输出行为
package com.lichmama.log.service.impl; import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer; import com.lichmama.log.service.LogType;
import com.lichmama.log.service.LogWriter; public class LogWriterImpl implements LogWriter
{
private Writer logWriter; public LogWriterImpl(LogType logType)
{
try
{
switch (logType)
{
case RUNTIME:
logWriter = new OutputStreamWriter(new FileOutputStream("D:\\log\\test\\runtime.log", true));
break;
case CONSOLE:
logWriter = new OutputStreamWriter(System.out);
break;
}
}
catch (Exception e)
{
e.printStackTrace();
} } @Override
public void log(String log)
{
try
{
logWriter.write(log);
logWriter.flush();
}
catch (IOException e)
{
e.printStackTrace();
}
} }
接口实现类:LoggerFactory,日志工厂类,用来生成不同类型的日志示例
package com.lichmama.log.service.impl; import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map; import com.lichmama.log.service.LogType;
import com.lichmama.log.service.LogWriter;
import com.lichmama.log.service.Logger;
import com.lichmama.log.service.LoggerBuilder; public class LoggerFactory implements LoggerBuilder
{
private LoggerFactory(){} private static class SingletonHolder
{
private static final LoggerFactory instance = new LoggerFactory();
} public static final LoggerFactory getInstance()
{
return SingletonHolder.instance;
} private static ThreadLocal<Map<String, Logger>> loggers = new ThreadLocal<Map<String, Logger>>() {
@Override
public Map<String, Logger> initialValue()
{
return new HashMap<String, Logger>();
}
}; @Override
public Logger getRunLogger(Class<?> T)
{
return getLogger(T, LogType.RUNTIME);
} @Override
public Logger getConLogger(Class<?> T)
{
return getLogger(T, LogType.CONSOLE);
} private Logger getLogger(Class<?> T, LogType logType)
{
String tagName = T.getName() + "@" + logType;
Logger logger = loggers.get().get(tagName);
if (logger == null)
{
logger = new LoggerInstance(T.getName(), new LogWriterImpl(logType));
loggers.get().put(tagName, logger);
}
return logger;
} private class LoggerInstance implements Logger
{
private LogWriter logWriter;
private String module;
private SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); public LoggerInstance(String module, LogWriter logWriter)
{
this.module = module;
this.logWriter = logWriter;
} @Override
public void debug(String msg)
{
log(msg, "DEBUG");
} @Override
public void info(String msg)
{
log(msg, "INFO");
} @Override
public void warn(String msg)
{
log(msg, "WARN");
} @Override
public void error(String msg)
{
log(msg, "ERROR");
} @Override
public void fatal(String msg)
{
log(msg, "FATAL");
} private void log(String msg, String logLevel)
{
String logText = String.format("%s-[%s] [%s] %s\r\n", sdf.format(new Date()), module, logLevel, msg);
logWriter.log(logText);
} @Override
public void debug(String format, Object... args)
{
String logText = String.format(format, args);
debug(logText);
} @Override
public void info(String format, Object... args)
{
String logText = String.format(format, args);
info(logText);
} @Override
public void warn(String format, Object... args)
{
String logText = String.format(format, args);
warn(logText);
} @Override
public void error(String format, Object... args)
{
String logText = String.format(format, args);
error(logText);
} @Override
public void fatal(String format, Object... args)
{
String logText = String.format(format, args);
fatal(logText);
}
}
}
使用:
public class Test
{
public static void main(String[] args)
{
Logger logger = LoggerFactory.getInstance().getConLogger(Test.class);
logger.warn("winter is coming");
logger.debug("%s said, 'valar morghulis'", "Jaqen H'ghar");
logger.info("%s answered: %s", "Arya", "Valar Dohaeris");
}
}
####################################################################################
CONSOLE OUTPUT:
####################################################################################
20160728171925-[com.lichmama.log.service.test.Test] [WARN] winter is coming
20160728171925-[com.lichmama.log.service.test.Test] [DEBUG] Jaqen H'ghar said, 'valar morghulis'
20160728171925-[com.lichmama.log.service.test.Test] [INFO] Arya answered: Valar Dohaeris
实现一个简单的Log框架的更多相关文章
- koa2源码解读及实现一个简单的koa2框架
阅读目录 一:封装node http server. 创建koa类构造函数. 二:构造request.response.及 context 对象. 三:中间件机制的实现. 四:错误捕获和错误处理. k ...
- 如何实现一个简单的MVVM框架
接触过web开发的同学想必都接触过MVVM,业界著名的MVVM框架就有AngelaJS.今天闲来无事,决定自己实现一个简单的MVVM框架玩一玩.所谓简单,就是仅仅实现一个骨架,仅表其意,不摹其形. 分 ...
- 徒手撸一个简单的RPC框架
来源:https://juejin.im/post/5c4481a4f265da613438aec3 之前在牛逼哄哄的 RPC 框架,底层到底什么原理得知了RPC(远程过程调用)简单来说就是调用远程的 ...
- VC++ 一个简单的Log类
在软件开发中,为程序建立Log日志是很必要的,它可以记录程序运行的状态以及出错信息,方便维护和调试. 下面实现了一个简单的Log类,使用非常简单,仅供参考. // CLogHelper.h : hea ...
- 用Python写一个简单的Web框架
一.概述 二.从demo_app开始 三.WSGI中的application 四.区分URL 五.重构 1.正则匹配URL 2.DRY 3.抽象出框架 六.参考 一.概述 在Python中,WSGI( ...
- 一个简单的web框架实现
一个简单的web框架实现 #!/usr/bin/env python # -- coding: utf-8 -- __author__ = 'EchoRep' from wsgiref.simple_ ...
- 自己实现的一个简单的EF框架(反射实现)
我实现了一个简单的EF框架,主要用于操纵数据库.实现了对数据库的基本操纵--CRUD 这是项目结构 这是一个 core 下的 DLL 写了一个数据库工厂,用于执行sql语句.调用sql语句工厂 写了一 ...
- python+selenium之自定义封装一个简单的Log类
python+selenium之自定义封装一个简单的Log类 一. 问题分析: 我们需要封装一个简单的日志类,主要有以下内容: 1. 生成的日志文件格式是 年月日时分秒.log 2. 生成的xxx.l ...
- Core1.1环境下,自己实现的一个简单的CRUD框架(反射实现)
我实现了一个简单的EF框架,主要用于操纵数据库.实现了对数据库的基本操纵--CRUD 这是项目结构 这是一个 core 下的 DLL 写了一个数据库工厂,用于执行sql语句.调用sql语句工厂 写了一 ...
随机推荐
- 当KDS晶振遇上爱普生晶振国内生产厂家该如何抉择?
当KDS晶振遇上爱普生晶振国内生产厂家该如何抉择? 全球做晶振行业的公司有很多,单说深圳一个城市就有几十上百家正规的晶振厂家,深圳市金洛电子就是其中之一.我们不光代理日本和台湾多家排得上名 ...
- STM32串口控制步进电机(原创)
用的42步进电机: 厂家可能不一样,两项四线步进电机,里面有两个线圈.在电机什么电都没有接的情况下,用万用表测量四个管脚:两两短接(或者阻值很小)的为一组,可以分别接A+,a-剩余接B+,B-;顺序可 ...
- OpenCV探索之路(十六):图像矫正技术深入探讨
刚进入实验室导师就交给我一个任务,就是让我设计算法给图像进行矫正.哎呀,我不太会图像这块啊,不过还是接下来了,硬着头皮开干吧! 那什么是图像的矫正呢?举个例子就好明白了. 我的好朋友小明给我拍了这几张 ...
- [原创]MongoDB综合实例二
MongoDB-Sharding部署方案 一. 部署环境 五台主机: Amongoshard01: 10.212.74.43 Amongoshard02: 10.212.84.4 Among ...
- 初码-Azure系列-文章目录
系统迁移 初码-Azure系列-记一次MySQL数据库向Azure的迁移 初码-Azure系列-迁移PHP应用至Azure的一些实践记录和思考 初码-Azure系列-记一次从阿里云到Azure的迁移和 ...
- C语言数组之冒泡排序+折半查找法(二分查找)
冒泡排序算法 将相邻的元素进行两两比较,大的向后"冒", 小的向前"赶". 口诀: N个数字来排队,两两比较小靠前 外层循环N-1(控制需要比较的轮数). 内层 ...
- 读Zepto源码之操作DOM
这篇依然是跟 dom 相关的方法,侧重点是操作 dom 的方法. 读Zepto源码系列文章已经放到了github上,欢迎star: reading-zepto 源码版本 本文阅读的源码为 zepto1 ...
- shiro不重启动态加载权限
最近一朋友让我帮他做一个后台权限管理的项目.我就在我原来的项目加加改改但是还是不理想,查了不少资料也走了不了弯路...... shiro基本的配置我就不多说了这个很简单自己查查资料就完成----下面是 ...
- (转)Java 读写Properties配置文件
原文:http://www.cnblogs.com/xudong-bupt/p/3758136.html 1.Properties类与Properties配置文件 Properties类继承自Hash ...
- Nim 博弈和 sg 函数
sg 函数 参考 通俗易懂 论文 几类经典的博弈问题 阶梯博弈: 只考虑奇数号楼梯Nim,若偶数楼梯只作容器,那么游戏变为Nim.题目 翻转硬币: 局面的SG值为局面中每个正面朝上的棋子单一存在时的S ...