怎样在log4j.xml配置文件中引入变量:小公司经验较多的我和阿里UC等大公司经验较多的Boss,一些技术交流和探讨
从最初学习使用log4j的时候,网上和书本上主要都是使用“log4j.properties”这种属性格式,配置日志。多年以来,一直使用这种格式,总的来说,简单、够用。
而有十多年经验的Boss,不建议使用properties格式配置,而是用xml格式配置。Boss之前在阿里(支付宝、淘宝)、UC等大公司工作过。
我们有个很明显的不同: 我比较注重,简单、快速。Boss比较注重,规范、严谨。
我的观点:没有对与错,只有适用与不适用。每个人都是根据自己的经历和追求,做出的技术选择。对于技术使用者来讲,明白不同配置的好处和坏处,才是需要注意的。
就log4j.xml这种配置来说,功能确实可能更多一些,可以单独把 业务日志和普通的系统日志分离,运维过程中,很容易看到业务错误,从而更快的解决问题。
------------------------------------------------------------------------------------------------------------
另外,Boss觉得需要把log4j的输出目录配置成变量。比如:<param name="File" value="${log4jOutputPath}/front/default.log" />,log4jOutputPath可以是“C:/log4j/”。
Boss根据之前在阿里的工作经验,开发和运维可能完全是2拨人。开发只管写代码,把代码写好,没有功能和业务问题。运维,负责把代码部署好,域名解析、Nginx、Tomcat、日志配置。运维导致的问题,运维背锅。功能问题,开发背锅。职责分明,流水化作业。
我对这种流水化的作业是非常认同的,这样的企业生产效率才高,才能为国家和社会创造更多的价值。
而象武汉一起好等很多在技术方面,偏向中小型规模的企业来说,开发和运维很可能就是“同一拨人”。这个时候,系统配置要怎么做,就是个值得探讨的问题了。
------------------------------------------------------------------------------------------------------------
Boss最初建议,修改Tomcat的启动脚本,在里面增加变量配置,比如“-Dlog4jOutputPath=c:/log4j”。
我一听,就不太赞成这种做法了。对于开发与运维都是一拨人,经常需要和其它开发人员交流的情况,修改Tomcat自身的配置比较麻烦。
为什么这么说呢?
Tomcat是系统级的程序,而我们的代码是应用级的程序。开发者,对自己的应用程序,一般是掌控度非常高的,但是对于Tomcat等不是自己写的系统程序,把控度比较低。Tomcat的随便一行启动代码,不小心改错了,就启动不了了。
修改Tomcat还有坏处,本地开发、线上部署、交接给其它客户,还得让客户去修改Tomcat这个和咱们的程序无关的配置,是不科学的。
我的建议是,把这些配置,放在外围,写入个文件,比如startupTomcat.sh,在启动的时候指定参数。每个人都可以很灵活地修改log4j等配置参数。
初步商议,我们采用这种做法。
总结下:
<appender name="DEFAULT-APPENDER" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="${log4jOutputPath}/front/default.log" /><!-- 设置日志输出文件名 -->
</appender>
Windows端Tomcat单独启动:
startupTomcat.bat
set JAVA_OPTS=%JAVA_OPTS% -Dlog4jOutputPath=c:/log4j -Dp2p.config_path=file:C:/apache-tomcat-7.0.37/
Linux端和Windows端类似~
----------------------------------------------------------------------------------------------------------
第2种做法,适合开发和运维都是同一人的情况,把log4j的变量,放在Web.xml里,部署的时候,需要手动修改这个变量。
log4j配置
可在web.xml中配置log4j.xml的位置,参数名称为:log4jXmlPath。
也可以,配置log4j的日志输出位置的目录,参数名称为:log4jOutputPath。
<servlet>
<servlet-name>Log4jInit</servlet-name>
<servlet-class>cn.fansunion.common.web.Log4jInit</servlet-class>
<init-param> <param-name>log4jXmlPath</param-name> <param-value>C:/log4j.xml</param-value> </init-param>
<init-param> <param-name>log4jOutputPath</param-name> <param-value>C:/log4j/xiaolei2</param-value> </init-param>
<load-on-startup>0</load-on-startup>
</servlet>
注意:这2个参数都必须输入绝对地址,如果log4jXmlPath没有值,或者对应的文件不存在,将把classpath下的log4j.xml作为默认配置文件。如果再找不到,将报错,log4j配置失败。
如果log4jOutputPath没有值,或者对应的文件不存在,将把classpath下的log4j文件夹作为默认的输出目录。
- Author:
- fansunion@qq.com 2015年1月8日
Java代码 Log4jInit.java
public class Log4jInit extends HttpServlet {
private static final long serialVersionUID = 1L;
public void init(ServletConfig config) throws ServletException {
// 从web.xml中找到log4j的输出目录
String log4jOutputPath = config.getInitParameter("log4jOutputPath");
// 默认的日志输出位置
if (StringUtils.isBlank(log4jOutputPath)) {
log4jOutputPath = Log4jInit.class.getClassLoader().getResource("")
.getFile()
+ "/log4j";
}
File log4jOutputPathFile = new File(log4jOutputPath);
// 如果输出文件不存在,手动创建
boolean log4xmlFileExists = log4jOutputPathFile.exists();
if (!log4xmlFileExists) {
System.out.println(log4jOutputPathFile.mkdirs());
}
// log4j.xml文件中的变量是在这里设置的
System.setProperty("log4jOutputPath", log4jOutputPath);
// 从web.xml中找到log4j.xml的输出目录
String log4jXmlPath = config.getInitParameter("log4jXmlPath");
boolean exist = false;
// 如果在web.xml手动配置,log4jXmlPath应该使用绝对地址,否则,就使用默认的位置和文件名就行
if (StringUtils.isNotBlank(log4jXmlPath)) {
File file = new File(log4jXmlPath);
exist = file.exists();
}
// log4jXmlPath默认位于classpath下log4j.xml
if (!exist) {
URL resource = Log4jInit.class.getClassLoader().getResource(
"log4j.xml");
if (resource != null) {
log4jXmlPath = resource.getFile();
}
}
DOMConfigurator.configure(log4jXmlPath);
}
}
----------------------------------------------------------------------------------------------------------
从技术方面的学习,加入一起好,遇到Boss,是我人生的大幸。要不然,我很难这么快就了解阿里等大公司的一些实际做法。
我决定扎根武汉,是不太可能去阿里系工作的。
怀揣梦想的我,也不可能委身于阿里。
小雷FansUnion-博学的互联网技术工作者,全栈式多屏开发工程师
2015年1月25日
湖北-武汉-循礼门
怎样在log4j.xml配置文件中引入变量:小公司经验较多的我和阿里UC等大公司经验较多的Boss,一些技术交流和探讨的更多相关文章
- SPRING IN ACTION 第4版笔记-第二章WIRING BEANS-008-在Java配置文件中引入xml配置文件@Import、@ImportResource
1. package soundsystem; import org.springframework.beans.factory.annotation.Autowired; public class ...
- 通过java程序调用ant build.xml配置文件中指定的target
一.概述 通过ant实现项目的自动化部署,jar包生成,替换,tomcat关停.启动,查看项目日志: 通过java程序调用已编辑好的ant脚本build.xml配置文件中指定的target: 文中文件 ...
- Spring依赖注入的方式、类型、Bean的作用域、自动注入、在Spring配置文件中引入属性文件
1.Spring依赖注入的方式 通过set方法完成依赖注入 通过构造方法完成依赖注入 2.依赖注入的类型 基本数据类型和字符串 使用value属性 如果是指向另一个对象的引入 使用ref属性 User ...
- @Required 注释应用于 bean 属性的 setter 方法,它表明受影响的 bean 属性在配置时必须放在 XML 配置文件中,否则容器就会抛出一个 BeanInitializationException 异常。
@Required 注释应用于 bean 属性的 setter 方法,它表明受影响的 bean 属性在配置时必须放在 XML 配置文件中,否则容器就会抛出一个 BeanInitializationEx ...
- 如何在web.xml文件中引入其他的xml文件(拆分web.xml)
转载自:http://www.blogjava.net/jiangjf/archive/2009/04/09/264685.html 最近在做一个Servlet+javaBean的项目,服务器用的是t ...
- 关于pom.xml文件中引入net.sf.json-lib出错问题
关于pom.xml文件中引入net.sf.json-lib出错问题 在项目中引入以下依赖时一直报错 <dependency> <groupId>net.sf.json-lib& ...
- Spring的xml配置文件中约束的必要性 找不到元素 'beans' 的声明
今天在复习Spring MVC框架的时候,只知道xml配置文件中的约束有规范书写格式的作用,所以在配置HandlerMapping对象信息的时候没有加入约束信息之后进行测试,没有遇到问题.后来在配置S ...
- mybatis 中的 xml 配置文件中 ‘<’、 ‘>’ 处理
mybatis 中的 xml 配置文件中 '<'. '>' 处理 1.使用转义字符将 '<'. '>' 替换掉. 描述 字符 转义字符 小于号 < < 大于号 &g ...
- web.xml配置文件中<async-supported>true</async-supported>报错
web.xml配置文件中<async-supported>true</async-supported>报错 http://blog.csdn.net/dream_ll/arti ...
随机推荐
- AsyncCallback BeginInvode endinvode 异步调用
下面是搜藏的代码: //首先准备好,要进行C#异步调用的方法(能C#异步调用的,最好不多线程) private string MethodName(int Num, out int Num2) { N ...
- 【习题 6-5 UVA-1600】Patrol Robot
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 设dis[x][y][z]表示到(x,y)连续走了z个墙的最短路 bfs一下就ok [代码] /* 1.Shoud it use l ...
- JSP与Servlet的介绍说明
什么是Servlet和JSP 用Java开发Web应用程序时用到的技术主要有两种,即Servlet和JSP. Servlet是在服务器端执行的Java程序,一个被称为Servlet容器的程序(其实就是 ...
- update进行跨表之间的更新
有时我们可能须要多个表之间进行更新数据. 我们能够使用这个语句 UPDATE table1,table2 SET table1.column=table2.column, table1.column1 ...
- [D3] SVG Graphics Containers and Text Elements in D3 v4
SVG is a great output format for data visualizations because of its scalability, but it comes with s ...
- PB导出数据excel格式dw2xls
PB导出数据excel格式dw2xls 使用DW2XLS控件 语法 uf_save_dw_as_excel ( dw, filename ) 參数 dw A reference to the data ...
- 数据结构-堆实现优先队列(java)
队列的特点是先进先出.通常都把队列比喻成排队买东西,大家都非常守秩序,先排队的人就先买东西. 可是优先队列有所不同,它不遵循先进先出的规则,而是依据队列中元素的优先权,优先权最大的先被取出. 这就非常 ...
- Swift UIView 层次调整
Swift 中添加的UIView都是有层级的. 我们先添加三个看一看 let view1=UIView(frame: CGRectMake(10, 50, 200, 200)) let view2=U ...
- 动态规划求解序列问题(LIS、JLIS)
1. 最长递增子序列 不要求位置连续:要求大小严格递增(strictly increasing) 穷举法解题 首先以每个数字为单位分割寻找最长递增子序列: int lis(const vector&l ...
- (嵌入式开发)移植最新uboot
一:准备移植 1.从下面的官网下载最新的U-boot.用google英文版搜索最新的u-boot源码 ftp://ftp.denx.de/pub/u-boot/ 2.建立sourceinsight工 ...