??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲av无码专区在线电影天堂 ,亚洲人精品亚洲人成在线,亚洲av之男人的天堂网站http://m.tkk7.com/libin2722/category/40802.html虚其心,可解天下之问Q专其心Q可d下之学;静其心,可?zhn)天下之理Q恒其心Q可成天下之业?/description>zh-cnSat, 18 Sep 2010 06:02:02 GMTSat, 18 Sep 2010 06:02:02 GMT60Tomcat讉K日志http://m.tkk7.com/libin2722/articles/332297.htmlC物C物Fri, 17 Sep 2010 06:50:00 GMThttp://m.tkk7.com/libin2722/articles/332297.htmlhttp://m.tkk7.com/libin2722/comments/332297.htmlhttp://m.tkk7.com/libin2722/articles/332297.html#Feedback0http://m.tkk7.com/libin2722/comments/commentRss/332297.htmlhttp://m.tkk7.com/libin2722/services/trackbacks/332297.html怋用web服务器的朋友大都了解Q一般的web server有两部分日志Q?br />     一是运行中的日志,它主要记录运行的一些信息,其是一些异帔R误日志信?br />     二是讉K日志信息Q它记录的访问的旉QIPQ访问的资料{相关信息?br />    
现在我来和大家介l一下利用tomcat产生的访问日志数据,我们能做哪些有效的分析数据?

首先是配|tomcat讉K日志数据Q默认情况下讉K日志没有打开Q配|的方式如下Q?br />     ~辑 ${catalina}/conf/server.xml文g.?${catalina}是tomcat的安装目?br />     把以下的注释(<!-- -->)L卛_?br />             <!--
        <Valve className="org.apache.catalina.valves.AccessLogValve"
                 directory="logs"  prefix="localhost_access_log." suffix=".txt"
                 pattern="common" resolveHosts="false"/>
        -->
    其中 directory是生的目录 tomcat安装${catalina}作ؓ当前目录
    pattern表示日志生的格式,common是tomcat提供的一个标准设|格式。其具体的表辑ּ?%h %l %u %t "%r" %s %b
    但本人徏议采用以下具体的配置Q因为标准配|有一些重要的日志数据无法生?br />         %h %l %u %t "%r" %s %b %T 
具体的日志生样式说明如?从官Ҏ(gu)档中摘录)Q?br />     * %a - Remote IP address
    * %A - Local IP address
    * %b - Bytes sent, excluding HTTP headers, or '-' if zero
    * %B - Bytes sent, excluding HTTP headers
    * %h - Remote host name (or IP address if resolveHosts is false)
    * %H - Request protocol
    * %l - Remote logical username from identd (always returns '-')
    * %m - Request method (GET, POST, etc.)
    * %p - Local port on which this request was received
    * %q - Query string (prepended with a '?' if it exists)
    * %r - First line of the request (method and request URI)
    * %s - HTTP status code of the response
    * %S - User session ID
    * %t - Date and time, in Common Log Format
    * %u - Remote user that was authenticated (if any), else '-'
    * %U - Requested URL path
    * %v - Local server name
    * %D - Time taken to process the request, in millis
    * %T - Time taken to process the request, in seconds

There is also support to write information from the cookie, incoming header, the Session or something else in the ServletRequest. It is modeled after the apache syntax:

    * %{xxx}i for incoming headers
    * %{xxx}c for a specific cookie
    * %{xxx}r xxx is an attribute in the ServletRequest
    * %{xxx}s xxx is an attribute in the HttpSession


现在我们回头再来看一下下面这个配|?%h %l %u %t "%r" %s %b %T 生的访问日志数据,我们可以做哪些事Q?br /> 先看一下,我们能得到的数据?
    * %h 讉K的用户IP地址
    * %l 讉K逻辑用户名,通常q回'-'
    * %u 讉K验证用户名,通常q回'-'
    * %t 讉K日时
    * %r 讉K的方?post或者是get)Q访问的资源和用的http协议版本
    * %s 讉Kq回的http状?br />     * %b 讉K资源q回的流?br />     * %T 讉K所使用的时?br />    
有了q些数据Q我们可以根据时间段做以下的分析处理(囄使用jfreechart工具动态生?Q?br />   * 独立IP数统?br />   * 讉Kh数统?br />   * 讉K资料文g数统?br />   * 讉K量l计
  * 讉K处理响应旉l计
  * l计所?04错误面
  * l计所?00错误的页?br />   * l计讉K最频繁面
  * l计讉K处理旉最久页?br />   * l计q发讉K频率最高的面

C物 2010-09-17 14:50 发表评论
]]>
log4j详解http://m.tkk7.com/libin2722/articles/287817.htmlC物C物Wed, 22 Jul 2009 03:13:00 GMThttp://m.tkk7.com/libin2722/articles/287817.htmlhttp://m.tkk7.com/libin2722/comments/287817.htmlhttp://m.tkk7.com/libin2722/articles/287817.html#Feedback0http://m.tkk7.com/libin2722/comments/commentRss/287817.htmlhttp://m.tkk7.com/libin2722/services/trackbacks/287817.html  在应用程序中d日志记录ȝ来说Z三个目的Q监视代码中变量的变化情况,周期性的记录到文件中供其他应用进行统计分析工作;跟踪代码q行时轨q,作ؓ日后审计的依据;担当集成开发环境中的调试器的作用,向文件或控制台打C码的调试信息?
  最普通的做法是在代码中嵌入许多的打印语句,q些打印语句可以输出到控制台或文件中Q比较好的做法就是构造一个日志操作类来封装此cL作,而不是让一pd的打印语句充斥了代码的主体?
1.2. Log4j?
  在强调可重用lg开发的今天Q除了自׃头到ּ发一个可重用的日志操作类外,Apache为我们提供了一个强有力的日志操作包-Log4j?
   Log4j是Apache的一个开放源代码目Q通过使用Log4jQ我们可以控制日志信息输送的目的地是控制台、文件、GUIlg、甚x套接口服? 器、NT的事件记录器、UNIX Syslog守护q程{;我们也可以控制每一条日志的输出格式Q通过定义每一条日志信息的U别Q我们能够更加细致地控制日志的生成过E。最令h感兴的? 是,q些可以通过一个配|文件来灉|地进行配|,而不需要修改应用的代码?
  此外Q通过Log4j其他语言接口Q?zhn)可以在C、C+ +?Net、PL/SQLE序中用Log4jQ其语法和用法与在JavaE序中一P使得多语a分布式系l得C个统一一致的日志lg模块。而且Q? q用各U第三方扩展Q?zhn)可以很方便地Log4j集成到J2EE、JINI甚至是SNMP应用中?
Log4j有三个主要的lgQ?/strong>
   Loggers(记录?QAppenders (输出?和Layouts(布局)Q这里可单理解ؓ日志cdQ日志要输出的地方和日志以何UŞ式输出。综合用这三个lg可以L的记录信息的cd? U别Qƈ可以在运行时控制日志输出的样式和位置。下面对三个lg分别q行说明Q?
1?Loggers
   Loggerslg在此pȝ中被分ؓ五个U别QDEBUG、INFO、WARN、ERROR和FATAL。这五个U别是有序的,DEBUG < INFO < WARN < ERROR < FATALQ分别用来指定这条日志信息的重要E度,明白q一点很重要Q这里Log4j有一个规则:假设LoggersU别为PQ如果在Loggers中发 生了一个别Q比P高,则可以启动,否则屏蔽掉?
假设你定义的U别是infoQ那么error和warn的日志可以显C比他低的debug信息׃昄了?
JavaE序举例来说Q?
   ***建立Logger的一个实例,命名为“com.foo?**
   Logger logger = Logger.getLogger("com.foo");
    ***"com.foo"是实例进行命名,也可以Q?**
   ***讄logger的别。通常不在E序中设|logger的别。一般在配置文g中设|?**
  logger.setLevel(Level.INFO);
  Logger barlogger = Logger.getLogger("com.foo.Bar");
  ***下面q个h可用Q因为WARN >= INFO***
  logger.warn("Low fuel level.");
  ***下面q个h不可用,因ؓDEBUG < INFO***
  logger.debug("Starting search for nearest gas station.");
  ***命名为“com.foo.bar”的实例barlogger会承实例“com.foo”的U别。因此,下面q个h可用Q因为INFO >= INFO***
  barlogger.info("Located nearest gas station.");
  ***下面q个h不可用,因ؓDEBUG < INFO***
  barlogger.debug("Exiting gas station search");
  q里“是否可用”的意思是能否输出Logger信息?
    在对Logger实例q行命名Ӟ没有限制Q可以取L自己感兴的名字。一般情况下以类的所在位|来命名Logger实例Q这是目前来讲比较有效的Logger命名方式。这样可以得每个类建立自己的日志信息,便于理。比如:
  static Logger logger = Logger.getLogger(ClientWithLog4j.class.getName());
2、Appenders
  用与用日志请求只是Log4j其中的一个小的地方QLog4j日志pȝ允许把日志输出到不同的地方,如控制台QConsoleQ、文ӞFilesQ、根据天数或者文件大生新的文件、以的形式发送到其它地方{等?
  
  其语法表CZؓQ?
  
  org.apache.log4j.ConsoleAppenderQ控制台Q?
  org.apache.log4j.FileAppenderQ文Ӟ
  org.apache.log4j.DailyRollingFileAppenderQ每天生一个日志文Ӟ
org.apache.log4j.RollingFileAppenderQ文件大到达指定尺寸的时候生一个新的文Ӟ
  org.apache.log4j.WriterAppenderQ将日志信息以流格式发送到L指定的地方)
  
  配置时用方式ؓQ?
  log4j.appender.appenderName = fully.qualified.name.of.appender.class
  log4j.appender.appenderName.option1 = value1
  ?
log4j.appender.appenderName.option = valueN
  q样׃ؓ日志的输出提供了相当大的便利?
3、Layouts
   有时用户希望Ҏ(gu)自己的喜好格式化自己的日志输出。Log4j可以在Appenders的后面附加Layouts来完成这个功能。Layouts提供? 四种日志输出样式Q如Ҏ(gu)HTML样式、自由指定样式、包含日志别与信息的样式和包含日志旉、线E、类别等信息的样式等{?
  
  其语法表CZؓQ?
  
  org.apache.log4j.HTMLLayoutQ以HTML表格形式布局Q,
  org.apache.log4j.PatternLayoutQ可以灵zd指定布局模式Q,
  org.apache.log4j.SimpleLayoutQ包含日志信息的U别和信息字W串Q,
  org.apache.log4j.TTCCLayoutQ包含日志生的旉、线E、类别等{信息)
  
  配置时用方式ؓQ?
  
  log4j.appender.appenderName.layout =fully.qualified.name.of.layout.class
  log4j.appender.appenderName.layout.option1 = value1
  ?
  log4j.appender.appenderName.layout.option = valueN
4 . Log4j的配|? 
  以上是从原理斚w说明Log4j的用方法,在具体Java~程使用Log4j可以参照以下CZQ?
  1?建立Logger实例Q?
  语法表示Qpublic static Logger getLogger( String name)
  实际使用Qstatic Logger logger = Logger.getLogger(ServerWithLog4j.class.getName ()) ;
  2?d配置文gQ?
  获得了Logger的实例之后,接下来将配置Log4j使用环境Q?
  语法表示Q?
  BasicConfigurator.configure()Q自动快速地使用~省Log4j环境?
  PropertyConfigurator.configure(String configFilename)Q读取用Java的特性文件编写的配置文g?
  DOMConfigurator.configure(String filename)Q读取XML形式的配|文件?
  实际使用Q?
PropertyConfigurator.configure("ServerWithLog4j.properties");
  3?插入日志信息
  完成了以上连个步骤以后,下面可以按日志的不同别插入到你要记录日志的Q何地方了?
  语法表示Q?
  Logger.debug(Object message);//调试信息
  Logger.info(Object message);//一般信?
  Logger.warn(Object message);//警告信息
  Logger.error(Object message);//错误信息
  Logger.fatal(Object message);//致命错误信息
  实际使用Qlogger.info("ServerSocket before accept: " + server);

5. 配置q程

 在实际编E时Q要使Log4j真正在系l中q行事先q要寚w|文件进行定义。定义步骤就是对Logger、Appender及Layout的分别用?
Log4j支持两种配置文g格式Q一U是XML格式的文Ӟ一U是java propertiesQkey=valueQ【JavaҎ(gu)文Ӟ?|】。下面我们介l用JavaҎ(gu)文件做为配|文件的Ҏ(gu)
具体如下Q?
  
  1、配|根LoggerQ其语法为:
  log4j.rootLogger = [ level ] , appenderName1, appenderName2, ?
level : 是日志记录的优先U,分ؓOFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者?zhn)定义的别。Log4j只用四个别,? 先从高C分别是ERROR、WARN、INFO、DEBUG。通过在这里定义的U别Q?zhn)可以控制到应用程序中相应U别的日志信息的开兟뀂比如在q里? 义了INFOU别Q则应用E序中所有DEBUGU别的日志信息将不被打印出来?
   appenderName:是指定日志信息输出到哪个地斏V?zhn)可以同时指定多个输出目的地?
例如Qlog4j.rootLoggerQinfo,A1,B2,C3
  
  2、配|日志信息输出目的地Q其语法为:
  log4j.appender.appenderName = fully.qualified.name.of.appender.class //
   "fully.qualified.name.of.appender.class" 可以指定下面五个目的C的一个:
1.org.apache.log4j.ConsoleAppenderQ控制台Q?
2.org.apache.log4j.FileAppenderQ文Ӟ
3.org.apache.log4j.DailyRollingFileAppenderQ每天生一个日志文Ӟ
4.org.apache.log4j.RollingFileAppenderQ文件大到达指定尺寸的时候生一个新的文Ӟ
5.org.apache.log4j.WriterAppenderQ将日志信息以流格式发送到L指定的地方)
1.ConsoleAppender选项
Threshold=WARN:指定日志消息的输出最低层ơ?
ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立卌出?
Target=System.errQ默认情况下是:System.out,指定输出控制?
2.FileAppender 选项
Threshold=WARN:指定日志消息的输出最低层ơ?
ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立卌出?
File=mylog.txt:指定消息输出到mylog.txt文g?
Append=false:默认值是true,卛_消息增加到指定文件中Qfalse指将消息覆盖指定的文件内宏V?
3.DailyRollingFileAppender 选项
Threshold=WARN:指定日志消息的输出最低层ơ?
ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立卌出?
File=mylog.txt:指定消息输出到mylog.txt文g?
Append=false:默认值是true,卛_消息增加到指定文件中Qfalse指将消息覆盖指定的文件内宏V?
DatePattern='.'yyyy-ww:每周滚动一ơ文Ӟx周生一个新的文件。当然也可以指定按月、周、天、时和分。即对应的格式如下:
1)'.'yyyy-MM: 每月
2)'.'yyyy-ww: 每周
3)'.'yyyy-MM-dd: 每天
4)'.'yyyy-MM-dd-a: 每天两次
5)'.'yyyy-MM-dd-HH: 每小?
6)'.'yyyy-MM-dd-HH-mm: 每分?
4.RollingFileAppender 选项
Threshold=WARN:指定日志消息的输出最低层ơ?
ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立卌出?
File=mylog.txt:指定消息输出到mylog.txt文g?
Append=false:默认值是true,卛_消息增加到指定文件中Qfalse指将消息覆盖指定的文件内宏V?
MaxFileSize=100KB: 后缀可以是KB, MB 或者是 GB. 在日志文件到达该大小Ӟ会自动滚动Q即原来的内容Udmylog.log.1文g?
MaxBackupIndex=2:指定可以产生的滚动文件的最大数?
实际应用Q?
  log4j.appender.A1=org.apache.log4j.ConsoleAppender //q里指定了日志输出的W一个位|A1是控制台ConsoleAppender
  
  3、配|日志信息的格式Q其语法为:
  A. log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class
"fully.qualified.name.of.layout.class" 可以指定下面4个格式中的一个:
1.org.apache.log4j.HTMLLayoutQ以HTML表格形式布局Q,
   2.org.apache.log4j.PatternLayoutQ可以灵zd指定布局模式Q,
   3.org.apache.log4j.SimpleLayoutQ包含日志信息的U别和信息字W串Q,
   4.org.apache.log4j.TTCCLayoutQ包含日志生的旉、线E、类别等{信息)
1.HTMLLayout 选项
LocationInfo=true:默认值是false,输出java文g名称和行?
Title=my app file: 默认值是 Log4J Log Messages.
2.PatternLayout 选项
ConversionPattern=%m%n :指定怎样格式化指定的消息?
3.XMLLayout 选项
LocationInfo=true:默认值是false,输出java文g和行?
实际应用Q?
  log4j.appender.A1.layout=org.apache.log4j.PatternLayout
B. log4j.appender.A1.layout.ConversionPattern=%-4r %-5p %d{yyyy-MM-dd HH:mm:ssS} %c %m%n
q里需要说明的是日志信息格式中几个符h代表的含义:
   QX? X信息输出时左寚wQ?
%p: 输出日志信息优先U,即DEBUGQINFOQWARNQERRORQFATAL,
%d: 输出日志旉点的日期或时_默认格式为ISO8601Q也可以在其后指定格式,比如Q?d{yyy MMM dd HH:mm:ss,SSS}Q输出类|2002q?0?8?22Q?0Q?8Q?21
%r: 输出自应用启动到输出该log信息耗费的毫U数
%c: 输出日志信息所属的cȝQ通常是所在类的全?
%t: 输出产生该日志事件的U程?
%l: 输出日志事g的发生位|,相当?C.%M(%F:%L)的组?包括cȝ名、发生的U程Q以及在代码中的行数。D例:Testlog4.main(TestLog4.java:10)
%x: 输出和当前线E相兌的NDC(嵌套诊断环境),其用到像java servletsq样的多客户多线E的应用中?
%%: 输出一?%"字符
%F: 输出日志消息产生时所在的文g名称
%L: 输出代码中的行号
%m: 输出代码中指定的消息,产生的日志具体信?
%n: 输出一个回车换行符QWindowsq_?\r\n"QUnixq_?\n"输出日志信息换行
可以?与模式字W之间加上修饰符来控制其最宽度、最大宽度、和文本的对齐方式。如Q?
1)%20cQ指定输出category的名Uͼ最的宽度?0Q如果category的名U小?0的话Q默认的情况下右寚w?
2)%-20c:指定输出category的名Uͼ最的宽度?0Q如果category的名U小?0的话Q?-"h定左寚w?
3)%.30c:指定输出category的名Uͼ最大的宽度?0Q如果category的名U大?0的话Q就会将左边多出的字W截掉,但小?0的话也不会有I格?
4)%20.30c:如果category的名U小?0pI格Qƈ且右寚wQ如果其名称长于30字符Q就从左边交q销出的字符截掉?
  q里上面三个步骤是对前面Log4jlg说明的一个简化;下面l出一个具体配|例子,在程序中可以参照执行Q?
  log4j.rootLogger=INFO,A1QB2
  log4j.appender.A1=org.apache.log4j.ConsoleAppender
  log4j.appender.A1.layout=org.apache.log4j.PatternLayout
  log4j.appender.A1.layout.ConversionPattern=%-4r %-5p %d{yyyy-MM-dd HH:mm:ssS} %c %m%n
  Ҏ(gu)上面的日志格式,某一个程序的输出l果如下Q?
  0  INFO 2003-06-13 13:23:46968 ClientWithLog4j Client socket: Socket[addr=localhost/127.0.0.1,port=8002,localport=2014]
16  DEBUG 2003-06-13 13:23:46984 ClientWithLog4j Server says: 'Java server with log4j, Fri Jun 13 13:23:46 CST 2003'
  16  DEBUG 2003-06-13 13:23:46984 ClientWithLog4j GOOD
  16  DEBUG 2003-06-13 13:23:46984 ClientWithLog4j Server responds: 'Command 'HELLO' not understood.'
  16  DEBUG 2003-06-13 13:23:46984 ClientWithLog4j HELP
  16  DEBUG 2003-06-13 13:23:46984 ClientWithLog4j Server responds: 'Vocabulary: HELP QUIT'
  16  DEBUG 2003-06-13 13:23:46984 ClientWithLog4j QUIT

4. # 当输Z息于回滚文g?
log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender //指定以文件的方式输出日志
log4j.appender.ROLLING_FILE.Threshold=ERROR
log4j.appender.ROLLING_FILE.File=rolling.log //文g位置,也可以用变量${java.home}、rolling.log
log4j.appender.ROLLING_FILE.Append=true
log4j.appender.ROLLING_FILE.MaxFileSize=10KB //文g最大尺?
log4j.appender.ROLLING_FILE.MaxBackupIndex=1 //备䆾?
log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.ROLLING_FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n

6. Log4j比较全面的配|?
  LOG4J的配|之单它遍及于来多的应用中了:Log4J配置文g实现了输出到控制台、文件、回滚文件、发送日志邮件、输出到数据库日志表、自定义标签{全套功能。择其一二用就够用了,
log4j.rootLogger=DEBUG,CONSOLE,A1,im
log4j.addivity.org.apache=true
# 应用于控制台
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.Threshold=DEBUG
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
#log4j.appender.CONSOLE.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[thread] n%c[CATEGORY]%n%m[MESSAGE]%n%n
#应用于文?
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=file.log
log4j.appender.FILE.Append=false
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
# Use this layout for LogFactor 5 analysis
# 应用于文件回?
log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender
log4j.appender.ROLLING_FILE.Threshold=ERROR
log4j.appender.ROLLING_FILE.File=rolling.log //文g位置,也可以用变量${java.home}、rolling.log
log4j.appender.ROLLING_FILE.Append=true //true:d false:覆盖
log4j.appender.ROLLING_FILE.MaxFileSize=10KB //文g最大尺?
log4j.appender.ROLLING_FILE.MaxBackupIndex=1 //备䆾?
log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.ROLLING_FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n

#应用于socket
log4j.appender.SOCKET=org.apache.log4j.RollingFileAppender
log4j.appender.SOCKET.RemoteHost=localhost
log4j.appender.SOCKET.Port=5001
log4j.appender.SOCKET.LocationInfo=true
# Set up for Log Facter 5
log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout
log4j.appender.SOCET.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[thread]%n%c[CATEGORY]%n%m[MESSAGE]%n%n

# Log Factor 5 Appender
log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender
log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000
# 发送日志给邮g
log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender
log4j.appender.MAIL.Threshold=FATAL
log4j.appender.MAIL.BufferSize=10
log4j.appender.MAIL.From=web@www.wuset.com
log4j.appender.MAIL.SMTPHost=www.wusetu.com
log4j.appender.MAIL.Subject=Log4J Message
log4j.appender.MAIL.To=web@www.wusetu.com
log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout
log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
# 用于数据?
log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/test
log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver
log4j.appender.DATABASE.user=root
log4j.appender.DATABASE.password=
log4j.appender.DATABASE.sql=INSERT INTO LOG4J (Message) VALUES ('[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n')
log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout
log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n

log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A1.File=SampleMessages.log4j
log4j.appender.A1.DatePattern=yyyyMMdd-HH'.log4j'
log4j.appender.A1.layout=org.apache.log4j.xml.XMLLayout
#自定义Appender
log4j.appender.im = net.cybercorlin.util.logger.appender.IMAppender
log4j.appender.im.host = mail.cybercorlin.net
log4j.appender.im.username = username
log4j.appender.im.password = password
log4j.appender.im.recipient = corlin@cybercorlin.net
log4j.appender.im.layout=org.apache.log4j.PatternLayout
log4j.appender.im.layout.ConversionPattern =[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n

C物 2009-07-22 11:13 发表评论
]]>
使用log4j的邮件功?/title><link>http://m.tkk7.com/libin2722/articles/287816.html</link><dc:creator>C物</dc:creator><author>C物</author><pubDate>Wed, 22 Jul 2009 03:12:00 GMT</pubDate><guid>http://m.tkk7.com/libin2722/articles/287816.html</guid><wfw:comment>http://m.tkk7.com/libin2722/comments/287816.html</wfw:comment><comments>http://m.tkk7.com/libin2722/articles/287816.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/libin2722/comments/commentRss/287816.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/libin2722/services/trackbacks/287816.html</trackback:ping><description><![CDATA[Log4j的邮件功能能够ؓ我们做这L事情----当程序运行完的时候,或者正在运行也是可以的Q它?yu)程序的日志通过邮g的方式发C的邮׃? <p>    q样Q对于程序运行的控制׃用每ơ都跑到机器上去看日志文件这么麻烦了Q我们需要的只是Q开开FoxmailQ用用鼠标,可以知道,E序到底q行的怎么样了?/p><p>    </p><ul><li><h3>    使用log4j-1.2.15</h3></li></ul><p>               之前用的?log4j-1.2.8 Q照理说Q它们之间的版本L区别够小Q应该没有什么区别,但是事实却让我丈二摸不着头脑?/p><p>             发送邮件的一个重要的cLSMTPAppender?/p><p>             ?.2.8的版本中QSMTPAppender没有smtpPassword 和smtpUsername 属性。这两个属性分别是dsmtp服务器用的用户名和密码。笔者到现在也没有想明白Q在通常的情况下怎样才可以不dsmtp服务器就可以发送邮件了? 有知道的朋友Q就留个a吧,先谢q啦?/p><p>              ׃不能解决上面的那个问题,我就只好使用1.2.15q个版本啦?/p><ul><li>   log4j.properties文g</li></ul><p>            </p><div id="yckae24" class="dp-highlighter"><div id="ugiqcq4" class="bar"><div id="yyquqmk" class="tools">Java代码 <embed lk_media="yes" lk_mediaid="lk_juiceapp_mediaPopup_1248229109797" src="http://www.javaeye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=log4j.appender.MAIL%3Dorg.apache.log4j.net.SMTPAppender%0A%0Alog4j.appender.MAIL.BufferSize%3D10%0A%0Alog4j.appender.MAIL.From%3Dyourname%40%20domain.com%0A%0Alog4j.appender.MAIL.SMTPHost%3Dmail.domain.com%0A%0Alog4j.appender.MAIL.Subject%3DLog4J%20Message%0A%0Alog4j.appender.MAIL.To%3Dtarget%40domain.com%0A%0Alog4j.appender.MAIL.SMTPUsername%3Dusername%0A%0Alog4j.appender.MAIL.SMTPPassword%3Dpassword%0A%0Alog4j.appender.MAIL.layout%3Dorg.apache.log4j.PatternLayout%0A%0Alog4j.appender.MAIL.layout%3Dorg.apache.log4j.PatternLayout%0A%0Alog4j.appender.MAIL.layout.ConversionPattern%3D%5Bframework%5D%20%25d%20-%20%25c%20-%25-4r%20%5B%25t%5D%20%25-5p%20%25c%20%25x%20-%20%25m%25n%0A" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" height="15" width="14"></embed></div></div><ol class="dp-j" start="1"><li><span><span>log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender  </span></span></li><li><span>  </span></li><li><span>log4j.appender.MAIL.BufferSize=<span id="u4myq24" class="number">10</span><span>  </span></span></li><li><span>  </span></li><li><span>log4j.appender.MAIL.From=yourname@ domain.com  </span></li><li><span>  </span></li><li><span>log4j.appender.MAIL.SMTPHost=mail.domain.com  </span></li><li><span>  </span></li><li><span>log4j.appender.MAIL.Subject=Log4J Message  </span></li><li><span>  </span></li><li><span>log4j.appender.MAIL.To=target<span id="gmo24o4" class="annotation">@domain</span><span>.com  </span></span></li><li><span>  </span></li><li><span>log4j.appender.MAIL.SMTPUsername=username  </span></li><li><span>  </span></li><li><span>log4j.appender.MAIL.SMTPPassword=password  </span></li><li><span>  </span></li><li><span>log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout  </span></li><li><span>  </span></li><li><span>log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout  </span></li><li><span>  </span></li><li><span>log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n  </span></li></ol></div><pre style="display: none;" name="code" class="java">log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender log4j.appender.MAIL.BufferSize=10 log4j.appender.MAIL.From=yourname@ domain.com log4j.appender.MAIL.SMTPHost=mail.domain.com log4j.appender.MAIL.Subject=Log4J Message log4j.appender.MAIL.To=target@domain.com log4j.appender.MAIL.SMTPUsername=username log4j.appender.MAIL.SMTPPassword=password log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n </pre><p>           q个文g配好以后Q恭喜你Q现在log4j的邮件功能,你就可以体会了?/p><ul><li>  SMTP的别默认是ERRORU别的,怎么?/li></ul><p>             默认的别是ERRORU别的,那就是说Q只有程序出错了Q你才可以收到邮Ӟ很显Ӟq还不能满我们日常理的要求。我们需要自定义的别?/p><p>            为此Q笔者承了TriggeringEventEvaluatorc,覆盖里面的一个方面,如下所C?/p><div id="kq2mqkk" class="dp-highlighter"><div id="y2oiaau" class="bar"><div id="2gy2es4" class="tools">Java代码 <embed lk_media="yes" lk_mediaid="lk_juiceapp_mediaPopup_1248229109808" src="http://www.javaeye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%40Override%0A%09public%20boolean%20isTriggeringEvent(LoggingEvent%20arg0)%20%7B%0A%09%09return%20arg0.getLevel().isGreaterOrEqual(Level.INFO)%3B%0A%09%7D" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" height="15" width="14"></embed></div></div><ol class="dp-j" start="1"><li><span><span id="oyamwwo" class="annotation">@Override</span><span>  </span></span></li><li><span>    <span id="oakuem4" class="keyword">public</span><span> </span><span id="gqik24o" class="keyword">boolean</span><span> isTriggeringEvent(LoggingEvent arg0) {  </span></span></li><li><span>        <span id="qga44m8" class="keyword">return</span><span> arg0.getLevel().isGreaterOrEqual(Level.INFO);  </span></span></li><li><span>    }  </span></li></ol></div><pre style="display: none;" name="code" class="java">@Override public boolean isTriggeringEvent(LoggingEvent arg0) { return arg0.getLevel().isGreaterOrEqual(Level.INFO); }</pre><p>  </p><ul><li>   每遇C个触发事件就发一邮Ӟ</li></ul><p>            SMTPAppender 实现是,每当isTriggeringEventQ)q个Ҏ(gu)q回true的时候,它都会发送邮件。这L话,一个程序执行下来,每个有能力触发的事g都会形成一邮件。这昄不是我们希望看到的场面?/p><p>            W者承了SMTPAppenderc,重装了appendҎ(gu)。         ?</p><div id="a2uuu2i" class="dp-highlighter"><div id="uye2c4w" class="bar"><div id="ey2ku2w" class="tools">Java代码 <embed lk_media="yes" lk_mediaid="lk_juiceapp_mediaPopup_1248229109816" src="http://www.javaeye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%40Override%0A%09public%20void%20append(LoggingEvent%20event)%20%7B%0A%0A%09%09if%20(!checkEntryConditions())%20%7B%0A%09%09%09return%3B%0A%09%09%7D%0A%0A%09%09event.getThreadName()%3B%0A%09%09event.getNDC()%3B%0A%09%09event.getMDCCopy()%3B%0A%09%09if%20(this.getLocationInfo())%20%7B%0A%09%09%09event.getLocationInformation()%3B%0A%09%09%7D%0A%09%09cb.add(event)%3B%0A%09%09if%20(evaluator.isTriggeringEvent(event))%20%7B%0A%09%09%09if%20(cb.length()%20%3E%20this.getBufferSize()%20%2F%202)%20%7B%0A%09%09%09%09sendBuffer()%3B%0A%09%09%09%7D%0A%0A%09%09%7D%0A%09%7D" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" height="15" width="14"></embed></div></div><ol class="dp-j" start="1"><li><span><span id="qcke4ew" class="annotation">@Override</span><span>  </span></span></li><li><span>    <span id="skuwiac" class="keyword">public</span><span> </span><span id="sewyais" class="keyword">void</span><span> append(LoggingEvent event) {  </span></span></li><li><span>  </span></li><li><span>        <span id="gmegqyq" class="keyword">if</span><span> (!checkEntryConditions()) {  </span></span></li><li><span>            <span id="cwyy4mq" class="keyword">return</span><span>;  </span></span></li><li><span>        }  </span></li><li><span>  </span></li><li><span>        event.getThreadName();  </span></li><li><span>        event.getNDC();  </span></li><li><span>        event.getMDCCopy();  </span></li><li><span>        <span id="oacucem" class="keyword">if</span><span> (</span><span id="imeyyiq" class="keyword">this</span><span>.getLocationInfo()) {  </span></span></li><li><span>            event.getLocationInformation();  </span></li><li><span>        }  </span></li><li><span>        cb.add(event);  </span></li><li><span>        <span id="euegaia" class="keyword">if</span><span> (evaluator.isTriggeringEvent(event)) {  </span></span></li><li><span>            <span id="sem2ykc" class="keyword">if</span><span> (cb.length() > </span><span id="oc4goas" class="keyword">this</span><span>.getBufferSize() / </span><span id="smemggi" class="number">2</span><span>) {  </span></span></li><li><span>                sendBuffer();  </span></li><li><span>            }  </span></li><li><span>  </span></li><li><span>        }  </span></li><li><span>    }  </span></li></ol></div><pre style="display: none;" name="code" class="java">@Override public void append(LoggingEvent event) { if (!checkEntryConditions()) { return; } event.getThreadName(); event.getNDC(); event.getMDCCopy(); if (this.getLocationInfo()) { event.getLocationInformation(); } cb.add(event); if (evaluator.isTriggeringEvent(event)) { if (cb.length() > this.getBufferSize() / 2) { sendBuffer(); } } }</pre><p>          q样的话Q当事g的个数达到bufferSize的一半的时候就会发一邮件了?/p><p>          但是另外一个问题也随之产生了,当程序结束时Q还在缓冲里面的事g是不会被发送出来的。因Z件数往往没有bufferSize的一半?/p><p>          </p><div id="ae4kcmw" class="dp-highlighter"><div id="ugg2cuw" class="bar"><div id="m4kkwgw" class="tools">Java代码 <embed lk_media="yes" lk_mediaid="lk_juiceapp_mediaPopup_1248229109825" src="http://www.javaeye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=public%20%20%20*****SMTPAppender()%20%7B%0A%09%09Runtime.getRuntime().addShutdownHook(new%20Thread()%20%7B%0A%0A%09%09%09%40Override%0A%09%09%09public%20void%20run()%20%7B%0A%09%09%09%09if%20(cb.length()%20%3E%200)%20%7B%0A%09%09%09%09%09sendBuffer()%3B%0A%09%09%09%09%7D%0A%0A%09%09%09%7D%0A%0A%09%09%7D)%3B%0A%09%7D" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" height="15" width="14"></embed></div></div><ol class="dp-j" start="1"><li><span><span id="uqkuweg" class="keyword">public</span><span>   *****SMTPAppender() {  </span></span></li><li><span>        Runtime.getRuntime().addShutdownHook(<span id="0sq4www" class="keyword">new</span><span> Thread() {  </span></span></li><li><span>  </span></li><li><span>            <span id="aum4qyy" class="annotation">@Override</span><span>  </span></span></li><li><span>            <span id="yummyum" class="keyword">public</span><span> </span><span id="u24akem" class="keyword">void</span><span> run() {  </span></span></li><li><span>                <span id="wgogyqq" class="keyword">if</span><span> (cb.length() > </span><span id="qeeysks" class="number">0</span><span>) {  </span></span></li><li><span>                    sendBuffer();  </span></li><li><span>                }  </span></li><li><span>  </span></li><li><span>            }  </span></li><li><span>  </span></li><li><span>        });  </span></li><li><span>    }  </span></li></ol></div><pre style="display: none;" name="code" class="java">public *****SMTPAppender() { Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { if (cb.length() > 0) { sendBuffer(); } } }); }</pre><p> </p><p>         W者在构造函CQ添加了一个程序结束时q行的线E,来处理这个问题?/p><ul><li>  讄Html格式的输?/li></ul><p>            按照刚刚W者给出的配置文gQ所产生的邮件的格式是纯文本的。其实log4j有网|式的输出的?/p><p>            </p><div id="ke4emck" class="dp-highlighter"><div id="yc2is4s" class="bar"><div id="ysu2kcc" class="tools">Property文g代码 <embed lk_media="yes" lk_mediaid="lk_juiceapp_mediaPopup_1248229109833" src="http://www.javaeye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=log4j.appender.MAIL.layout%3Dorg.apache.log4j.HTMLLayout" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" height="15" width="14"></embed></div></div><ol class="dp-default" start="1"><li><span><span>log4j.appender.MAIL.layout=org.apache.log4j.HTMLLayout  </span></span></li></ol></div><pre style="display: none;" name="code" class="property文g">log4j.appender.MAIL.layout=org.apache.log4j.HTMLLayout</pre><p> </p><p>          q样的话Q邮件就好看很多啦?/p><ul><li>  解决邮g中的中文q问题</li></ul><p>            最后,你会发现中文是ؕ码的Q而且HTMLLayout没有提供~码方式的属性设|,哎,又是一阉|语中?/p><p>           得,W者也只好再写一个类Q承HTMLLayout,覆盖getContentTypeҎ(gu)</p><p>           </p><div id="scgggqy" class="dp-highlighter"><div id="co24kk4" class="bar"><div id="ugassmk" class="tools">Java代码 <embed lk_media="yes" lk_mediaid="lk_juiceapp_mediaPopup_1248229109841" src="http://www.javaeye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=%40Override%0A%09public%20String%20getContentType()%20%7B%0A%09%09return%20%22text%2Fhtml%3Bcharset%3DGBK%22%3B%0A%0A%09%7D" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" height="15" width="14"></embed></div></div><ol class="dp-j" start="1"><li><span><span id="2ssccmm" class="annotation">@Override</span><span>  </span></span></li><li><span>    <span id="uggicsu" class="keyword">public</span><span> String getContentType() {  </span></span></li><li><span>        <span id="qicegwe" class="keyword">return</span><span> </span><span id="m4iq4me" class="string">"text/html;charset=GBK"</span><span>;  </span></span></li><li><span>  </span></li><li><span>    }  </span></li></ol></div><pre style="display: none;" name="code" class="java">@Override public String getContentType() { return "text/html;charset=GBK"; }</pre><p>           d上述功能之后的配|文件如下所C:</p><div id="csmwo4i" class="dp-highlighter"><div id="i2c4iks" class="bar"><div id="e2au4w4" class="tools">Java代码 <embed lk_media="yes" lk_mediaid="lk_juiceapp_mediaPopup_1248229109850" src="http://www.javaeye.com/javascripts/syntaxhighlighter/clipboard_new.swf" flashvars="clipboard=log4j.appender.MAIL.To%3Dtarget%40domain.com%0A%0Alog4j.appender.MAIL.From%3Dyourname%40domain.com%0A%0Alog4j.appender.MAIL.SMTPHost%3Dsmtp.domain.com%0A%0Alog4j.appender.MAIL.Subject%3D%20Information%0A%0Alog4j.appender.MAIL.SMTPUsername%3Dusername%0A%0Alog4j.appender.MAIL.SMTPPassword%3Dpassword%0A%0Alog4j.appender.MAIL.EvaluatorClass%3Dcom.wole.***.MailEvaluator%0A%0Alog4j.appender.MAIL.layout%3Dcom.wole.log4j.net.DefaultLayOut" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" height="15" width="14"></embed></div></div><ol class="dp-j" start="1"><li><span><span>log4j.appender.MAIL.To=target</span><span id="gik2moy" class="annotation">@domain</span><span>.com  </span></span></li><li><span>  </span></li><li><span>log4j.appender.MAIL.From=yourname<span id="swoa4gy" class="annotation">@domain</span><span>.com  </span></span></li><li><span>  </span></li><li><span>log4j.appender.MAIL.SMTPHost=smtp.domain.com  </span></li><li><span>  </span></li><li><span>log4j.appender.MAIL.Subject= Information  </span></li><li><span>  </span></li><li><span>log4j.appender.MAIL.SMTPUsername=username  </span></li><li><span>  </span></li><li><span>log4j.appender.MAIL.SMTPPassword=password  </span></li><li><span>  </span></li><li><span>log4j.appender.MAIL.EvaluatorClass=com.wole.***.MailEvaluator  </span></li><li><span>  </span></li><li><span>log4j.appender.MAIL.layout=com.wole.log4j.net.DefaultLayOut  <br /></span></li></ol></div><img src ="http://m.tkk7.com/libin2722/aggbug/287816.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/libin2722/" target="_blank">C物</a> 2009-07-22 11:12 <a href="http://m.tkk7.com/libin2722/articles/287816.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>比较有用的log4j.propertieshttp://m.tkk7.com/libin2722/articles/287815.htmlC物C物Wed, 22 Jul 2009 03:10:00 GMThttp://m.tkk7.com/libin2722/articles/287815.htmlhttp://m.tkk7.com/libin2722/comments/287815.htmlhttp://m.tkk7.com/libin2722/articles/287815.html#Feedback0http://m.tkk7.com/libin2722/comments/commentRss/287815.htmlhttp://m.tkk7.com/libin2722/services/trackbacks/287815.htmllog4j.rootLogger=DEBUG,CONSOLE,DATABASE,FILE
log4j.addivity.org.apache=true

# 应用于控制台
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Threshold=INFO
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.Encoding=GBK
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n

# 用于数据?br />#log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender
#log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/ww
#log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver
#log4j.appender.DATABASE.user=root 
#log4j.appender.DATABASE.password=123
#log4j.appender.CONSOLE.Threshold=WARN
#log4j.appender.DATABASE.sql=INSERT INTO LOG4J(stamp,thread, infolevel,class,messages) VALUES ('%d{yyyy-MM-dd HH:mm:ss}', '%t', '%p', '%l', '%m')
# INSERT INTO LOG4J (Message) VALUES ('[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n')
# 写入数据库中的表LOG4J的Message字段中,内容QdQ日期)%c: 日志信息所在地Q类名)%p: 日志信息U别%m: 产生的日志具体信?%n: 输出日志信息换行
#log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout
#log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n

# 每天新徏日志
log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A1.File=C:/log4j/log
log4j.appender.A1.Encoding=GBK
log4j.appender.A1.Threshold=DEBUG
log4j.appender.A1.DatePattern='.'yyyy-MM-dd
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L : %m%n

#应用于文?br />log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=C:/log4j/file.log
log4j.appender.FILE.Append=false
log4j.appender.FILE.Encoding=GBK
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n

# 应用于文件回?br />log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender
log4j.appender.ROLLING_FILE.Threshold=ERROR
log4j.appender.ROLLING_FILE.File=rolling.log
log4j.appender.ROLLING_FILE.Append=true
log4j.appender.CONSOLE_FILE.Encoding=GBK
log4j.appender.ROLLING_FILE.MaxFileSize=10KB
log4j.appender.ROLLING_FILE.MaxBackupIndex=1
log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.ROLLING_FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n

#自定义Appender
log4j.appender.im = net.cybercorlin.util.logger.appender.IMAppender
log4j.appender.im.host = mail.cybercorlin.net
log4j.appender.im.username = username
log4j.appender.im.password = password
log4j.appender.im.recipient = corlin@cybercorlin.net
log4j.appender.im.layout=org.apache.log4j.PatternLayout
log4j.appender.im.layout.ConversionPattern =[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n

#应用于socket
log4j.appender.SOCKET=org.apache.log4j.RollingFileAppender
log4j.appender.SOCKET.RemoteHost=localhost
log4j.appender.SOCKET.Port=5001
log4j.appender.SOCKET.LocationInfo=true
# Set up for Log Facter 5
log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout
log4j.appender.SOCET.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD]%n%c[CATEGORY]%n%m[MESSAGE]%n%n
# Log Factor 5 Appender
log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender
log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000

# 发送日志给邮g
log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender
log4j.appender.MAIL.Threshold=FATAL
log4j.appender.MAIL.BufferSize=10
log4j.appender.MAIL.From=web@www.wuset.com
log4j.appender.MAIL.SMTPHost=www.wusetu.com
log4j.appender.MAIL.Subject=Log4J Message
log4j.appender.MAIL.To=web@www.wusetu.com
log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout
log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n



C物 2009-07-22 11:10 发表评论
]]>
使用相对路径加蝲Log4j配置文ghttp://m.tkk7.com/libin2722/articles/287813.htmlC物C物Wed, 22 Jul 2009 02:59:00 GMThttp://m.tkk7.com/libin2722/articles/287813.htmlhttp://m.tkk7.com/libin2722/comments/287813.htmlhttp://m.tkk7.com/libin2722/articles/287813.html#Feedback0http://m.tkk7.com/libin2722/comments/commentRss/287813.htmlhttp://m.tkk7.com/libin2722/services/trackbacks/287813.html
URL url  =  UserServiceImpl. class .getResource( " /config/log4j.properties " );
Properties properties 
=   new  Properties();
try  {
     properties.load(
new  InputStreamReader(url.openStream()));
    } 
catch  (IOException e) {
        e.printStackTrace();
    }
PropertyConfigurator.configure(properties);

/config/log4j.properties 可以攑֜对应的jar文g?/span>


C物 2009-07-22 10:59 发表评论
]]>
使用 Web Service Appender for Log4j 理日志U录http://m.tkk7.com/libin2722/articles/286831.htmlC物C物Wed, 15 Jul 2009 03:49:00 GMThttp://m.tkk7.com/libin2722/articles/286831.htmlhttp://m.tkk7.com/libin2722/comments/286831.htmlhttp://m.tkk7.com/libin2722/articles/286831.html#Feedback0http://m.tkk7.com/libin2722/comments/commentRss/286831.htmlhttp://m.tkk7.com/libin2722/services/trackbacks/286831.html使用定制?Web Service Appender for Log4j 日志信息发送到某一集中位置。Log4j Appender 使?zhn)可以在面向服务架?(SOA) 解决Ҏ(gu)中调试和跟踪L问题?/blockquote>

引言

? 可以使用 Web Service Appender 日志集中到某一位置Q同ӞWeb Service Appender 允许理者监控、开发者调试面向服务架?SOA)环境里可能存在的M问题。Web Service Appender 是一U扩?JAVA c,它由 Log4j ?Appender cL展而来?/p>

从定义上看,SOA 是一U彼此可以互盔R信的服务集合,但这些服务的内容是各自独立的Q每一cL务均不受其它服务内容或服务状态的影响Qƈ且这些服务都工作在分布式的系l架 构里。在 SOA 中,Web 服务通常被用来在l定事务中处理请求,q些h可以是遗留代码、企业 Java Beans(EJBs) 的封装,也可以是 Java cȝ装Q用一U可以将日志信息聚集在中心位|里的日志纪录方法,能帮助?zhn)隔离~陷和问题,q能让你更好的理解逻辑的处理?

特定模块或服务的日志消息纪录到一个中心位|的机制Q可以把可能潜在的问题和~陷降低到最?/p>

本文?Log4j 的功能进行了大体的概qͼq介l了如何~写自定义的 Log4j AppenderQ这cȝD的 Appender 日志消息编CU特定的 Web 服务?/p>



回页?/b>


Log4j 快速入?/span>

Log4j 是一U开放源代码的日志库Q它已被发展?Apache Software Foundation 日志服务目的子目。该库是?IBM ?90 q代末开发的日志库ؓ基础的,W一版发布于 1999 q。现在它在开放源代码团体得到了广泛用,它的体系是围l以下三个主要概忉|v来的Q?/p>

  • Logger
  • Appender
  • Layout

q些概念可以让?zhn)?gu)消息cd、消息优先来纪录消息,(zhn)可以控制消息在何处l束及消息如何格式化? Logger 是应用程序首先调用以初始化消息纪录的对象。当把某一消息传递给日志Ӟlogger 会生?LoggingEventQ对消息q行装。之后,Logger 对象?LoggingEvent 传递给与之兌?Appender?/p>

Appender ?LoggingEvent 所包含的消息发送给指定的目标输出文件。所谓指定的文gQ大多数情况下,?Log4 属性文件。一?Appender 存在?Log4j 中。?zhn)也可以扩?AppenderQ之支持其它的目标文gQ比?XML 文g、控制台{等?/p>

?Log4j 里, LoggingEvent 被赋予某一U别Q以表明它们的优先。缺省的U别包括如下几种Q?

  • OFFQ可能是最高的U别Q它是用来关闭日志纪录的
  • FATALQ指出现了非怸重的错误事gQ这些错误可能会D应用E序异常中止
  • ERRORQ指虽有错误Q但仍允许应用程序l运?/li>
  • WARNQ指q行环境潜藏着危害
  • INFOQ指报告信息Q这些信息在_粒度别上H出昄应用E序的进E?/li>
  • DEBUGQ指l粒度信息事Ӟl粒度信息事件对于应用程序的调试是最有用?/li>
  • ALLQ可能是最低的U别Q其目的是打开所有日志记?/li>
Logger ?Appender 也被赋予上述的某一U别Qƈ且仅执行{于或高于它们自w的U别的日志请求。比如,如果一?Appender 属于 INFO U别Q而日志请求属?DEBUGQ那?Appender 不会ؓl定的日志事件写消息?



回页?/b>


客户端组?/span>

客户?log4j.properties 文g

客户?log4j.properties 文g是一U标准文Ӟ它包含服务或模块使用的所?Appender。Web Service Appender 要求有一?i>端点QendpointQ?/i> 属性以指定所使用的日志服务?/p>

清单 1 描述了?WebServiceAppender 所必需?Web 服务客户?Log4j 属性?黑体昄的文本指明了访?WebServiceAppender 服务器端?Appender。属性文件是使用 Log4j 的基本需求,它可以让(zhn)配|应用程序以使用多个 Appender 以及 logging severity。一旦应用程序进入运行状态或潜在的问题得到解冻I(zhn)就可以LC改属性文件?/p>
清单 1Q客L Log4j 的属性文?/b>

#set the level of the root logger
log4j.rootLogger = INFO, CONSOLE
#set own logger
log4j.logger.com.carmelouria.logging.test=CONSOLE
log4j.appender.CONSOLE=com.carmelouria.logging.WebServiceAppender
log4j.appender.CONSOLE.endpoint=
http://localhost:9080/log4j/services/LogAppenderService

log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%p [%t] %c{2} (%M:%L) :: %m%n





回页?/b>


服务器的 Log4j.properties 文g

? 务器 Log4j.properties 文g被用来关联客L Log4j 属性文Ӟ它指定了日志的别及服务器将如何输出消息。对于支? Log4j 的应用程序,(zhn)可以定义多?appender。当Ӟq些 appender 既可以用于客L服务Q也可以用于服务模块?/p>

清单 2 描述了一份典型的 Log4j 属性文Ӟ服务器端?WebServiceAppender 使用~省?Log4j Appenders。服务器端的 Appender 可以潜在的调用另一?WebServiceAppenderQƈ日志信?i>链接hQ?/p>
清单 2Q服务器端的 Log4j 属性文?/b>

#set the level of the root logger
log4j.rootLogger = INFO, FILE
#set own logger
log4j.appender.FILE=org.apache.log4j.RollingFileAppender
log4j.appender.FILE.file=c:/temp/log4j/server/server.log
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=%p [%t] %c{2} (%M:%L) :: %m%n

客户端程序测试示例:

q个客户端程序示例是无格式普?Java 对象(POJO)Q它记录了一条消息,q被配置Z?Web Service Appender 来处理消息?a >清单 3 昄了这个示例:


清单 3Q客L应用E序使用 WebServiceAppender 的示?/b>

package com.carmelouria.logging.test;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
/**
* @author Carmelo Uria
*
*/
public class LoggingSample
{
private static Logger logger = Logger.getLogger(LoggingSample.class.getName());
/**
*
*/
public LoggingSample()
{
super();
PropertyConfigurator.configure("c:/temp/log4j.properties");
logger.log(Level.INFO, "LoggingSample instantiation...");
System.out.println("finished...");
}
public static void main(String[] args)
{
LoggingSample sample = new LoggingSample();
}
}





回页?/b>


WebServiceAppender

WebServiceAppender 是必需的,它可以将消息发送到指定?Web 服务?code>WebServiceAppender l承?org.log4j.AppenderQ它允许使用 log4.propertiesQƈ成ؓ有效?Log4j Appender?/p>

WebServiceAppender 使用Z XML 的远E过E调?(JAX-RPC) ?Java APIQ来消息发送到服务器。JAX-RPC 是一U规范,它描qC? RPC ?XML 构徏 Web 服务?Web 服务客户端的应用~程接口 (API) 和约定。JAX-RPC 又被UCؓ JSR 101?/p>

LoggingEvent 通过 SOAPElement 被分割ƈ表示?XML。javax.xml.soap.SOAPElement 接口意味着服务端点接口包含一个参敎ͼ或返?javax.xml.soap.SOAPElement cd的|以对应于 schema 中每个?code><xsd:any/>的地斏V从本质上看Q它?XML 参数的封装,且没有相应的序列?反序列化 JAVA cR例如,一旦客戯求记录一个消息,׃创徏一?LoggEvent 对象Q然后传送给 Appender。在q种情况下,Appender 是 WebServiceAppender。Appender 索事Ӟq在解析事g中的信息。一些额外的信息会被加入Q如L名称Q这hq道这些消息来自哪个系l。同Ӟappend Ҏ(gu)也将消息转换?SOAPElementQ这样就可以通过 executeWebService Ҏ(gu)消息传递给 Web 服务。?SOAPElement 充分考虑?WebServiceAppender 未来版本的可扩展性问题?/p>
清单4Q执?WebServiceAppender 服务?Append Ҏ(gu)

protected void append(LoggingEvent event)
{
// create Web Service client using endpoint
if (endpoint == null)
{
System.out.println("no endpoint set. Check configuration file");
System.out.println("[" + hostname + "] " + this.layout.format(event));
return;
}
executeWebService(event);
}
private void executeWebService(LoggingEvent event)
{
SoapClient client = new SoapClient();
URL endPoint = null;
try
{
endPoint = new URL(getendpoint());
}
catch (MalformedURLException e1)
{
e1.printStackTrace();
}
String nameSpace = "http://ejb.logging.carmelouria.com";
QName serviceName = new QName(nameSpace, "LogAppenderServiceService");
QName operation = new QName(nameSpace, "log");
QName port = new QName(nameSpace, "LogAppenderService");
Parameter message =
new Parameter("log", Constants.XSD_ANY, SOAPElement.class, ParameterMode.IN);
try
{
/**
*create SOAPElement from LoggingEvent need hostname
*/
Level level = event.getLevel();
String sysLog = "<syslog>" + new Integer(level.getSyslogEquivalent()).toString()
+ "</syslog>";
String startTime = new Long(LoggingEvent.getStartTime()).toString();
String timeTag = "<start_time>" + startTime + "</start_time>";
String hostName = "<hostname>" + InetAddress.getLocalHost() +
"</hostname>";
String threadName = "<thread_name>" + event.getThreadName()
+"</thread_name>";
String logger = "<logger>" + event.getLoggerName() + "</logger>";
String eventMessage = "<message>" + event.getRenderedMessage() +
"</message>";
String log = hostName + threadName + logger + timeTag + sysLog +
eventMessage;
String throwableInformation[] = event.getThrowableStrRep();
if (throwableInformation != null)
{
for (int i = 0; i < throwableInformation.length; i++)
{
String throwable = "<throwable_information>" + throwableInformation[i] +
"</throwable_information>";
log += throwable;
}
}
String ndcString = event.getNDC();
if (throwableInformation != null)
{
String throwable = <ndc>" + ndcString + </ndc>";
log += throwable;
}
message.setValue(SOAPElementFactory.create(<log>" + log + </log>"));
}
catch (UnknownHostException unknownHostException)
{
unknownHostException.printStackTrace();
}
catch (SOAPException e2)
{
e2.printStackTrace();
}
Parameter resultType = newParameter("logResponse",
Constants.WEBSERVICES_VOID,
Object.class,
ParameterMode.OUT);
Parameter[] parameters = { message };
try
{
// execute client
Object result =
client.execute(endPoint, serviceName, operation, "wrapped", null,
port, resultType, parameters);
if ((result != null) && (result instanceof String))
System.out.println((String) result);
}
catch (ClientException e)
{
e.printStackTrace();
}
}

Hostname

不幸的是QLog4j ?LoggingEvent 没有包含 HostnameQ?Hostname ?Web Service Appender 众多需求之一。在创徏 SOAPElement 以前Q?zhn)可以用下面的语句?Hostname d?XML 文g里:

String hostName = "<hostname>" + InetAddress.getLocalHost() + "</hostname>";

SoapElementFactory

SoapElementFactory 是主要用于创?SOAPElement 的类。它同时支持创徏 IBM ?Java ?SOAPElement 实现Q如清单 5 所C:


清单 5Q?SoapElementFactory cȝ创徏Ҏ(gu)

public static javax.xml.soap.SOAPElement create(String xml) throws SOAPException
{
com.ibm.ws.webservices.engine.xmlsoap.SOAPFactory factory =
(com.ibm.ws.webservices.engine.xmlsoap.SOAPFactory)
com.ibm.ws.webservices.engine.xmlsoap.SOAPFactory
.newInstance();
SOAPElement element =
(javax.xml.soap.SOAPElement)factory.createElementFromXMLString(xml);
return(element);
}
public static SOAPElement create(String arg0, String arg1, String arg2,
boolean ibmSoapElement) throws
SOAPException
{
if (ibmSoapElement)
{
SOAPFactory soapFactory =
(com.ibm.ws.webservices.engine.xmlsoap.SOAPFactory)
com.ibm.ws.webservices.engine.xmlsoap.SOAPFactory.newInstance();
return (soapFactory.createSOAPElement(arg0, arg1));
}
javax.xml.soap.SOAPFactory soapFactory =
javax.xml.soap.SOAPFactory.newInstance();
return (soapFactory.createElement(arg0, arg1, arg2));
}

SoapClient

SoapClient cd装了 Call 接口?JAX-RPC 实现Qjavax.xml.rpc.Call 接口提供了对服务端点动态调用的支持。javax.xml.rpc.Service 接口好象是创徏 Call 实例的工厂?/p>

清单 6 说明了客L如何动态调用服务。这允许Ҏ(gu)务进行变_而无需生成客户端代理来讉Kq程服务?/p>
清单 6Q?SoapClient cȝ调用Ҏ(gu)

private Object call(SoapService service, QName operation, QName portType,
String operationStyleProperty,
String encodingURIProperty, Parameter returnType,
Parameter[] parameters) throws ClientException
{
QName portName;
String response = null;
Object results = null;
Call call = null;
try
{
// check to see if Service object exists
if (service == null)
throw new ClientException("Invalid Service object. It maybe null.");
// retrieve call from Service object
call = service.createCall();
call.setOperationName(operation);
call.setPortTypeName(portType);
// check call object
if (call == null)
throw new ClientException("invalid operation. Call object is null.");
// set default values
if (operationStyleProperty == null)
call.setProperty(Call.OPERATION_STYLE_PROPERTY,
OPERATION_STYLE_DOCUMENT_TYPE);
else
call.setProperty(Call.OPERATION_STYLE_PROPERTY,
operationStyleProperty);
if (encodingURIProperty == null)
call.setProperty(Call.ENCODINGSTYLE_URI_PROPERTY,
ENCODING_LITERAL);
else
call.setProperty(Call.ENCODINGSTYLE_URI_PROPERTY,
encodingURIProperty);
call.setTargetEndpointAddress(service.getServiceEndPoint());
//create Parameter class for SoapClient
for (int i = 0; i < parameters.length; i++)
{
Class classObject = parameters[i].getClassObject();
if (classObject != null)
call.addParameter(parameters[i].getName(), parameters[i].getXmlType(),
parameters[i].getClassObject(), parameters[i].getMode());
else
call.addParameter(parameters[i].getName(), parameters[i].getXmlType(),
parameters[i].getMode());
}
// pass parameter as ReturnType
if (returnType != null)
{
if (returnType.getClassObject() != null)
call.setReturnType(returnType.getXmlType(), returnType.getClassObject());
else
call.setReturnType(returnType.getXmlType());
}
Object[] request = new Object[parameters.length];
// add parameter values
for (int i = 0; i < request.length; i++)
{
request[i] = parameters[i].getValue();
}
results = call.invoke(request);
}
catch (SOAPFaultException e)
{
System.out.println(e.getFaultString());
e.getStackTrace();
throw new ClientException(e.getLocalizedMessage(), e);
}
catch (ServiceException serviceException)
{
serviceException.getStackTrace();
throw new ClientException(serviceException.getLocalizedMessage(),
serviceException);
}
catch (RemoteException exception)
{
exception.printStackTrace();
throw new ClientException(exception.getLocalizedMessage(), exception);
}
return (results); }





回页?/b>


服务lg

Log4j.server.properties

Log4j.server.properties 文g包含了一个基本的 Log4j 配置文gQ该文g可以让?zhn)指定把哪些日志发送给 Web 服务pȝ?/p>
清单 7QLog4j.server.properties 文g

#set the level of the root logger
log4j.rootLogger = INFO, FILE
#set own logger
log4j.appender.FILE=org.apache.log4j.RollingFileAppender
log4j.appender.FILE.file=c:/temp/log4j/server/server.log
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=%p [%t] %c{2} (%M:%L) :: %m%n

LogAppenderBean.java

LogAppenderBean.java ?Web Service Appender 服务所要用的 EJB。该服务启动 LogAppenderBean 以处理来自每?Web Service Appender 客户端的每一个请求?/p>

清单 8 昄了来?WebServiceAppender EJB ?log Ҏ(gu)Q该Ҏ(gu)解析来自客户端的消息Qƈ客L信息U录到服务的服务器端?/p>
清单 8QLogAppenderBean ?log Ҏ(gu)

public void log(SOAPElement message)
{
try
{
InputSource source = ((IBMSOAPElement)
message).toInputSource(false);
Document document = Parser.parse(source);
String log = null;
String hostname =
document.selectSingleNode("http://hostname").getText();
String threadName =
document.selectSingleNode("http://thread_name").getText();
String syslog =
document.selectSingleNode("http://syslog").getText();
String startTime = new Long(
document.selectSingleNode("http://start_time").
getText()).toString();
log = '[' + startTime + ':' + hostname + ':' + threadName +
"] " + document.selectSingleNode(
"http://message").getText();
// retrieve any throwable messages
List throwableList = document.selectNodes(
"http://throwable_information");
if(throwableList != null)
{
Iterator throwables = throwableList.iterator();
while(throwables.hasNext())
{
log += '\n' + ((Node)throwables.next()).getText();
}

log += '\n';
}

logger.log(Level.toLevel(new Integer(syslog).intValue()),
log);
logger.log(Level.INFO,log);
}
catch(ParserException parseException)
{
parseException.printStackTrace();
}
catch (SAXException e)
{
e.printStackTrace();
}
}

通过 IBM SOAPElement ?InputSourceQ每一?SOAPElement 的内定w会被索。目前,只有 IBM WebSphere] Application Server (Application Server) 支持q些代码Q请参阅参考资?/a>Q?然而,如果(zhn)移?IBM SOAPElementQ那么?zhn)可以在M应用服务器上使用q些代码。IBM SOAPElement 内置的性能优化也适用?Application Server?/p>

每一?SOAPElement 都?Dom4j 来读取、解析和转换。Dom4j 是一U在内存中表C?XML 树的对象模型。Dom4j 提供了一l易于用的 APIQ从而ؓ我们提供了一整套强大的功能来处理、操作或定位 XMLQ?XPath ?XSLT q行工作Q以及与 SAX? JAXP、DOM 集成?/p>

除了可以使用L?XML 解析器外QDOM4J q允怋用Q意的 SAX 解析器,为实现更好的性能Q还允许使用所有标准的 XSLT 转换器? 转换被用来析取发送给 Web Service Appender 的客L LoggingEvent 的元素?/p>

如果(zhn)允怋?SOAPElementQ那么就需要在代码中维持最大限度的灉|性。Web Service Appender 服务可以被修改,以支持所有发送给服务?XML?





回页?/b>


输出

下面的示例展CZ Web Service Appender 的可能的输出Q?/p>

INFO [WebContainer : 0] ejb.LogAppenderBean (log:?) :: [1111513482641:OO7-64BIT/9.48.114.183:main]LoggingSample instantiation...

OO7-64BIT/9.48.114.183 是机器名?IP 地址Q?main 是日志所在处的方法名?/p>



回页?/b>


l束?/span>

Web Service Appender 是将日志集中到某一位置的基本工兗由?Web Service Appender ?Log4j ? Appender cȝ子集Q因而配|和使用 Appender 都非常简单易懂。?zhn)可以修?Log4j 的属性文Ӟq样Q?Log4j 的现有应用程序和服务可以马上?Web Service Appender?/p>




回页?/b>


下蝲

描述名字大小下蝲Ҏ(gu)
Foundation Class Libraryfoundation.zip47 KBHTTP
Logging Web Service J2EE ApplicationLoggingWebService.ear1976 KBHTTP
Unit Test Sample CodeSoapClientTest.java5 KBHTTP


C物 2009-07-15 11:49 发表评论
]]>
վ֩ģ壺 1000žžʮδֹۿ | ޹ŮƵ| þѾƷһ| ҹ޾ƷС˵| ۺ| ҹƵվ| ۺŷ㻨| ëƬƵ| ˾Ʒþ޸岻| ѿƸվƵ| ˵վ| ƵƷѵĹ| ½޾Ʒ| ëƬav߲һ| ŮоƷվѹۿ| þþƷ˵| ѹۿ߽Ƭ| ޹˾ƷӰ| ëƬAëƬѲ| avĻɫ| ѳҹƵ| Ƶ| ޹Ʒۺϸר| ëƬƵ| Ů۳Ƶ߿| A޾VƷ| 99ֻоƷ6| ޹ƷۺϾþ20| һƵ| aëƬ˾þ| ޳aƬ7777| ѹԺ߹ۿ| ҹѿƬڵ| ޾ƷĻ鶹| 鶹VAѾƷ | ŮëƬѲƵm| Ʒֻ| ޹Ʒva߲| ѿһëƬ| aëƬѹۿ| ޹պۺϾþþƷ|