• No results found

Software Construction

N/A
N/A
Protected

Academic year: 2021

Share "Software Construction"

Copied!
19
0
0

Loading.... (view fulltext now)

Full text

(1)

Software Construction

Documentation and Logging

Jürg Luthiger

University of Applied Sciences Northwestern Switzerland Institute for Mobile and Distributed Systems

Learning Target

You

ƒ

can use Mock Objects as an efficient alternative

for Unit Testing

ƒ

know how to setup log4j

(2)

Institut für Mobile und Verteilte Systeme J. Luthiger 3

Documentation

ƒ

IMPORTANT

‹

All documentation is a mirror of the code

Build Documentation In, Don't Bolt It On

Tip 68 (The Pragmatic Programmer)

Internal Documentation

ƒ

Includes source code, comments, design and

test documents, …

ƒ

Documenting the source code

‹

Use Naming Convention

‹

Integrate comments into source code

‹

Use tool to generate appropriate docs out of the

source code

(3)

Institut für Mobile und Verteilte Systeme J. Luthiger 5

Java Naming Conventions

ƒ

Naming conventions make programs more

understandable by making them

‹

easier to read

‹

easier to understand

‹

easier to improve

‹

easier to detect bugs

ƒ

Use coding guidelines

‹

e.g. from SUN "Code Conventions for the JavaTM

Programming Language" (see Resources)

Tool JavaDoc

ƒ

Purpose

‹

Instead of writing and maintaining separate

documentation, the programmer writes

specially-formatted comments in the Java code itself. JavaDoc

takes these comments and transforms them into

(4)

Institut für Mobile und Verteilte Systeme J. Luthiger 7

General Format

ƒ

Start with the normal beginning of comment

delimiter (/*) followed by another (*). All

following lines start with an asterisk lined up

under the first asterisk in the first line. The last

line contains just the normal end of comment

delimiter (*/).

/**

* The number of students in the class.

* This variable must not be negative or greater than 200. */

public int numStudents;

JavaDoc Tags

ƒ

Tags for Classes

‹

@author

ƒ

Tags for Methods

‹

@param

‹

@return

‹

@exception

ƒ

Tags for Variables

(5)

Institut für Mobile und Verteilte Systeme J. Luthiger 9

Package Level Comments

ƒ

Each package can have its own package-level

doc comment source file

ƒ

The Javadoc tool will merge them into the final

documentation

ƒ

This file is named

package.html

ƒ

This file is kept in the source directory

Integrate JavaDoc into the Build Process

ƒ

Use the

javadoc

Ant Task

(6)

Institut für Mobile und Verteilte Systeme J. Luthiger 11

External Documentation

ƒ

Includes everything which is published to the

outside world like user manual, …

ƒ

Use a markup language to produce the final

documentation

‹

e.g. DocBook, Latex, …

ƒ

DocBook

‹

XML based

‹

text-oriented => easily to integrate into a VCS

‹

supports different output formats:

z HTML, PDF, Tex, …

‹

supports automation => Ant integration

Resources

ƒ

Sun Reference:

"How to Write Doc Comments for the Javadoc Tool"

http://java.sun.com/j2se/javadoc/writingdoccomments

ƒ

Code Conventions for the Java Language

http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html

ƒ

DocBook Home

http://www.docbook.org
(7)

Institut für Mobile und Verteilte Systeme J. Luthiger 13

Why Logging?

ƒ

Debuggers focus on the state of a program NOW

‹ A stack trace can you tell only how got here directly

‹ It is not possible to detect what was before this actual call

ƒ

Logging can provide information about the state of a

program or a data structure

over time

‹ Logging can reveal several classes of errors that debugger's can't

ƒ

Logging is invaluable in any system where time itself is a

factor

‹ concurrent processes ‹ real-time systems

‹ event-based application ‹ distributed environment

Brian W. Kernighan says...

As personal choice, we tend not to use debuggers beyond getting a stack trace or the value of a variable or two. One reason is that it is easy to get lost in details of complicated data structures and control flow; we find stepping through a program less productive than thinking harder and adding output statements and self-checking code at critical places. Clicking over statements takes longer than scanning the output of judiciously-placed displays. It takes less time to decide where to put print statements than to single-step to the critical section of code, even assuming we know where that is. More important, debugging

statements stay with the program; debugging sessions are transient. In "The Practice of Programming"

(8)

Institut für Mobile und Verteilte Systeme J. Luthiger 15

Approaches to Logging

ƒ

System.out.println

‹ Poor performance

‹ All or none – Example below Some people use a class like:

Class foo{

public static final boolean debug = true; public void test(){

if (debug) System.out.println(“I exist only in a test environmnet”); }

}

ƒ

Custom log api

‹ More code to maintain

‹ Classic build vs. buy (or use) decision

ƒ

Open Source (like Log4j)

Java Specification Request JSR 47

ƒ

Enable/disable logging at runtime

ƒ

Control logging at a fairly fine granularity

‹ Disable logging for specific functionality

ƒ

Bridge services that connect the logging APIs to existing

logging services (Operating System Logs, Third party

logs)

(9)

Institut für Mobile und Verteilte Systeme J. Luthiger 17

Requirements for a Logging Framework

ƒ

Configuration of the logging features should be

externalized

ƒ

Log messages should have priorities

ƒ

Logging should support different message

formats

ƒ

Logging should not slow down the program

speed, it must support message caching

Logging Frameworks

ƒ

Log4j:

Apache Open Source Project

http://jakarta.apache.org/log4j

ƒ

Java1.4 Logging

Logging API by SUN

introduced with JDK1.4

(10)

Institut für Mobile und Verteilte Systeme J. Luthiger 19

log4j background

ƒ

Originally developed by IBM at their Zurich

research lab. (www.zurich.ibm.com)

ƒ

Currently maintained by Source Forge

ƒ

Open source

ƒ

Release 1.0+ documentation at

http://logging.apache.org/log4j/docs/

Basic API

ƒ

As of 1.0, printing messages are of the form:

debug(Object message, Throwable t) debug(Object message)

If the 1st argument is a String object, it will be written in its present

form. Other objects rendered by a registered Object Renderer for its class or using the Object.toString method.

(11)

Institut für Mobile und Verteilte Systeme J. Luthiger 21

Basic Usage Example

ƒ

Standard usage:

class Foo {

Logger logger = null; public Foo(){

logger = Logger.getLogger(Foo.class); logger.info(“Constructing foo”);

}

public String doStuff(Long x){

logger.debug(“doing stuff”);

} }

Priorities

ƒ

Five recognized message priorities:

‹ DEBUG,INFO,WARN,ERROR ,FATAL

ƒ

Priority specific log methods following the the form:

‹ debug(Object message);

‹ debug(Object message, Throwable throwable);

ƒ General log methods for wrappers and custom priorities:

‹ log(Priority level, Object message);

‹ log(Priority level, Object message,Throwable throwable);

ƒ Localized log methods supporting ResourceBundles:

‹ L7dlog(Priority level, String message, Throwable throwable) ‹ L7dlog(Priority level, Object[] params, Throwable throwable) ‹ setResourceBundle(ResourceBundle);

(12)

Institut für Mobile und Verteilte Systeme J. Luthiger 23

Priorities Usage

ƒ

DEBUG

‹ Least Importance Level

‹ Log requests that are relevant while debugging the application.

ƒ

INFO

‹ Log requests that informs the user of the application about

something (e.g., informs him about application progress)

ƒ

WARN

‹ Log requests to alert about harmful situations.

ƒ

ERROR

‹ When an error is encountered (but you application can still run).

ƒ

FATAL

‹ In case of very sever errors after which your application cannot

continue any more.

Loggers

The notion of loggers lies at the heart of log4j.

ƒ

Loggers define a hierarchy and give the programmer run-time

control on which statements are printed or not.

ƒ

Loggers are assigned priorities. A log statement is printed depending on its priority and its category.

ƒ

Used to support output to multiple logs (Appenders) at the same time.
(13)

Institut für Mobile und Verteilte Systeme J. Luthiger 25

Logger Names

ƒ

Name loggers by

locality

.

‹ It turns out that instantiating a logger in each class, with the logger name equal to the fully-qualified name of the class, is a useful and straightforward approach of defining loggers.

ƒ

However, this is not the only way for naming loggers. A

common alternative is to name loggers by

functional

areas

. For example, the "database" category, "RMI"

category, "security" category, or the "XML" category.

Benefits of using fully qualified class names

ƒ

It is very simple to implement.

ƒ

It is very simple to explain to new developers.

ƒ

It automatically mirrors the application's own

modular design.

ƒ

It can be further refined at will.

ƒ

Printing the logger automatically gives

(14)

Institut für Mobile und Verteilte Systeme J. Luthiger 27

Root Logger

ƒ

If no logger is defined via a configuration file or

programmatically, then all messages will be sent to the

root logger.

ƒ

All loggers define

‹ a priority level ‹ an appender

# set log level of rental package to DEBUG

log4j.logger.ch.fhnw.edu.rental=DEBUG

# configuration of stdout appender

log4j.appender.stdout=org.apache.log4j.ConsoleAppender

Appenders

ƒ

An Appender is a object that sends log messages to their final destination.

‹ ConsoleAppender - Write log to System.out or System.err

‹ FileAppender – Write to a log file

‹ SocketAppender – Dumps log output to a socket

‹ SyslogAppender – Write to the syslog.

‹ NTEventLogAppender – Write the logs to the NT Event Log system. ‹ RollingFileAppender – After a certain size is reached it will rename the

old file and start with a new one.

‹ SocketAppender – Dumps log output to a socket

‹ SMTPAppender – Send Messages to email

‹ JMSAppender – Sends messages using Java Messaging Service ‹ …

(15)

Institut für Mobile und Verteilte Systeme J. Luthiger 29

PatternLayout – Customize your message

ƒ Used to customize the layout of a log entry. The format is closely related to conversion pattern of the printf function in ‘c’

ƒ see

http://logging.apache.org/log4j/docs/api/org/apache/log4j/PatternLayout.html

ƒ The following options are available:

‹ c - Used to output the Logger name of the logging event.

‹ C - Used to output the fully qualified class name of the caller issuing the logging request.

‹ d - Used to output the date of the logging event.

The date conversion specifier may be followed by a date format specifier enclosed between braces.

For example: %d{HH:mm:ss,SSS} or %d{dd MMM yyyy HH:mm:ss,SSS}. If no date format specifier is given then ISO8601 format is assumed

‹ F - Used to output the file name where the logging request was issued.

‹ l - Used to output location information of the caller which generated the logging event. (C+M+L)

‹ L - Used to output the line number from where the logging request was issued. Performance penalty!

PatternLayout – Customize your message

‹ n - Outputs the platform dependent line separator character or characters.

‹ M - Used to output the method name where the logging request was issued.

‹ p - Used to output the priority of the logging event.

‹ t - Used to output the name of the thread that generated the logging event.

‹ x - Used to output the NDC (nested diagnostic context) associated with the

(16)

Institut für Mobile und Verteilte Systeme J. Luthiger 31

Sample log4j.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" > <log4j:configuration>

<appender name="stdout" class="org.apache.log4j.ConsoleAppender"> <layout class="org.apache.log4j.SimpleLayout"></layout> </appender> <root> <priority value="debug"></priority> <appender-ref ref="stdout"/> </root> </log4j:configuration>

ƒ

log4j.xml will be searched first

Sample log4j.properties

log4j.rootLogger=info, stdout

# set log level of rental package to DEBUG log4j.logger.ch.fhnw.edu.rental=debug

# configuration of stdout appender

log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout

(17)

Institut für Mobile und Verteilte Systeme J. Luthiger 33

Logging performance

ƒ

Log4j claims to be fast and flexible:

‹

speed first

‹

flexibility second

ƒ

Although log4j has a many features, its first

design goal was speed.

‹

Some log4j components have been rewritten many

times to improve performance.

Cost of logging

ƒ

When logging is turned off entirely or just for a set of

priorities, the cost of a log request consists of a method

invocation plus an integer comparison.

ƒ

The typical cost of actually logging is about 100 to 300

microseconds. This is the cost of formatting the log

output and sending it to its target destination.

logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));

Example:

constructing the message parameter, i.e. converting both integer i and entry[i] to a String, and concatenating intermediate strings, regardless of whether the message will be logged or not

(18)

Institut für Mobile und Verteilte Systeme J. Luthiger 35

Hidden costs of logging

ƒ

Method invocation involves the "hidden" cost of

parameter construction.

ƒ

To avoid the parameter construction cost write:

if (logger.isDebugEnabled() {

logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));

}

Some best practices

ƒ

Don't use

e.printStackTrace()

use

log.error("Exception message", e)

instead

ƒ

Don't log exception and throw it again

ƒ

Don't swallow the Stack Trace

} catch(SQLException e){

throw new RuntimeException("DB excpetion"+e.getMessage()); }

(19)

Institut für Mobile und Verteilte Systeme J. Luthiger 37

Apache Commons Logging JCL

ƒ

The Logging package is an ultra-thin bridge

between different logging implementations.

ƒ

Commons Logging will guess (discover) the

preferred logging system and you won't need to

do any configuration of JCL at all!

ƒ

There are two base abstractions used by JCL:

‹

Log (the basic logger)

‹

LogFactory (which knows how to create Log

instances).

Using JCL

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory; ...

private Log log = LogFactory.getLog(this.getClass()); ...

if (log.isDebugEnabled()) {

log.debug("Song '" + song.getTitle() + "' added to playlist"); }

References

Related documents

The network community pharmacists received a written summary from the hospital pharmacist of medication management that included the reconciled medication list at discharge,

al(2016) indicated that technology use can exert positive influence on online engagement; Sun &amp; Rueda (2012) found that situational interest and self regulation

To return the logging of syslog messages to the default level, use the no logging history global configuration command. To return the number of messages in the history table to

At any point m time during the year, a quota holder can either use the license (by shipping the goods or by making a temporary transfer to someone else) or defer the license

The protocol that we presented in Section 3 required the prover to be able to prove the knowledge of a signature on a value that he has committed to, where we used Pedersen

This framework predicts that forms of social and political action among civilians to resist armed groups thus occur in two settings: communities with high institutional and

Two-group permutation tests based on median differences, for all treatments compared to the control, using a Bonferroni adjustment to control the FWER, may also be used..

Notwithstanding any other provision of law, funds appropriated or limited under this division and made available to carry out the new fixed guideway program of the Federal Transit