summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreea1 <eea1@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1999-08-24 23:12:20 +0000
committereea1 <eea1@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1999-08-24 23:12:20 +0000
commitb1e6c61c9647b7ceaadfc7f35a0e88070ec80baa (patch)
tree341b00fac0bbf39dc1a853cf3282198e8c4f0673
parent5d089e7886f85b6a5d64740fa9bb6ee7e0f7b128 (diff)
downloadATCD-b1e6c61c9647b7ceaadfc7f35a0e88070ec80baa.tar.gz
Updated source files for netsvcs/Logger.
-rw-r--r--java/JACE/netsvcs/Logger/LogRecord.java290
-rw-r--r--java/JACE/netsvcs/Logger/LoggingStrategy.java35
-rw-r--r--java/JACE/netsvcs/Logger/ServerLoggingAcceptor.java147
-rw-r--r--java/JACE/netsvcs/Logger/ServerLoggingHandler.java60
-rw-r--r--java/JACE/netsvcs/Logger/StderrStrategy.java30
-rw-r--r--java/JACE/netsvcs/Logger/c.bat2
-rw-r--r--java/JACE/netsvcs/Logger/package.html17
7 files changed, 581 insertions, 0 deletions
diff --git a/java/JACE/netsvcs/Logger/LogRecord.java b/java/JACE/netsvcs/Logger/LogRecord.java
new file mode 100644
index 00000000000..972cf45af74
--- /dev/null
+++ b/java/JACE/netsvcs/Logger/LogRecord.java
@@ -0,0 +1,290 @@
+/*************************************************
+ *
+ * = PACKAGE
+ * JACE.netsvcs.Logger
+ *
+ * = FILENAME
+ * LogRecord.java
+ *
+ *@author Chris Cleeland, Everett Anderson
+ *
+ *************************************************/
+package JACE.netsvcs.Logger;
+
+import java.util.*;
+import java.io.*;
+import JACE.OS.*;
+
+/**
+ * Communicates logging information. Compatible with the C++ ACE
+ * ACE_Log_Record class.
+ */
+public class LogRecord
+{
+ /**
+ * Maximum size of a LogRecord
+ */
+ final public int MAXLOGMSGLEN = 4 * 1024;
+
+ private int type_;
+ private int length_;
+ private long msec_;
+ private int pid_;
+ private byte[] msgData_;
+ private final static int numIntMembers = 5;
+ private final static int sizeofIntInBytes = 4;
+
+ /**
+ * Create a default instance.
+ */
+ public LogRecord()
+ {
+ type(0);
+ timeStamp((int)new Date().getTime());
+ length(0);
+ pid(0);
+ }
+
+ /**
+ * Create a LogRecord. This is the designated initializer.
+ * @param priority a numeric specification of the priority (ascending)
+ * @param milliseconds time attached to the log entry in Unix <pre>time_t</pre> format
+ * @param pid the process ID
+ */
+ public LogRecord(int priority,
+ long milliseconds,
+ int pid)
+ {
+ type(priority);
+ timeStamp(milliseconds);
+ length(0);
+ pid(pid);
+ }
+
+ /**
+ * Create a LogRecord with the current time and the given message.
+ *
+ *@param message message to log
+ */
+ public LogRecord (String message)
+ {
+ this ();
+
+ msgData (message);
+ }
+
+ /**
+ * Conversion to string. Only includes the <pre>msgData_</pre> member.
+ */
+ public String toString()
+ {
+ String result = null;
+ try {
+ result = new String (msgData_,
+ "US-ASCII");
+ } catch (UnsupportedEncodingException e) {
+ result = new String (msgData_);
+ }
+
+ return result;
+ }
+
+ /**
+ * Place a textual representation of the record on a PrintStream.
+ * When verbose is specified to be true, the output takes the form
+ * <PRE>(Date)@(host name)@(PID)@(type)@(message)</PRE>
+ * Otherwise it just prints the message.
+ * @param hostname name of the host generating this record
+ * @param verbose specify how much information to print (see above)
+ * @param ps A PrintStream instance to which the output should go.
+ */
+ public void print(String hostname,
+ boolean verbose,
+ PrintStream ps)
+ {
+ String toprint;
+ if (verbose)
+ {
+ Date now = new Date(this.timeStamp());
+
+ /* 01234567890123456789012345 */
+ /* Wed Oct 18 14:25:36 1989n0 */
+ toprint = now.toString().substring(4) + "@"
+ + hostname + "@" + pid_ + "@" + type_ + "@"
+ + this.toString();
+ }
+ else
+ {
+ toprint = this.toString();
+ }
+ ps.println(toprint);
+ }
+
+ /**
+ * Read in the data for this LogRecord from the given InputStream.
+ *
+ *@param is InputStream to read from
+ *@exception IOException error during transmission
+ */
+ public void streamInFrom (InputStream is) throws IOException
+ {
+ BufferedInputStream bis = new BufferedInputStream (is);
+
+ DataInputStream dis = new DataInputStream (bis);
+
+ streamInFrom (dis);
+ }
+
+ /**
+ * Read in the data for this LogRecord from the given DataInputStream.
+ *
+ *@param dis DataInputStream to read from
+ *@exception IOException error during transmission
+ */
+ public void streamInFrom(DataInputStream dis) throws IOException
+ {
+ // Order here must match layout order in the C++ class.
+ length(dis.readInt());
+ type(dis.readInt());
+ this.timeStamp((long)dis.readInt() * 1000);
+
+ // Skip smaller time resolution info since we're lucky if Java's
+ // timer can handle more than millisecond precision, anyway
+ dis.skipBytes(4);
+
+ pid(dis.readInt());
+
+ int dataLength = (int) (length_ - numIntMembers * sizeofIntInBytes);
+
+ msgData_ = new byte[dataLength];
+
+ dis.readFully(msgData_, 0, dataLength);
+ }
+
+ /**
+ * Write this LogRecord out to the given OutputStream.
+ *
+ *@param os OutputStream to write to
+ *@exception IOException error during transmission
+ */
+ public void streamOutTo (OutputStream os) throws IOException
+ {
+ BufferedOutputStream bos = new BufferedOutputStream (os);
+
+ DataOutputStream dos = new DataOutputStream (bos);
+
+ streamOutTo (dos);
+ }
+
+ /**
+ * Write this LogRecord out to the given DataOutputStream.
+ *
+ *@param dos OutputStream to write to
+ *@exception IOException error during transmission
+ */
+ public void streamOutTo(DataOutputStream dos) throws IOException
+ {
+ dos.writeInt(length());
+ dos.writeInt(type());
+ dos.writeInt((int)(this.msec_ / 1000));
+ dos.writeInt(0);
+ dos.writeInt(pid());
+
+ dos.write(msgData_);
+
+ dos.flush ();
+ }
+
+ /**
+ * Return the LogRecord type.
+ */
+ public int type() { return type_; }
+
+ /**
+ * Set the LogRecord type.
+ */
+ public void type(int t) { type_ = t; }
+
+ /**
+ * Return the length of this LogRecord.
+ */
+ public int length() { return length_; }
+
+ /**
+ * Set the length of this LogRecord.
+ */
+ public void length(int l) { length_ = l; }
+
+ /**
+ * Calculate the length of this LogRecord from the size of
+ * the message and the header.
+ */
+ private void setLen(int msgLen)
+ { length(msgLen + numIntMembers * sizeofIntInBytes); }
+
+ /**
+ * Return the millisec time stamp of this LogRecord.
+ */
+ public long timeStamp() { return this.msec_; }
+
+ /**
+ * Set the millisec time stamp of this LogRecord.
+ */
+ public void timeStamp(long msec){ this.msec_ = msec; }
+
+ /**
+ * Return the PID of this LogRecord.
+ */
+ public int pid() { return pid_; }
+
+ /**
+ * Set the PID of this LogRecord.
+ */
+ public void pid(int p) { pid_ = p; }
+
+ /**
+ * Return the message of this LogRecord as a byte array.
+ */
+ public byte[] msgData() { return msgData_; }
+
+ /**
+ * Set the message of this LogRecord to a given byte array.
+ */
+ public void msgData(byte[] m)
+ {
+ int size = m.length;
+
+ if (size > MAXLOGMSGLEN)
+ size = MAXLOGMSGLEN;
+
+ this.msgData_ = new byte[size];
+
+ System.arraycopy(m, 0, msgData_, 0, size);
+
+ setLen(size);
+ }
+
+ /**
+ * Set the message of this LogRecord to a given byte array. First
+ * tries to use US-ASCII encoding, then uses the default encoding
+ * if that fails. The toString method is essentially the opposite
+ * version.
+ */
+ public void msgData(String m)
+ {
+ byte temp[] = null;
+ try {
+ temp = m.getBytes("US-ASCII");
+ } catch (UnsupportedEncodingException e) {
+ temp = m.getBytes ();
+ }
+ if (temp.length > MAXLOGMSGLEN) {
+ this.msgData_ = new byte[MAXLOGMSGLEN];
+
+ System.arraycopy(temp, 0, msgData_, 0, MAXLOGMSGLEN);
+ } else
+ this.msgData_ = temp;
+
+ setLen(msgData_.length);
+ }
+}
diff --git a/java/JACE/netsvcs/Logger/LoggingStrategy.java b/java/JACE/netsvcs/Logger/LoggingStrategy.java
new file mode 100644
index 00000000000..b7912499385
--- /dev/null
+++ b/java/JACE/netsvcs/Logger/LoggingStrategy.java
@@ -0,0 +1,35 @@
+/*************************************************
+ *
+ * = PACKAGE
+ * netsvcs.Logger
+ *
+ * = FILENAME
+ * LogMessageReceiver.java
+ *
+ *@author Everett Anderson
+ *
+ *************************************************/
+package JACE.netsvcs.Logger;
+
+import java.io.*;
+
+/**
+ * Encapsulates the handling of a LogRecord from a given host, allowing
+ * easy swapping of behavior in the logging service. Strategies could
+ * be developed to save to a file, print on a certain stream, forward
+ * to another service, etc.
+ *
+ *@see StderrStrategy
+ *@see LogRecord
+ */
+public interface LoggingStrategy
+{
+ /**
+ * Process the given LogRecord.
+ *
+ *@param hostname host from which this LogRecord originated
+ *@param record LogRecord instance to process
+ */
+ public void logRecord (String hostname,
+ LogRecord record);
+}
diff --git a/java/JACE/netsvcs/Logger/ServerLoggingAcceptor.java b/java/JACE/netsvcs/Logger/ServerLoggingAcceptor.java
new file mode 100644
index 00000000000..c0ef8831fc6
--- /dev/null
+++ b/java/JACE/netsvcs/Logger/ServerLoggingAcceptor.java
@@ -0,0 +1,147 @@
+package JACE.netsvcs.Logger;
+
+import java.util.*;
+import java.io.*;
+import java.net.*;
+import JACE.SOCK_SAP.*;
+import JACE.Connection.*;
+import JACE.OS.*;
+import JACE.Misc.*;
+import JACE.netsvcs.Server;
+
+/**
+ * Server for the logging service. Sets the default logging strategy
+ * to StderrStrategy so that logging requests are printed on the
+ * System.err stream. Other strategies can be specified on the
+ * command line.
+ * <P>
+ * <B>Valid command line arguments:</B>
+ * <PRE>
+ * -r (class name) Specify a LoggingStrategy
+ * (Default is StdErrStrategy)
+ * -p (port) Port to listen on for clients
+ * -d Enable debugging messages
+ * -a (class name) Specify ActivateStrategy
+ * (Default is thread per connection)
+ * </PRE>
+ *
+ *@see LoggingStrategy
+ *@see StderrStrategy
+ */
+public class ServerLoggingAcceptor extends Server
+{
+ /**
+ * Default constructor. Sets the default LoggingStrategy to
+ * StderrStrategy.
+ */
+ public ServerLoggingAcceptor ()
+ {
+ name ("Logging Service");
+ logStrategy_ = new StderrStrategy ();
+ }
+
+ /**
+ * Simple main program for running the logging service without the
+ * service configurator.
+ *
+ *@param args command line arguments
+ */
+ public static void main (String [] args)
+ {
+ ServerLoggingAcceptor sla = new ServerLoggingAcceptor();
+
+ sla.init(args);
+ }
+
+ /**
+ * Accessor for the LoggingStrategy
+ */
+ public LoggingStrategy loggingStrategy ()
+ {
+ return this.logStrategy_;
+ }
+
+ /**
+ * Creates a new ServerLoggingHandler instance.
+ */
+ protected SvcHandler makeSvcHandler ()
+ {
+ return new ServerLoggingHandler ();
+ }
+
+ /**
+ * Prints out the valid command line arguments. See the class
+ * description for more information. Called by Server.init when
+ * parseArgs returns -1.
+ */
+ protected void printUsage ()
+ {
+ ACE.ERROR ("Valid options:\n");
+ ACE.ERROR ("-r <class name> Specify a LoggingStrategy");
+ ACE.ERROR (" (Default is StdErrStrategy");
+ ACE.ERROR ("-p <port> Port to listen on for clients");
+ ACE.ERROR ("-d Enable debugging messages");
+ ACE.ERROR ("-a <class name> Specify ActivateStrategy");
+ ACE.ERROR (" (Default is single threaded");
+ }
+
+ /**
+ * Parses the command line arguments. See the class description
+ * for more information.
+ *
+ *@param args command line arguments
+ *@return -1 on failure, 0 on success
+ */
+ protected int parseArgs (String args[])
+ {
+ String s;
+ Object strategy;
+ GetOpt opt = new GetOpt (args, "p:r:da:", true);
+ int c = 0;
+
+ try {
+
+ while ((c = opt.next ()) != -1)
+ {
+ switch (c)
+ {
+ case 'd':
+ ACE.enableDebugging ();
+ ACE.DEBUG ("Debugging is enabled");
+ break;
+ case 'p':
+ if (!port (opt.optarg ()))
+ return -1;
+ break;
+ case 'a':
+ strategy = newStrategyInstance (opt.optarg (),
+ "ActivateStrategy");
+ if (strategy == null)
+ return -1;
+
+ activateStrategy ((ActivateStrategy) strategy);
+ break;
+ case 'r':
+ // Load the Strategy with the given name
+ strategy = newStrategyInstance (opt.optarg (),
+ "LoggingStrategy");
+ if (strategy == null)
+ return -1;
+
+ logStrategy_ = (LoggingStrategy)strategy;
+ break;
+ default:
+ ACE.ERROR ("Unknown argument: " + c);
+ return -1;
+ }
+ }
+ } catch (ArrayIndexOutOfBoundsException e) {
+ ACE.ERROR ("Option -" + (char)c + " requires an argument");
+ return -1;
+ }
+
+ return 0;
+ }
+
+ private LoggingStrategy logStrategy_;
+}
diff --git a/java/JACE/netsvcs/Logger/ServerLoggingHandler.java b/java/JACE/netsvcs/Logger/ServerLoggingHandler.java
new file mode 100644
index 00000000000..88a564c2c34
--- /dev/null
+++ b/java/JACE/netsvcs/Logger/ServerLoggingHandler.java
@@ -0,0 +1,60 @@
+/*************************************************
+ *
+ * = PACKAGE
+ * netsvcs.Logger
+ *
+ * = FILENAME
+ * ServerLoggingHandler.java
+ *
+ *@author Everett Anderson
+ *
+ *************************************************/
+package JACE.netsvcs.Logger;
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import JACE.SOCK_SAP.*;
+import JACE.Connection.*;
+import JACE.OS.*;
+import JACE.netsvcs.Handler;
+
+/**
+ *
+ * Created by ServerLoggingAcceptor to handle logging requests. This
+ * simply reads the record and hands it to the registered LoggingStrategy.
+ *
+ * @see JACE.netsvcs.Logger.ServerLoggingAcceptor
+ */
+public class ServerLoggingHandler extends Handler
+{
+ /**
+ * Reads in the given LogRecord request and hands it to the
+ * LoggingStrategy registered with the ServerLoggingAcceptor parent.
+ *
+ *@param request LogRecord instance to use
+ */
+ public void processRequest (Object request)
+ throws SocketException, EOFException, IOException
+ {
+ LogRecord rec = (LogRecord)request;
+
+ rec.streamInFrom (this.peer ().dataInputStream ());
+
+ ServerLoggingAcceptor parent = (ServerLoggingAcceptor)parent ();
+
+ parent.loggingStrategy ().logRecord (this.hostName (), rec);
+ }
+
+ /**
+ * Creates a new instance of LogRecord.
+ */
+ public Object newRequest ()
+ {
+ return new LogRecord ();
+ }
+}
+
+
+
+
diff --git a/java/JACE/netsvcs/Logger/StderrStrategy.java b/java/JACE/netsvcs/Logger/StderrStrategy.java
new file mode 100644
index 00000000000..4012cab4ab3
--- /dev/null
+++ b/java/JACE/netsvcs/Logger/StderrStrategy.java
@@ -0,0 +1,30 @@
+/*************************************************
+ *
+ * = PACKAGE
+ * netsvcs.Logger
+ *
+ * = FILENAME
+ * DefaultLMR.java
+ *
+ *
+ *@author Everett Anderson
+ *
+ *************************************************/
+package JACE.netsvcs.Logger;
+
+import java.io.*;
+
+/**
+ * Default LoggingStrategy for the logging service. This prints out the
+ * LogRecord on the System.err stream.
+ *
+ * @see JACE.netsvcs.Logger.LogRecord
+ */
+public class StderrStrategy implements LoggingStrategy
+{
+ public void logRecord (String hostname,
+ LogRecord record)
+ {
+ record.print(hostname, true, System.err);
+ }
+}
diff --git a/java/JACE/netsvcs/Logger/c.bat b/java/JACE/netsvcs/Logger/c.bat
new file mode 100644
index 00000000000..6600766df1d
--- /dev/null
+++ b/java/JACE/netsvcs/Logger/c.bat
@@ -0,0 +1,2 @@
+@echo off
+javac -d C:\Everett\JACE\classes *.java
diff --git a/java/JACE/netsvcs/Logger/package.html b/java/JACE/netsvcs/Logger/package.html
new file mode 100644
index 00000000000..84bffb246d9
--- /dev/null
+++ b/java/JACE/netsvcs/Logger/package.html
@@ -0,0 +1,17 @@
+<!-- $Id$ -->
+<HTML>
+<BODY>
+Logging Service for processing logging records received from remote hosts.
+<P>
+The strategy for how to process the records can be easily changed via the
+command line.
+<P>
+A simple test client is available in the tests directory under netsvcs\Logger.
+The service itself can either be run on the command line (by running
+ServerLoggingAcceptor) or by loading it with a ServiceConfig file (see
+the tests for the service configurator).
+
+@see JACE.netsvcs.Logger.LoggingStrategy
+@see <a href="http://www.cs.wustl.edu/~schmidt/ACE-netsvcs.html">ACE Network Services</a>
+</BODY>
+</HTML>