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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 package org.apache.log4j.varia;
20 import java.io.DataInputStream;
21 import java.io.DataOutputStream;
22 import java.io.IOException;
23 import java.io.InterruptedIOException;
24 import java.net.ServerSocket;
25 import java.net.Socket;
27 import org.apache.log4j.RollingFileAppender;
28 import org.apache.log4j.helpers.LogLog;
31 This appender listens on a socket on the port specified by the
32 <b>Port</b> property for a "RollOver" message. When such a message
33 is received, the underlying log file is rolled over and an
34 acknowledgment message is sent back to the process initiating the
37 <p>This method of triggering roll over has the advantage of being
38 operating system independent, fast and reliable.
40 <p>A simple application {@link Roller} is provided to initiate the
43 <p>Note that the initiator is not authenticated. Anyone can trigger
44 a rollover. In production environments, it is recommended that you
45 add some form of protection to prevent undesired rollovers.
48 @author Ceki Gülcü
49 @since version 0.9.0 */
50 public class ExternallyRolledFileAppender extends RollingFileAppender {
53 The string constant sent to initiate a roll over. Current value of
54 this string constant is <b>RollOver</b>.
56 static final public String ROLL_OVER = "RollOver";
59 The string constant sent to acknowledge a roll over. Current value of
60 this string constant is <b>OK</b>.
62 static final public String OK = "OK";
68 The default constructor does nothing but calls its super-class
71 ExternallyRolledFileAppender() {
75 The <b>Port</b> [roperty is used for setting the port for
76 listening to external roll over messages.
79 void setPort(int port) {
84 Returns value of the <b>Port</b> option.
92 Start listening on the port specified by a preceding call to
95 void activateOptions() {
96 super.activateOptions();
101 hup = new HUP(this, port);
109 class HUP extends Thread {
112 ExternallyRolledFileAppender er;
114 HUP(ExternallyRolledFileAppender er, int port) {
121 while(!isInterrupted()) {
123 ServerSocket serverSocket = new ServerSocket(port);
125 Socket socket = serverSocket.accept();
126 LogLog.debug("Connected to client at " + socket.getInetAddress());
127 new Thread(new HUPNode(socket, er), "ExternallyRolledFileAppender-HUP").start();
129 } catch(InterruptedIOException e) {
130 Thread.currentThread().interrupt();
132 } catch(IOException e) {
134 } catch(RuntimeException e) {
141 class HUPNode implements Runnable {
145 DataOutputStream dos;
146 ExternallyRolledFileAppender er;
149 HUPNode(Socket socket, ExternallyRolledFileAppender er) {
150 this.socket = socket;
153 dis = new DataInputStream(socket.getInputStream());
154 dos = new DataOutputStream(socket.getOutputStream());
155 } catch(InterruptedIOException e) {
156 Thread.currentThread().interrupt();
158 } catch(IOException e) {
160 } catch(RuntimeException e) {
167 String line = dis.readUTF();
168 LogLog.debug("Got external roll over signal.");
169 if(ExternallyRolledFileAppender.ROLL_OVER.equals(line)) {
173 dos.writeUTF(ExternallyRolledFileAppender.OK);
176 dos.writeUTF("Expecting [RollOver] string.");
179 } catch(InterruptedIOException e) {
180 Thread.currentThread().interrupt();
181 LogLog.error("Unexpected exception. Exiting HUPNode.", e);
182 } catch(IOException e) {
183 LogLog.error("Unexpected exception. Exiting HUPNode.", e);
184 } catch(RuntimeException e) {
185 LogLog.error("Unexpected exception. Exiting HUPNode.", e);