View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.log4j.nt;
19  
20  import org.apache.log4j.AppenderSkeleton;
21  import org.apache.log4j.Layout;
22  import org.apache.log4j.TTCCLayout;
23  import org.apache.log4j.helpers.LogLog;
24  import org.apache.log4j.spi.LoggingEvent;
25  
26  
27  /**
28     Append to the NT event log system.
29  
30     <p><b>WARNING</b> This appender can only be installed and used on a
31     Windows system.
32  
33     <p>Do not forget to place NTEventLogAppender.dll,
34     NTEventLogAppender.amd64.dll, NTEventLogAppender.ia64.dll
35     or NTEventLogAppender.x86.dll as appropriate in a
36     directory that is on the PATH of the Windows system. Otherwise, you
37     will get a java.lang.UnsatisfiedLinkError.
38  
39     @author <a href="mailto:cstaylor@pacbell.net">Chris Taylor</a>
40     @author <a href="mailto:jim_cakalic@na.biomerieux.com">Jim Cakalic</a> */
41  public class NTEventLogAppender extends AppenderSkeleton {
42    private int _handle = 0;
43  
44    private String source = null;
45    private String server = null;
46  
47  
48    public NTEventLogAppender() {
49      this(null, null, null);
50    }
51  
52    public NTEventLogAppender(String source) {
53      this(null, source, null);
54    }
55  
56    public NTEventLogAppender(String server, String source) {
57      this(server, source, null);
58    }
59  
60    public NTEventLogAppender(Layout layout) {
61      this(null, null, layout);
62    }
63  
64    public NTEventLogAppender(String source, Layout layout) {
65      this(null, source, layout);
66    }
67  
68    public NTEventLogAppender(String server, String source, Layout layout) {
69      if (source == null) {
70        source = "Log4j";
71      }
72      if (layout == null) {
73        this.layout = new TTCCLayout();
74      } else {
75        this.layout = layout;
76      }
77  
78      try {
79        _handle = registerEventSource(server, source);
80      } catch (Exception e) {
81        e.printStackTrace();
82        _handle = 0;
83      }
84    }
85  
86    public
87    void close() {
88      // unregister ...
89    }
90  
91    public
92    void activateOptions() {
93      if (source != null) {
94        try {
95     _handle = registerEventSource(server, source);
96        } catch (Exception e) {
97     LogLog.error("Could not register event source.", e);
98     _handle = 0;
99        }
100     }
101   }
102 
103 
104   public void append(LoggingEvent event) {
105 
106     StringBuffer sbuf = new StringBuffer();
107 
108     sbuf.append(layout.format(event));
109     if(layout.ignoresThrowable()) {
110       String[] s = event.getThrowableStrRep();
111       if (s != null) {
112    int len = s.length;
113    for(int i = 0; i < len; i++) {
114      sbuf.append(s[i]);
115    }
116       }
117     }
118     // Normalize the log message level into the supported categories
119     int nt_category = event.getLevel().toInt();
120 
121     // Anything above FATAL or below DEBUG is labeled as INFO.
122     //if (nt_category > FATAL || nt_category < DEBUG) {
123     //  nt_category = INFO;
124     //}
125     reportEvent(_handle, sbuf.toString(), nt_category);
126   }
127 
128 
129   public
130   void finalize() {
131     deregisterEventSource(_handle);
132     _handle = 0;
133   }
134 
135   /**
136      The <b>Source</b> option which names the source of the event. The
137      current value of this constant is <b>Source</b>.
138    */
139   public
140   void setSource(String source) {
141     this.source = source.trim();
142   }
143 
144   public
145   String getSource() {
146     return source;
147   }
148 
149 /**
150      The <code>NTEventLogAppender</code> requires a layout. Hence,
151      this method always returns <code>true</code>. */
152   public
153   boolean requiresLayout() {
154     return true;
155   }
156 
157   native private int registerEventSource(String server, String source);
158   native private void reportEvent(int handle, String message, int level);
159   native private void deregisterEventSource(int handle);
160 
161   static {
162     String[] archs;
163     try {
164         archs = new String[] { System.getProperty("os.arch")};
165     } catch(SecurityException e) {
166         archs = new String[] { "amd64", "ia64", "x86"};
167     }
168     boolean loaded = false;
169     for(int i = 0; i < archs.length; i++) {
170         try {
171             System.loadLibrary("NTEventLogAppender." + archs[i]);
172             loaded = true;
173             break;
174         } catch(java.lang.UnsatisfiedLinkError e) {
175             loaded = false;
176         }
177     }
178     if (!loaded) {
179         System.loadLibrary("NTEventLogAppender");
180     }
181 }
182 }