实际上算不上框架,只是自己对日志框架的一点理解。

核心接口: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框架的更多相关文章

  1. koa2源码解读及实现一个简单的koa2框架

    阅读目录 一:封装node http server. 创建koa类构造函数. 二:构造request.response.及 context 对象. 三:中间件机制的实现. 四:错误捕获和错误处理. k ...

  2. 如何实现一个简单的MVVM框架

    接触过web开发的同学想必都接触过MVVM,业界著名的MVVM框架就有AngelaJS.今天闲来无事,决定自己实现一个简单的MVVM框架玩一玩.所谓简单,就是仅仅实现一个骨架,仅表其意,不摹其形. 分 ...

  3. 徒手撸一个简单的RPC框架

    来源:https://juejin.im/post/5c4481a4f265da613438aec3 之前在牛逼哄哄的 RPC 框架,底层到底什么原理得知了RPC(远程过程调用)简单来说就是调用远程的 ...

  4. VC++ 一个简单的Log类

    在软件开发中,为程序建立Log日志是很必要的,它可以记录程序运行的状态以及出错信息,方便维护和调试. 下面实现了一个简单的Log类,使用非常简单,仅供参考. // CLogHelper.h : hea ...

  5. 用Python写一个简单的Web框架

    一.概述 二.从demo_app开始 三.WSGI中的application 四.区分URL 五.重构 1.正则匹配URL 2.DRY 3.抽象出框架 六.参考 一.概述 在Python中,WSGI( ...

  6. 一个简单的web框架实现

    一个简单的web框架实现 #!/usr/bin/env python # -- coding: utf-8 -- __author__ = 'EchoRep' from wsgiref.simple_ ...

  7. 自己实现的一个简单的EF框架(反射实现)

    我实现了一个简单的EF框架,主要用于操纵数据库.实现了对数据库的基本操纵--CRUD 这是项目结构 这是一个 core 下的 DLL 写了一个数据库工厂,用于执行sql语句.调用sql语句工厂 写了一 ...

  8. python+selenium之自定义封装一个简单的Log类

    python+selenium之自定义封装一个简单的Log类 一. 问题分析: 我们需要封装一个简单的日志类,主要有以下内容: 1. 生成的日志文件格式是 年月日时分秒.log 2. 生成的xxx.l ...

  9. Core1.1环境下,自己实现的一个简单的CRUD框架(反射实现)

    我实现了一个简单的EF框架,主要用于操纵数据库.实现了对数据库的基本操纵--CRUD 这是项目结构 这是一个 core 下的 DLL 写了一个数据库工厂,用于执行sql语句.调用sql语句工厂 写了一 ...

随机推荐

  1. (one) 条件判断的总结

    第一:if语句的一般形式: if(expression)   statement1; statement2; 对于条件判断,我觉得要点在于“条件”(expression),它是一个结果为false或t ...

  2. 《Android进阶》之第六篇 Fragment 的使用2

    最近通过学习,对fragment的使用有了新的认识. 一开始接触android的时候,很是受不了这个fragment,总感觉它把一个简单的事情搞复杂啦,所以每次新建工程的时候总是固执的选择empty ...

  3. 《安卓网络编程》之第六篇 Android中的WIFI和蓝牙

    关于WIFI就不多介绍啦,直接来个段子吧. 问:“WiFi对人体有伤害么?” 答:“不清楚,反正没有WiFi我就浑身不舒服. 比较重要的一点就是WifiManager  wm=(WifiManager ...

  4. (高级篇 Netty多协议开发和应用)第十章-Http协议开发应用(基于Netty的HttpServer和HttpClient的简单实现)

    1.HttpServer package nettyHttpTest; import io.netty.bootstrap.ServerBootstrap; import io.netty.chann ...

  5. axis2 和 xfire 接口调用问题排查

    背景: 1个运营商厂家开发人员离职,我们为了上线对接接口,迁就对方客户端调用.对方客户端框架用的是xfire.调用方式基本为:   Service serviceModel = new ObjectS ...

  6. [c++]大数运算1---利用C++ string实现任意长度正小数、整数之间的加减法

    一.概述 本文属于大大维原创,未经笔者本人允许,严禁转载!!! C/C++中的int类型能表示的范围是-2E31-2E31–1.unsigned类型能表示的范围是0-2E32–1,即 0-429496 ...

  7. Android WebView 不支持 H5 input type="file" 解决方法

    最近因为赶项目进度,因此将本来要用原生控件实现的界面,自己做了H5并嵌入webview中.发现点击H5中 标签 不能打开android资源管理器. 通过网络搜索发现是因为 android webvie ...

  8. Java IO流之【缓冲流和文件流复制文件对比】

    与文件流相比,缓冲流复制文件更快 代码: package Homework; import java.io.BufferedOutputStream; import java.io.File; imp ...

  9. hdu 5975---Aninteresting game(树状数组)

    题目链接 Problem Description Let’s play a game.We add numbers 1,2...n in increasing order from 1 and put ...

  10. Coursera 机器学习笔记(七)

    主要为第九周内容:异常检测.推荐系统 (一)异常检测(DENSITY ESTIMATION) 核密度估计(kernel density estimation)是在概率论中用来估计未知的密度函数,属于非 ...