log4j想必大家都很熟了,它是apache组织旗下的一个开源项目,用于记录程序运行时的一些信息,这些信息有助于我们分析程序的性能找出bug。log4j共有六个级别,按级别升序排序分别是
TRACK 记录比debug级别还要详细的信息(finer-grained 细颗粒度) DEBUG 记录程序运行时一些有用的信息,用来分析程序的性能,发现bug(finer-grained 细颗粒度) INFO 记录程序运行时正常输出的提示信息(coarse-grained 粗颗粒度) WARN 指明程序运行状态处在欠佳状态,可能会出现异常情况。 ERROR 指明程序发生了错误,但还可以允许程序继续运行。 FATAL 指明程序发生了非常重大的错误,并引导程序停止运行。
一般情况下这几个级别已经够用,但在一些情况下并不能满足我们的要求,例如在我开发的自动跟踪定位程序中,要每间隔10秒针钟查询一次数据库,取出当前时间需要定位的终端然后发起定位,每定一次位需要从账户中扣除一定的费用,如果费用被扣完,则要向客服及市场部发送提醒邮件,提醒xxx企业已经欠费,请联系该企业及时充值。这实现这样的功能,这几个级别显然不能满足我们的要求的,所以要自定义一个级别,专门用来发送提醒邮件的
1、自定义级别类
package com.tdt.log4j.extend;
import org.apache.log4j.Level;
/**
* @project MRMAutoloc
* @author sunnylocus
* @vresion 1.0 2009-7-22
* @description 自定义级别REMIND,该级别用来发送提醒邮件,级别要比INFO低
*/
public class TDTLevel extends Level {
private static final long serialVersionUID = 7288304330257085144L;
static public final int REMIND_INT = Level.INFO_INT - 1;
static public final int LETHAL_INT = Level.FATAL_INT + 1;
private static String REMIND_STR = "REMIND";
private static String LETHAL_STR = "LETHAL";
public static final TDTLevel REMIND = new TDTLevel(REMIND_INT, REMIND_STR,7);
public static final TDTLevel LETHAL = new TDTLevel(LETHAL_INT, LETHAL_STR,0);
protected TDTLevel(int level, String strLevel, int syslogEquiv) {
super(level, strLevel, syslogEquiv);
}
/**
* Convert the string passed as argument to a level. If the conversion
* fails, then this method returns {@link #REMIND}.
*/
public static Level toLevel(String sArg) {
return (Level) toLevel(sArg, TDTLevel.REMIND);
}
public static Level toLevel(String sArg, Level defaultValue) {
if (sArg == null) {
return defaultValue;
}
String stringVal = sArg.toUpperCase();
if (stringVal.equals(REMIND_STR)) {
return TDTLevel.REMIND;
} else if (stringVal.equals(LETHAL_STR)) {
return TDTLevel.LETHAL;
}
return Level.toLevel(sArg, (Level) defaultValue);
}
public static Level toLevel(int i) throws IllegalArgumentException {
switch (i) {
case REMIND_INT:
return TDTLevel.REMIND;
case LETHAL_INT:
return TDTLevel.LETHAL;
}
return Level.toLevel(i);
}
}
写好自定义级别,还要作邮件发送策略的处理
2、邮件发送处理类
package com.tdt.log4j.extend;
import org.apache.log4j.Logger;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.TriggeringEventEvaluator;
import com.tdt.util.DateUtil;
public final class MockTriggeringEventEvaluator {
//处理程序出错邮件提醒
public final static class ErrorMockTriggeringEventEvaluator implements TriggeringEventEvaluator{
private static boolean isSended = false;//是否已发送邮件
private static String senedTime ="";//发送时间
@Override
public boolean isTriggeringEvent(LoggingEvent arg0) {
if(!isSended) {
isSended = true;////标记邮件已发送
senedTime = DateUtil.currentTime();
Logger.getLogger(getClass()).info("已发送程序出错提醒邮件!");
return true;
}
String currentTime = DateUtil.currentTime();
if(DateUtil.calculateTimeoutByMinute(senedTime, currentTime) > 10) { //距上次发送邮件已超过10分名钟,再次发送邮件
return true;
}
return false;
}
}
//处理企业欠费邮件提醒
public final static class RemindMockTriggeringEventEvaluator implements TriggeringEventEvaluator{
public boolean isTriggeringEvent(LoggingEvent arg0) {
Logger.getLogger(getClass()).info("已发送企业欠费提醒邮件!");
return true; //欠费邮件不作处理,直接发送
}
}
}
3、日期工具类
package com.tdt.util;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
/**
* @project MRMAutoloc
* @author sunnylocus
* @vresion 1.0 2009-7-13
* @description 日期工具类,提供日期的加减及比较
*/
public class DateUtil {
/**
*@return String 当前时间(格式yyyyMMddHHmmss)
*/
public static String currentTime(){
SimpleDateFormat formate = new SimpleDateFormat("yyyyMMddHHmmss");
Calendar calendar = Calendar.getInstance();
return formate.format(calendar.getTime());
}
/**
* 计算两个时间之间相差多少分钟
* @param pretiem 之前的时间 (格式:yyyyMMddHHmmss)
* @param currentTime 现在的时间 (格式:yyyyMMddHHmmss)
* @return int 相差多少分钟
*/
public static int calculateTimeoutByMinute(String pretiem,String currentTime) {
try {
//设置时间
SimpleDateFormat formate = new SimpleDateFormat("yyyyMMddHHmmss");
Calendar calendar = Calendar.getInstance();
calendar.setTime(formate.parse(pretiem));
int pre =calendar.get(Calendar.MINUTE);
calendar.setTime(formate.parse(currentTime));
int curr = calendar.get(Calendar.MINUTE);
return (curr - pre);
} catch (ParseException e) {
throw new IllegalArgumentException(e);
}
}
}
测试
package com.tdt.test;
import org.apache.log4j.Logger;
import com.tdt.log4j.extend.TDTLevel;
public class TestSendMail {
static Logger log = Logger.getLogger(TestSendMail.class);
public static void main(String[] args) {
log.log(TDTLevel.REMIND, "测试,xxx,企业欠费,该企业所属终端的定位请求将被过滤");
log.error("测试,程序运行发生了一个错误");
log.error("测试,程序运行发生了一个错误");
}
}
log4j.xml
然后在log4j.xml配置我们自定义的级别。大家最好用xml配置log4j的参数,因为properties的方式已经过时,log4j不推荐使用。
收到两封邮件
对错误邮件的发送,间隔控制在10分钟,如果不作控制一旦程序(多线程情况下)出错,每个线程会发送相同内容的邮件,会把你的信箱填满。
对邮件正文出现乱码解决的方案
将org.apache.log4j.Layout类
public String getContentType() {
return "text/plain";
}
改为
public String getContentType() {
return "text/plain;charset=UTF-8";
}
然后重新编译,将编译后的类替换原来的class文件
本文来自: ★JAVA开发者 - 原创博文★ http://www.5lone.com 详细出处参考:http://www.hezubbs.cn/html/java/200907/kuozhanLog4jjibie-shixianyoujiantixing-_8339.html
分享到:
相关推荐
这是一个用Python编写的日历拼图求解程序,主要用来解决以下问题:给定8块不规则形状的拼图,在一个7x7的网格中拼出所有可能的日期组合。程序需要确保每次拼图都恰好留出两个空格,分别代表月份(1-12)和日期(1-31,根据月份不同天数不同)。 程序的核心算法采用深度优先搜索(DFS),通过不断尝试不同的拼图放置位置、旋转角度和翻转方式来寻找所有可能的解。为了提高运行效率,程序使用了多进程并行计算,同时利用NumPy进行矩阵运算,大大提升了计算速度。 此外,程序还包含了一些实用的功能,比如解的查重、结果保存、进度日志等。它不仅能找出所有可能的日期组合,还会将结果以易读的格式保存到文件中。对于想要研究组合优化问题或者对拼图游戏感兴趣的同学来说,这是一个不错的参考示例。
库存报表1113
法律事务_
百分点:2024年4月食品餐饮行业舆情分析报告.pdf
进程间通信.pptx
ISO协议和SAE协议对应关系.docx
基于uniapp校园帮外卖跑腿快递代拿平台设计【可发布到小程序和HTML5】毕业源码案例设计Uniapp_Campus_Help_Delivery基于uniapp校园帮外卖跑腿快递代拿平台设计【可发布到小程序和HTML5】毕业源码案例设计开发软件 Eclipse或者Idea + HbuilderX + Mysql + Redis开发技术uni-app 是一个使用vue的语法+微信小程序的标签和API的跨平台接口框架,开发者编写一套代码,可编译到iOS、Android、H5、小程序等多个平台,几乎覆盖所有流量端端接口符合java语言的Springboot技术开发后台登录地址http://localhost:8888/gp/login管理员账号密码 admin/123456用户账号密码ys4/123456骑手账号密码pt4/123456功能介绍系统共有3个身份用户、跑腿员和管理员,其中用户和跑腿员在移动端实现,管理员在web端登录管理,在移动端可以注册成为用户或者跑腿人员。用户登录后可以发布订单的订单,订单分类有很多外卖订单、购物订单、快递订单
测绘工程_
配电网自动化技术—配电网馈线监控终端.pptx
内容概要:本文探讨了通过微调预训练语言模型(LMs)来构建更好的语言智能体的方法。研究提出了一个新的方法——FireAct,它利用从多个任务和提示方法生成的任务解决轨迹数据对小型模型进行微调,提高了模型在自然问答任务中的表现、鲁棒性和泛化能力。实验表明,通过这种多元化的学习支持,语言智能体能够更好地应对噪声环境、跨任务泛化,并提高效率和性能。 适合人群:对语言模型微调及应用感兴趣的学术研究人员和工程技术人员。 使用场景及目标:本文的研究旨在推动语言智能体的发展,特别是提升它们在多任务场景下的推理能力和行动效果。主要应用场景包括基于文本的知识检索、复杂问题解答和工具交互等。 其他说明:作者详细展示了不同数据规模、提示方式以及模型大小对微调效果的影响,为未来进一步探索提供了有益的指导。同时,文章强调了多方法和多任务混合微调的重要性和潜力,为进一步优化语言智能体指明了方向。
教学教务系统原型设计
wygdove 本科毕业设计一个集成医疗传感器,室内传感器,及调用外部环境数据的综合平台。主要对应一个人的身体健康检测,人的周围环境,以及外界大环境,以人为主体的智能医疗系统。
非常好的python学习资料包含笔记+源代码+教程100%好用.zip
洗衣店全球市场报告:2023年洗衣机零售额高达934亿元,潜力无限 在快节奏的现代生活中,衣物清洁与保养成为了人们日常不可或缺的需求之一。洗衣店,作为这一需求的直接响应者,正悄然经历着一场前所未有的变革。在这片充满机遇的海域中,如何精准把握市场脉搏,有效利用技术创新提升服务品质,成为了众多洗衣店企业亟需解答的关键问题。本文将深入探讨洗衣店市场的现状、趋势及咨询服务的重要性,为您揭示这片蓝海的无限潜力。 市场概况 近年来,洗衣店市场展现出强劲的增长势头。据QYR最新调研,2023年洗衣机全渠道零售量达到4005万台,零售额高达934亿元,这一数据不仅反映了家庭洗涤需求的持续扩大,也间接映射出洗衣店作为专业洗涤服务提供商的市场潜力。随着生活水平的提高和消费观念的转变,消费者对衣物清洁的品质要求日益提升,传统的家庭洗涤方式已难以满足高端面料和特殊衣物的保养需求,这为洗衣店行业提供了广阔的发展空间。预计未来几年,受智能洗涤设备、自助洗衣柜、线上预约平台等新兴业务模式的推动,洗衣店市场将保持年均10%以上的增长率,市场规模持续扩大。 技术创新与趋势 技术创新是推动洗衣店行业转型升级的核心动力。智
3690-机械设计制造及其自动化
DCP-7090/7095D/7190DN/7195DW DCP-B7500D/B7520DW/B7530DN/B7535DW DCP-L2510D/L2511D/L2512D/L2530DW DCP-L2531DW/L2532DW/L2535D/L2535DW DCP-L2536D/L2537DW/L2550DN/L2550DW DCP-L2551DN/L2551DW/L2552DN HL-L2390DW/L2395DW MFC-7390/7490D/7890DN/7895DW MFC-B7700D/B7715DW/B7720DN MFC-L2690DW/L2710DN/L2710DW/L2712DN MFC-L2712DW/L2713DW/L2715D/L2715DW MFC-L2716D/L2716DW/L2717DW MFC-L2730DW/L2732DW/L2750DW/L2750DWXL
faster rcnn算法pytorch版本,按requirements.txt文件配置即可。
信息化教学基本理论省公共课一等奖全国赛课获奖课件.pptx
内容概要:本文档主要介绍了Westport Channel(简称WPC)与Logan Beach(简称LGB)两个硬件设备的DPLL固件更新方法,以及I2C驱动器的具体编程指南。文章从WPC和LGB的针脚布局开始,逐步讲解了连接设置方式、固件升级步骤和可能出现的问题及其解决办法,最后还附带了Microchip DPLL固件升级工具的安装指导和操作截图。 适用人群:适用于需要进行网络接口卡固件维护的技术人员、IT管理员或有一定电子技术背景的研发工程师。 使用场景及目标:为确保通信系统的稳定性和安全性,对网络适配器的关键部件如数字锁相环路(DPLL)实施正确的固件升级是必要的。文档详细指导用户完成这一过程,避免错误导致的设备故障。 其他说明:本文档为Intel公司的内部资料,涉及多项技术细节,仅供授权用户查阅。阅读前请确保已准备好相关软硬件环境并严格按照指引执行。对于复杂情况,可咨询Intel技术支持获取帮助。