CS 580 Client-Server Spring Semester, 2004 Logging & Configuration Files |
||
---|---|---|
© 2004, All Rights Reserved, SDSU & Roger Whitney San Diego State University -- This page last updated 17-Feb-04 |
Logging
public void run() { while (true) { try { Socket client = acceptor.accept(); processRequest( client ); } catch (IOException acceptError) { // for a later lecture - this is the lecture } } }
Why logging?
What should be logged?
Normally a log entry contains several pieces of information:
Log File Examples
Assignment 1 Log file
68.7.92.191: default POST /Restaurant -> 200 text/html Tue, 17 Feb 2004 06:46:27 GMT 192.231.106.2: default POST /Restaurant -> 200 text/html Tue, 17 Feb 2004 07:08:00 GMT 192.231.106.2: default POST /Restaurant -> 200 text/html Tue, 17 Feb 2004 07:08:15 GMTApacheAccess
211.90.88.43 - - [21/Oct/2002:08:33:29 -0700] "GET /scripts/..%25%35%63../winnt/system32/cmd.exe?/c+dir HTTP/1.0" 404 303 211.90.88.43 - - [21/Oct/2002:08:33:30 -0700] "GET /scripts/..%252f../winnt/system32/cmd.exe?/c+dir HTTP/1.0" 404 303
Error
[Mon Oct 21 08:33:29 2002] [error] [client 211.90.88.43] File does not exist: /opt/etc/apache-1.3.26/htdocs/scripts/..%5c../winnt/system32/cmd.exe [Mon Oct 21 08:33:30 2002] [error] [client 211.90.88.43] File does not exist: /opt/etc/apache-1.3.26/htdocs/scripts/..%2f../winnt/system32/cmd.exe
Note that the log files contain the client IP address not the name of the machine
Dnews – A News Server
Log files
Dnews Log file examplesusers.log
Mon Oct 21 04:50:23 Bytes Read, Current Connections, Area/IPrange Mon Oct 21 04:50:23 197k 1 194.170.42.68 Mon Oct 21 04:50:23 197k 1 byu Mon Oct 21 04:50:23 0mb 2 Grand Totals
dnews.log
21 09:41:27 :info: db_piles_trim called 21 09:42:08 :info: db_pile_status 21 09:42:08 :info: db_pile_status_done 21 09:42:08 :info: dnews_status 1 21 09:42:08 :info: dnews_status 2 21 09:42:08 :info: dnews_status 3 21 09:42:08 :info: Timezone Offset 25200 dst 3600 21 09:42:16 :info: Writing list of read groups to a file for this slave 21 09:42:16 :info: Wrote 17 records 21 09:42:28 :info: db_piles_trim called
Log file formats
Log files get big
Assignment1 log file was 12.8MB
Web server logs get 10 - 100 Mbs before rotating the file
Make the log file machine parsable!
How should clients and servers log?
Basic choices:
Simple appending problems
This simplistic approach can cause problems with the following:
Logging Systems
VisualWorks – LoggingTool
Load parcel LoggingTool in parcels directory
Mainly used for debugging, but will work for our purposes
The logging tool is in the namespace Tools
If your code is a namespace other than Smalltalk you either need to:
Basic Operations Accessing the logger
LogEnvironment default “Returns a unique instance of LogEnvironment”Turn logging on
LogEnvironment default traceOn.
Turn logging off
LogEnvironment default traceOff.
Logging
LogEnvironment default log: 'Here is a real meaningless log entry'.Logging with levels
LogEnvironment default log: 'Out of memory error occured' level: #error
Logging & Levels
Most logging systems have different levels like:
LogEnvironment Logging Levels
Levels indicated by symbols
Default level is #general
To turn logging of a level on:
LogEnvironment default addDebugCategory: #error
To turn logging of a level on:
LogEnvironment default removeDebugCategory: #error
LogEnvironment & The logs
Writes logs to a stream
Until the stream is set, all log requests are ignored
If you want logs to go to a file use
| logFile | logFile := 'server.log' asFilename. LogEnvironment default debugStream: logFile writeStream
You can also use LoggingTool window
Methods Used to Log
log: aStringOrBlock
self log: aStringOrBlock level: #general
log: aStringOrBlock level: aLevel
Example
(LogEnvironment default) reset; debugStream: 'server.log' asFilename writeStream; addDebugCategory: #foo; traceOn.
LogEnvironment default log: 'log entry 1'. LogEnvironment default log: 'log entry 2' level: #bar. LogEnvironment default log: ['log entry 3'] level: #foo. LogEnvironment default debug: [Transcript show: 'Debug entry' ] level: #foo.
Note
For a server:
LogEnvironment>>log:level:
Should be modified to use printTrace:
LogEnvironment>>printTrace
Should be modified to make is a bit more parsable
LoggingTool Window
The VisualWorks logging system is mainly for debugging
Log entries can be displayed in a Window
To open the logging window:
LoggingTool open
Your classes can register with LoggingTool to
How to Register with LoggingTool
Smalltalk defineClass: #SampleClassWithLogging
SampleClassWithLogging class methods
menuItemName ^'SampleClass Messages'
debugLabelsAndValues ^(List new) add: 'Errors' -> #error; add: 'SampleClass Debug' -> #SampleClassDebug; add: 'SampleClass Commands' -> #SampleClassCommands; yourself
registerToDebug LogEnvironment default addToDebug: self
initialize self registerToDebug
log: aString level: aSymbol LogEnvironment default log: aString level: aSymbol
Sample Use of Logging Methods
SampleClassWithLogging methodsFor: 'method with logging '
foo [1 / 0] on: Exception do: [:error | self class log: Timestamp now printString , '; Error - SampleClassWithLogging>>foo; ' , error description level: #error]. self class log: Timestamp now printString , ' Sample Command ' level: #SampleClassDebug
JDK 1.4 Logging
Starting with JDK 1.4 Java API has a logging system
Supports
Log Levels
SimpleExample
import java.util.logging.*; public class SimpleLoggingExample { private static Logger logger = Logger.getLogger("edu.sdsu.cs580"); public static void main (String args[]) { new SimpleLoggingExample().someLogMessages(); } public void someLogMessages() { logger.severe( "A severe log message"); Logger.getLogger("edu.sdsu.cs580").fine( "A fine message"); logger.warning( "Be careful" ); } }Output To System.err
Default Settings
Use a ConsoleHandler
Level set to INFO
System administrator can change default settings
Five Categories of Logging MessagesConvenience Methods
Precise Log Methods
Add class and method to log messages
logp(Level logLevel, String class, String method,String message);
etc.
Logs with Resource Bundles
Add resource bundle to logp messages
logrb(Level logLevel, String class, String method, String bundlename,
String message);
etc.
Example of Different Message Types
import java.io.*; import java.util.Vector; import java.util.logging.*; public class MessageTypes { private static Logger logger = Logger.getLogger("edu.sdsu.cs580"); static { try { Handler textLog = new FileHandler("textLog.txt"); textLog.setFormatter( new SimpleFormatter()); textLog.setLevel(Level.ALL); Handler xmlLog = new FileHandler("xmlLog.txt"); xmlLog.setFormatter( new XMLFormatter()); xmlLog.setLevel(Level.ALL); logger.addHandler(textLog); logger.addHandler(xmlLog); logger.setLevel(Level.ALL); } catch (IOException fileError) { System.err.println( "Could not open log files"); } }
Example Continued public static void main (String args[]) { new MessageTypes().someLogMessages(); } public void someLogMessages() { logger.entering("MessageTypes", "someLogMessages"); Vector data = new Vector(); data.add( "Cat"); logger.log(Level.SEVERE, "Show Vector", data); logger.severe( "A severe log message"); logger.logp(Level.SEVERE, "MessageTypes", "someLogMessages", "Logp example"); try { int zeroDivide = 1/ (1 - 1); } catch (Exception zeroDivide) { logger.log(Level.SEVERE, "Exception example", zeroDivide); } logger.exiting("MessageTypes", "someLogMessages"); } }
SimpleFormatter Output
Feb 16, 2004 11:01:53 PM MessageTypes someLogMessages
FINER: ENTRY
Feb 16, 2004 11:01:53 PM MessageTypes someLogMessages
SEVERE: Show Vector
Feb 16, 2004 11:01:53 PM MessageTypes someLogMessages
SEVERE: A severe log message
Feb 16, 2004 11:01:54 PM MessageTypes someLogMessages
SEVERE: Logp example
Feb 16, 2004 11:01:54 PM MessageTypes someLogMessages
SEVERE: Exception example
java.lang.ArithmeticException: / by zero
at MessageTypes.someLogMessages(MessageTypes.java:45)
at MessageTypes.main(MessageTypes.java:32)
Feb 16, 2004 11:01:54 PM MessageTypes someLogMessages
FINER: RETURN
XMLFormatter Sample Output
<?xml version="1.0" encoding="US-ASCII" standalone="no"?>
<!DOCTYPE log SYSTEM "logger.dtd">
<log>
<record>
<date>2004-02-16T23:01:53</date>
<millis>1077001313695</millis>
<sequence>0</sequence>
<logger>edu.sdsu.cs580</logger>
<level>FINER</level>
<class>MessageTypes</class>
<method>someLogMessages</method>
<thread>10</thread>
<message>ENTRY</message>
</record>
FileHandlers
Can be set to rotate files
Can be located in temp directory
Can be set to
FileHandler(String pattern, boolean append)
Loggers
Can have
Logger Names
Logger names are arbitrary
Logger.getLogger("edu.sdsu.cs580") Logger.getLogger("foo") Logger.getLogger("")
Sun recommends using hierarchical names with format
"domain.package"
"domain.package.class"
Loggers inherit settings from “parent” logger
Logger "edu.sdsu.cs580" would inherit settings of "edu.sdsu"
Debug Example
import java.io.*; import java.util.logging.*; public class Logging { private static Logger logger = Logger.getLogger("edu.sdsu.cs580"); private static Logger debug = Logger.getLogger("debug"); // screen loging is default, as in INFO level static { try { // Parent sends log to the screen logger.setUseParentHandlers( false); Handler textLog = new FileHandler("textLog.txt"); textLog.setLevel(Level.ALL); logger.addHandler(textLog); logger.setLevel(Level.ALL); debug.setUseParentHandlers( false); Handler screenLog = new ConsoleHandler(); debug.addHandler( screenLog); debug.setLevel( Level.INFO ); } catch (IOException fileError) { System.err.println( "Could not open log files"); } }
Example continued
public static void main (String args[]) { new Logging().someLogMessages(); } public void someLogMessages() { logger.info( "A severe log message"); debug.info( "this is a debug statement"); } }
Logger Scope
Logger settings can be defined in
Sample Configuration File
# Use two loggers handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler # Default global logging level. .level= WARNING # File logger default settings # Default file output is in user's home directory (%h/). # %g – use generation numbers to distinguish rotated logs # limit = max size of each log file # count = number of output files to cycle through java.util.logging.FileHandler.pattern = %h/cs580Server%g.log java.util.logging.FileHandler.limit = 50000 java.util.logging.FileHandler.count = 3 java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter # Limit the message that are printed on the console to INFO and above. java.util.logging.ConsoleHandler.level = INFO java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter # Set levels of specific loggers edu.sdsu.level = SEVERE edu.sdsu.cs580.level = INFO
Using the Configuration File
Assume that configuration file is in
java -Djava.util.logging.config.file=cs580Log.properties yourClassGoesHere
SDSU Logger
A number of Java logging systems exits for pre-JDK 1.4 Java
SDSU Java library contains one
SDSU Logger Example
import sdsu.logging.*; public class LoggingExample { public static void main(String[] args ) throws LoggerCreationException { FileLogger.register( "MyLog"); LoggingExample test = new LoggingExample(); test.bar(); test.foo(); } public void foo() { Logger.log( "foo called"); } public void bar(){ try { Logger.log( "bar called"); int a = 1; int b = 0; int c = a/b; } catch (Exception error ) { Logger.error( "Error in bar"); Logger.error( error); } } }MyLog.log contents time='2:47:57 PM';date=10/2/00;type=Log;message='bar called'; time='2:47:57 PM';date=10/2/00;type=Error;message='Error in bar'; time='2:47:57 PM';date=10/2/00;type=Error;message='java.lang.ArithmeticException: / by zero'; time='2:47:57 PM';date=10/2/00;type=Log;message='foo called';
Types of Loggers
FileLogger - Sends log messages to file
Application Parameters & Configuration Files
Applications normal have configuration files to store
cvs co assignment2
ls -la ps -aux
Servers
Servers normally use configuration files & command line flags
Environment variables are uses much in servers (why?)
Java
Some systems have libraries to handle config files & command line arguments
JDK does not seem to have such classes
There should be a number of Java libraries that provide such support
sdsu Java library is one such library
sdsu.util.ProgramProperties
Parses
Simple Example
import sdsu.util.ProgramProperties; public class ConfigurationExample { public static void main(String args[]) { try { ProgramProperties flags = new ProgramProperties( args, "configurationFile"); String nameValue = flags.getString( "name" , "No name given"); int size = flags.getInt( "size", 0); boolean switchOn = flags.containsKey( "s"); System.out.println( " nameValue: " + nameValue); System.out.println( " size: " + size); System.out.println( " switchOn: " + switchOn); } catch (java.io.IOException readParseProblem) { System.err.println( "Program aborted on error " + readParseProblem); } } }
File "configurationFile.labeledData" name=Roger; size=12;
Sample Runs
java ConfigurationExample
Output nameValue: Roger
size: 12
switchOn: false
java ConfigurationExample -s -name Pete
Output nameValue: Pete
size: 12
switchOn: true
java ConfigurationExample -conf=otherFile
Output nameValue: Sam
size: 8
switchOn: true
VisualWorks
Command Line Arguments
CEnvironment
Cenvironment class>>commandLine
visual script.im -port 5 -host=rohan.sdsu.edu -xyzCEnvironment commandLine returns
#('visual' 'script.im' '-port' '5' '-host=rohan.sdsu.edu' '-xyz')
CEnvironment class>> userEnvironment
| user | user :=CEnvironment userEnvironment. user at: 'CVSROOT'
Registering for Flags
To avoid parsing the command line array
Classes can register to be informed of individual flags
To register add method to CommanlLineInterest class
In dependencies-pragma protocol
Example
CommanlLineInterest class>>port: aTokenReadStream <triggerAtSystemEvent: #returnFromSnapshot option: '-port'> | port | port := aTokenReadStream next asNumber. SimpleDateServer port: port. “Now make SimpleDateServer>>port: set the port.
aTokenReadStream next returns the value after the flag
CommanlLineInterest class>>port: is called on startup when flag -port exits on command line
Only supports -flag value options
Can have method triggered at
Configuration Files
VisualWorks servers use configuration files
No system wide classes for supporting them
Too easy to create own system?
Copyright ©, All rights reserved.
2004 SDSU & Roger Whitney, 5500 Campanile Drive, San Diego, CA 92182-7700 USA.
OpenContent license defines the copyright on this document.
Previous    visitors since 17-Feb-04    Next